Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxfenc.c @ faac3f0f

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
} 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,0x05,0x01,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 int mxf_write_essence_container_refs(AVFormatContext *s, int write)
249
{
250
    ByteIOContext *pb = s->pb;
251
    AVStream *st;
252
    int i, count = 0, j = 0;
253
    const MXFCodecUL *codec_ul;
254
    int essence_container_ul_sign[sizeof(ff_mxf_essence_container_uls) / sizeof(MXFCodecUL)] = { 0 };
255

    
256
    for (codec_ul = ff_mxf_essence_container_uls; codec_ul->id; codec_ul++) {
257
        for (i = 0; i < s->nb_streams; i++) {
258
            st = s->streams[i];
259
            if (st->codec->codec_id == codec_ul->id) {
260
                essence_container_ul_sign[count] = j;
261
                count++;
262
                break;
263
            }
264
        }
265
        j++;
266
        // considering WAV/AES3 frame wrapped, when get the first CODEC_ID_PCM_S16LE, break;
267
        // this is a temporary method, when we can get  more information, modofy this.
268
        if (codec_ul->id == CODEC_ID_PCM_S16LE)
269
            break;
270
    }
271

    
272
    if (write) {
273
        mxf_write_refs_count(pb, count);
274
        for (i = 0; i < count; i++) {
275
            put_buffer(pb, ff_mxf_essence_container_uls[essence_container_ul_sign[i]].uid, 16);
276
        }
277
        av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", count);
278
        for (i = 0; i < count; i++)
279
            PRINT_KEY(s, "essence container ul:\n", ff_mxf_essence_container_uls[essence_container_ul_sign[i]].uid);
280
    }
281
    return count;
282
}
283

    
284
static void mxf_write_preface(AVFormatContext *s)
285
{
286
    MXFContext *mxf = s->priv_data;
287
    ByteIOContext *pb = s->pb;
288

    
289
    mxf_write_metadata_key(pb, 0x012f00);
290
    PRINT_KEY(s, "preface key", pb->buf_ptr - 16);
291
    klv_encode_ber_length(pb, 130 + 16 * mxf->essence_container_count);
292

    
293
    // write preface set uid
294
    mxf_write_local_tag(pb, 16, 0x3C0A);
295
    mxf_write_uuid(pb, Preface, 0);
296
    PRINT_KEY(s, "preface uid", pb->buf_ptr - 16);
297

    
298
    // write create date as unknown
299
    mxf_write_local_tag(pb, 8, 0x3B02);
300
    put_be64(pb, 0);
301

    
302
    // write version
303
    mxf_write_local_tag(pb, 2, 0x3B05);
304
    put_be16(pb, 1);
305

    
306
    // write identification_refs
307
    mxf_write_local_tag(pb, 16 + 8, 0x3B06);
308
    mxf_write_refs_count(pb, 1);
309
    mxf_write_uuid(pb, Identification, 0);
310

    
311
    // write content_storage_refs
312
    mxf_write_local_tag(pb, 16, 0x3B03);
313
    mxf_write_uuid(pb, ContentStorage, 0);
314

    
315
    mxf_write_local_tag(pb, 16, 0x3B09);
316
    put_buffer(pb, op1a_ul, 16);
317

    
318
    // write essence_container_refs
319
    mxf_write_local_tag(pb, 8 + 16 * mxf->essence_container_count, 0x3B0A);
320
    mxf_write_essence_container_refs(s, 1);
321

    
322
    // write dm_scheme_refs
323
    mxf_write_local_tag(pb, 8, 0x3B0B);
324
    put_be64(pb, 0);
325
}
326

    
327
static void mxf_write_identification(AVFormatContext *s)
328
{
329
    ByteIOContext *pb = s->pb;
330
    int length, company_name_len, product_name_len, version_string_len;
331

    
332
    mxf_write_metadata_key(pb, 0x013000);
333
    PRINT_KEY(s, "identification key", pb->buf_ptr - 16);
334
    company_name_len = sizeof("FFmpeg");
335
    product_name_len = sizeof("OP1a Muxer");
336

    
337
    length = 80 + company_name_len + product_name_len;
338
    if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
339
        version_string_len = sizeof(LIBAVFORMAT_IDENT);
340
        length += 4 + version_string_len;
341
    }
