Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxfenc.c @ e14d374e

History | View | Annotate | Download (29.6 KB)

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
    const UID *essence_container_ul;
44
} MXFStreamContext;
45

    
46
typedef struct MXFContext {
47
    int64_t header_byte_count;
48
    int64_t header_byte_count_offset;
49
    int64_t header_footer_partition_offset;
50
    int essence_container_count;
51
    uint8_t essence_containers_indices[sizeof(ff_mxf_essence_container_uls)/
52
                                       sizeof(*ff_mxf_essence_container_uls)];
53
} MXFContext;
54

    
55
typedef struct {
56
    const UID key;
57
    void (*write)();
58
    enum CodecType type;
59
} MXFDescriptorWriteTableEntry;
60

    
61
static const uint8_t uuid_base[]            = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
62
static const uint8_t umid_base[]            = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x00,0x13,0x00,0x00,0x00 };
63

    
64
/**
65
 * complete key for operation pattern, partitions, and primer pack
66
 */
67
static const uint8_t op1a_ul[]              = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x01,0x00 };
68
static const uint8_t header_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete
69
static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete
70
static const uint8_t primer_pack_key[]      = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 };
71

    
72
/**
73
 * partial key for header metadata
74
 */
75
static const uint8_t header_metadata_key[]  = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 };
76

    
77
static const MXFCodecUL mxf_essence_element_key[] = {
78
    { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, 14, CODEC_ID_MPEG2VIDEO},
79
    { { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE},
80
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE},
81
};
82

    
83
static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 };
84

    
85
/**
86
 * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html
87
 */
