[FFmpeg-devel] [PATCH v2 3/3] avformat/mxfdec: Read Apple private Content Light Level from MXF

Harry Mallon harry.mallon at codex.online
Wed Sep 9 17:56:39 EEST 2020


* As embedded by Apple Compressor

Signed-off-by: Harry Mallon <harry.mallon at codex.online>
---
 libavformat/mxfdec.c                |  27 +++++
 tests/fate/mxf.mak                  |   4 +
 tests/ref/fate/mxf-probe-applehdr10 | 169 ++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+)
 create mode 100644 tests/ref/fate/mxf-probe-applehdr10

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]
-- 
2.28.0



More information about the ffmpeg-devel mailing list