342
    klv_encode_ber_length(pb, length);
343

    
344
    // write uid
345
    mxf_write_local_tag(pb, 16, 0x3C0A);
346
    mxf_write_uuid(pb, Identification, 0);
347
    PRINT_KEY(s, "identification uid", pb->buf_ptr - 16);
348
    // write generation uid
349
    mxf_write_local_tag(pb, 16, 0x3C09);
350
    mxf_write_uuid(pb, Identification, 1);
351

    
352
    mxf_write_local_tag(pb, company_name_len, 0x3C01);
353
    put_buffer(pb, "FFmpeg", company_name_len);
354

    
355
    mxf_write_local_tag(pb, product_name_len, 0x3C02);
356
    put_buffer(pb, "OP1a Muxer", product_name_len);
357

    
358
    if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) {
359
        mxf_write_local_tag(pb, version_string_len, 0x3C04);
360
        put_buffer(pb, LIBAVFORMAT_IDENT, version_string_len);
361
    }
362

    
363
    // write product uid
364
    mxf_write_local_tag(pb, 16, 0x3C05);
365
    mxf_write_uuid(pb, Identification, 2);
366

    
367
    // write modified date
368
    mxf_write_local_tag(pb, 8, 0x3C06);
369
    put_be64(pb, 0);
370
}
371

    
372
static void mxf_write_content_storage(AVFormatContext *s)
373
{
374
    ByteIOContext *pb = s->pb;
375

    
376
    mxf_write_metadata_key(pb, 0x011800);
377
    PRINT_KEY(s, "content storage key", pb->buf_ptr - 16);
378
    klv_encode_ber_length(pb, 64);
379

    
380
    // write uid
381
    mxf_write_local_tag(pb, 16, 0x3C0A);
382
    mxf_write_uuid(pb, ContentStorage, 0);
383
    PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16);
384
    // write package reference
385
    mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901);
386
    mxf_write_refs_count(pb, 2);
387
    mxf_write_uuid(pb, MaterialPackage, 0);
388
    mxf_write_uuid(pb, SourcePackage, 0);
389
}
390

    
391
static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type)
392
{
393
    ByteIOContext *pb = s->pb;
394
    int i;
395

    
396
    if (type == MaterialPackage) {
397
        mxf_write_metadata_key(pb, 0x013600);
398
        PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16);
399
        klv_encode_ber_length(pb, 92 + 16 * s->nb_streams);
400
    }
401
    else {
402
        mxf_write_metadata_key(pb, 0x013700);
403
        PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16);
404
        klv_encode_ber_length(pb, 112 + 16 * s->nb_streams); // 20 bytes length for descriptor reference
405
    }
406

    
407
    // write uid
408
    mxf_write_local_tag(pb, 16, 0x3C0A);
409
    mxf_write_uuid(pb, type, 0);
410
    av_log(s,AV_LOG_DEBUG, "package type:%d\n", type);
411
    PRINT_KEY(s, "package uid", pb->buf_ptr - 16);
412

    
413
    // write package umid
414
    mxf_write_local_tag(pb, 32, 0x4401);
415
    mxf_write_umid(pb, type, 0);
416
    PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
417
    // write create date
418
    mxf_write_local_tag(pb, 8, 0x4405);
419
    put_be64(pb, 0);
420

    
421
    // write modified date
422
    mxf_write_local_tag(pb, 8, 0x4404);
423
    put_be64(pb, 0);
424

    
425
    // write track refs
426
    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x4403);
427
    mxf_write_refs_count(pb, s->nb_streams);
428
    for (i = 0; i < s->nb_streams; i++)
429
        mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i);
