[FFmpeg-devel] [PATCH 3/4] avformat/mov: add support for reading Mastering Display Metadata Box

James Almer jamrial at gmail.com
Sat May 27 02:55:42 EEST 2017


On 5/26/2017 8:05 PM, Michael Niedermayer wrote:
> On Wed, May 17, 2017 at 09:49:40PM -0300, James Almer wrote:
>> As defined in "VP Codec ISO Media File Format Binding v1.0"
>> https://github.com/webmproject/vp9-dash/blob/master/VPCodecISOMediaFileFormatBinding.md
>>
>> Partially based on Matroska decoder code.
>>
>> Signed-off-by: James Almer <jamrial at gmail.com>
>> ---
>>  libavformat/isom.h |  2 ++
>>  libavformat/mov.c  | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 67 insertions(+)
>>
>> diff --git a/libavformat/isom.h b/libavformat/isom.h
>> index d9956cf63a..426f732247 100644
>> --- a/libavformat/isom.h
>> +++ b/libavformat/isom.h
>> @@ -27,6 +27,7 @@
>>  #include <stddef.h>
>>  #include <stdint.h>
>>  
>> +#include "libavutil/mastering_display_metadata.h"
>>  #include "libavutil/spherical.h"
>>  #include "libavutil/stereo3d.h"
>>  
>> @@ -194,6 +195,7 @@ typedef struct MOVStreamContext {
>>      AVStereo3D *stereo3d;
>>      AVSphericalMapping *spherical;
>>      size_t spherical_size;
>> +    AVMasteringDisplayMetadata *mastering;
>>  
>>      uint32_t format;
>>  
>> diff --git a/libavformat/mov.c b/libavformat/mov.c
>> index afef53b79a..0b5fd849f3 100644
>> --- a/libavformat/mov.c
>> +++ b/libavformat/mov.c
>> @@ -4612,6 +4612,60 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>>      return 0;
>>  }
>>  
>> +static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
>> +{
>> +    MOVStreamContext *sc;
>> +    const int chroma_den = 50000;
>> +    const int luma_den = 10000;
>> +    int version;
>> +
>> +    if (c->fc->nb_streams < 1)
>> +        return AVERROR_INVALIDDATA;
>> +
>> +    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
>> +
>> +    if (atom.size < 5) {
>> +        av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
>> +        return AVERROR_INVALIDDATA;
>> +    }
>> +
>> +    version = avio_r8(pb);
>> +    if (version) {
>> +        av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version);
>> +        return 0;
>> +    }
>> +    avio_skip(pb, 3); /* flags */
>> +
>> +    sc->mastering = av_mastering_display_metadata_alloc();
>> +    if (!sc->mastering)
>> +        return AVERROR(ENOMEM);
>> +
> 
>> +    sc->mastering->display_primaries[0][0] =
>> +        av_make_q(lrint(((double)avio_rb16(pb) / (1 << 16)) * chroma_den), chroma_den);
> 
> this is not optimal, precission wise
> av_d2q() should produce closer rationals
> alternativly av_reduce() can be used directly
> 
> but iam not sure why a fixed chroma_den and luma_den is fixed
> maybe iam missing something

I took the constants from hevcdec.c and matroskadec.c and basically
copied how they handled these values.
At least based on what lavf's dump.c and mkvtoolnix's mkvinfo reported,
this implementation is the most precise i tried. Using av_d2q() directly
was worse.


More information about the ffmpeg-devel mailing list