Described in Annex B SMPTE ST 2067-21:2020 Signed-off-by: Harry Mallon <harry.mallon@codex.online> --- libavformat/mxfdec.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 6f6e8d586c..a7a1e74a0a 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -28,6 +28,7 @@ * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container + * SMPTE 2067-21 Interoperable Master Format — Application #2E * * Principle * Search for Track numbers which will identify essence element KLV packets. @@ -47,6 +48,7 @@ #include "libavutil/aes.h" #include "libavutil/avassert.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/mathematics.h" #include "libavcodec/bytestream.h" #include "libavutil/intreadwrite.h" @@ -213,6 +215,7 @@ typedef struct MXFDescriptor { UID color_primaries_ul; UID color_trc_ul; UID color_space_ul; + AVMasteringDisplayMetadata *mastering; } MXFDescriptor; typedef struct MXFIndexTableSegment { @@ -328,6 +331,10 @@ static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; +static const uint8_t mxf_mastering_display_primaries[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x01,0x00,0x00 }; +static const uint8_t mxf_mastering_display_white_point_chromaticity[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x02,0x00,0x00 }; +static const uint8_t mxf_mastering_display_maximum_luminance[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x03,0x00,0x00 }; +static const uint8_t mxf_mastering_display_minimum_luminance[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x04,0x00,0x00 }; #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) @@ -337,6 +344,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) switch ((*ctx)->type) { case Descriptor: av_freep(&((MXFDescriptor *)*ctx)->extradata); + av_freep(&((MXFDescriptor *)*ctx)->mastering); break; case MultipleDescriptor: av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); @@ -1272,6 +1280,60 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K) descriptor->pix_fmt = AV_PIX_FMT_XYZ12; } + if (IS_KLV_KEY(uid, mxf_mastering_display_primaries)) { + const int chroma_den = 50000; + int i; + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + for (i = 0; i < 3; i++) { + /* Order: large x, large y, other (i.e. RGB) */ + descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), chroma_den); + descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), chroma_den); + } + /* Check we have seen mxf_mastering_display_white_point_chromaticity */ + if (descriptor->mastering->white_point[0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_white_point_chromaticity)) { + const int chroma_den = 50000; + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), chroma_den); + descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), chroma_den); + /* Check we have seen mxf_mastering_display_primaries */ + if (descriptor->mastering->display_primaries[0][0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_maximum_luminance)) { + const int luma_den = 10000; + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), luma_den); + /* Check we have seen mxf_mastering_display_minimum_luminance */ + if (descriptor->mastering->min_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } + if (IS_KLV_KEY(uid, mxf_mastering_display_minimum_luminance)) { + const int luma_den = 10000; + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), luma_den); + /* Check we have seen mxf_mastering_display_maximum_luminance */ + if (descriptor->mastering->max_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } break; } return 0; @@ -2532,6 +2594,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id; st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id; st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id; + if (descriptor->mastering) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + (uint8_t *)descriptor->mastering, + sizeof(*descriptor->mastering)); + if (ret < 0) + goto fail_and_free; + descriptor->mastering = NULL; + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul); /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */ -- 2.28.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".