[FFmpeg-devel] [PATCH 3/4] avformat/mxfenc: write reel_name if metadata key is present

Mark Reid mindmark at gmail.com
Mon Nov 27 07:42:18 EET 2017


---
 libavformat/mxf.h    |  1 +
 libavformat/mxfenc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index 2d5b44943b..ffcc429a8b 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -47,6 +47,7 @@ enum MXFMetadataSetType {
     EssenceContainerData,
     EssenceGroup,
     TaggedValue,
+    TapeDescriptor,
 };
 
 enum MXFFrameLayout {
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index d573586fe4..8280f0236e 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -106,6 +106,7 @@ typedef struct MXFPackage {
     enum MXFMetadataSetType type;
     int instance;
     int uuid_offset;
+    struct MXFPackage *ref;
 } MXFPackage;
 
 enum ULIndex {
@@ -999,20 +1000,33 @@ static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, MXF
 
     // write source package uid, end of the reference
     mxf_write_local_tag(pb, 32, 0x1101);
-    if (package->type == SourcePackage) {
+    if (!package->ref) {
         for (i = 0; i < 4; i++)
             avio_wb64(pb, 0);
     } else
-        mxf_write_umid(s, 1);
+        mxf_write_umid(s, package->ref->instance);
 
     // write source track id
     mxf_write_local_tag(pb, 4, 0x1102);
-    if (package->type == SourcePackage)
+    if (package->type == SourcePackage && !package->ref)
         avio_wb32(pb, 0);
     else
         avio_wb32(pb, st->index+2);
 }
 
+static void mxf_write_tape_descriptor(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+
+    mxf_write_metadata_key(pb, 0x012e00);
+    PRINT_KEY(s, "tape descriptor key", pb->buf_ptr - 16);
+    klv_encode_ber_length(pb, 20);
+    mxf_write_local_tag(pb, 16, 0x3C0A);
+    mxf_write_uuid(pb, TapeDescriptor, 0);
+    PRINT_KEY(s, "tape_desc uid", pb->buf_ptr - 16);
+}
+
+
 static void mxf_write_multi_descriptor(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
@@ -1396,13 +1410,17 @@ static int mxf_write_package(AVFormatContext *s, MXFPackage *package)
     }
 
     // write multiple descriptor reference
-    if (package->type == SourcePackage) {
+    if (package->instance == 1) {
         mxf_write_local_tag(pb, 16, 0x4701);
         if (s->nb_streams > 1) {
             mxf_write_uuid(pb, MultipleDescriptor, 0);
             mxf_write_multi_descriptor(s);
         } else
             mxf_write_uuid(pb, SubDescriptor, 0);
+    } else if (package->instance == 2) {
+        mxf_write_local_tag(pb, 16, 0x4701);
+        mxf_write_uuid(pb, TapeDescriptor, 0);
+        mxf_write_tape_descriptor(s);
     }
 
     // write timecode track
@@ -1416,7 +1434,7 @@ static int mxf_write_package(AVFormatContext *s, MXFPackage *package)
         mxf_write_sequence(s, st, package);
         mxf_write_structural_component(s, st, package);
 
-        if (package->type == SourcePackage) {
+        if (package->instance == 1) {
             MXFStreamContext *sc = st->priv_data;
             mxf_essence_container_uls[sc->index].write_desc(s, st);
         }
@@ -1452,11 +1470,13 @@ static int mxf_write_header_metadata_sets(AVFormatContext *s)
     AVStream *st = NULL;
     int i;
     int track_count = 0;
-    MXFPackage packages[2] = {};
+    MXFPackage packages[3] = {};
     int package_count = 2;
     packages[0].type = MaterialPackage;
     packages[1].type = SourcePackage;
     packages[1].instance = 1;
+    packages[0].ref = &packages[1];
+
 
     if (entry = av_dict_get(s->metadata, "material_package_name", NULL, 0))
        packages[0].name = entry->value;
@@ -1474,6 +1494,26 @@ static int mxf_write_header_metadata_sets(AVFormatContext *s)
         }
     }
 
+    if (entry = av_dict_get(s->metadata, "reel_name", NULL, 0)) {
+        packages[2].name = entry->value;
+    } else {
+        /* check if any of the streams contain a reel_name */
+        for (i = 0; i < s->nb_streams; i++) {
+            st = s->streams[i];
+            if (entry = av_dict_get(st->metadata, "reel_name", NULL, 0)) {
+                packages[2].name = entry->value;
+                break;
+            }
+        }
+    }
+
+    if (packages[2].name) {
+        packages[2].type = SourcePackage;
+        packages[2].instance = 2;
+        packages[1].ref = &packages[2];
+        package_count = 3;
+    }
+
     mxf_write_preface(s);
     mxf_write_identification(s);
     mxf_write_content_storage(s, packages, package_count);
-- 
2.13.6 (Apple Git-96)



More information about the ffmpeg-devel mailing list