430

    
431
    if (type == SourcePackage) {
432
        // write multiple descriptor reference
433
        mxf_write_local_tag(pb, 16, 0x4701);
434
        mxf_write_uuid(pb, MultipleDescriptor, 0);
435
    }
436
}
437

    
438
static void mxf_write_track(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type, int *track_number_sign)
439
{
440
    ByteIOContext *pb = s->pb;
441
    AVStream *st;
442
    MXFStreamContext *sc;
443
    const MXFCodecUL *element;
444
    int i = 0;
445

    
446
    mxf_write_metadata_key(pb, 0x013b00);
447
    PRINT_KEY(s, "track key", pb->buf_ptr - 16);
448
    klv_encode_ber_length(pb, 80);
449

    
450
    st = s->streams[stream_index];
451
    sc = st->priv_data;
452

    
453
    // write track uid
454
    mxf_write_local_tag(pb, 16, 0x3C0A);
455
    mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, stream_index);
456
    PRINT_KEY(s, "track uid", pb->buf_ptr - 16);
457
    // write track id
458
    mxf_write_local_tag(pb, 4, 0x4801);
459
    put_be32(pb, stream_index);
460

    
461
    mxf_write_local_tag(pb, 4, 0x4804);
462
    if (type != MaterialPackage) {
463
        for (element = mxf_essence_element_key; element->id != CODEC_ID_NONE; element++) {
464
            if (st->codec->codec_id== element->id) {
465
                // set essence_element key
466
                memcpy(sc->track_essence_element_key, element->uid, 16);
467
                sc->track_essence_element_key[15] += track_number_sign[i];
468
                // write track number
469
                put_buffer(pb, sc->track_essence_element_key + 12, 4);
470

    
471
                track_number_sign[i] ++;
472
                break;
473
            }
474
            i++;
475
        }
476
    } else {
477
        put_be32(pb, 0); // track number of material package is 0
478
    }
479

    
480
    mxf_write_local_tag(pb, 8, 0x4B01);
481
    put_be32(pb, st->time_base.den);
482
    put_be32(pb, st->time_base.num);
483

    
484
    // write origin
485
    mxf_write_local_tag(pb, 8, 0x4B02);
486
    put_be64(pb, 0);
487

    
488
    // write sequence refs
489
    mxf_write_local_tag(pb, 16, 0x4803);
490
    mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
491
}
492

    
493
static void mxf_write_common_fields(    ByteIOContext *pb, AVStream *st)
494
{
495
    const MXFDataDefinitionUL * data_def_ul;
496

    
497
    // find data define uls
498
    data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type);
499
    mxf_write_local_tag(pb, 16, 0x0201);
500
    put_buffer(pb, data_def_ul->uid, 16);
501

    
502
    // write duration
503
    mxf_write_local_tag(pb, 8, 0x0202);
504
    put_be64(pb, st->duration);
505
}
506

    
507
static void mxf_write_sequence(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
508
{
509
    ByteIOContext *pb = s->pb;
510
    AVStream *st;
511

    
512
    mxf_write_metadata_key(pb, 0x010f00);
513
    PRINT_KEY(s, "sequence key", pb->buf_ptr - 16);
514
    klv_encode_ber_length(pb, 80);
515

    
516
    st = s->streams[stream_index];
517

    
518
    mxf_write_local_tag(pb, 16, 0x3C0A);
519
    mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, stream_index);
520

    
521
    PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16);
522
    mxf_write_common_fields(pb, st);
523

    
524
    // write structural component
525
    mxf_write_local_tag(pb, 16 + 8, 0x1001);
526
    mxf_write_refs_count(pb, 1);
527
    mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, stream_index);
528
}
529

    
530
static void mxf_write_structural_component(AVFormatContext *s, int stream_index, enum MXFMetadataSetType type)
531
{
532
    ByteIOContext *pb = s->pb;
533
    AVStream *st;
534
    int i;
535

    
536
    mxf_write_metadata_key(pb, 0x011100);
537
    PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16);
538
    klv_encode_ber_length(pb, 108);
