]> git.sesse.net Git - ffmpeg/blob - libavformat/mxfenc.c
Import more ok'ed chunks of the mxf muxer from the soc tree
[ffmpeg] / 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_package(AVFormatContext *s, enum MXFMetadataSetType type)
356 {
357     ByteIOContext *pb = s->pb;
358     int i;
359
360     if (type == MaterialPackage) {
361         mxf_write_metadata_key(pb, 0x013600);
362         PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
363         klv_encode_ber_length(pb, 92 + 16 * s->nb_streams);
364     }
365     else {
366         mxf_write_metadata_key(pb, 0x013700);
367         PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
368         klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference
369     }
370
371     // write uid
372     mxf_write_local_tag(pb, 16, 0x3C0A);
373     mxf_write_uuid(pb, type, 0);
374     av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
375     PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
376
377     // write package umid
378     mxf_write_local_tag(pb, 32, 0x4401);
379     mxf_write_umid(pb, type, 0);
380     PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
381     // write create date
382     mxf_write_local_tag(pb, 8, 0x4405);
383     put_be64(pb, 0);
384
385     // write modified date
386     mxf_write_local_tag(pb, 8, 0x4404);
387     put_be64(pb, 0);
388
389     // write track refs
390     mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403);
391     mxf_write_refs_count(pb, s->nb_streams);
392     for (i = 0; i < s->nb_streams; i++)
393         mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
394
395     if (type == SourcePackage) {
396         // write multiple descriptor reference
397         mxf_write_local_tag(pb, 16, 0x4701);
398         mxf_write_uuid(pb, MultipleDescriptor, 0);
399     }
400 }
401
402 static void mxf_write_track(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type, int *track_number_sign)
403 {
404     ByteIOContext *pb = s->pb;
405     AVStream *st;
406     MXFStreamContext *sc;
407     const MXFCodecUL *element;
408     int i = 0;
409
410     mxf_write_metadata_key(pb, 0x013b00);
411     PRINT_KEY(s, "track key", pb->buf_ptr - 16);
412     klv_encode_ber_length(pb, 80);
413
414     st = s->streams[stream_index];
415     sc = st->priv_data;
416
417     // write track uid
418     mxf_write_local_tag(pb, 16, 0x3C0A);
419     mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, stream_index);
420     PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
421     // write track id
422     mxf_write_local_tag(pb, 4, 0x4801);
423     put_be32(pb, stream_index);
424
425     mxf_write_local_tag(pb, 4, 0x4804);
426     if (type != MaterialPackage) {
427         for (element = mxf_essence_element_key; element->id != CODEC_ID_NONE; element++) {
428             if (st->codec->codec_id== element->id) {
429                 // set essence_element key
430                 memcpy(sc->track_essence_element_key, element->uid, 16);
431                 sc->track_essence_element_key[15] += track_number_sign[i];
432                 // write track number
433                 put_buffer(pb, sc->track_essence_element_key + 12, 4);
434
435                 track_number_sign[i] ++;
436                 break;
437             }
438             i++;
439         }
440     } else {
441         put_be32(pb, 0); // track number of material package is 0
442     }
443
444     mxf_write_local_tag(pb, 8, 0x4B01);
445     put_be32(pb, st->time_base.den);
446     put_be32(pb, st->time_base.num);
447
448     // write origin
449     mxf_write_local_tag(pb, 8, 0x4B02);
450     put_be64(pb, 0);
451
452     // write sequence refs
453     mxf_write_local_tag(pb, 16, 0x4803);
454     mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
455 }
456
457 static void mxf_write_common_fields(    ByteIOContext *pb, AVStream *st)
458 {
459     const MXFDataDefinitionUL * data_def_ul;
460
461     // find data define uls
462     data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
463     mxf_write_local_tag(pb, 16, 0x0201);
464     put_buffer(pb, data_def_ul->uid, 16);
465
466     // write duration
467     mxf_write_local_tag(pb, 8, 0x0202);
468     put_be64(pb, st->duration);
469 }
470
471 static int mux_write_packet(AVFormatContext *s, AVPacket *pkt)
472 {
473     ByteIOContext *pb = s->pb;
474     AVStream *st = s->streams[pkt->stream_index];
475     MXFStreamContext *sc = st->priv_data;
476
477     put_buffer(pb, sc->track_essence_element_key, 16); // write key
478     klv_encode_ber_length(pb, pkt->size); // write length
479     put_buffer(pb, pkt->data, pkt->size); // write value
480
481     put_flush_packet(pb);
482     return 0;
483 }
484
485 static void mxf_write_sequence(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
486 {
487     ByteIOContext *pb = s->pb;
488     AVStream *st;
489
490     mxf_write_metadata_key(pb, 0x010f00);
491     PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
492     klv_encode_ber_length(pb, 80);
493
494     st = s->streams[stream_index];
495
496     mxf_write_local_tag(pb, 16, 0x3C0A);
497     mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
498
499     PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
500     mxf_write_common_fields(pb, st);
501
502     // write structural component
503     mxf_write_local_tag(pb, 16 + 8, 0x1001);
504     mxf_write_refs_count(pb, 1);
505     mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, stream_index);
506 }
507
508 static void mxf_write_structural_component(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
509 {
510     ByteIOContext *pb = s->pb;
511     AVStream *st;
512     int i;
513
514     mxf_write_metadata_key(pb, 0x011100);
515     PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
516     klv_encode_ber_length(pb, 108);
517
518     st = s->streams[stream_index];
519
520     // write uid
521     mxf_write_local_tag(pb, 16, 0x3C0A);
522     mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, stream_index);
523
524     PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
525     mxf_write_common_fields(pb, st);
526
527     // write start_position
528     mxf_write_local_tag(pb, 8, 0x1201);
529     put_be64(pb, 0);
530
531     mxf_write_local_tag(pb, 32, 0x1101);
532     if (type == SourcePackage) {
533         // write source package uid, end of the reference
534         for (i = 0; i < 4; i++) {
535             put_be64(pb, 0);
536         }
537     } else
538         mxf_write_umid(pb, SourcePackage, 0);
539
540     mxf_write_local_tag(pb, 4, 0x1102);
541     if (type == SourcePackage)
542         // write source track id
543         put_be32(pb, 0);
544     else
545         put_be32(pb, stream_index);
546 }
547
548 static void mxf_write_multi_descriptor(AVFormatContext *s)
549 {
550     ByteIOContext *pb = s->pb;
551     int i;
552
553     mxf_write_metadata_key(pb, 0x014400);
554     PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
555     klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
556
557     mxf_write_local_tag(pb, 16, 0x3C0A);
558     mxf_write_uuid(pb, MultipleDescriptor, 0);
559     PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
560
561     // write sample rate
562     mxf_write_local_tag(pb, 8, 0x3001);
563     put_be32(pb, s->streams[0]->time_base.den);
564     put_be32(pb, s->streams[0]->time_base.num);
565
566     // write essence container ul
567     mxf_write_local_tag(pb, 16, 0x3004);
568     put_buffer(pb, multiple_desc_ul, 16);
569
570     // write sub descriptor refs
571     mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
572     mxf_write_refs_count(pb, s->nb_streams);
573     for (i = 0; i < s->nb_streams; i++) {
574         mxf_write_uuid(pb, SubDescriptor, i);
575     }
576 }
577
578 static void mxf_write_header_desc(ByteIOContext *pb, const MXFDescriptorWriteTableEntry *desc_tbl, AVStream *st)
579 {
580     const MXFCodecUL *codec_ul;
581
582     put_buffer(pb, desc_tbl->key, 16);
583     klv_encode_ber_length(pb, 108);
584
585     mxf_write_local_tag(pb, 16, 0x3C0A);
586     mxf_write_uuid(pb, SubDescriptor, st->index);
587
588     mxf_write_local_tag(pb, 4, 0x3006);
589     put_be32(pb, st->index);
590
591     mxf_write_local_tag(pb, 8, 0x3001);
592     put_be32(pb, st->time_base.den);
593     put_be32(pb, st->time_base.num);
594
595     codec_ul = mxf_get_essence_container_ul(st->codec->codec_id);
596     mxf_write_local_tag(pb, 16, 0x3004);
597     put_buffer(pb, codec_ul->uid, 16);
598 }
599
600 static void mxf_write_mpeg_video_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
601 {
602     ByteIOContext *pb = s->pb;
603     AVStream *st;
604
605     st = s->streams[stream_index];
606     mxf_write_header_desc(pb, desc_tbl, st);
607
608     mxf_write_local_tag(pb, 4, 0x3203);
609     put_be32(pb, st->codec->width);
610
611     mxf_write_local_tag(pb, 4, 0x3202);
612     put_be32(pb, st->codec->height);
613
614     mxf_write_local_tag(pb, 8, 0x320E);
615     put_be32(pb, st->codec->height * st->sample_aspect_ratio.den);
616     put_be32(pb, st->codec->width  * st->sample_aspect_ratio.num);
617
618     // tmp write, will modified later
619     mxf_write_local_tag(pb, 16, 0x3201);
620     put_buffer(pb, ff_mxf_codec_uls->uid, 16);
621 }
622
623 static void mxf_write_wav_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
624 {
625     ByteIOContext *pb = s->pb;
626     AVStream *st;
627
628     st = s->streams[stream_index];
629     mxf_write_header_desc(pb, desc_tbl, st);
630
631     // write audio sampling rate
632     mxf_write_local_tag(pb, 8, 0x3D03);
633     put_be32(pb, st->codec->sample_rate);
634     put_be32(pb, 1);
635
636     mxf_write_local_tag(pb, 4, 0x3D07);
637     put_be32(pb, st->codec->channels);
638
639     mxf_write_local_tag(pb, 4, 0x3D01);
640     put_be32(pb, st->codec->bits_per_sample);
641
642     // tmp write, will modified later
643     mxf_write_local_tag(pb, 16, 0x3201);
644     put_buffer(pb, (ff_mxf_codec_uls + 8) ->uid, 16);
645 }
646
647 static const MXFDescriptorWriteTableEntry mxf_descriptor_write_table[] = {
648     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_write_mpeg_video_desc, CODEC_ID_MPEG2VIDEO},
649     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_write_wav_desc, CODEC_ID_PCM_S16LE},
650     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, CODEC_ID_NONE},
651 };
652
653 static void mxf_build_structural_metadata(AVFormatContext *s, enum MXFMetadataSetType type)
654 {
655     int i;
656     const MXFDescriptorWriteTableEntry *desc = NULL;
657     int track_number_sign[sizeof(mxf_essence_element_key)/sizeof(MXFCodecUL)] = { 0 };
658
659     mxf_write_package(s, type);
660     if (type == SourcePackage)
661         mxf_write_multi_descriptor(s);
662
663     for (i = 0;i < s->nb_streams; i++) {
664         mxf_write_track(s, i, type, track_number_sign);
665         mxf_write_sequence(s, i, type);
666         mxf_write_structural_component(s, i, type);
667
668         if (type == SourcePackage) {
669             for (desc = mxf_descriptor_write_table; desc->write; desc++) {
670                 if (s->streams[i]->codec->codec_id == desc->type) {
671                     desc->write(s, desc, i);
672                     break;
673                 }
674             }
675         }
676     }
677 }
678
679 static int mxf_write_header_metadata_sets(AVFormatContext *s)
680 {
681     AVStream *st;
682     MXFStreamContext *sc = NULL;
683     int i;
684     mxf_write_preface(s);
685
686     mxf_write_identification(s);
687
688     mxf_write_content_storage(s);
689
690     for (i = 0; i < s->nb_streams; i++) {
691         st = s->streams[i];
692         sc = av_mallocz(sizeof(MXFStreamContext));
693         if (!sc)
694             return AVERROR(ENOMEM);
695         st->priv_data = sc;
696         // set pts information
697         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
698             av_set_pts_info(st, 64, 1, st->codec->time_base.den);
699         } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
700             av_set_pts_info(st, 64, 1, st->codec->sample_rate);
701         }
702     }
703
704     mxf_build_structural_metadata(s, MaterialPackage);
705     mxf_build_structural_metadata(s, SourcePackage);
706     return 0;
707 }
708
709 static void mxf_write_partition(AVFormatContext *s, int64_t byte_position, int bodysid, const uint8_t *key)
710 {
711     MXFContext *mxf = s->priv_data;
712     ByteIOContext *pb = s->pb;
713     // write klv
714     put_buffer(pb, key, 16);
715     if (!mxf->essence_container_count)
716         mxf->essence_container_count = mxf_write_essence_container_refs(s, 0);
717     klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count);
718
719     // write partition value
720     put_be16(pb, 1); // majorVersion
721     put_be16(pb, 2); // minorVersion
722     put_be32(pb, 1); // kagSize
723
724     put_be64(pb, byte_position); // thisPartition
725     put_be64(pb, 0); // previousPartition
726
727     // set offset
728     if (!byte_position)
729         mxf->header_footer_partition_offset = url_ftell(pb);
730     put_be64(pb, byte_position); // footerPartition,update later
731
732     // set offset
733     if (!byte_position)
734         mxf->header_byte_count_offset = url_ftell(pb);
735     put_be64(pb, 0); // headerByteCount, update later
736
737     // no indexTable
738     put_be64(pb, 0); // indexByteCount
739     put_be32(pb, 0); // indexSID
740     put_be64(pb, 0); // bodyOffset
741
742     put_be32(pb, bodysid); // bodySID
743     put_buffer(pb, op1a_ul, 16); // operational pattern
744
745     // essence container
746     mxf_write_essence_container_refs(s, 1);
747 }
748
749 static int mux_write_header(AVFormatContext *s)
750 {
751     MXFContext *mxf = s->priv_data;
752     ByteIOContext *pb = s->pb;
753     int64_t header_metadata_start, offset_now;
754
755     mxf_write_partition(s, 0, 1, header_partition_key);
756
757     // mark the start of the headermetadata and calculate metadata size
758     header_metadata_start = url_ftell(s->pb);
759     mxf_write_primer_pack(s);
760     if (mxf_write_header_metadata_sets(s) < 0)
761         goto fail;
762     offset_now = url_ftell(s->pb);
763     mxf->header_byte_count = offset_now - header_metadata_start;
764     // update header_byte_count
765     url_fseek(pb, mxf->header_byte_count_offset, SEEK_SET);
766     put_be64(pb, mxf->header_byte_count);
767     url_fseek(pb, offset_now, SEEK_SET);
768
769     put_flush_packet(pb);
770     return 0;
771 fail:
772     mxf_free(s);
773     return -1;
774 }
775
776 static void mxf_update_header_partition(AVFormatContext *s, int64_t footer_partition_offset)
777 {
778     MXFContext *mxf = s->priv_data;
779     ByteIOContext *pb = s->pb;
780
781     url_fseek(pb, mxf->header_footer_partition_offset, SEEK_SET);
782     put_be64(pb, footer_partition_offset);
783     put_flush_packet(pb);
784 }
785
786
787 static int mux_write_footer(AVFormatContext *s)
788 {
789     ByteIOContext *pb = s->pb;
790
791     int64_t byte_position= url_ftell(pb);
792     if (!url_is_streamed(s->pb)) {
793         mxf_write_partition(s, byte_position, 0, footer_partition_key);
794
795         put_flush_packet(pb);
796
797         mxf_update_header_partition(s, byte_position);
798     }
799     mxf_free(s);
800     return 0;
801 }
802
803 AVOutputFormat mxf_muxer = {
804     "mxf",
805     NULL_IF_CONFIG_SMALL("Material eXchange Format"),
806     NULL,
807     "mxf",
808     sizeof(MXFContext),
809     CODEC_ID_PCM_S16LE,
810     CODEC_ID_MPEG2VIDEO,
811     mux_write_header,
812     mux_write_packet,
813     mux_write_footer,
814 };
815
816