[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