diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 8d315620bc..d16a7af0df 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -216,6 +216,8 @@ typedef struct MXFDescriptor { UID color_trc_ul; UID color_space_ul; AVMasteringDisplayMetadata *mastering; + AVContentLightMetadata *coll; + size_t coll_size; } MXFDescriptor; typedef struct MXFIndexTableSegment { @@ -321,6 +323,7 @@ static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 }; static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 }; static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; +static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 }; /* complete keys to match */ static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; @@ -331,6 +334,8 @@ 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_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 }; +static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 }; #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) @@ -341,6 +346,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) case Descriptor: av_freep(&((MXFDescriptor *)*ctx)->extradata); av_freep(&((MXFDescriptor *)*ctx)->mastering); + av_freep(&((MXFDescriptor *)*ctx)->coll); break; case MultipleDescriptor: av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); @@ -1312,6 +1318,19 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int descriptor->mastering->has_luminance = 1; } } + if (IS_KLV_KEY(uid, mxf_apple_coll_prefix)) { + if (!descriptor->coll) { + descriptor->coll = av_content_light_metadata_alloc(&descriptor->coll_size); + if (!descriptor->coll) + return AVERROR(ENOMEM); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_cll)) { + descriptor->coll->MaxCLL = avio_rb16(pb); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_fall)) { + descriptor->coll->MaxFALL = avio_rb16(pb); + } + } break; } return 0; @@ -2580,6 +2599,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) goto fail_and_free; descriptor->mastering = NULL; } + if (descriptor->coll) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + (uint8_t *)descriptor->coll, + descriptor->coll_size); + if (ret < 0) + goto fail_and_free; + descriptor->coll = 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. */ diff --git a/tests/fate/mxf.mak b/tests/fate/mxf.mak index 4aafc1f578..3adef939dc 100644 --- a/tests/fate/mxf.mak +++ b/tests/fate/mxf.mak @@ -33,6 +33,10 @@ FATE_MXF_PROBE-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += fate-mxf-probe-dv25 fate-mxf-probe-dv25: SRC = $(TARGET_SAMPLES)/mxf/Avid-00005.mxf fate-mxf-probe-dv25: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" +FATE_MXF_PROBE-$(call ENCDEC2, PRORES, PCM_S24LE, MXF) += fate-mxf-probe-applehdr10 +fate-mxf-probe-applehdr10: SRC = $(TARGET_SAMPLES)/mxf/Meridian-Apple_ProResProxy-HDR10.mxf +fate-mxf-probe-applehdr10: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" + FATE_MXF_REEL_NAME-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-reel_name fate-mxf-reel_name: $(SAMPLES)/mxf/Sony-00001.mxf fate-mxf-reel_name: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001.mxf -c copy -timecode 00:00:00:00 -metadata "reel_name=test_reel" -fflags +bitexact -f mxf diff --git a/tests/ref/fate/mxf-probe-applehdr10 b/tests/ref/fate/mxf-probe-applehdr10 new file mode 100644 index 0000000000..3430670c52 --- /dev/null +++ b/tests/ref/fate/mxf-probe-applehdr10 @@ -0,0 +1,169 @@ +[STREAM] +index=0 +codec_name=prores +profile=0 +codec_type=video +codec_time_base=0/1 +codec_tag_string=apco +codec_tag=0x6f637061 +width=1280 +height=720 +coded_width=1280 +coded_height=720 +closed_captions=0 +has_b_frames=0 +sample_aspect_ratio=1:1 +display_aspect_ratio=16:9 +pix_fmt=yuv422p10le +level=-99 +color_range=tv +color_space=bt2020nc +color_transfer=smpte2084 +color_primaries=bt2020 +chroma_location=unspecified +field_order=progressive +timecode=N/A +refs=1 +id=N/A +r_frame_rate=60000/1001 +avg_frame_rate=0/0 +time_base=1001/60000 +start_pts=0 +start_time=0.000000 +duration_ts=5 +duration=0.083417 +bit_rate=N/A +max_bit_rate=N/A +bits_per_raw_sample=10 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/50000 +red_y=16000/50000 +green_x=13250/50000 +green_y=34500/50000 +blue_x=7500/50000 +blue_y=3000/50000 +white_point_x=15635/50000 +white_point_y=16450/50000 +min_luminance=0/10000 +max_luminance=10000000/10000 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=100 +[/SIDE_DATA] +[/STREAM] +[STREAM] +index=1 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_time_base=1/48000 +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[STREAM] +index=2 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_time_base=1/48000 +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[FORMAT] +format_name=mxf +duration=0.083417 +bit_rate=30913698 +TAG:operational_pattern_ul=060e2b34.04010101.0d010201.01010900 +TAG:uid=0002475a-49e3-430b-85d9-3b35d180e3b5 +TAG:generation_uid=240f15ec-50ee-4285-83bf-7c17122fac0c +TAG:company_name=Apple Inc. +TAG:product_name=Compressor +TAG:product_version=4.4.7 (4.4.7) +TAG:product_uid=00000000-0000-0000-0000-000000000000 +TAG:modification_date=2020-09-08T16:18:57.036000Z +TAG:material_package_umid=0x060A2B340101010501010D201300000045843C9FE69D4B8FA90DDAAA1602A2E8 +TAG:timecode=00:01:15;26 +[/FORMAT]