539

    
540
    st = s->streams[stream_index];
541

    
542
    // write uid
543
    mxf_write_local_tag(pb, 16, 0x3C0A);
544
    mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, stream_index);
545

    
546
    PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16);
547
    mxf_write_common_fields(pb, st);
548

    
549
    // write start_position
550
    mxf_write_local_tag(pb, 8, 0x1201);
551
    put_be64(pb, 0);
552

    
553
    mxf_write_local_tag(pb, 32, 0x1101);
554
    if (type == SourcePackage) {
555
        // write source package uid, end of the reference
556
        for (i = 0; i < 4; i++) {
557
            put_be64(pb, 0);
558
        }
559
    } else
560
        mxf_write_umid(pb, SourcePackage, 0);
561

    
562
    mxf_write_local_tag(pb, 4, 0x1102);
563
    if (type == SourcePackage)
564
        // write source track id
565
        put_be32(pb, 0);
566
    else
567
        put_be32(pb, stream_index);
568
}
569

    
570
static void mxf_write_multi_descriptor(AVFormatContext *s)
571
{
572
    ByteIOContext *pb = s->pb;
573
    int i;
574

    
575
    mxf_write_metadata_key(pb, 0x014400);
576
    PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);
577
    klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);
578

    
579
    mxf_write_local_tag(pb, 16, 0x3C0A);
580
    mxf_write_uuid(pb, MultipleDescriptor, 0);
581
    PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);
582

    
583
    // write sample rate
584
    mxf_write_local_tag(pb, 8, 0x3001);
585
    put_be32(pb, s->streams[0]->time_base.den);
586
    put_be32(pb, s->streams[0]->time_base.num);
587

    
588
    // write essence container ul
589
    mxf_write_local_tag(pb, 16, 0x3004);
590
    put_buffer(pb, multiple_desc_ul, 16);
591

    
592
    // write sub descriptor refs
593
    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);
594
    mxf_write_refs_count(pb, s->nb_streams);
595
    for (i = 0; i < s->nb_streams; i++) {
596
        mxf_write_uuid(pb, SubDescriptor, i);
597
    }
