00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #include <math.h>
00036 #include <time.h>
00037 
00038 #include "libavutil/opt.h"
00039 #include "libavutil/random_seed.h"
00040 #include "libavutil/timecode.h"
00041 #include "libavcodec/bytestream.h"
00042 #include "audiointerleave.h"
00043 #include "avformat.h"
00044 #include "internal.h"
00045 #include "mxf.h"
00046 
00047 static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 };
00048 static const int PAL_samples_per_frame[]  = { 1920, 0 };
00049 
00050 extern AVOutputFormat ff_mxf_d10_muxer;
00051 
00052 #define EDIT_UNITS_PER_BODY 250
00053 #define KAG_SIZE 512
00054 
00055 typedef struct {
00056     int local_tag;
00057     UID uid;
00058 } MXFLocalTagPair;
00059 
00060 typedef struct {
00061     uint8_t flags;
00062     uint64_t offset;
00063     unsigned slice_offset; 
00064     uint16_t temporal_ref;
00065 } MXFIndexEntry;
00066 
00067 typedef struct {
00068     AudioInterleaveContext aic;
00069     UID track_essence_element_key;
00070     int index;               
00071     const UID *codec_ul;
00072     int order;               
00073     int interlaced;          
00074     int temporal_reordering;
00075     AVRational aspect_ratio; 
00076     int closed_gop;          
00077 } MXFStreamContext;
00078 
00079 typedef struct {
00080     UID container_ul;
00081     UID element_ul;
00082     UID codec_ul;
00083     void (*write_desc)(AVFormatContext *, AVStream *);
00084 } MXFContainerEssenceEntry;
00085 
00086 static const struct {
00087     enum CodecID id;
00088     int index;
00089 } mxf_essence_mappings[] = {
00090     { CODEC_ID_MPEG2VIDEO, 0 },
00091     { CODEC_ID_PCM_S24LE,  1 },
00092     { CODEC_ID_PCM_S16LE,  1 },
00093     { CODEC_ID_NONE }
00094 };
00095 
00096 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st);
00097 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st);
00098 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st);
00099 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st);
00100 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st);
00101 
00102 static const MXFContainerEssenceEntry mxf_essence_container_uls[] = {
00103     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 },
00104       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
00105       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 },
00106       mxf_write_mpegvideo_desc },
00107     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },
00108       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 },
00109       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00110       mxf_write_aes3_desc },
00111     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },
00112       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 },
00113       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00114       mxf_write_wav_desc },
00115     
00116     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
00117       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00118       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 },
00119       mxf_write_cdci_desc },
00120     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },
00121       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00122       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00123       mxf_write_generic_sound_desc },
00124     
00125     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
00126       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00127       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 },
00128       mxf_write_cdci_desc },
00129     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },
00130       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00131       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00132       mxf_write_generic_sound_desc },
00133     
00134     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
00135       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00136       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 },
00137       mxf_write_cdci_desc },
00138     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },
00139       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00140       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00141       mxf_write_generic_sound_desc },
00142     
00143     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
00144       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00145       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 },
00146       mxf_write_cdci_desc },
00147     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },
00148       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00149       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00150       mxf_write_generic_sound_desc },
00151     
00152     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
00153       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00154       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 },
00155       mxf_write_cdci_desc },
00156     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },
00157       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00158       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00159       mxf_write_generic_sound_desc },
00160     
00161     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
00162       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 },
00163       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 },
00164       mxf_write_cdci_desc },
00165     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },
00166       { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 },
00167       { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },
00168       mxf_write_generic_sound_desc },
00169     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00170       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00171       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
00172       NULL },
00173 };
00174 
00175 typedef struct MXFContext {
00176     AVClass *av_class;
00177     int64_t footer_partition_offset;
00178     int essence_container_count;
00179     AVRational time_base;
00180     int header_written;
00181     MXFIndexEntry *index_entries;
00182     unsigned edit_units_count;
00183     uint64_t timestamp;   
00184     uint8_t slice_count;  
00185     int last_indexed_edit_unit;
00186     uint64_t *body_partition_offset;
00187     unsigned body_partitions_count;
00188     int last_key_index;  
00189     uint64_t duration;
00190     char *tc_opt_str;    
00191     AVTimecode tc;       
00192     AVStream *timecode_track;
00193     int timecode_base;       
00194     int edit_unit_byte_count; 
00195     uint64_t body_offset;
00196     uint32_t instance_number;
00197     uint8_t umid[16];        
00198 } MXFContext;
00199 
00200 static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
00201 static const uint8_t umid_ul[]              = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
00202 
00206 static const uint8_t op1a_ul[]                     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 };
00207 static const uint8_t footer_partition_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; 
00208 static const uint8_t primer_pack_key[]             = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
00209 static const uint8_t index_table_segment_key[]     = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 };
00210 static const uint8_t random_index_pack_key[]       = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
00211 static const uint8_t header_open_partition_key[]   = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; 
00212 static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; 
00213 static const uint8_t klv_fill_key[]                = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 };
00214 static const uint8_t body_partition_key[]          = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; 
00215 
00219 static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
00220 static const uint8_t multiple_desc_ul[]     = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
00221 
00225 static const MXFLocalTagPair mxf_local_tag_batch[] = {
00226     
00227     { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, 
00228     { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, 
00229     { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, 
00230     { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, 
00231     { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, 
00232     { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, 
00233     { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, 
00234     { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, 
00235     
00236     { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, 
00237     { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, 
00238     { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, 
00239     { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, 
00240     { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, 
00241     { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, 
00242     
00243     { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, 
00244     { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, 
00245     
00246     { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, 
00247     { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, 
00248     
00249     { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, 
00250     { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, 
00251     { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, 
00252     { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, 
00253     { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, 
00254     
00255     { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, 
00256     { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, 
00257     { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, 
00258     { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, 
00259     { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, 
00260     
00261     { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, 
00262     { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, 
00263     { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, 
00264     
00265     { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, 
00266     { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, 
00267     { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, 
00268     
00269     { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, 
00270     { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, 
00271     { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, 
00272     
00273     { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, 
00274     { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, 
00275     { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, 
00276     { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, 
00277     
00278     { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, 
00279     { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, 
00280     { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, 
00281     { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, 
00282     { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, 
00283     { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, 
00284     { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, 
00285     { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, 
00286     
00287     { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, 
00288     { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, 
00289     
00290     { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, 
00291     { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, 
00292     { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, 
00293     { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, 
00294     { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, 
00295     
00296     { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, 
00297     { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, 
00298     { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, 
00299     { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, 
00300     { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, 
00301     { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, 
00302     { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, 
00303     { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, 
00304     
00305     { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, 
00306     { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, 
00307     
00308     { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, 
00309     { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, 
00310 };
00311 
00312 static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value)
00313 {
00314     avio_write(pb, uuid_base, 12);
00315     avio_wb16(pb, type);
00316     avio_wb16(pb, value);
00317 }
00318 
00319 static void mxf_write_umid(AVFormatContext *s, int type)
00320 {
00321     MXFContext *mxf = s->priv_data;
00322     avio_write(s->pb, umid_ul, 13);
00323     avio_wb24(s->pb, mxf->instance_number);
00324     avio_write(s->pb, mxf->umid, 15);
00325     avio_w8(s->pb, type);
00326 }
00327 
00328 static void mxf_write_refs_count(AVIOContext *pb, int ref_count)
00329 {
00330     avio_wb32(pb, ref_count);
00331     avio_wb32(pb, 16);
00332 }
00333 
00334 static int klv_ber_length(uint64_t len)
00335 {
00336     if (len < 128)
00337         return 1;
00338     else
00339         return (av_log2(len) >> 3) + 2;
00340 }
00341 
00342 static int klv_encode_ber_length(AVIOContext *pb, uint64_t len)
00343 {
00344     
00345     int size;
00346     if (len < 128) {
00347         
00348         avio_w8(pb, len);
00349         return 1;
00350     }
00351 
00352     size = (av_log2(len) >> 3) + 1;
00353 
00354     
00355     avio_w8(pb, 0x80 + size);
00356     while(size) {
00357         size--;
00358         avio_w8(pb, len >> 8 * size & 0xff);
00359     }
00360     return 0;
00361 }
00362 
00363 static void klv_encode_ber4_length(AVIOContext *pb, int len)
00364 {
00365     avio_w8(pb, 0x80 + 3);
00366     avio_wb24(pb, len);
00367 }
00368 
00369 
00370 
00371 
00372 static int mxf_get_essence_container_ul_index(enum CodecID id)
00373 {
00374     int i;
00375     for (i = 0; mxf_essence_mappings[i].id; i++)
00376         if (mxf_essence_mappings[i].id == id)
00377             return mxf_essence_mappings[i].index;
00378     return -1;
00379 }
00380 
00381 static void mxf_write_primer_pack(AVFormatContext *s)
00382 {
00383     AVIOContext *pb = s->pb;
00384     int local_tag_number, i = 0;
00385 
00386     local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch);
00387 
00388     avio_write(pb, primer_pack_key, 16);
00389     klv_encode_ber_length(pb, local_tag_number * 18 + 8);
00390 
00391     avio_wb32(pb, local_tag_number); 
00392     avio_wb32(pb, 18); 
00393 
00394     for (i = 0; i < local_tag_number; i++) {
00395         avio_wb16(pb, mxf_local_tag_batch[i].local_tag);
00396         avio_write(pb, mxf_local_tag_batch[i].uid, 16);
00397     }
00398 }
00399 
00400 static void mxf_write_local_tag(AVIOContext *pb, int size, int tag)
00401 {
00402     avio_wb16(pb, tag);
00403     avio_wb16(pb, size);
00404 }
00405 
00406 static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value)
00407 {
00408     avio_write(pb, header_metadata_key, 13);
00409     avio_wb24(pb, value);
00410 }
00411 
00412 static void mxf_free(AVFormatContext *s)
00413 {
00414     int i;
00415 
00416     for (i = 0; i < s->nb_streams; i++) {
00417         AVStream *st = s->streams[i];
00418         av_freep(&st->priv_data);
00419     }
00420 }
00421 
00422 static const MXFCodecUL *mxf_get_data_definition_ul(int type)
00423 {
00424     const MXFCodecUL *uls = ff_mxf_data_definition_uls;
00425     while (uls->uid[0]) {
00426         if (type == uls->id)
00427             break;
00428         uls++;
00429     }
00430     return uls;
00431 }
00432 
00433 static void mxf_write_essence_container_refs(AVFormatContext *s)
00434 {
00435     MXFContext *c = s->priv_data;
00436     AVIOContext *pb = s->pb;
00437     int i;
00438 
00439     mxf_write_refs_count(pb, c->essence_container_count);
00440     av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
00441     for (i = 0; i < c->essence_container_count; i++) {
00442         MXFStreamContext *sc = s->streams[i]->priv_data;
00443         avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00444     }
00445 }
00446 
00447 static void mxf_write_preface(AVFormatContext *s)
00448 {
00449     MXFContext *mxf = s->priv_data;
00450     AVIOContext *pb = s->pb;
00451 
00452     mxf_write_metadata_key(pb, 0x012f00);
00453     PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
00454     klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);
00455 
00456     
00457     mxf_write_local_tag(pb, 16, 0x3C0A);
00458     mxf_write_uuid(pb, Preface, 0);
00459     PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
00460 
00461     
00462     mxf_write_local_tag(pb, 8, 0x3B02);
00463     avio_wb64(pb, mxf->timestamp);
00464 
00465     
00466     mxf_write_local_tag(pb, 2, 0x3B05);
00467     avio_wb16(pb, 258); 
00468 
00469     
00470     mxf_write_local_tag(pb, 16 + 8, 0x3B06);
00471     mxf_write_refs_count(pb, 1);
00472     mxf_write_uuid(pb, Identification, 0);
00473 
00474     
00475     mxf_write_local_tag(pb, 16, 0x3B03);
00476     mxf_write_uuid(pb, ContentStorage, 0);
00477 
00478     
00479     mxf_write_local_tag(pb, 16, 0x3B09);
00480     avio_write(pb, op1a_ul, 16);
00481 
00482     
00483     mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);
00484     mxf_write_essence_container_refs(s);
00485 
00486     
00487     mxf_write_local_tag(pb, 8, 0x3B0B);
00488     avio_wb64(pb, 0);
00489 }
00490 
00491 
00492 
00493 
00494 static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value)
00495 {
00496     int i, size = strlen(value);
00497     mxf_write_local_tag(pb, size*2, tag);
00498     for (i = 0; i < size; i++)
00499         avio_wb16(pb, value[i]);
00500 }
00501 
00502 static void mxf_write_identification(AVFormatContext *s)
00503 {
00504     MXFContext *mxf = s->priv_data;
00505     AVIOContext *pb = s->pb;
00506     const char *company = "FFmpeg";
00507     const char *product = "OP1a Muxer";
00508     const char *version;
00509     int length;
00510 
00511     mxf_write_metadata_key(pb, 0x013000);
00512     PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
00513 
00514     version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
00515         "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
00516     length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; 
00517     klv_encode_ber_length(pb, length);
00518 
00519     
00520     mxf_write_local_tag(pb, 16, 0x3C0A);
00521     mxf_write_uuid(pb, Identification, 0);
00522     PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
00523 
00524     
00525     mxf_write_local_tag(pb, 16, 0x3C09);
00526     mxf_write_uuid(pb, Identification, 1);
00527 
00528     mxf_write_local_tag_utf16(pb, 0x3C01, company); 
00529     mxf_write_local_tag_utf16(pb, 0x3C02, product); 
00530     mxf_write_local_tag_utf16(pb, 0x3C04, version); 
00531 
00532     
00533     mxf_write_local_tag(pb, 16, 0x3C05);
00534     mxf_write_uuid(pb, Identification, 2);
00535 
00536     
00537     mxf_write_local_tag(pb, 8, 0x3C06);
00538     avio_wb64(pb, mxf->timestamp);
00539 }
00540 
00541 static void mxf_write_content_storage(AVFormatContext *s)
00542 {
00543     AVIOContext *pb = s->pb;
00544 
00545     mxf_write_metadata_key(pb, 0x011800);
00546     PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
00547     klv_encode_ber_length(pb, 92);
00548 
00549     
00550     mxf_write_local_tag(pb, 16, 0x3C0A);
00551     mxf_write_uuid(pb, ContentStorage, 0);
00552     PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
00553 
00554     
00555     mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
00556     mxf_write_refs_count(pb, 2);
00557     mxf_write_uuid(pb, MaterialPackage, 0);
00558     mxf_write_uuid(pb, SourcePackage, 0);
00559 
00560     
00561     mxf_write_local_tag(pb, 8 + 16, 0x1902);
00562     mxf_write_refs_count(pb, 1);
00563     mxf_write_uuid(pb, EssenceContainerData, 0);
00564 }
00565 
00566 static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00567 {
00568     MXFContext *mxf = s->priv_data;
00569     AVIOContext *pb = s->pb;
00570     MXFStreamContext *sc = st->priv_data;
00571 
00572     mxf_write_metadata_key(pb, 0x013b00);
00573     PRINT_KEY(s, "track key", pb->buf_ptr - 16);
00574     klv_encode_ber_length(pb, 80);
00575 
00576     
00577     mxf_write_local_tag(pb, 16, 0x3C0A);
00578     mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index);
00579     PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
00580 
00581     
00582     mxf_write_local_tag(pb, 4, 0x4801);
00583     avio_wb32(pb, st->index+2);
00584 
00585     
00586     mxf_write_local_tag(pb, 4, 0x4804);
00587     if (type == MaterialPackage)
00588         avio_wb32(pb, 0); 
00589     else
00590         avio_write(pb, sc->track_essence_element_key + 12, 4);
00591 
00592     mxf_write_local_tag(pb, 8, 0x4B01);
00593     avio_wb32(pb, mxf->time_base.den);
00594     avio_wb32(pb, mxf->time_base.num);
00595 
00596     
00597     mxf_write_local_tag(pb, 8, 0x4B02);
00598     avio_wb64(pb, 0);
00599 
00600     
00601     mxf_write_local_tag(pb, 16, 0x4803);
00602     mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00603 }
00604 
00605 static const uint8_t smpte_12m_timecode_track_data_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x01,0x01,0x00,0x00,0x00 };
00606 
00607 static void mxf_write_common_fields(AVFormatContext *s, AVStream *st)
00608 {
00609     MXFContext *mxf = s->priv_data;
00610     AVIOContext *pb = s->pb;
00611 
00612     
00613     mxf_write_local_tag(pb, 16, 0x0201);
00614     if (st == mxf->timecode_track)
00615         avio_write(pb, smpte_12m_timecode_track_data_ul, 16);
00616     else {
00617         const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
00618         avio_write(pb, data_def_ul->uid, 16);
00619     }
00620 
00621     
00622     mxf_write_local_tag(pb, 8, 0x0202);
00623     avio_wb64(pb, mxf->duration);
00624 }
00625 
00626 static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00627 {
00628     MXFContext *mxf = s->priv_data;
00629     AVIOContext *pb = s->pb;
00630     enum MXFMetadataSetType component;
00631 
00632     mxf_write_metadata_key(pb, 0x010f00);
00633     PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
00634     klv_encode_ber_length(pb, 80);
00635 
00636     mxf_write_local_tag(pb, 16, 0x3C0A);
00637     mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index);
00638 
00639     PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
00640     mxf_write_common_fields(s, st);
00641 
00642     
00643     mxf_write_local_tag(pb, 16 + 8, 0x1001);
00644     mxf_write_refs_count(pb, 1);
00645     if (st == mxf->timecode_track)
00646         component = TimecodeComponent;
00647     else
00648         component = SourceClip;
00649     if (type == SourcePackage)
00650         component += TypeBottom;
00651     mxf_write_uuid(pb, component, st->index);
00652 }
00653 
00654 static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00655 {
00656     MXFContext *mxf = s->priv_data;
00657     AVIOContext *pb = s->pb;
00658 
00659     mxf_write_metadata_key(pb, 0x011400);
00660     klv_encode_ber_length(pb, 75);
00661 
00662     
00663     mxf_write_local_tag(pb, 16, 0x3C0A);
00664     mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent :
00665                    TimecodeComponent + TypeBottom, st->index);
00666 
00667     mxf_write_common_fields(s, st);
00668 
00669     
00670     mxf_write_local_tag(pb, 8, 0x1501);
00671     avio_wb64(pb, mxf->tc.start);
00672 
00673     
00674     mxf_write_local_tag(pb, 2, 0x1502);
00675     avio_wb16(pb, mxf->timecode_base);
00676 
00677     
00678     mxf_write_local_tag(pb, 1, 0x1503);
00679     avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
00680 }
00681 
00682 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
00683 {
00684     AVIOContext *pb = s->pb;
00685     int i;
00686 
00687     mxf_write_metadata_key(pb, 0x011100);
00688     PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
00689     klv_encode_ber_length(pb, 108);
00690 
00691     
00692     mxf_write_local_tag(pb, 16, 0x3C0A);
00693     mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index);
00694 
00695     PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
00696     mxf_write_common_fields(s, st);
00697 
00698     
00699     mxf_write_local_tag(pb, 8, 0x1201);
00700     avio_wb64(pb, 0);
00701 
00702     
00703     mxf_write_local_tag(pb, 32, 0x1101);
00704     if (type == SourcePackage) {
00705         for (i = 0; i < 4; i++)
00706             avio_wb64(pb, 0);
00707     } else
00708         mxf_write_umid(s, 1);
00709 
00710     
00711     mxf_write_local_tag(pb, 4, 0x1102);
00712     if (type == SourcePackage)
00713         avio_wb32(pb, 0);
00714     else
00715         avio_wb32(pb, st->index+2);
00716 }
00717 
00718 static void mxf_write_multi_descriptor(AVFormatContext *s)
00719 {
00720     MXFContext *mxf = s->priv_data;
00721     AVIOContext *pb = s->pb;
00722     const uint8_t *ul;
00723     int i;
00724 
00725     mxf_write_metadata_key(pb, 0x014400);
00726     PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
00727     klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
00728 
00729     mxf_write_local_tag(pb, 16, 0x3C0A);
00730     mxf_write_uuid(pb, MultipleDescriptor, 0);
00731     PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
00732 
00733     
00734     mxf_write_local_tag(pb, 8, 0x3001);
00735     avio_wb32(pb, mxf->time_base.den);
00736     avio_wb32(pb, mxf->time_base.num);
00737 
00738     
00739     mxf_write_local_tag(pb, 16, 0x3004);
00740     if (mxf->essence_container_count > 1)
00741         ul = multiple_desc_ul;
00742     else {
00743         MXFStreamContext *sc = s->streams[0]->priv_data;
00744         ul = mxf_essence_container_uls[sc->index].container_ul;
00745     }
00746     avio_write(pb, ul, 16);
00747 
00748     
00749     mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
00750     mxf_write_refs_count(pb, s->nb_streams);
00751     for (i = 0; i < s->nb_streams; i++)
00752         mxf_write_uuid(pb, SubDescriptor, i);
00753 }
00754 
00755 static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00756 {
00757     MXFContext *mxf = s->priv_data;
00758     MXFStreamContext *sc = st->priv_data;
00759     AVIOContext *pb = s->pb;
00760 
00761     avio_write(pb, key, 16);
00762     klv_encode_ber4_length(pb, size+20+8+12+20);
00763 
00764     mxf_write_local_tag(pb, 16, 0x3C0A);
00765     mxf_write_uuid(pb, SubDescriptor, st->index);
00766 
00767     mxf_write_local_tag(pb, 4, 0x3006);
00768     avio_wb32(pb, st->index+2);
00769 
00770     mxf_write_local_tag(pb, 8, 0x3001);
00771     avio_wb32(pb, mxf->time_base.den);
00772     avio_wb32(pb, mxf->time_base.num);
00773 
00774     mxf_write_local_tag(pb, 16, 0x3004);
00775     avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
00776 }
00777 
00778 static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 };
00779 static const UID mxf_wav_descriptor_key       = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 };
00780 static const UID mxf_aes3_descriptor_key      = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 };
00781 static const UID mxf_cdci_descriptor_key      = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 };
00782 static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 };
00783 
00784 static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00785 {
00786     MXFStreamContext *sc = st->priv_data;
00787     AVIOContext *pb = s->pb;
00788     int stored_height = (st->codec->height+15)/16*16;
00789     int display_height;
00790     int f1, f2;
00791 
00792     mxf_write_generic_desc(s, st, key, size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20);
00793 
00794     mxf_write_local_tag(pb, 4, 0x3203);
00795     avio_wb32(pb, st->codec->width);
00796 
00797     mxf_write_local_tag(pb, 4, 0x3202);
00798     avio_wb32(pb, stored_height>>sc->interlaced);
00799 
00800     mxf_write_local_tag(pb, 4, 0x3209);
00801     avio_wb32(pb, st->codec->width);
00802 
00803     if (st->codec->height == 608) 
00804         display_height = 576;
00805     else if (st->codec->height == 512)  
00806         display_height = 486;
00807     else
00808         display_height = st->codec->height;
00809 
00810     mxf_write_local_tag(pb, 4, 0x3208);
00811     avio_wb32(pb, display_height>>sc->interlaced);
00812 
00813     
00814     mxf_write_local_tag(pb, 4, 0x3301);
00815     avio_wb32(pb, 8);
00816 
00817     
00818     mxf_write_local_tag(pb, 4, 0x3302);
00819     avio_wb32(pb, 2);
00820 
00821     
00822     mxf_write_local_tag(pb, 1, 0x320C);
00823     avio_w8(pb, sc->interlaced);
00824 
00825     
00826     switch (st->codec->height) {
00827     case  576: f1 = 23; f2 = 336; break;
00828     case  608: f1 =  7; f2 = 320; break;
00829     case  480: f1 = 20; f2 = 283; break;
00830     case  512: f1 =  7; f2 = 270; break;
00831     case  720: f1 = 26; f2 =   0; break; 
00832     case 1080: f1 = 21; f2 = 584; break;
00833     default:   f1 =  0; f2 =   0; break;
00834     }
00835 
00836     if (!sc->interlaced) {
00837         f2  = 0;
00838         f1 *= 2;
00839     }
00840 
00841     mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D);
00842     avio_wb32(pb, sc->interlaced ? 2 : 1);
00843     avio_wb32(pb, 4);
00844     avio_wb32(pb, f1);
00845     if (sc->interlaced)
00846         avio_wb32(pb, f2);
00847 
00848     mxf_write_local_tag(pb, 8, 0x320E);
00849     avio_wb32(pb, sc->aspect_ratio.num);
00850     avio_wb32(pb, sc->aspect_ratio.den);
00851 
00852     mxf_write_local_tag(pb, 16, 0x3201);
00853     avio_write(pb, *sc->codec_ul, 16);
00854 }
00855 
00856 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
00857 {
00858     mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0);
00859 }
00860 
00861 static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st)
00862 {
00863     AVIOContext *pb = s->pb;
00864     int profile_and_level = (st->codec->profile<<4) | st->codec->level;
00865 
00866     mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5);
00867 
00868     
00869     mxf_write_local_tag(pb, 4, 0x8000);
00870     avio_wb32(pb, st->codec->bit_rate);
00871 
00872     
00873     mxf_write_local_tag(pb, 1, 0x8007);
00874     if (!st->codec->profile)
00875         profile_and_level |= 0x80; 
00876     avio_w8(pb, profile_and_level);
00877 }
00878 
00879 static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00880 {
00881     AVIOContext *pb = s->pb;
00882 
00883     mxf_write_generic_desc(s, st, key, size+5+12+8+8);
00884 
00885     
00886     mxf_write_local_tag(pb, 1, 0x3D02);
00887     avio_w8(pb, 1);
00888 
00889     
00890     mxf_write_local_tag(pb, 8, 0x3D03);
00891     avio_wb32(pb, st->codec->sample_rate);
00892     avio_wb32(pb, 1);
00893 
00894     mxf_write_local_tag(pb, 4, 0x3D07);
00895     avio_wb32(pb, st->codec->channels);
00896 
00897     mxf_write_local_tag(pb, 4, 0x3D01);
00898     avio_wb32(pb, av_get_bits_per_sample(st->codec->codec_id));
00899 }
00900 
00901 static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size)
00902 {
00903     AVIOContext *pb = s->pb;
00904 
00905     mxf_write_generic_sound_common(s, st, key, size+6+8);
00906 
00907     mxf_write_local_tag(pb, 2, 0x3D0A);
00908     avio_wb16(pb, st->codec->block_align);
00909 
00910     
00911     mxf_write_local_tag(pb, 4, 0x3D09);
00912     avio_wb32(pb, st->codec->block_align*st->codec->sample_rate);
00913 }
00914 
00915 static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st)
00916 {
00917     mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0);
00918 }
00919 
00920 static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st)
00921 {
00922     mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0);
00923 }
00924 
00925 static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st)
00926 {
00927     mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0);
00928 }
00929 
00930 static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
00931 {
00932     MXFContext *mxf = s->priv_data;
00933     AVIOContext *pb = s->pb;
00934     int i, track_count = s->nb_streams+1;
00935 
00936     if (type == MaterialPackage) {
00937         mxf_write_metadata_key(pb, 0x013600);
00938         PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
00939         klv_encode_ber_length(pb, 92 + 16*track_count);
00940     } else {
00941         mxf_write_metadata_key(pb, 0x013700);
00942         PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
00943         klv_encode_ber_length(pb, 112 + 16*track_count); 
00944     }
00945 
00946     
00947     mxf_write_local_tag(pb, 16, 0x3C0A);
00948     mxf_write_uuid(pb, type, 0);
00949     av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
00950     PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
00951 
00952     
00953     mxf_write_local_tag(pb, 32, 0x4401);
00954     mxf_write_umid(s, type == SourcePackage);
00955     PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
00956 
00957     
00958     mxf_write_local_tag(pb, 8, 0x4405);
00959     avio_wb64(pb, mxf->timestamp);
00960 
00961     
00962     mxf_write_local_tag(pb, 8, 0x4404);
00963     avio_wb64(pb, mxf->timestamp);
00964 
00965     
00966     mxf_write_local_tag(pb, track_count*16 + 8, 0x4403);
00967     mxf_write_refs_count(pb, track_count);
00968     mxf_write_uuid(pb, type == MaterialPackage ? Track :
00969                    Track + TypeBottom, -1); 
00970     for (i = 0; i < s->nb_streams; i++)
00971         mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
00972 
00973     
00974     if (type == SourcePackage) {
00975         mxf_write_local_tag(pb, 16, 0x4701);
00976         if (s->nb_streams > 1) {
00977             mxf_write_uuid(pb, MultipleDescriptor, 0);
00978             mxf_write_multi_descriptor(s);
00979         } else
00980             mxf_write_uuid(pb, SubDescriptor, 0);
00981     }
00982 
00983     
00984     mxf_write_track(s, mxf->timecode_track, type);
00985     mxf_write_sequence(s, mxf->timecode_track, type);
00986     mxf_write_timecode_component(s, mxf->timecode_track, type);
00987 
00988     for (i = 0; i < s->nb_streams; i++) {
00989         AVStream *st = s->streams[i];
00990         mxf_write_track(s, st, type);
00991         mxf_write_sequence(s, st, type);
00992         mxf_write_structural_component(s, st, type);
00993 
00994         if (type == SourcePackage) {
00995             MXFStreamContext *sc = st->priv_data;
00996             mxf_essence_container_uls[sc->index].write_desc(s, st);
00997         }
00998     }
00999 }
01000 
01001 static int mxf_write_essence_container_data(AVFormatContext *s)
01002 {
01003     AVIOContext *pb = s->pb;
01004 
01005     mxf_write_metadata_key(pb, 0x012300);
01006     klv_encode_ber_length(pb, 72);
01007 
01008     mxf_write_local_tag(pb, 16, 0x3C0A); 
01009     mxf_write_uuid(pb, EssenceContainerData, 0);
01010 
01011     mxf_write_local_tag(pb, 32, 0x2701); 
01012     mxf_write_umid(s, 1);
01013 
01014     mxf_write_local_tag(pb, 4, 0x3F07); 
01015     avio_wb32(pb, 1);
01016 
01017     mxf_write_local_tag(pb, 4, 0x3F06); 
01018     avio_wb32(pb, 2);
01019 
01020     return 0;
01021 }
01022 
01023 static int mxf_write_header_metadata_sets(AVFormatContext *s)
01024 {
01025     mxf_write_preface(s);
01026     mxf_write_identification(s);
01027     mxf_write_content_storage(s);
01028     mxf_write_package(s, MaterialPackage);
01029     mxf_write_package(s, SourcePackage);
01030     mxf_write_essence_container_data(s);
01031     return 0;
01032 }
01033 
01034 static unsigned klv_fill_size(uint64_t size)
01035 {
01036     unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1));
01037     if (pad < 20) 
01038         return pad + KAG_SIZE;
01039     else
01040         return pad & (KAG_SIZE-1);
01041 }
01042 
01043 static void mxf_write_index_table_segment(AVFormatContext *s)
01044 {
01045     MXFContext *mxf = s->priv_data;
01046     AVIOContext *pb = s->pb;
01047     int i, j, temporal_reordering = 0;
01048     int key_index = mxf->last_key_index;
01049 
01050     av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count);
01051 
01052     if (!mxf->edit_units_count && !mxf->edit_unit_byte_count)
01053         return;
01054 
01055     avio_write(pb, index_table_segment_key, 16);
01056 
01057     if (mxf->edit_unit_byte_count) {
01058         klv_encode_ber_length(pb, 80);
01059     } else {
01060         klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1)*6 +
01061                               12+mxf->edit_units_count*(11+mxf->slice_count*4));
01062     }
01063 
01064     
01065     mxf_write_local_tag(pb, 16, 0x3C0A);
01066     mxf_write_uuid(pb, IndexTableSegment, 0);
01067 
01068     
01069     mxf_write_local_tag(pb, 8, 0x3F0B);
01070     avio_wb32(pb, mxf->time_base.den);
01071     avio_wb32(pb, mxf->time_base.num);
01072 
01073     
01074     mxf_write_local_tag(pb, 8, 0x3F0C);
01075     avio_wb64(pb, mxf->last_indexed_edit_unit);
01076 
01077     
01078     mxf_write_local_tag(pb, 8, 0x3F0D);
01079     if (mxf->edit_unit_byte_count)
01080         avio_wb64(pb, 0); 
01081     else
01082         avio_wb64(pb, mxf->edit_units_count);
01083 
01084     
01085     mxf_write_local_tag(pb, 4, 0x3F05);
01086     avio_wb32(pb, mxf->edit_unit_byte_count);
01087 
01088     
01089     mxf_write_local_tag(pb, 4, 0x3F06);
01090     avio_wb32(pb, 2);
01091 
01092     
01093     mxf_write_local_tag(pb, 4, 0x3F07);
01094     avio_wb32(pb, 1);
01095 
01096     if (!mxf->edit_unit_byte_count) {
01097         
01098         mxf_write_local_tag(pb, 1, 0x3F08);
01099         avio_w8(pb, mxf->slice_count);
01100 
01101         
01102         mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09);
01103         avio_wb32(pb, s->nb_streams+1); 
01104         avio_wb32(pb, 6);               
01105         
01106         avio_w8(pb, 0);
01107         avio_w8(pb, 0); 
01108         avio_wb32(pb, 0); 
01109         for (i = 0; i < s->nb_streams; i++) {
01110             AVStream *st = s->streams[i];
01111             MXFStreamContext *sc = st->priv_data;
01112             avio_w8(pb, sc->temporal_reordering);
01113             if (sc->temporal_reordering)
01114                 temporal_reordering = 1;
01115             if (i == 0) { 
01116                 avio_w8(pb, 0); 
01117                 avio_wb32(pb, KAG_SIZE); 
01118             } else { 
01119                 unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size;
01120                 audio_frame_size += klv_fill_size(audio_frame_size);
01121                 avio_w8(pb, 1);
01122                 avio_wb32(pb, (i-1)*audio_frame_size); 
01123             }
01124         }
01125 
01126         mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A);
01127         avio_wb32(pb, mxf->edit_units_count);  
01128         avio_wb32(pb, 11+mxf->slice_count*4);  
01129 
01130         for (i = 0; i < mxf->edit_units_count; i++) {
01131             int temporal_offset = 0;
01132 
01133             if (!(mxf->index_entries[i].flags & 0x33)) { 
01134                 mxf->last_key_index = key_index;
01135                 key_index = i;
01136             }
01137 
01138             if (temporal_reordering) {
01139                 int pic_num_in_gop = i - key_index;
01140                 if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) {
01141                     for (j = key_index; j < mxf->edit_units_count; j++) {
01142                         if (pic_num_in_gop == mxf->index_entries[j].temporal_ref)
01143                             break;
01144                     }
01145                     if (j == mxf->edit_units_count)
01146                         av_log(s, AV_LOG_WARNING, "missing frames\n");
01147                     temporal_offset = j - key_index - pic_num_in_gop;
01148                 }
01149             }
01150             avio_w8(pb, temporal_offset);
01151 
01152             if ((mxf->index_entries[i].flags & 0x30) == 0x30) { 
01153                 avio_w8(pb, mxf->last_key_index - i);
01154             } else {
01155                 avio_w8(pb, key_index - i); 
01156                 if ((mxf->index_entries[i].flags & 0x20) == 0x20) 
01157                     mxf->last_key_index = key_index;
01158             }
01159 
01160             if (!(mxf->index_entries[i].flags & 0x33) && 
01161                 mxf->index_entries[i].flags & 0x40 && !temporal_offset)
01162                 mxf->index_entries[i].flags |= 0x80; 
01163             avio_w8(pb, mxf->index_entries[i].flags);
01164             
01165             avio_wb64(pb, mxf->index_entries[i].offset);
01166             if (s->nb_streams > 1)
01167                 avio_wb32(pb, mxf->index_entries[i].slice_offset);
01168         }
01169 
01170         mxf->last_key_index = key_index - mxf->edit_units_count;
01171         mxf->last_indexed_edit_unit += mxf->edit_units_count;
01172         mxf->edit_units_count = 0;
01173     }
01174 }
01175 
01176 static void mxf_write_klv_fill(AVFormatContext *s)
01177 {
01178     unsigned pad = klv_fill_size(avio_tell(s->pb));
01179     if (pad) {
01180         avio_write(s->pb, klv_fill_key, 16);
01181         pad -= 16 + 4;
01182         klv_encode_ber4_length(s->pb, pad);
01183         for (; pad; pad--)
01184             avio_w8(s->pb, 0);
01185         assert(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01186     }
01187 }
01188 
01189 static void mxf_write_partition(AVFormatContext *s, int bodysid,
01190                                 int indexsid,
01191                                 const uint8_t *key, int write_metadata)
01192 {
01193     MXFContext *mxf = s->priv_data;
01194     AVIOContext *pb = s->pb;
01195     int64_t header_byte_count_offset;
01196     unsigned index_byte_count = 0;
01197     uint64_t partition_offset = avio_tell(pb);
01198 
01199     if (!mxf->edit_unit_byte_count && mxf->edit_units_count)
01200         index_byte_count = 85 + 12+(s->nb_streams+1)*6 +
01201             12+mxf->edit_units_count*(11+mxf->slice_count*4);
01202     else if (mxf->edit_unit_byte_count && indexsid)
01203         index_byte_count = 80;
01204 
01205     if (index_byte_count) {
01206         
01207         index_byte_count += 16 + klv_ber_length(index_byte_count);
01208         index_byte_count += klv_fill_size(index_byte_count);
01209     }
01210 
01211     if (!memcmp(key, body_partition_key, 16)) {
01212         mxf->body_partition_offset =
01213             av_realloc(mxf->body_partition_offset,
01214                        (mxf->body_partitions_count+1)*
01215                        sizeof(*mxf->body_partition_offset));
01216         mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset;
01217     }
01218 
01219     
01220     avio_write(pb, key, 16);
01221     klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count);
01222 
01223     
01224     avio_wb16(pb, 1); 
01225     avio_wb16(pb, 2); 
01226     avio_wb32(pb, KAG_SIZE); 
01227 
01228     avio_wb64(pb, partition_offset); 
01229 
01230     if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1)
01231         avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]); 
01232     else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count)
01233         avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]); 
01234     else
01235         avio_wb64(pb, 0);
01236 
01237     avio_wb64(pb, mxf->footer_partition_offset); 
01238 
01239     
01240     header_byte_count_offset = avio_tell(pb);
01241     avio_wb64(pb, 0); 
01242 
01243     
01244     avio_wb64(pb, index_byte_count); 
01245     avio_wb32(pb, index_byte_count ? indexsid : 0); 
01246 
01247     
01248     if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) {
01249         avio_wb64(pb, mxf->body_offset);
01250     } else
01251         avio_wb64(pb, 0);
01252 
01253     avio_wb32(pb, bodysid); 
01254 
01255     
01256     avio_write(pb, op1a_ul, 16);
01257 
01258     
01259     mxf_write_essence_container_refs(s);
01260 
01261     if (write_metadata) {
01262         
01263         int64_t pos, start;
01264         unsigned header_byte_count;
01265 
01266         mxf_write_klv_fill(s);
01267         start = avio_tell(s->pb);
01268         mxf_write_primer_pack(s);
01269         mxf_write_header_metadata_sets(s);
01270         pos = avio_tell(s->pb);
01271         header_byte_count = pos - start + klv_fill_size(pos);
01272 
01273         
01274         avio_seek(pb, header_byte_count_offset, SEEK_SET);
01275         avio_wb64(pb, header_byte_count);
01276         avio_seek(pb, pos, SEEK_SET);
01277     }
01278 
01279     avio_flush(pb);
01280 }
01281 
01282 static const UID mxf_mpeg2_codec_uls[] = {
01283     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, 
01284     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 
01285     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, 
01286     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, 
01287     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, 
01288     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 
01289     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 
01290     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, 
01291     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, 
01292     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, 
01293 };
01294 
01295 static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx)
01296 {
01297     int long_gop = avctx->gop_size > 1 || avctx->has_b_frames;
01298 
01299     if (avctx->profile == 4) { 
01300         if (avctx->level == 8) 
01301             return &mxf_mpeg2_codec_uls[0+long_gop];
01302         else if (avctx->level == 4) 
01303             return &mxf_mpeg2_codec_uls[4+long_gop];
01304         else if (avctx->level == 6) 
01305             return &mxf_mpeg2_codec_uls[8+long_gop];
01306     } else if (avctx->profile == 0) { 
01307         if (avctx->level == 5) 
01308             return &mxf_mpeg2_codec_uls[2+long_gop];
01309         else if (avctx->level == 2) 
01310             return &mxf_mpeg2_codec_uls[6+long_gop];
01311     }
01312     return NULL;
01313 }
01314 
01315 static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st,
01316                                  AVPacket *pkt, MXFIndexEntry *e)
01317 {
01318     MXFStreamContext *sc = st->priv_data;
01319     uint32_t c = -1;
01320     int i;
01321 
01322     for(i = 0; i < pkt->size - 4; i++) {
01323         c = (c<<8) + pkt->data[i];
01324         if (c == 0x1b5) {
01325             if ((pkt->data[i+1] & 0xf0) == 0x10) { 
01326                 st->codec->profile = pkt->data[i+1] & 0x07;
01327                 st->codec->level   = pkt->data[i+2] >> 4;
01328             } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { 
01329                 sc->interlaced = !(pkt->data[i+5] & 0x80); 
01330                 break;
01331             }
01332         } else if (c == 0x1b8) { 
01333             if (pkt->data[i+4]>>6 & 0x01) { 
01334                 sc->closed_gop = 1;
01335                 if (e->flags & 0x40) 
01336                     e->flags |= 0x80; 
01337             }
01338         } else if (c == 0x1b3) { 
01339             e->flags |= 0x40;
01340             switch ((pkt->data[i+4]>>4) & 0xf) {
01341             case 2:  sc->aspect_ratio = (AVRational){  4,  3}; break;
01342             case 3:  sc->aspect_ratio = (AVRational){ 16,  9}; break;
01343             case 4:  sc->aspect_ratio = (AVRational){221,100}; break;
01344             default:
01345                 av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
01346                           st->codec->width, st->codec->height, 1024*1024);
01347             }
01348         } else if (c == 0x100) { 
01349             int pict_type = (pkt->data[i+2]>>3) & 0x07;
01350             e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
01351             if (pict_type == 2) { 
01352                 e->flags |= 0x22;
01353                 sc->closed_gop = 0; 
01354             } else if (pict_type == 3) { 
01355                 if (sc->closed_gop)
01356                     e->flags |= 0x13; 
01357                 else
01358                     e->flags |= 0x33;
01359                 sc->temporal_reordering = -1;
01360             } else if (!pict_type) {
01361                 av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n");
01362                 return 0;
01363             }
01364         }
01365     }
01366     if (s->oformat != &ff_mxf_d10_muxer)
01367         sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec);
01368     return !!sc->codec_ul;
01369 }
01370 
01371 static uint64_t mxf_parse_timestamp(time_t timestamp)
01372 {
01373     struct tm *time = gmtime(×tamp);
01374     if (!time)
01375         return 0;
01376     return (uint64_t)(time->tm_year+1900) << 48 |
01377            (uint64_t)(time->tm_mon+1)     << 40 |
01378            (uint64_t) time->tm_mday       << 32 |
01379                       time->tm_hour       << 24 |
01380                       time->tm_min        << 16 |
01381                       time->tm_sec        << 8;
01382 }
01383 
01384 static void mxf_gen_umid(AVFormatContext *s)
01385 {
01386     MXFContext *mxf = s->priv_data;
01387     uint32_t seed = av_get_random_seed();
01388     uint64_t umid = seed + 0x5294713400000000LL;
01389 
01390     AV_WB64(mxf->umid  , umid);
01391     AV_WB64(mxf->umid+8, umid>>8);
01392 
01393     mxf->instance_number = seed;
01394 }
01395 
01396 static int mxf_write_header(AVFormatContext *s)
01397 {
01398     MXFContext *mxf = s->priv_data;
01399     int i, ret;
01400     uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
01401     const int *samples_per_frame = NULL;
01402     AVDictionaryEntry *t;
01403     int64_t timestamp = 0;
01404 
01405     if (!s->nb_streams)
01406         return -1;
01407 
01408     for (i = 0; i < s->nb_streams; i++) {
01409         AVStream *st = s->streams[i];
01410         MXFStreamContext *sc = av_mallocz(sizeof(*sc));
01411         if (!sc)
01412             return AVERROR(ENOMEM);
01413         st->priv_data = sc;
01414 
01415         if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
01416             av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
01417             return -1;
01418         }
01419 
01420         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
01421             AVRational rate;
01422             if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) {
01423                 samples_per_frame = PAL_samples_per_frame;
01424                 mxf->time_base = (AVRational){ 1, 25 };
01425                 mxf->timecode_base = 25;
01426             } else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) {
01427                 samples_per_frame = NTSC_samples_per_frame;
01428                 mxf->time_base = (AVRational){ 1001, 30000 };
01429                 mxf->timecode_base = 30;
01430             } else {
01431                 av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n");
01432                 return -1;
01433             }
01434             rate = (AVRational){mxf->time_base.den, mxf->time_base.num};
01435             avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
01436             if (mxf->tc_opt_str)
01437                 ret = av_timecode_init_from_string(&mxf->tc, rate,
01438                                                    mxf->tc_opt_str, s);
01439             else
01440                 ret = av_timecode_init(&mxf->tc, rate, 0, 0, s);
01441             if (ret < 0)
01442                 return ret;
01443             if (s->oformat == &ff_mxf_d10_muxer) {
01444                 if (st->codec->bit_rate == 50000000)
01445                     if (mxf->time_base.den == 25) sc->index = 3;
01446                     else                          sc->index = 5;
01447                 else if (st->codec->bit_rate == 40000000)
01448                     if (mxf->time_base.den == 25) sc->index = 7;
01449                     else                          sc->index = 9;
01450                 else if (st->codec->bit_rate == 30000000)
01451                     if (mxf->time_base.den == 25) sc->index = 11;
01452                     else                          sc->index = 13;
01453                 else {
01454                     av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");
01455                     return -1;
01456                 }
01457 
01458                 mxf->edit_unit_byte_count = KAG_SIZE; 
01459                 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
01460                     mxf->time_base.num / (8*mxf->time_base.den);
01461                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01462                 mxf->edit_unit_byte_count += 16 + 4 + 4 + samples_per_frame[0]*8*4;
01463                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
01464             }
01465         } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
01466             if (st->codec->sample_rate != 48000) {
01467                 av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");
01468                 return -1;
01469             }
01470             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
01471             if (s->oformat == &ff_mxf_d10_muxer) {
01472                 if (st->index != 1) {
01473                     av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");
01474                     return -1;
01475                 }
01476                 if (st->codec->codec_id != CODEC_ID_PCM_S16LE &&
01477                     st->codec->codec_id != CODEC_ID_PCM_S24LE) {
01478                     av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");
01479                 }
01480                 sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;
01481             } else
01482             mxf->slice_count = 1;
01483         }
01484 
01485         if (!sc->index) {
01486             sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);
01487             if (sc->index == -1) {
01488                 av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
01489                        "codec not currently supported in container\n", i);
01490                 return -1;
01491             }
01492         }
01493 
01494         sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;
01495 
01496         memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);
01497         sc->track_essence_element_key[15] = present[sc->index];
01498         PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);
01499 
01500         if (!present[sc->index])
01501             mxf->essence_container_count++;
01502         present[sc->index]++;
01503     }
01504 
01505     if (s->oformat == &ff_mxf_d10_muxer) {
01506         mxf->essence_container_count = 1;
01507     }
01508 
01509     if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
01510         mxf_gen_umid(s);
01511 
01512     for (i = 0; i < s->nb_streams; i++) {
01513         MXFStreamContext *sc = s->streams[i]->priv_data;
01514         
01515         sc->track_essence_element_key[13] = present[sc->index];
01516         sc->order = AV_RB32(sc->track_essence_element_key+12);
01517     }
01518 
01519     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
01520         timestamp = ff_iso8601_to_unix_time(t->value);
01521     if (timestamp)
01522         mxf->timestamp = mxf_parse_timestamp(timestamp);
01523     mxf->duration = -1;
01524 
01525     mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
01526     if (!mxf->timecode_track)
01527         return AVERROR(ENOMEM);
01528     mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));
01529     if (!mxf->timecode_track->priv_data)
01530         return AVERROR(ENOMEM);
01531     mxf->timecode_track->index = -1;
01532 
01533     if (!samples_per_frame)
01534         samples_per_frame = PAL_samples_per_frame;
01535 
01536     if (ff_audio_interleave_init(s, samples_per_frame, mxf->time_base) < 0)
01537         return -1;
01538 
01539     return 0;
01540 }
01541 
01542 static const uint8_t system_metadata_pack_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
01543 static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 };
01544 
01545 static void mxf_write_system_item(AVFormatContext *s)
01546 {
01547     MXFContext *mxf = s->priv_data;
01548     AVIOContext *pb = s->pb;
01549     unsigned frame;
01550     uint32_t time_code;
01551 
01552     frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
01553 
01554     
01555     avio_write(pb, system_metadata_pack_key, 16);
01556     klv_encode_ber4_length(pb, 57);
01557     avio_w8(pb, 0x5c); 
01558     avio_w8(pb, 0x04); 
01559     avio_w8(pb, 0x00); 
01560     avio_wb16(pb, 0x00); 
01561     avio_wb16(pb, mxf->tc.start + frame); 
01562     if (mxf->essence_container_count > 1)
01563         avio_write(pb, multiple_desc_ul, 16);
01564     else {
01565         MXFStreamContext *sc = s->streams[0]->priv_data;
01566         avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16);
01567     }
01568     avio_w8(pb, 0);
01569     avio_wb64(pb, 0);
01570     avio_wb64(pb, 0); 
01571 
01572     avio_w8(pb, 0x81); 
01573     time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
01574     avio_wb32(pb, time_code);
01575     avio_wb32(pb, 0); 
01576     avio_wb64(pb, 0);
01577 
01578     
01579     avio_write(pb, system_metadata_package_set_key, 16);
01580     klv_encode_ber4_length(pb, 35);
01581     avio_w8(pb, 0x83); 
01582     avio_wb16(pb, 0x20);
01583     mxf_write_umid(s, 1);
01584 }
01585 
01586 static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01587 {
01588     MXFContext *mxf = s->priv_data;
01589     AVIOContext *pb = s->pb;
01590     int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num /
01591         (8*mxf->time_base.den); 
01592     int pad;
01593 
01594     packet_size += 16 + 4;
01595     packet_size += klv_fill_size(packet_size);
01596 
01597     klv_encode_ber4_length(pb, pkt->size);
01598     avio_write(pb, pkt->data, pkt->size);
01599 
01600     
01601     pad = packet_size - pkt->size - 16 - 4;
01602     if (pad > 20) {
01603         avio_write(s->pb, klv_fill_key, 16);
01604         pad -= 16 + 4;
01605         klv_encode_ber4_length(s->pb, pad);
01606         for (; pad; pad--)
01607             avio_w8(s->pb, 0);
01608         assert(!(avio_tell(s->pb) & (KAG_SIZE-1)));
01609     } else {
01610         av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
01611         for (; pad > 0; pad--)
01612             avio_w8(s->pb, 0);
01613     }
01614 }
01615 
01616 static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
01617 {
01618     MXFContext *mxf = s->priv_data;
01619     AVIOContext *pb = s->pb;
01620     int frame_size = pkt->size / st->codec->block_align;
01621     uint8_t *samples = pkt->data;
01622     uint8_t *end = pkt->data + pkt->size;
01623     int i;
01624 
01625     klv_encode_ber4_length(pb, 4 + frame_size*4*8);
01626 
01627     avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1));
01628     avio_wl16(pb, frame_size);
01629     avio_w8(pb, (1<<st->codec->channels)-1);
01630 
01631     while (samples < end) {
01632         for (i = 0; i < st->codec->channels; i++) {
01633             uint32_t sample;
01634             if (st->codec->codec_id == CODEC_ID_PCM_S24LE) {
01635                 sample = AV_RL24(samples)<< 4;
01636                 samples += 3;
01637             } else {
01638                 sample = AV_RL16(samples)<<12;
01639                 samples += 2;
01640             }
01641             avio_wl32(pb, sample | i);
01642         }
01643         for (; i < 8; i++)
01644             avio_wl32(pb, i);
01645     }
01646 }
01647 
01648 static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt)
01649 {
01650     MXFContext *mxf = s->priv_data;
01651     AVIOContext *pb = s->pb;
01652     AVStream *st = s->streams[pkt->stream_index];
01653     MXFStreamContext *sc = st->priv_data;
01654     MXFIndexEntry ie = {0};
01655 
01656     if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) {
01657         mxf->index_entries = av_realloc(mxf->index_entries,
01658             (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries));
01659         if (!mxf->index_entries) {
01660             av_log(s, AV_LOG_ERROR, "could not allocate index entries\n");
01661             return -1;
01662         }
01663     }
01664 
01665     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
01666         if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) {
01667             av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
01668             return -1;
01669         }
01670     }
01671 
01672     if (!mxf->header_written) {
01673         if (mxf->edit_unit_byte_count) {
01674             mxf_write_partition(s, 1, 2, header_open_partition_key, 1);
01675             mxf_write_klv_fill(s);
01676             mxf_write_index_table_segment(s);
01677         } else {
01678             mxf_write_partition(s, 0, 0, header_open_partition_key, 1);
01679         }
01680         mxf->header_written = 1;
01681     }
01682 
01683     if (st->index == 0) {
01684         if (!mxf->edit_unit_byte_count &&
01685             (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) &&
01686             !(ie.flags & 0x33)) { 
01687             mxf_write_klv_fill(s);
01688             mxf_write_partition(s, 1, 2, body_partition_key, 0);
01689 
01690             mxf_write_klv_fill(s);
01691             mxf_write_index_table_segment(s);
01692         }
01693 
01694         mxf_write_klv_fill(s);
01695         mxf_write_system_item(s);
01696 
01697         if (!mxf->edit_unit_byte_count) {
01698             mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset;
01699             mxf->index_entries[mxf->edit_units_count].flags = ie.flags;
01700             mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref;
01701             mxf->body_offset += KAG_SIZE; 
01702         }
01703         mxf->edit_units_count++;
01704     } else if (!mxf->edit_unit_byte_count && st->index == 1) {
01705         mxf->index_entries[mxf->edit_units_count-1].slice_offset =
01706             mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset;
01707     }
01708 
01709     mxf_write_klv_fill(s);
01710     avio_write(pb, sc->track_essence_element_key, 16); 
01711     if (s->oformat == &ff_mxf_d10_muxer) {
01712         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
01713             mxf_write_d10_video_packet(s, st, pkt);
01714         else
01715             mxf_write_d10_audio_packet(s, st, pkt);
01716     } else {
01717         klv_encode_ber4_length(pb, pkt->size); 
01718         avio_write(pb, pkt->data, pkt->size);
01719         mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size);
01720     }
01721 
01722     avio_flush(pb);
01723 
01724     return 0;
01725 }
01726 
01727 static void mxf_write_random_index_pack(AVFormatContext *s)
01728 {
01729     MXFContext *mxf = s->priv_data;
01730     AVIOContext *pb = s->pb;
01731     uint64_t pos = avio_tell(pb);
01732     int i;
01733 
01734     avio_write(pb, random_index_pack_key, 16);
01735     klv_encode_ber_length(pb, 28 + 12*mxf->body_partitions_count);
01736 
01737     if (mxf->edit_unit_byte_count)
01738         avio_wb32(pb, 1); 
01739     else
01740         avio_wb32(pb, 0);
01741     avio_wb64(pb, 0); 
01742 
01743     for (i = 0; i < mxf->body_partitions_count; i++) {
01744         avio_wb32(pb, 1); 
01745         avio_wb64(pb, mxf->body_partition_offset[i]);
01746     }
01747 
01748     avio_wb32(pb, 0); 
01749     avio_wb64(pb, mxf->footer_partition_offset);
01750 
01751     avio_wb32(pb, avio_tell(pb) - pos + 4);
01752 }
01753 
01754 static int mxf_write_footer(AVFormatContext *s)
01755 {
01756     MXFContext *mxf = s->priv_data;
01757     AVIOContext *pb = s->pb;
01758 
01759     mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count;
01760 
01761     mxf_write_klv_fill(s);
01762     mxf->footer_partition_offset = avio_tell(pb);
01763     if (mxf->edit_unit_byte_count) { 
01764         mxf_write_partition(s, 0, 0, footer_partition_key, 0);
01765     } else {
01766         mxf_write_partition(s, 0, 2, footer_partition_key, 0);
01767 
01768         mxf_write_klv_fill(s);
01769         mxf_write_index_table_segment(s);
01770     }
01771 
01772     mxf_write_klv_fill(s);
01773     mxf_write_random_index_pack(s);
01774 
01775     if (s->pb->seekable) {
01776         avio_seek(pb, 0, SEEK_SET);
01777         if (mxf->edit_unit_byte_count) {
01778             mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
01779             mxf_write_klv_fill(s);
01780             mxf_write_index_table_segment(s);
01781         } else {
01782             mxf_write_partition(s, 0, 0, header_closed_partition_key, 1);
01783         }
01784     }
01785 
01786     avio_flush(pb);
01787 
01788     ff_audio_interleave_close(s);
01789 
01790     av_freep(&mxf->index_entries);
01791     av_freep(&mxf->body_partition_offset);
01792     av_freep(&mxf->timecode_track->priv_data);
01793     av_freep(&mxf->timecode_track);
01794 
01795     mxf_free(s);
01796 
01797     return 0;
01798 }
01799 
01800 static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
01801 {
01802     int i, stream_count = 0;
01803 
01804     for (i = 0; i < s->nb_streams; i++)
01805         stream_count += !!s->streams[i]->last_in_packet_buffer;
01806 
01807     if (stream_count && (s->nb_streams == stream_count || flush)) {
01808         AVPacketList *pktl = s->packet_buffer;
01809         if (s->nb_streams != stream_count) {
01810             AVPacketList *last = NULL;
01811             
01812             while (pktl) {
01813                 if (!stream_count || pktl->pkt.stream_index == 0)
01814                     break;
01815                 last = pktl;
01816                 pktl = pktl->next;
01817                 stream_count--;
01818             }
01819             
01820             while (pktl) {
01821                 AVPacketList *next = pktl->next;
01822 
01823                 if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
01824                     s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
01825                 av_free_packet(&pktl->pkt);
01826                 av_freep(&pktl);
01827                 pktl = next;
01828             }
01829             if (last)
01830                 last->next = NULL;
01831             else {
01832                 s->packet_buffer = NULL;
01833                 s->packet_buffer_end= NULL;
01834                 goto out;
01835             }
01836             pktl = s->packet_buffer;
01837         }
01838 
01839         *out = pktl->pkt;
01840         
01841         s->packet_buffer = pktl->next;
01842         if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
01843             s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
01844         if(!s->packet_buffer)
01845             s->packet_buffer_end= NULL;
01846         av_freep(&pktl);
01847         return 1;
01848     } else {
01849     out:
01850         av_init_packet(out);
01851         return 0;
01852     }
01853 }
01854 
01855 static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
01856 {
01857     MXFStreamContext *sc  = s->streams[pkt ->stream_index]->priv_data;
01858     MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data;
01859 
01860     return next->dts > pkt->dts ||
01861         (next->dts == pkt->dts && sc->order < sc2->order);
01862 }
01863 
01864 static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
01865 {
01866     return ff_audio_rechunk_interleave(s, out, pkt, flush,
01867                                mxf_interleave_get_packet, mxf_compare_timestamps);
01868 }
01869 
01870 static const AVClass mxf_class = {
01871     .class_name = "mxf",
01872     .item_name  = av_default_item_name,
01873     .version    = LIBAVUTIL_VERSION_INT,
01874     .option     = (const AVOption[]){
01875         {AV_TIMECODE_OPTION(MXFContext, tc_opt_str, AV_OPT_FLAG_ENCODING_PARAM)},
01876         {NULL}
01877     },
01878 };
01879 
01880 static const AVClass mxf_d10_class = {
01881     .class_name = "mxf_d10",
01882     .item_name  = av_default_item_name,
01883     .version    = LIBAVUTIL_VERSION_INT,
01884     .option     = (const AVOption[]){
01885         {AV_TIMECODE_OPTION(MXFContext, tc_opt_str, AV_OPT_FLAG_ENCODING_PARAM)},
01886         {NULL}
01887     },
01888 };
01889 
01890 AVOutputFormat ff_mxf_muxer = {
01891     .name              = "mxf",
01892     .long_name         = NULL_IF_CONFIG_SMALL("Material eXchange Format"),
01893     .mime_type         = "application/mxf",
01894     .extensions        = "mxf",
01895     .priv_data_size    = sizeof(MXFContext),
01896     .audio_codec       = CODEC_ID_PCM_S16LE,
01897     .video_codec       = CODEC_ID_MPEG2VIDEO,
01898     .write_header      = mxf_write_header,
01899     .write_packet      = mxf_write_packet,
01900     .write_trailer     = mxf_write_footer,
01901     .flags             = AVFMT_NOTIMESTAMPS,
01902     .interleave_packet = mxf_interleave,
01903     .priv_class        = &mxf_class,
01904 };
01905 
01906 AVOutputFormat ff_mxf_d10_muxer = {
01907     .name              = "mxf_d10",
01908     .long_name         = NULL_IF_CONFIG_SMALL("Material eXchange Format, D-10 Mapping"),
01909     .mime_type         = "application/mxf",
01910     .priv_data_size    = sizeof(MXFContext),
01911     .audio_codec       = CODEC_ID_PCM_S16LE,
01912     .video_codec       = CODEC_ID_MPEG2VIDEO,
01913     .write_header      = mxf_write_header,
01914     .write_packet      = mxf_write_packet,
01915     .write_trailer     = mxf_write_footer,
01916     .flags             = AVFMT_NOTIMESTAMPS,
01917     .interleave_packet = mxf_interleave,
01918     .priv_class        = &mxf_d10_class,
01919 };