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

James Almer jamrial at gmail.com
Sat May 27 04:14:41 EEST 2017


On 5/26/2017 8:55 PM, James Almer wrote:
> 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.

By dump.c i mean i remuxed an mkv file with mastering metadata using the
muxer implementation of this same patchset then compared the reported
values.
By mkvinfo i mean mkv -> mov (using my muxer implementation) -> mkv
roundtrip then compared the double precision values stored in the
original mkv and the new mkv.


More information about the ffmpeg-devel mailing list