88
static const MXFLocalTagPair mxf_local_tag_batch[] = {
89
    // preface set
90
    { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */
91
    { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */
92
    { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */
93
    { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */
94
    { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */
95
    { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */
96
    { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */
97
    { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */
98
    // Identification
99
    { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */
100
    { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */
101
    { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */
102
    { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */
103
    { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */
104
    { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */
105
    // Content Storage
106
    { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */
107
    // Essence Container Data
108
    { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */
109
    { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */
110
    // Package
111
    { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */
112
    { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */
113
    { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */
114
    { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */
115
    { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */
116
    // Track
117
    { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */
118
    { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x03,0x00,0x00}}, /* Track Number */
119
    { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */
120
    { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */
121
    { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */
122
    // Sequence
123
    { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */
124
    { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */
125
    { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */
126
    // Source Clip
127
    { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Start position */
128
    { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */
129
    { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */
130
    // File Descriptor
131
    { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */
132
    { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */
133
    { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */
134
    { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */
135
    // Generic Picture Essence Descriptor
136
    { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */
137
    { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */
138
    { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
139
    { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
140
    // Generic Sound Essence Descriptor
141
    { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */
142
    { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */
143
    { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */
144
    { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */
145
};
146

    
147
static void mxf_write_uuid(ByteIOContext *pb, enum CodecID type, int value)
148
{
149
    put_buffer(pb, uuid_base, 12);
150
    put_be16(pb, type);
151
    put_be16(pb, value);
152
}
153

    
154
static void mxf_write_umid(ByteIOContext *pb, enum CodecID type, int value)
155
{
156
    put_buffer(pb, umid_base, 16);
157
    mxf_write_uuid(pb, type, value);
158
}
159

    
160
static void mxf_write_refs_count(ByteIOContext *pb, int ref_count)
161
{
162
    put_be32(pb, ref_count);
163
    put_be32(pb, 16);
164
}
165

    
166
static int klv_encode_ber_length(ByteIOContext *pb, uint64_t len)
167
{
168
    // Determine the best BER size
169
    int size;
170
    if (len < 128) {
171
        //short form
172
        put_byte(pb, len);
173
        return 1;
174
    }
175

    
176
    size = (av_log2(len) >> 3) + 1;
177

    
178
    // long form
179
    put_byte(pb, 0x80 + size);
180
    while(size) {
181
        size --;
182
        put_byte(pb, len >> 8 * size & 0xff);
183
    }
184
    return 0;
185
}
186

    
187
/*
188
 * Get essence container ul and return its index position
189
 */
190
static const UID *mxf_get_essence_container_ul(enum CodecID type, int *index)
191
{
192
    const MXFCodecUL *uls = ff_mxf_essence_container_uls;
193
    for (*index = 0; *index < sizeof(ff_mxf_essence_container_uls)/sizeof(*ff_mxf_essence_container_uls); (*index)++)
194
        if (ff_mxf_essence_container_uls[*index].id == type)
195
            return &uls->uid;
196
    *index = -1;
197
    return NULL;
198
}
199

    
200
static void mxf_write_primer_pack(AVFormatContext *s)
201
{
202
    ByteIOContext *pb = s->pb;
203
    int local_tag_number, i = 0;
204

    
205
    local_tag_number = sizeof(mxf_local_tag_batch)/sizeof(*mxf_local_tag_batch);
206

    
207
    put_buffer(pb, primer_pack_key, 16);
208
    klv_encode_ber_length(pb, local_tag_number * 18 + 8);
209

    
210
    put_be32(pb, local_tag_number); // local_tag num
211
    put_be32(pb, 18); // item size, always 18 according to the specs
212

    
213
    for (i = 0; i < local_tag_number; i++) {
214
        put_be16(pb, mxf_local_tag_batch[i].local_tag);
215
        put_buffer(pb, mxf_local_tag_batch[i].uid, 16);
216
    }
217
}
218

    
219
static void mxf_write_local_tag(ByteIOContext *pb, int size, int tag)
220
{
221
    put_be16(pb, tag);
222
    put_be16(pb, size);
223
}
224

    
225
static void mxf_write_metadata_key(ByteIOContext *pb, unsigned int value)
226
{
227
    put_buffer(pb, header_metadata_key, 13);
228
    put_be24(pb, value);
229
}
230

    
231
static void mxf_free(AVFormatContext *s)
232
{
233
    int i;
234

    
235
    for (i = 0; i < s->nb_streams; i++) {
236
        AVStream *st = s->streams[i];
237
        av_freep(&st->priv_data);
238
    }
239
}
240

    
241
static const MXFDataDefinitionUL *mxf_get_data_definition_ul(enum CodecType type)
242
{
243
    const MXFDataDefinitionUL *uls = ff_mxf_data_definition_uls;
244
    while (uls->type != CODEC_TYPE_DATA) {
245
        if (type == uls->type)
246
            break;
247
        uls++;
248
    }
249
    return uls;
250
}
251

    
252
static void mxf_write_essence_container_refs(AVFormatContext *s)
253
{
254
    MXFContext *c = s->priv_data;
255
    ByteIOContext *pb = s->pb;
256
    int i;
257

    
258
    mxf_write_refs_count(pb, c->essence_container_count);
259
    av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count);
260
    for (i = 0; i < c->essence_container_count; i++) {
261
        put_buffer(pb, ff_mxf_essence_container_uls[c->essence_containers_indices[i]].uid, 16);
262
        PRINT_KEY(s, "essence container ul:\n", ff_mxf_essence_container_uls[c->essence_containers_indices[i]].uid);
263
    }
264
}
265

    
266
static void mxf_write_preface(AVFormatContext *s)
267
{
268
    MXFContext *mxf = s->priv_data;
269
    ByteIOContext *pb = s->pb;
270

    
271
    mxf_write_metadata_key(pb, 0x012f00);
272
    PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
273
    klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);
274

    
275
    // write preface set uid
276
    mxf_write_local_tag(pb, 16, 0x3C0A);
277
    mxf_write_uuid(pb, Preface, 0);
278
    PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
279

    
280
    // write create date as unknown
281
    mxf_write_local_tag(pb, 8, 0x3B02);
282
    put_be64(pb, 0);
283

    
284
    // write version
285
    mxf_write_local_tag(pb, 2, 0x3B05);
286
    put_be16(pb, 1);
287

    
288
    // write identification_refs
289
    mxf_write_local_tag(pb, 16 + 8, 0x3B06);
290
    mxf_write_refs_count(pb, 1);
291
    mxf_write_uuid(pb, Identification, 0);
292

    
293
    // write content_storage_refs
294
    mxf_write_local_tag(pb, 16, 0x3B03);
295
    mxf_write_uuid(pb, ContentStorage, 0);
296

    
297
    mxf_write_local_tag(pb, 16, 0x3B09);
298
    put_buffer(pb, op1a_ul, 16);
299

    
300
    // write essence_container_refs
301
    mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);
302
    mxf_write_essence_container_refs(s);
303

    
304
    // write dm_scheme_refs
305
    mxf_write_local_tag(pb, 8, 0x3B0B);
306
    put_be64(pb, 0);
307
}
308

    
309
/*
310
 * Write a local tag containing an ascii string as utf-16
311
 */
312
static void mxf_write_local_tag_utf16(ByteIOContext *pb, int tag, const char *value)
313
{
314
    int i, size = strlen(value);
315
    mxf_write_local_tag(pb, size*2, tag);
316
    for (i = 0; i < size; i++)
317
        put_be16(pb, value[i]);
318
}
319

    
320
static void mxf_write_identification(AVFormatContext *s)
321
{
322
    ByteIOContext *pb = s->pb;
323
    const char *company = "FFmpeg";
324
    const char *product = "OP1a Muxer";
325
    const char *version;
326
    int length;
327

    
328
    mxf_write_metadata_key(pb, 0x013000);
329
    PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
330

    
331
    version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ?
332
        "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION);
333
    length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16
334
    klv_encode_ber_length(pb, length);
335

    
336
    // write uid
337
    mxf_write_local_tag(pb, 16, 0x3C0A);
338
    mxf_write_uuid(pb, Identification, 0);
339
    PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
340

    
341
    // write generation uid
342
    mxf_write_local_tag(pb, 16, 0x3C09);
343
    mxf_write_uuid(pb, Identification, 1);
344

    
345
    mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name
346
    mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name
347
    mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String
348

    
349
    // write product uid
350
    mxf_write_local_tag(pb, 16, 0x3C05);
351
    mxf_write_uuid(pb, Identification, 2);
352

    
353
    // write modified date
354
    mxf_write_local_tag(pb, 8, 0x3C06);
355
    put_be64(pb, 0);
356
}
357

    
358
static void mxf_write_content_storage(AVFormatContext *s)
359
{
360
    ByteIOContext *pb = s->pb;
361

    
362
    mxf_write_metadata_key(pb, 0x011800);
363
    PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
364
    klv_encode_ber_length(pb, 64);
365

    
366
    // write uid
367
    mxf_write_local_tag(pb, 16, 0x3C0A);
368
    mxf_write_uuid(pb, ContentStorage, 0);
369
    PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
370

    
371
    // write package reference
372
    mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
373
    mxf_write_refs_count(pb, 2);
374
    mxf_write_uuid(pb, MaterialPackage, 0);
375
    mxf_write_uuid(pb, SourcePackage, 0);
376
}
377

    
378
static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
379
{
380
    ByteIOContext *pb = s->pb;
381
    int i;
382

    
383
    if (type == MaterialPackage) {
384
        mxf_write_metadata_key(pb, 0x013600);
385
        PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
386
        klv_encode_ber_length(pb, 92 + 16 * s->nb_streams);
387
    } else {
388
        mxf_write_metadata_key(pb, 0x013700);
389
        PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
390
        klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference
391
    }
392

    
393
    // write uid
394
    mxf_write_local_tag(pb, 16, 0x3C0A);
395
    mxf_write_uuid(pb, type, 0);
396
    av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
397
    PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
398

    
399
    // write package umid
400
    mxf_write_local_tag(pb, 32, 0x4401);
401
    mxf_write_umid(pb, type, 0);
402
    PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
403

    
404
    // write create date
405
    mxf_write_local_tag(pb, 8, 0x4405);
406
    put_be64(pb, 0);
407

    
408
    // write modified date
409
    mxf_write_local_tag(pb, 8, 0x4404);
410
    put_be64(pb, 0);
411

    
412
    // write track refs
413
    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403);
414
    mxf_write_refs_count(pb, s->nb_streams);
415
    for (i = 0; i < s->nb_streams; i++)
416
        mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
417

    
418
    // write multiple descriptor reference
419
    if (type == SourcePackage) {
420
        mxf_write_local_tag(pb, 16, 0x4701);
421
        mxf_write_uuid(pb, MultipleDescriptor, 0);
422
    }
423
}
424

    
425
static void mxf_write_track(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type, int *track_number_sign)
426
{
427
    ByteIOContext *pb = s->pb;
428
    AVStream *st = s->streams[stream_index];
429
    MXFStreamContext *sc = st->priv_data;
430
    const MXFCodecUL *element;
431
    int i = 0;
432

    
433
    mxf_write_metadata_key(pb, 0x013b00);
434
    PRINT_KEY(s, "track key", pb->buf_ptr - 16);
435
    klv_encode_ber_length(pb, 80);
436

    
437
    // write track uid
438
    mxf_write_local_tag(pb, 16, 0x3C0A);
439
    mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, stream_index);
440
    PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
441

    
442
    // write track id
443
    mxf_write_local_tag(pb, 4, 0x4801);
444
    put_be32(pb, stream_index);
445

    
446
    mxf_write_local_tag(pb, 4, 0x4804);
447
    if (type != MaterialPackage) {
448
        for (element = mxf_essence_element_key; element->id != CODEC_ID_NONE; element++) {
449
            if (st->codec->codec_id== element->id) {
450
                // set essence_element key
451
                memcpy(sc->track_essence_element_key, element->uid, 16);
452
                sc->track_essence_element_key[15] += track_number_sign[i];
453
                // write track number
454
                put_buffer(pb, sc->track_essence_element_key + 12, 4);
455

    
456
                track_number_sign[i]++;
457
                break;
458
            }
459
            i++;
460
        }
461
    } else
462
        put_be32(pb, 0); // track number of material package is 0
463

    
464
    mxf_write_local_tag(pb, 8, 0x4B01);
465
    put_be32(pb, st->time_base.den);
466
    put_be32(pb, st->time_base.num);
467

    
468
    // write origin
469
    mxf_write_local_tag(pb, 8, 0x4B02);
470
    put_be64(pb, 0);
471

    
472
    // write sequence refs
473
    mxf_write_local_tag(pb, 16, 0x4803);
474
    mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
475
}
476

    
477
static void mxf_write_common_fields(ByteIOContext *pb, AVStream *st)
478
{
479
    const MXFDataDefinitionUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
480
    // find data define uls
481
    mxf_write_local_tag(pb, 16, 0x0201);
482
    put_buffer(pb, data_def_ul->uid, 16);
483

    
484
    // write duration
485
    mxf_write_local_tag(pb, 8, 0x0202);
486
    put_be64(pb, st->duration);
487
}
488

    
489
static void mxf_write_sequence(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
490
{
491
    ByteIOContext *pb = s->pb;
492
    AVStream *st = s->streams[stream_index];
493

    
494
    mxf_write_metadata_key(pb, 0x010f00);
495
    PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
496
    klv_encode_ber_length(pb, 80);
497

    
498
    mxf_write_local_tag(pb, 16, 0x3C0A);
499
    mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
500

    
501
    PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
502
    mxf_write_common_fields(pb, st);
503

    
504
    // write structural component
505
    mxf_write_local_tag(pb, 16 + 8, 0x1001);
506
    mxf_write_refs_count(pb, 1);
507
    mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, stream_index);
508
}
509

    
510
static void mxf_write_structural_component(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
511
{
512
    ByteIOContext *pb = s->pb;
513
    AVStream *st = s->streams[stream_index];
514
    int i;
515

    
516
    mxf_write_metadata_key(pb, 0x011100);
517
    PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
518
    klv_encode_ber_length(pb, 108);
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
    // write source package uid, end of the reference
532
    mxf_write_local_tag(pb, 32, 0x1101);
533
    if (type == SourcePackage) {
534
        for (i = 0; i < 4; i++)
535
            put_be64(pb, 0);
536
    } else
537
        mxf_write_umid(pb, SourcePackage, 0);
538

    
539
    // write source track id
540
    mxf_write_local_tag(pb, 4, 0x1102);
541
    if (type == SourcePackage)
542
        put_be32(pb, 0);
543
    else
544
        put_be32(pb, stream_index);
545
}
546

    
547
static void mxf_write_multi_descriptor(AVFormatContext *s)
548
{
549
    ByteIOContext *pb = s->pb;
550
    int i;
551

    
552
    mxf_write_metadata_key(pb, 0x014400);
553
    PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
554
    klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
555

    
556
    mxf_write_local_tag(pb, 16, 0x3C0A);
557
    mxf_write_uuid(pb, MultipleDescriptor, 0);
558
    PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
559

    
560
    // write sample rate
561
    mxf_write_local_tag(pb, 8, 0x3001);
562
    put_be32(pb, s->streams[0]->time_base.den);
563
    put_be32(pb, s->streams[0]->time_base.num);
564

    
565
    // write essence container ul
566
    mxf_write_local_tag(pb, 16, 0x3004);
567
    put_buffer(pb, multiple_desc_ul, 16);
568

    
569
    // write sub descriptor refs
570
    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
571
    mxf_write_refs_count(pb, s->nb_streams);
572
    for (i = 0; i < s->nb_streams; i++)
573
        mxf_write_uuid(pb, SubDescriptor, i);
574
}
575

    
576
static void mxf_write_generic_desc(ByteIOContext *pb, const MXFDescriptorWriteTableEntry *desc_tbl, AVStream *st)
577
{
578
    MXFStreamContext *sc = st->priv_data;
579

    
580
    put_buffer(pb, desc_tbl->key, 16);
581
    klv_encode_ber_length(pb, 108);
582

    
583
    mxf_write_local_tag(pb, 16, 0x3C0A);
584
    mxf_write_uuid(pb, SubDescriptor, st->index);
585

    
586
    mxf_write_local_tag(pb, 4, 0x3006);
587
    put_be32(pb, st->index);
588

    
589
    mxf_write_local_tag(pb, 8, 0x3001);
590
    put_be32(pb, st->time_base.den);
591
    put_be32(pb, st->time_base.num);
592

    
593
    mxf_write_local_tag(pb, 16, 0x3004);
594
    put_buffer(pb, *sc->essence_container_ul, 16);
595
}
596

    
597
static void mxf_write_mpegvideo_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
598
{
599
    ByteIOContext *pb = s->pb;
600
    AVStream *st = s->streams[stream_index];
601

    
602
    mxf_write_generic_desc(pb, desc_tbl, st);
603

    
604
    mxf_write_local_tag(pb, 4, 0x3203);
605
    put_be32(pb, st->codec->width);
606

    
607
    mxf_write_local_tag(pb, 4, 0x3202);
608
    put_be32(pb, st->codec->height);
609

    
610
    mxf_write_local_tag(pb, 8, 0x320E);
611
    put_be32(pb, st->codec->height * st->sample_aspect_ratio.den);
612
    put_be32(pb, st->codec->width  * st->sample_aspect_ratio.num);
613

    
614
    // tmp write, will modified later
615
    mxf_write_local_tag(pb, 16, 0x3201);
616
    put_buffer(pb, ff_mxf_codec_uls->uid, 16);
617
}
618

    
619
static void mxf_write_wav_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
620
{
621
    ByteIOContext *pb = s->pb;
622
    AVStream *st;
623

    
624
    st = s->streams[stream_index];
625
    mxf_write_generic_desc(pb, desc_tbl, st);
626

    
627
    // write audio sampling rate
628
    mxf_write_local_tag(pb, 8, 0x3D03);
629
    put_be32(pb, st->codec->sample_rate);
630
    put_be32(pb, 1);
631

    
632
    mxf_write_local_tag(pb, 4, 0x3D07);
633
    put_be32(pb, st->codec->channels);
634

    
635
    mxf_write_local_tag(pb, 4, 0x3D01);
636
    put_be32(pb, st->codec->bits_per_sample);
637

    
638
    // tmp write, will modified later
639
    mxf_write_local_tag(pb, 16, 0x3201);
640
    put_buffer(pb, (ff_mxf_codec_uls + 8)->uid, 16);
641
}
642

    
643
static const MXFDescriptorWriteTableEntry mxf_descriptor_write_table[] = {
644
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_write_mpegvideo_desc, CODEC_ID_MPEG2VIDEO},
645
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_write_wav_desc, CODEC_ID_PCM_S16LE},
646
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, CODEC_ID_NONE},
647
};
648

    
649
static void mxf_build_structural_metadata(AVFormatContext *s, enum MXFMetadataSetType type)
650
{
651
    int i;
652
    const MXFDescriptorWriteTableEntry *desc = NULL;
653
    int track_number_sign[sizeof(mxf_essence_element_key)/
654
                          sizeof(*mxf_essence_element_key)] = {0};
655

    
656
    mxf_write_package(s, type);
657
    if (type == SourcePackage)
658
        mxf_write_multi_descriptor(s);
659

    
660
    for (i = 0;i < s->nb_streams; i++) {
661
        mxf_write_track(s, i, type, track_number_sign);
662
        mxf_write_sequence(s, i, type);
663
        mxf_write_structural_component(s, i, type);
664

    
665
        if (type == SourcePackage) {
666
            for (desc = mxf_descriptor_write_table; desc->write; desc++) {
667
                if (s->streams[i]->codec->codec_id == desc->type) {
668
                    desc->write(s, desc, i);
669
                    break;
670
                }
671
            }
672
        }
673
    }
674
}
675

    
676
static int mxf_write_header_metadata_sets(AVFormatContext *s)
677
{
678
    mxf_write_preface(s);
679
    mxf_write_identification(s);
680
    mxf_write_content_storage(s);
681
    mxf_build_structural_metadata(s, MaterialPackage);
682
    mxf_build_structural_metadata(s, SourcePackage);
683
    return 0;
684
}
685

    
686
static void mxf_write_partition(AVFormatContext *s, int64_t byte_position, int bodysid, const uint8_t *key)
687
{
688
    MXFContext *mxf = s->priv_data;
689
    ByteIOContext *pb = s->pb;
690

    
691
    // write klv
692
    put_buffer(pb, key, 16);
693

    
694
    klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count);
695

    
696
    // write partition value
697
    put_be16(pb, 1); // majorVersion
698
    put_be16(pb, 2); // minorVersion
699
    put_be32(pb, 1); // kagSize
700

    
701
    put_be64(pb, byte_position); // thisPartition
702
    put_be64(pb, 0); // previousPartition
703

    
704
    // set offset
705
    if (!byte_position)
706
        mxf->header_footer_partition_offset = url_ftell(pb);
707
    put_be64(pb, byte_position); // footerPartition,update later
708

    
709
    // set offset
710
    if (!byte_position)
711
        mxf->header_byte_count_offset = url_ftell(pb);
712
    put_be64(pb, 0); // headerByteCount, update later
713

    
714
    // no indexTable
715
    put_be64(pb, 0); // indexByteCount
716
    put_be32(pb, 0); // indexSID
717
    put_be64(pb, 0); // bodyOffset
718

    
719
    put_be32(pb, bodysid); // bodySID
720
    put_buffer(pb, op1a_ul, 16); // operational pattern
721

    
722
    // essence container
723
    mxf_write_essence_container_refs(s);
724
}
725

    
726
static int mux_write_header(AVFormatContext *s)
727
{
728
    MXFContext *mxf = s->priv_data;
729
    ByteIOContext *pb = s->pb;
730
    int64_t header_metadata_start, offset_now;
731
    int i, index;
732
    uint8_t present[sizeof(ff_mxf_essence_container_uls)/
733
                    sizeof(*ff_mxf_essence_container_uls)] = {0};
734

    
735
    for (i = 0; i < s->nb_streams; i++) {
736
        AVStream *st = s->streams[i];
737
        MXFStreamContext *sc = av_mallocz(sizeof(*sc));
738
        if (!sc)
739
            return AVERROR(ENOMEM);
740
        st->priv_data = sc;
741
        // set pts information
742
        if (st->codec->codec_type == CODEC_TYPE_VIDEO)
743
            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
744
        else if (st->codec->codec_type == CODEC_TYPE_AUDIO)
745
            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
746
        sc->essence_container_ul = mxf_get_essence_container_ul(st->codec->codec_id, &index);
747
        if (!sc->essence_container_ul) {
748
            av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "
749
                   "codec not currently supported in container\n", i);
750
            return -1;
751
        }
752
        if (!present[index]) {
753
            mxf->essence_containers_indices[mxf->essence_container_count++] = index;
754
            present[index] = 1;
755
        }
756
    }
757

    
758
    mxf_write_partition(s, 0, 1, header_partition_key);
759

    
760
    // mark the start of the headermetadata and calculate metadata size
761
    header_metadata_start = url_ftell(s->pb);
762
    mxf_write_primer_pack(s);
763
    if (mxf_write_header_metadata_sets(s) < 0)
764
        goto fail;
765
    offset_now = url_ftell(s->pb);
766
    mxf->header_byte_count = offset_now - header_metadata_start;
767
    // update header_byte_count
768
    url_fseek(pb, mxf->header_byte_count_offset, SEEK_SET);
769
    put_be64(pb, mxf->header_byte_count);
770
    url_fseek(pb, offset_now, SEEK_SET);
771

    
772
    put_flush_packet(pb);
773
    return 0;
774
fail:
775
    mxf_free(s);
776
    return -1;
777
}
778

    
779
static int mux_write_packet(AVFormatContext *s, AVPacket *pkt)
780
{
781
    ByteIOContext *pb = s->pb;
782
    AVStream *st = s->streams[pkt->stream_index];
783
    MXFStreamContext *sc = st->priv_data;
784

    
785
    put_buffer(pb, sc->track_essence_element_key, 16); // write key
786
    klv_encode_ber_length(pb, pkt->size); // write length
787
    put_buffer(pb, pkt->data, pkt->size); // write value
788

    
789
    put_flush_packet(pb);
790
    return 0;
791
}
792

    
793
static void mxf_update_header_partition(AVFormatContext *s, int64_t footer_partition_offset)
794
{
795
    MXFContext *mxf = s->priv_data;
796
    ByteIOContext *pb = s->pb;
797

    
798
    url_fseek(pb, mxf->header_footer_partition_offset, SEEK_SET);
799
    put_be64(pb, footer_partition_offset);
800
    put_flush_packet(pb);
801
}
802

    
803

    
804
static int mux_write_footer(AVFormatContext *s)
805
{
806
    ByteIOContext *pb = s->pb;
807
    int64_t byte_position= url_ftell(pb);
808

    
809
    if (!url_is_streamed(s->pb)) {
810
        mxf_write_partition(s, byte_position, 0, footer_partition_key);
811
        put_flush_packet(pb);
812
        mxf_update_header_partition(s, byte_position);
813
    }
814
    mxf_free(s);
815
    return 0;
816
}
817

    
818
AVOutputFormat mxf_muxer = {
819
    "mxf",
820
    NULL_IF_CONFIG_SMALL("Material eXchange Format"),
821
    NULL,
822
    "mxf",
823
    sizeof(MXFContext),
824
    CODEC_ID_PCM_S16LE,
825
    CODEC_ID_MPEG2VIDEO,
826
    mux_write_header,
827
    mux_write_packet,
828
    mux_write_footer,
829
};
830

    
831