598
}
599

    
600
static void mxf_write_header_desc(ByteIOContext *pb, const MXFDescriptorWriteTableEntry *desc_tbl, AVStream *st)
601
{
602
    const MXFCodecUL *codec_ul;
603

    
604
    put_buffer(pb, desc_tbl->key, 16);
605
    klv_encode_ber_length(pb, 108);
606

    
607
    mxf_write_local_tag(pb, 16, 0x3C0A);
608
    mxf_write_uuid(pb, SubDescriptor, st->index);
609

    
610
    mxf_write_local_tag(pb, 4, 0x3006);
611
    put_be32(pb, st->index);
612

    
613
    mxf_write_local_tag(pb, 8, 0x3001);
614
    put_be32(pb, st->time_base.den);
615
    put_be32(pb, st->time_base.num);
616

    
617
    codec_ul = mxf_get_essence_container_ul(st->codec->codec_id);
618
    mxf_write_local_tag(pb, 16, 0x3004);
619
    put_buffer(pb, codec_ul->uid, 16);
620
}
621

    
622
static void mxf_write_mpeg_video_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
623
{
624
    ByteIOContext *pb = s->pb;
625
    AVStream *st;
626

    
627
    st = s->streams[stream_index];
628
    mxf_write_header_desc(pb, desc_tbl, st);
629

    
630
    mxf_write_local_tag(pb, 4, 0x3203);
631
    put_be32(pb, st->codec->width);
632

    
633
    mxf_write_local_tag(pb, 4, 0x3202);
634
    put_be32(pb, st->codec->height);
635

    
636
    mxf_write_local_tag(pb, 8, 0x320E);
637
    put_be32(pb, st->codec->height * st->sample_aspect_ratio.den);
638
    put_be32(pb, st->codec->width  * st->sample_aspect_ratio.num);
639

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

    
645
static void mxf_write_wav_desc(AVFormatContext *s, const MXFDescriptorWriteTableEntry *desc_tbl, int stream_index)
646
{
647
    ByteIOContext *pb = s->pb;
648
    AVStream *st;
649

    
650
    st = s->streams[stream_index];
651
    mxf_write_header_desc(pb, desc_tbl, st);
652

    
653
    // write audio sampling rate
654
    mxf_write_local_tag(pb, 8, 0x3D03);
655
    put_be32(pb, st->codec->sample_rate);
656
    put_be32(pb, 1);
657

    
658
    mxf_write_local_tag(pb, 4, 0x3D07);
659
    put_be32(pb, st->codec->channels);
660

    
661
    mxf_write_local_tag(pb, 4, 0x3D01);
662
    put_be32(pb, st->codec->bits_per_sample);
663

    
664
    // tmp write, will modified later
665
    mxf_write_local_tag(pb, 16, 0x3201);
666
    put_buffer(pb, (ff_mxf_codec_uls + 8) ->uid, 16);
667
}
668

    
669
static const MXFDescriptorWriteTableEntry mxf_descriptor_write_table[] = {
670
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_write_mpeg_video_desc, CODEC_ID_MPEG2VIDEO},
671
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_write_wav_desc, CODEC_ID_PCM_S16LE},
672
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, CODEC_ID_NONE},
673
};
674

    
675
static void mxf_build_structural_metadata(AVFormatContext *s, enum MXFMetadataSetType type)
676
{
677
    int i;
678
    const MXFDescriptorWriteTableEntry *desc = NULL;
679
    int track_number_sign[sizeof(mxf_essence_element_key)/sizeof(MXFCodecUL)] = { 0 };
680

    
681
    mxf_write_package(s, type);
682
    if (type == SourcePackage)
683
        mxf_write_multi_descriptor(s);
684

    
685
    for (i = 0;i < s->nb_streams; i++) {
686
        mxf_write_track(s, i, type, track_number_sign);
687
        mxf_write_sequence(s, i, type);
688
        mxf_write_structural_component(s, i, type);
689

    
690
        if (type == SourcePackage) {
691
            for (desc = mxf_descriptor_write_table; desc->write; desc++) {
692
                if (s->streams[i]->codec->codec_id == desc->type) {
693
                    desc->write(s, desc, i);
694
                    break;
695
                }
696
            }
697
        }
698
    }
699
}
700

    
701
static int mxf_write_header_metadata_sets(AVFormatContext *s)
702
{
703
    AVStream *st;
704
    MXFStreamContext *sc = NULL;
705
    int i;
706
    mxf_write_preface(s);
707

    
708
    mxf_write_identification(s);
709

    
710
    mxf_write_content_storage(s);
711

    
712
    for (i = 0; i < s->nb_streams; i++) {
713
        st = s->streams[i];
714
        sc = av_mallocz(sizeof(MXFStreamContext));
715
        if (!sc)
716
            return AVERROR(ENOMEM);
717
        st->priv_data = sc;
718
        // set pts information
719
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
720
            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
721
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
722
            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
723
        }
724
    }
725

    
726
    mxf_build_structural_metadata(s, MaterialPackage);
727
    mxf_build_structural_metadata(s, SourcePackage);
728
    return 0;
