Ok-ed parts from patch by zhentan feng.
authorZhentan Feng <spyfeng@gmail.com>
Mon, 18 Aug 2008 18:11:00 +0000 (18:11 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 18 Aug 2008 18:11:00 +0000 (18:11 +0000)
Originally committed as revision 14827 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/mxfenc.c

index 913d984..dae5c49 100644 (file)
 
 //#define DEBUG
 
 
 //#define DEBUG
 
+#include "mxf.h"
+
+typedef struct {
+    int local_tag;
+    UID uid;
+} MXFLocalTagPair;
+
+static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
+static const uint8_t umid_base[]            = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00,0x13,0x00,0x00,0x00 };
+
+/**
+ * complete key for operation pattern, partitions, and primer pack
+ */
+static const uint8_t op1a_ul[]              = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x01,0x00 };
+static const uint8_t header_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
+static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
+static const uint8_t primer_pack_key[]      = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
+
+static void mxf_write_uuid(ByteIOContext *pb, enum CodecID type, int value)
+{
+    put_buffer(pb, uuid_base, 12);
+    put_be16(pb, type);
+    put_be16(pb, value);
+}
+
+static int klv_encode_ber_length(ByteIOContext *pb, uint64_t len)
+{
+    // Determine the best BER size
+    int size;
+    if (len < 128) {
+        //short form
+        put_byte(pb, len);
+        return 1;
+    }
+
+    size = (av_log2(len) >> 3) + 1;
+
+    // long form
+    put_byte(pb, 0x80 + size);
+    while(size) {
+        size --;
+        put_byte(pb, len >> 8 * size & 0xff);
+    }
+    return 0;
+}
+
 static const MXFCodecUL *mxf_get_essence_container_ul(enum CodecID type)
 {
 static const MXFCodecUL *mxf_get_essence_container_ul(enum CodecID type)
 {
-    const MXFCodecUL *uls = mxf_essence_container_uls;
+    const MXFCodecUL *uls = ff_mxf_essence_container_uls;
     while (uls->id != CODEC_ID_NONE) {
         if (uls->id == type)
             break;
     while (uls->id != CODEC_ID_NONE) {
         if (uls->id == type)
             break;
@@ -42,29 +88,48 @@ static const MXFCodecUL *mxf_get_essence_container_ul(enum CodecID type)
     return uls;
 }
 
     return uls;
 }
 
+static int mxf_write_primer_pack(AVFormatContext *s)
+{
+    ByteIOContext *pb = s->pb;
+    int local_tag_number, i = 0;
+
+    local_tag_number = sizeof(mxf_local_tag_batch) / sizeof(MXFLocalTagPair);
+
+    put_buffer(pb, primer_pack_key, 16);
+    klv_encode_ber_length(pb, local_tag_number * 18 + 8);
+
+    put_be32(pb, local_tag_number); // local_tag num
+    put_be32(pb, 18); // item size, always 18 according to the specs
+
+    for (i = 0; i < local_tag_number; i++) {
+        put_be16(pb, mxf_local_tag_batch[i].local_tag);
+        put_buffer(pb, mxf_local_tag_batch[i].uid, 16);
+    }
+    return 0;
+}
+
+static void mxf_write_local_tag(ByteIOContext *pb, int value_size, int tag)
+{
+    put_be16(pb, tag);
+    put_be16(pb, value_size);
+}
+
 static void mxf_free(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
     AVStream *st;
     int i;
 
 static void mxf_free(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
     AVStream *st;
     int i;
 
-    av_freep(&mxf->reference.identification);
-    av_freep(mxf->reference.package);
-    av_freep(&mxf->reference.package);
-    av_freep(&mxf->reference.content_storage);
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
         av_freep(&st->priv_data);
     }
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
         av_freep(&st->priv_data);
     }
-    av_freep(mxf->reference.sub_desc);
-    av_freep(&mxf->reference.sub_desc);
-    av_freep(&mxf->reference.mul_desc);
     av_freep(&mxf->essence_container_uls);
 }
 
 static const MXFDataDefinitionUL *mxf_get_data_definition_ul(enum CodecType type)
 {
     av_freep(&mxf->essence_container_uls);
 }
 
 static const MXFDataDefinitionUL *mxf_get_data_definition_ul(enum CodecType type)
 {
-    const MXFDataDefinitionUL *uls = mxf_data_definition_uls;
+    const MXFDataDefinitionUL *uls = ff_mxf_data_definition_uls;
     while (uls->type != CODEC_TYPE_DATA) {
         if (type == uls->type)
             break;
     while (uls->type != CODEC_TYPE_DATA) {
         if (type == uls->type)
             break;