d7ed84704f0bbd8c409d0e739e01e0e5fec282a2
[ffmpeg.git] / libavformat / mxfenc.c
1 /*
2  * MXF muxer
3  * Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /*
23  * References
24  * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
25  * SMPTE 377M MXF File Format Specifications
26  * SMPTE 379M MXF Generic Container
27  * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
28  * SMPTE RP210: SMPTE Metadata Dictionary
29  * SMPTE RP224: Registry of SMPTE Universal Labels
30  */
31
32 //#define DEBUG
33
34 #include "mxf.h"
35
36 typedef struct {
37     int local_tag;
38     UID uid;
39 } MXFLocalTagPair;
40
41 typedef struct {
42     UID track_essence_element_key;
43 } MXFStreamContext;
44
45 typedef struct MXFContext {
46     int64_t header_byte_count;
47     int64_t header_byte_count_offset;
48     int64_t header_footer_partition_offset;
49     int essence_container_count;
50 } MXFContext;
51
52 typedef struct {
53     const UID key;
54     void (*write)();
55     enum CodecType type;
56 } MXFDescriptorWriteTableEntry;
57
58 static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
59 static const uint8_t umid_base[]            = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00,0x13,0x00,0x00,0x00 };
60
61 /**
62  * complete key for operation pattern, partitions, and primer pack
63  */
64 static const uint8_t op1a_ul[]              = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x01,0x00 };
65 static const uint8_t header_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
66 static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
67 static const uint8_t primer_pack_key[]      = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
68
69 /**
70  * partial key for header metadata
71  */
72 static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
73
74 static const MXFCodecUL mxf_essence_element_key[] = {
75     { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, 14, CODEC_ID_MPEG2VIDEO},
76     { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE},
77     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE},
78 };
79
80 static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
81
82 /**
83  * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
84  */
85 static const MXFLocalTagPair mxf_local_tag_batch[] = {
86     // preface set
87     { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
88     { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
89     { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
90     { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
91     { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
92     { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
93     { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
94     { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
95     // Identification
96     { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
97     { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
98     { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
99     { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x04,0x00,0x00,0x00}}, /* Version String */
100     { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
101     { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
102     // Content Storage
103     { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
104     // Essence Container Data
105     { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
106     { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
107     // Package
108     { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
109     { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
110     { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
111     { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
112     { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
113     // Track
114     { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
115     { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x03,0x00,0x00}}, /* Track Numberr */
116     { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
117     { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
118     { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
119     // Sequence
120     { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
121     { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
122     { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
123     // Source Clip
124     { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Start position */
125     { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
126     { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
127     // file descriptor
128     { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* sub descriptor uid*/
129     { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
130     { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
131     { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* essence container ul */
132     // generic picture eseence descriptor
133     { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* stored width */
134     { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* stored heigth */
135     { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* aspect ratio*/
136     { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* picture essence coding*/
137     // generic sound essence descriptor
138     { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* audio sampling rate */
139     { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* channel count */
140     { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* quantization bits */
141     { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* sound essence compression */
142 };
143
144 static void mxf_write_uuid(ByteIOContext *pb, enum CodecID type, int value)
145 {
146     put_buffer(pb, uuid_base, 12);
147     put_be16(pb, type);
148     put_be16(pb, value);
149 }
150
151 static void mxf_write_umid(ByteIOContext *pb, enum CodecID type, int value)
152 {
153     put_buffer(pb, umid_base, 16);
154     mxf_write_uuid(pb, type, value);
155 }
156
157 static void mxf_write_refs_count(ByteIOContext *pb, int ref_count)
158 {
159     put_be32(pb, ref_count);
160     put_be32(pb, 16);
161 }
162
163 static int klv_encode_ber_length(ByteIOContext *pb, uint64_t len)
164 {
165     // Determine the best BER size
166     int size;
167     if (len < 128) {
168         //short form
169         put_byte(pb, len);
170         return 1;
171     }
172
173     size = (av_log2(len) >> 3) + 1;
174
175     // long form
176     put_byte(pb, 0x80 + size);
177     while(size) {
178         size --;
179         put_byte(pb, len >> 8 * size & 0xff);
180     }
181     return 0;
182 }
183
184 static const MXFCodecUL *mxf_get_essence_container_ul(enum CodecID type)
185 {
186     const MXFCodecUL *uls = ff_mxf_essence_container_uls;
187     while (uls->id != CODEC_ID_NONE) {
188         if (uls->id == type)
189             break;
190         uls++;
191     }
192     return uls;
193 }
194
195 static void mxf_write_primer_pack(AVFormatContext *s)
196 {
197     ByteIOContext *pb = s->pb;
198     int local_tag_number, i = 0;
199
200     local_tag_number = sizeof(mxf_local_tag_batch) / sizeof(MXFLocalTagPair);
201
202     put_buffer(pb, primer_pack_key, 16);
203     klv_encode_ber_length(pb, local_tag_number * 18 + 8);
204
205     put_be32(pb, local_tag_number); // local_tag num
206     put_be32(pb, 18); // item size, always 18 according to the specs
207
208     for (i = 0; i < local_tag_number; i++) {
209         put_be16(pb, mxf_local_tag_batch[i].local_tag);
210         put_buffer(pb, mxf_local_tag_batch[i].uid, 16);
211     }
212 }
213
214 static void mxf_write_local_tag(ByteIOContext *pb, int value_size, int tag)
215 {
216     put_be16(pb, tag);
217     put_be16(pb, value_size);
218 }
219
220 static void mxf_write_metadata_key(ByteIOContext *pb, unsigned int value)
221 {
222     put_buffer(pb, header_metadata_key, 13);
223     put_be24(pb, value);
224 }
225
226 static void mxf_free(AVFormatContext *s)
227 {
228     AVStream *st;
229     int i;
230
231     for (i = 0; i < s->nb_streams; i++) {
232         st = s->streams[i];
233         av_freep(&st->priv_data);
234     }
235 }
236
237 static const MXFDataDefinitionUL *mxf_get_data_definition_ul(enum CodecType type)
238 {
239     const MXFDataDefinitionUL *uls = ff_mxf_data_definition_uls;
240     while (uls->type != CODEC_TYPE_DATA) {
241         if (type == uls->type)
242             break;
243         uls ++;
244     }
245     return uls;
246 }
247
248 static void mxf_write_preface(AVFormatContext *s)
249 {
250     MXFContext *mxf = s->priv_data;
251     ByteIOContext *pb = s->pb;
252
253     mxf_write_metadata_key(pb, 0x012f00);
254     PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
255     klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);
256
257     // write preface set uid
258     mxf_write_local_tag(pb, 16, 0x3C0A);
259     mxf_write_uuid(pb, Preface, 0);
260     PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
261
262     // write create date as unknown
263     mxf_write_local_tag(pb, 8, 0x3B02);
264     put_be64(pb, 0);
265
266     // write version
267     mxf_write_local_tag(pb, 2, 0x3B05);
268     put_be16(pb, 1);
269
270     // write identification_refs
271     mxf_write_local_tag(pb, 16 + 8, 0x3B06);
272     mxf_write_refs_count(pb, 1);
273     mxf_write_uuid(pb, Identification, 0);
274
275     // write content_storage_refs
276     mxf_write_local_tag(pb, 16, 0x3B03);
277     mxf_write_uuid(pb, ContentStorage, 0);
278
279     mxf_write_local_tag(pb, 16, 0x3B09);
280     put_buffer(pb, op1a_ul, 16);
281
282     // write essence_container_refs
283     mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);
284     mxf_write_essence_container_refs(s, 1);
285
286     // write dm_scheme_refs
287     mxf_write_local_tag(pb, 8, 0x3B0B);
288     put_be64(pb, 0);
289 }
290
291 static void mxf_write_identification(AVFormatContext *s)
292 {
293     ByteIOContext *pb = s->pb;
294     int length, company_name_len, product_name_len, version_string_len;
295
296     mxf_write_metadata_key(pb, 0x013000);
297     PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
298     company_name_len = sizeof("FFmpeg");
299     product_name_len = sizeof("OP1a Muxer");
300
301     length = 80 + company_name_len + product_name_len;
302     if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
303         version_string_len = sizeof(LIBAVFORMAT_IDENT);
304         length += 4 + version_string_len;
305     }
306     klv_encode_ber_length(pb, length);
307
308     // write uid
309     mxf_write_local_tag(pb, 16, 0x3C0A);
310     mxf_write_uuid(pb, Identification, 0);
311     PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
312     // write generation uid
313     mxf_write_local_tag(pb, 16, 0x3C09);
314     mxf_write_uuid(pb, Identification, 1);
315
316     mxf_write_local_tag(pb, company_name_len, 0x3C01);
317     put_buffer(pb, "FFmpeg", company_name_len);
318
319     mxf_write_local_tag(pb, product_name_len, 0x3C02);
320     put_buffer(pb, "OP1a Muxer", product_name_len);
321
322     if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
323         mxf_write_local_tag(pb, version_string_len, 0x3C04);
324         put_buffer(pb, LIBAVFORMAT_IDENT, version_string_len);
325     }
326
327     // write product uid
328     mxf_write_local_tag(pb, 16, 0x3C05);
329     mxf_write_uuid(pb, Identification, 2);
330
331     // write modified date
332     mxf_write_local_tag(pb, 8, 0x3C06);
333     put_be64(pb, 0);
334 }
335
336 static void mxf_write_content_storage(AVFormatContext *s)
337 {
338     ByteIOContext *pb = s->pb;
339
340     mxf_write_metadata_key(pb, 0x011800);
341     PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
342     klv_encode_ber_length(pb, 64);
343
344     // write uid
345     mxf_write_local_tag(pb, 16, 0x3C0A);
346     mxf_write_uuid(pb, ContentStorage, 0);
347     PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
348     // write package reference
349     mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
350     mxf_write_refs_count(pb, 2);
351     mxf_write_uuid(pb, MaterialPackage, 0);
352     mxf_write_uuid(pb, SourcePackage, 0);
353 }
354
355 static void mxf_write_common_fields(    ByteIOContext *pb, AVStream *st)
356 {
357     const MXFDataDefinitionUL * data_def_ul;
358
359     // find data define uls
360     data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
361     mxf_write_local_tag(pb, 16, 0x0201);
362     put_buffer(pb, data_def_ul->uid, 16);
363
364     // write duration
365     mxf_write_local_tag(pb, 8, 0x0202);
366     put_be64(pb, st->duration);
367 }
368
369 static int mux_write_packet(AVFormatContext *s, AVPacket *pkt)
370 {
371     ByteIOContext *pb = s->pb;
372     AVStream *st = s->streams[pkt->stream_index];
373     MXFStreamContext *sc = st->priv_data;
374
375     put_buffer(pb, sc->track_essence_element_key, 16); // write key
376     klv_encode_ber_length(pb, pkt->size); // write length
377     put_buffer(pb, pkt->data, pkt->size); // write value
378
379     put_flush_packet(pb);
380     return 0;
381 }
382
383 static void mxf_write_multi_descriptor(AVFormatContext *s)
384 {
385     ByteIOContext *pb = s->pb;
386     int i;
387
388     mxf_write_metadata_key(pb, 0x014400);
389     PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
390     klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
391
392     mxf_write_local_tag(pb, 16, 0x3C0A);
393     mxf_write_uuid(pb, MultipleDescriptor, 0);
394     PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
395
396     // write sample rate
397     mxf_write_local_tag(pb, 8, 0x3001);
398     put_be32(pb, s->streams[0]->time_base.den);
399     put_be32(pb, s->streams[0]->time_base.num);
400
401     // write essence container ul
402     mxf_write_local_tag(pb, 16, 0x3004);
403     put_buffer(pb, multiple_desc_ul, 16);
404
405     // write sub descriptor refs
406     mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
407     mxf_write_refs_count(pb, s->nb_streams);
408     for (i = 0; i < s->nb_streams; i++) {
409         mxf_write_uuid(pb, SubDescriptor, i);
410     }
411 }
412
413 static void mxf_write_header_desc(ByteIOContext *pb, const MXFDescriptorWriteTableEntry *desc_tbl, AVStream *st)
414 {
415     const MXFCodecUL *codec_ul;
416
417     put_buffer(pb, desc_tbl->key, 16);
418     klv_encode_ber_length(pb, 108);
419
420     mxf_write_local_tag(pb, 16, 0x3C0A);
421     mxf_write_uuid(pb, SubDescriptor, st->index);
422
423     mxf_write_local_tag(pb, 4, 0x3006);
424     put_be32(pb, st->index);
425
426     mxf_write_local_tag(pb, 8, 0x3001);
427     put_be32(pb, st->time_base.den);
428     put_be32(pb, st->time_base.num);
429
430     codec_ul = mxf_get_essence_container_ul(st->codec->codec_id);
431     mxf_write_local_tag(pb, 16, 0x3004);
432     put_buffer(pb, codec_ul->uid, 16);
433 }
434
435 static void mxf_write_mpeg_video_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
436 {
437     ByteIOContext *pb = s->pb;
438     AVStream *st;
439
440     st = s->streams[stream_index];
441     mxf_write_header_desc(pb, desc_tbl, st);
442
443     mxf_write_local_tag(pb, 4, 0x3203);
444     put_be32(pb, st->codec->width);
445
446     mxf_write_local_tag(pb, 4, 0x3202);
447     put_be32(pb, st->codec->height);
448
449     mxf_write_local_tag(pb, 8, 0x320E);
450     put_be32(pb, st->codec->height * st->codec->sample_aspect_ratio.den);
451     put_be32(pb, st->codec->width * st->codec->sample_aspect_ratio.num);
452
453     // tmp write, will modified later
454     mxf_write_local_tag(pb, 16, 0x3201);
455     put_buffer(pb, ff_mxf_codec_uls->uid, 16);
456 }
457
458 static void mxf_write_wav_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
459 {
460     ByteIOContext *pb = s->pb;
461     AVStream *st;
462
463     st = s->streams[stream_index];
464     mxf_write_header_desc(pb, desc_tbl, st);
465
466     // write audio sampling rate
467     mxf_write_local_tag(pb, 8, 0x3D03);
468     put_be32(pb, st->codec->sample_rate);
469     put_be32(pb, 1);
470
471     mxf_write_local_tag(pb, 4, 0x3D07);
472     put_be32(pb, st->codec->channels);
473
474     mxf_write_local_tag(pb, 4, 0x3D01);
475     put_be32(pb, st->codec->bits_per_sample);
476
477     // tmp write, will modified later
478     mxf_write_local_tag(pb, 16, 0x3201);
479     put_buffer(pb, (ff_mxf_codec_uls + 8) ->uid, 16);
480 }
481
482 static const MXFDescriptorWriteTableEntry mxf_descriptor_write_table[] = {
483     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_write_mpeg_video_desc, CODEC_ID_MPEG2VIDEO},
484     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_write_wav_desc, CODEC_ID_PCM_S16LE},
485     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, CODEC_ID_NONE},
486 };
487
488 static void mxf_build_structural_metadata(AVFormatContext *s, enum MXFMetadataSetType type)
489 {
490     int i;
491     const MXFDescriptorWriteTableEntry *desc = NULL;
492     int track_number_sign[sizeof(mxf_essence_element_key)/sizeof(MXFCodecUL)] = { 0 };
493
494     mxf_write_package(s, type);
495     if (type == SourcePackage)
496         mxf_write_multi_descriptor(s);
497
498     for (i = 0;i < s->nb_streams; i++) {
499         mxf_write_track(s, i, type, track_number_sign);
500         mxf_write_sequence(s, i, type);
501         mxf_write_structural_component(s, i, type);
502
503         if (type == SourcePackage) {
504             for (desc = mxf_descriptor_write_table; desc->write; desc++) {
505                 if (s->streams[i]->codec->codec_id == desc->type) {
506                     desc->write(s, desc, i);
507                     break;
508                 }
509             }
510         }
511     }
512 }
513
514 static int mxf_write_header_metadata_sets(AVFormatContext *s)
515 {
516     AVStream *st;
517     MXFStreamContext *sc = NULL;
518     int i;
519     mxf_write_preface(s);
520
521     mxf_write_identification(s);
522
523     mxf_write_content_storage(s);
524
525     for (i = 0; i < s->nb_streams; i++) {
526         st = s->streams[i];
527         sc = av_mallocz(sizeof(MXFStreamContext));
528         if (!sc)
529             return AVERROR(ENOMEM);
530         st->priv_data = sc;
531         // set pts information
532         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
533             av_set_pts_info(st, 64, 1, st->codec->time_base.den);
534         } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
535             av_set_pts_info(st, 64, 1, st->codec->sample_rate);
536         }
537     }
538
539     mxf_build_structural_metadata(s, MaterialPackage);
540     mxf_build_structural_metadata(s, SourcePackage);
541     return 0;
542 }
543
544 static int mux_write_header(AVFormatContext *s)
545 {
546     MXFContext *mxf = s->priv_data;
547     ByteIOContext *pb = s->pb;
548     int64_t header_metadata_start, offset_now;
549
550     mxf_write_partition(s, 0, 1, header_partition_key);
551
552     // mark the start of the headermetadata and calculate metadata size
553     header_metadata_start = url_ftell(s->pb);
554     mxf_write_primer_pack(s);
555     if (mxf_write_header_metadata_sets(s) < 0)
556         goto fail;
557     offset_now = url_ftell(s->pb);
558     mxf->header_byte_count = offset_now - header_metadata_start;
559     // update header_byte_count
560     url_fseek(pb, mxf->header_byte_count_offset, SEEK_SET);
561     put_be64(pb, mxf->header_byte_count);
562     url_fseek(pb, offset_now, SEEK_SET);
563
564     put_flush_packet(pb);
565     return 0;
566 fail:
567     mxf_free(s);
568     return -1;
569 }
570
571 static void mxf_update_header_partition(AVFormatContext *s, int64_t footer_partition_offset)
572 {
573     MXFContext *mxf = s->priv_data;
574     ByteIOContext *pb = s->pb;
575
576     url_fseek(pb, mxf->header_footer_partition_offset, SEEK_SET);
577     put_be64(pb, footer_partition_offset);
578     put_flush_packet(pb);
579 }
580
581
582 static int mux_write_footer(AVFormatContext *s)
583 {
584     ByteIOContext *pb = s->pb;
585
586     int64_t byte_position= url_ftell(pb);
587     if (!url_is_streamed(s->pb)) {
588         mxf_write_partition(s, byte_position, 0, footer_partition_key);
589
590         put_flush_packet(pb);
591
592         mxf_update_header_partition(s, byte_position);
593     }
594     mxf_free(s);
595     return 0;
596 }
597
598 AVOutputFormat mxf_muxer = {
599     "mxf",
600     NULL_IF_CONFIG_SMALL("Material eXchange Format"),
601     NULL,
602     "mxf",
603     sizeof(MXFContext),
604     CODEC_ID_PCM_S16LE,
605     CODEC_ID_MPEG2VIDEO,
606     mux_write_header,
607     mux_write_packet,
608     mux_write_footer,
609 };
610
611