729
}
730

    
731
static void mxf_write_partition(AVFormatContext *s, int64_t byte_position, int bodysid, const uint8_t *key)
732
{
733
    MXFContext *mxf = s->priv_data;
734
    ByteIOContext *pb = s->pb;
735
    // write klv
736
    put_buffer(pb, key, 16);
737
    if (!mxf->essence_container_count)
738
        mxf->essence_container_count = mxf_write_essence_container_refs(s, 0);
739
    klv_encode_ber_length(pb, 88 + 16 * mxf->essence_container_count);
740

    
741
    // write partition value
742
    put_be16(pb, 1); // majorVersion
743
    put_be16(pb, 2); // minorVersion
744
    put_be32(pb, 1); // kagSize
745

    
746
    put_be64(pb, byte_position); // thisPartition
747
    put_be64(pb, 0); // previousPartition
748

    
749
    // set offset
750
    if (!byte_position)
751
        mxf->header_footer_partition_offset = url_ftell(pb);
752
    put_be64(pb, byte_position); // footerPartition,update later
753

    
754
    // set offset
755
    if (!byte_position)
756
        mxf->header_byte_count_offset = url_ftell(pb);
757
    put_be64(pb, 0); // headerByteCount, update later
758

    
759
    // no indexTable
760
    put_be64(pb, 0); // indexByteCount
761
    put_be32(pb, 0); // indexSID
762
    put_be64(pb, 0); // bodyOffset
763

    
764
    put_be32(pb, bodysid); // bodySID
765
    put_buffer(pb, op1a_ul, 16); // operational pattern
766

    
767
    // essence container
768
    mxf_write_essence_container_refs(s, 1);
769
}
770

    
771
static int mux_write_header(AVFormatContext *s)
772
{
773
    MXFContext *mxf = s->priv_data;
774
    ByteIOContext *pb = s->pb;
775
    int64_t header_metadata_start, offset_now;
776

    
777
    mxf_write_partition(s, 0, 1, header_partition_key);
778

    
779
    // mark the start of the headermetadata and calculate metadata size
780
    header_metadata_start = url_ftell(s->pb);
781
    mxf_write_primer_pack(s);
782
    if (mxf_write_header_metadata_sets(s) < 0)
783
        goto fail;
784
    offset_now = url_ftell(s->pb);
785
    mxf->header_byte_count = offset_now - header_metadata_start;
786
    // update header_byte_count
787
    url_fseek(pb, mxf->header_byte_count_offset, SEEK_SET);
788
    put_be64(pb, mxf->header_byte_count);
789
    url_fseek(pb, offset_now, SEEK_SET);
790

    
791
    put_flush_packet(pb);
792
    return 0;
793
fail:
794
    mxf_free(s);
795
    return -1;
796
}
797

    
798
static int mux_write_packet(AVFormatContext *s, AVPacket *pkt)
799
{
800
    ByteIOContext *pb = s->pb;
801
    AVStream *st = s->streams[pkt->stream_index];
802
    MXFStreamContext *sc = st->priv_data;
803

    
804
    put_buffer(pb, sc->track_essence_element_key, 16); // write key
805
    klv_encode_ber_length(pb, pkt->size); // write length
806
    put_buffer(pb, pkt->data, pkt->size); // write value
807

    
808
    put_flush_packet(pb);
809
    return 0;
810
}
811

    
812
static void mxf_update_header_partition(AVFormatContext *s, int64_t footer_partition_offset)
813
{
814
    MXFContext *mxf = s->priv_data;
815
    ByteIOContext *pb = s->pb;
816

    
817
    url_fseek(pb, mxf->header_footer_partition_offset, SEEK_SET);
818
    put_be64(pb, footer_partition_offset);
819
    put_flush_packet(pb);
820
}
821

    
822

    
823
static int mux_write_footer(AVFormatContext *s)
824
{
825
    ByteIOContext *pb = s->pb;
826

    
827
    int64_t byte_position= url_ftell(pb);
828
    if (!url_is_streamed(s->pb)) {
829
        mxf_write_partition(s, byte_position, 0, footer_partition_key);
830

    
831
        put_flush_packet(pb);
832

    
833
        mxf_update_header_partition(s, byte_position);
834
    }
835
    mxf_free(s);
836
    return 0;
837
}
838

    
839
AVOutputFormat mxf_muxer = {
840
    "mxf",
841
    NULL_IF_CONFIG_SMALL("Material eXchange Format"),
842
    NULL,
843
    "mxf",
844
    sizeof(MXFContext),
845
    CODEC_ID_PCM_S16LE,
846
    CODEC_ID_MPEG2VIDEO,
847
    mux_write_header,
848
    mux_write_packet,
849
    mux_write_footer,
850
};
851

    
852