[FFmpeg-devel] [Read EXIF metadata 3/3] Read EXIF metadata in JPEG input.

Thilo Borgmann thilo.borgmann at mail.de
Sun Aug 11 19:01:10 CEST 2013


Am 11.08.13 14:30, schrieb Michael Niedermayer:
> On Sat, Aug 10, 2013 at 10:35:40PM +0200, Thilo Borgmann wrote:
>> Am 10.08.13 22:34, schrieb Thilo Borgmann:
>>> 3/3 rev 6
>>>
>>> -Thilo
>>>
>>
> 
>>  Changelog             |    1 +
>>  libavcodec/Makefile   |    2 +-
>>  libavcodec/mjpegdec.c |   43 +++++++++++++++++++++++++++++++++++++++++++
>>  libavcodec/mjpegdec.h |    1 +
>>  4 files changed, 46 insertions(+), 1 deletion(-)
>> 06d1a65e7deba2853ef41a1a232590e793e46cb9  0003-Read-EXIF-metadata-in-JPEG-input.patch
>> From d88397cd308cb086f1416041289e401246b7873c Mon Sep 17 00:00:00 2001
>> From: Thilo Borgmann <thilo.borgmann at googlemail.com>
>> Date: Sat, 10 Aug 2013 22:32:00 +0200
>> Subject: [PATCH 3/3] Read EXIF metadata in JPEG input.
>>
>> ---
>>  Changelog             |    1 +
>>  libavcodec/Makefile   |    2 +-
>>  libavcodec/mjpegdec.c |   43 +++++++++++++++++++++++++++++++++++++++++++
>>  libavcodec/mjpegdec.h |    1 +
>>  4 files changed, 46 insertions(+), 1 deletions(-)
>>
>> diff --git a/Changelog b/Changelog
>> index f1d7fa6..4a6c60c 100644
>> --- a/Changelog
>> +++ b/Changelog
>> @@ -14,6 +14,7 @@ version <next>
>>  - ffmpeg -t option can now be used for inputs, to limit the duration of
>>    data read from an input file
>>  - incomplete Voxware MetaSound decoder
>> +- read EXIF metadata from JPEG
>>  
>>  
>>  version 2.0:
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index 487153c..6c800e0 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -265,7 +265,7 @@ OBJS-$(CONFIG_METASOUND_DECODER)       += metasound.o metasound_data.o \
>>                                            twinvq.o
>>  OBJS-$(CONFIG_MICRODVD_DECODER)        += microdvddec.o ass.o
>>  OBJS-$(CONFIG_MIMIC_DECODER)           += mimic.o
>> -OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o mjpeg.o
>> +OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o mjpeg.o exif.o tiff_common.o
>>  OBJS-$(CONFIG_MJPEG_ENCODER)           += mjpegenc.o mjpeg.o
>>  OBJS-$(CONFIG_MJPEGB_DECODER)          += mjpegbdec.o mjpegdec.o mjpeg.o
>>  OBJS-$(CONFIG_MLP_DECODER)             += mlpdec.o mlpdsp.o
>> diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
>> index c92738f..ac20830 100644
>> --- a/libavcodec/mjpegdec.c
>> +++ b/libavcodec/mjpegdec.c
>> @@ -39,6 +39,9 @@
>>  #include "mjpeg.h"
>>  #include "mjpegdec.h"
>>  #include "jpeglsdec.h"
>> +#include "tiff.h"
>> +#include "exif.h"
>> +#include "bytestream.h"
>>  
>>  
>>  static int build_vlc(VLC *vlc, const uint8_t *bits_table,
>> @@ -1493,6 +1496,43 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
>>          goto out;
>>      }
>>  
>> +    /* EXIF metadata */
>> +    if (s->start_code == APP1 && id == AV_RB32("Exif")) {
>> +        GetByteContext gbytes;
>> +        int ret, le, ifd_offset, bytes_read;
>> +        const uint8_t *aligned;
>> +
>> +        skip_bits(&s->gb, 16); // skip padding
>> +        len -= 2;
>> +
>> +        // init byte wise reading
>> +        aligned = align_get_bits(&s->gb);
>> +        bytestream2_init(&gbytes, aligned, get_bits_left(&s->gb) >> 3);
>> +
>> +        // read TIFF header
>> +        ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
>> +        if (ret) {
>> +            av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n");
>> +            return ret;
>> +        }
>> +
>> +        bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
>> +
>> +        // read 0th IFDs and store the metadata
>> +        // (return values > 0 indicate the presence of subimage metadata)
>> +        ret = ff_exif_decode_ifd(s->avctx, &gbytes, le, &s->exif_metadata);
>> +        if (ret < 0) {
>> +            av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n");
>> +            return ret;
>> +        }
>> +
>> +        bytes_read = bytestream2_tell(&gbytes);
>> +        skip_bits(&s->gb, bytes_read << 3);
>> +        len -= bytes_read;
>> +
>> +        goto out;
>> +    }
>> +
>>      /* Apple MJPEG-A */
>>      if ((s->start_code == APP1) && (len > (0x28 - 8))) {
>>          id   = get_bits_long(&s->gb, 32);
>> @@ -1916,6 +1956,9 @@ the_end:
>>          }
>>      }
>>  
>> +    av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
>> +    av_dict_free(&s->exif_metadata);
> 
> this looks like it could leak on errors

left-overs from previous frames are freed from the context at the beginning of
decode_frame() and decode_end() to catch the last frame's possible left-overs.

If 'data' is a problem, I need more hints.

Updated Patchset rebased on latest tiff.c changes to come in a few seconds.

Thanks!
-Thilo



More information about the ffmpeg-devel mailing list