Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ b7889fce

History | View | Annotate | Download (41.5 KB)

1 07bf2af8 Baptiste Coudurier
/*
2
 * MXF demuxer.
3
 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>.
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 07bf2af8 Baptiste Coudurier
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 07bf2af8 Baptiste Coudurier
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 07bf2af8 Baptiste Coudurier
 * 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 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 07bf2af8 Baptiste Coudurier
 * 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 378M Operational Pattern 1a
27
 * SMPTE 379M MXF Generic Container
28
 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
29
 * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
30
 * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
31
 *
32
 * Principle
33
 * Search for Track numbers which will identify essence element KLV packets.
34
 * Search for SourcePackage which define tracks which contains Track numbers.
35 743d772c Baptiste Coudurier
 * Material Package contains tracks with reference to SourcePackage tracks.
36 07bf2af8 Baptiste Coudurier
 * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
37
 * Assign Descriptors to correct Tracks.
38
 *
39 d2cdbd5f Baptiste Coudurier
 * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
40
 * Metadata parsing resolves Strong References to objects.
41 743d772c Baptiste Coudurier
 *
42
 * Simple demuxer, only OP1A supported and some files might not work at all.
43
 * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
44 07bf2af8 Baptiste Coudurier
 */
45
46 49b6f162 Baptiste Coudurier
//#define DEBUG
47 07bf2af8 Baptiste Coudurier
48
#include "avformat.h"
49 80a289b9 Reimar Döffinger
#include "aes.h"
50 07bf2af8 Baptiste Coudurier
51 f03b6426 Baptiste Coudurier
typedef uint8_t UID[16];
52 4bfff768 Baptiste Coudurier
53 d2cdbd5f Baptiste Coudurier
enum MXFMetadataSetType {
54 6ac558ee Baptiste Coudurier
    AnyType,
55 743d772c Baptiste Coudurier
    MaterialPackage,
56
    SourcePackage,
57
    SourceClip,
58 d2cdbd5f Baptiste Coudurier
    TimecodeComponent,
59
    Sequence,
60
    MultipleDescriptor,
61
    Descriptor,
62
    Track,
63
    EssenceContainerData,
64 80a289b9 Reimar Döffinger
    CryptoContext,
65 743d772c Baptiste Coudurier
};
66
67 80a289b9 Reimar Döffinger
typedef struct MXFCryptoContext {
68
    UID uid;
69
    enum MXFMetadataSetType type;
70
    UID context_uid;
71
    UID source_container_ul;
72
} MXFCryptoContext;
73
74 743d772c Baptiste Coudurier
typedef struct MXFStructuralComponent {
75
    UID uid;
76 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
77 743d772c Baptiste Coudurier
    UID source_package_uid;
78
    UID data_definition_ul;
79
    int64_t duration;
80
    int64_t start_position;
81
    int source_track_id;
82
} MXFStructuralComponent;
83
84
typedef struct MXFSequence {
85
    UID uid;
86 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
87 743d772c Baptiste Coudurier
    UID data_definition_ul;
88
    UID *structural_components_refs;
89
    int structural_components_count;
90
    int64_t duration;
91
} MXFSequence;
92
93
typedef struct MXFTrack {
94
    UID uid;
95 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
96 743d772c Baptiste Coudurier
    MXFSequence *sequence; /* mandatory, and only one */
97
    UID sequence_ref;
98 07bf2af8 Baptiste Coudurier
    int track_id;
99 f03b6426 Baptiste Coudurier
    uint8_t track_number[4];
100 743d772c Baptiste Coudurier
    AVRational edit_rate;
101 07bf2af8 Baptiste Coudurier
} MXFTrack;
102
103 743d772c Baptiste Coudurier
typedef struct MXFDescriptor {
104
    UID uid;
105 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
106 e076173f Baptiste Coudurier
    UID essence_container_ul;
107
    UID essence_codec_ul;
108 07bf2af8 Baptiste Coudurier
    AVRational sample_rate;
109
    AVRational aspect_ratio;
110
    int width;
111
    int height;
112
    int channels;
113
    int bits_per_sample;
114 743d772c Baptiste Coudurier
    UID *sub_descriptors_refs;
115
    int sub_descriptors_count;
116 07bf2af8 Baptiste Coudurier
    int linked_track_id;
117 e1dacee1 Baptiste Coudurier
    uint8_t *extradata;
118
    int extradata_size;
119 07bf2af8 Baptiste Coudurier
} MXFDescriptor;
120
121 743d772c Baptiste Coudurier
typedef struct MXFPackage {
122
    UID uid;
123 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
124 743d772c Baptiste Coudurier
    UID package_uid;
125
    UID *tracks_refs;
126 07bf2af8 Baptiste Coudurier
    int tracks_count;
127 743d772c Baptiste Coudurier
    MXFDescriptor *descriptor; /* only one */
128
    UID descriptor_ref;
129
} MXFPackage;
130
131
typedef struct MXFEssenceContainerData {
132
    UID uid;
133 d2cdbd5f Baptiste Coudurier
    enum MXFMetadataSetType type;
134 743d772c Baptiste Coudurier
    UID linked_package_uid;
135
} MXFEssenceContainerData;
136
137 d2cdbd5f Baptiste Coudurier
typedef struct {
138
    UID uid;
139
    enum MXFMetadataSetType type;
140
} MXFMetadataSet;
141
142 743d772c Baptiste Coudurier
typedef struct MXFContext {
143
    UID *packages_refs;
144
    int packages_count;
145 d2cdbd5f Baptiste Coudurier
    MXFMetadataSet **metadata_sets;
146
    int metadata_sets_count;
147 9bdeba37 Baptiste Coudurier
    const uint8_t *sync_key;
148 743d772c Baptiste Coudurier
    AVFormatContext *fc;
149 80a289b9 Reimar Döffinger
    struct AVAES *aesc;
150 07bf2af8 Baptiste Coudurier
} MXFContext;
151
152 743d772c Baptiste Coudurier
typedef struct KLVPacket {
153 4bfff768 Baptiste Coudurier
    UID key;
154 07bf2af8 Baptiste Coudurier
    offset_t offset;
155
    uint64_t length;
156
} KLVPacket;
157
158 3bb63b82 Baptiste Coudurier
enum MXFWrappingScheme {
159
    Frame,
160
    Clip,
161
};
162
163 743d772c Baptiste Coudurier
typedef struct MXFCodecUL {
164
    UID uid;
165
    enum CodecID id;
166 3bb63b82 Baptiste Coudurier
    enum MXFWrappingScheme wrapping;
167 743d772c Baptiste Coudurier
} MXFCodecUL;
168
169 dd202ff6 Baptiste Coudurier
typedef struct MXFDataDefinitionUL {
170
    UID uid;
171
    enum CodecType type;
172
} MXFDataDefinitionUL;
173
174 b92c61e0 Baptiste Coudurier
typedef struct MXFMetadataReadTableEntry {
175
    const UID key;
176 33bddcdc Baptiste Coudurier
    int (*read)();
177
    int ctx_size;
178
    enum MXFMetadataSetType type;
179 b92c61e0 Baptiste Coudurier
} MXFMetadataReadTableEntry;
180 4bfff768 Baptiste Coudurier
181
/* partial keys to match */
182 dd15f9bf Baptiste Coudurier
static const uint8_t mxf_header_partition_pack_key[]       = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
183 f03b6426 Baptiste Coudurier
static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
184 cabe2527 Baptiste Coudurier
static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
185 86074ce3 Reimar Döffinger
/* complete keys to match */
186
static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
187 80a289b9 Reimar Döffinger
static const uint8_t mxf_encrypted_essence_container[]     = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
188 07bf2af8 Baptiste Coudurier
189
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
190
191 318c5e05 Michel Bardiaux
#define PRINT_KEY(pc, s, x) dprintf(pc, "%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \
192 6c6ec47a Baptiste Coudurier
                             (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15])
193 07bf2af8 Baptiste Coudurier
194
static int64_t klv_decode_ber_length(ByteIOContext *pb)
195
{
196 1fe68f0e Reimar Döffinger
    uint64_t size = get_byte(pb);
197
    if (size & 0x80) { /* long form */
198
        int bytes_num = size & 0x7f;
199 07bf2af8 Baptiste Coudurier
        /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
200
        if (bytes_num > 8)
201
            return -1;
202 1fe68f0e Reimar Döffinger
        size = 0;
203 07bf2af8 Baptiste Coudurier
        while (bytes_num--)
204
            size = size << 8 | get_byte(pb);
205
    }
206
    return size;
207
}
208
209 cabe2527 Baptiste Coudurier
static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
210
{
211
    int i, b;
212
    for (i = 0; i < size && !url_feof(pb); i++) {
213
        b = get_byte(pb);
214
        if (b == key[0])
215
            i = 0;
216
        else if (b != key[i])
217
            i = -1;
218
    }
219
    return i == size;
220
}
221
222 07bf2af8 Baptiste Coudurier
static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb)
223
{
224 cabe2527 Baptiste Coudurier
    if (!mxf_read_sync(pb, mxf_klv_key, 4))
225
        return -1;
226
    klv->offset = url_ftell(pb) - 4;
227
    memcpy(klv->key, mxf_klv_key, 4);
228
    get_buffer(pb, klv->key + 4, 12);
229 07bf2af8 Baptiste Coudurier
    klv->length = klv_decode_ber_length(pb);
230 b7522224 Baptiste Coudurier
    return klv->length == -1 ? -1 : 0;
231 07bf2af8 Baptiste Coudurier
}
232
233
static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
234
{
235
    int i;
236
237
    for (i = 0; i < s->nb_streams; i++) {
238 f03b6426 Baptiste Coudurier
        MXFTrack *track = s->streams[i]->priv_data;
239 55de95b9 Baptiste Coudurier
        /* SMPTE 379M 7.3 */
240 f03b6426 Baptiste Coudurier
        if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
241 07bf2af8 Baptiste Coudurier
            return i;
242
    }
243 03da8726 Baptiste Coudurier
    /* return 0 if only one stream, for OP Atom files with 0 as track number */
244
    return s->nb_streams == 1 ? 0 : -1;
245 07bf2af8 Baptiste Coudurier
}
246
247 885e691a Baptiste Coudurier
/* XXX: use AVBitStreamFilter */
248
static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
249
{
250
    uint8_t buffer[61444];
251
    uint8_t *buf_ptr, *end_ptr, *data_ptr;
252
253
    if (length > 61444) /* worst case PAL 1920 samples 8 channels */
254
        return -1;
255
    get_buffer(pb, buffer, length);
256
    av_new_packet(pkt, length);
257
    data_ptr = pkt->data;
258
    end_ptr = buffer + length;
259
    buf_ptr = buffer + 4; /* skip SMPTE 331M header */
260
    for (; buf_ptr < end_ptr; buf_ptr += 4) {
261
        if (st->codec->bits_per_sample == 24) {
262
            data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4);
263
            data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4);
264
            data_ptr[2] = (buf_ptr[0] >> 4) | ((buf_ptr[1] & 0x0f) << 4);
265
            data_ptr += 3;
266
        } else {
267
            data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4);
268
            data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4);
269
            data_ptr += 2;
270
        }
271
    }
272
    pkt->size = data_ptr - pkt->data;
273
    return 0;
274
}
275
276 80a289b9 Reimar Döffinger
static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
277
{
278
    static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
279
    MXFContext *mxf = s->priv_data;
280
    ByteIOContext *pb = &s->pb;
281
    offset_t end = url_ftell(pb) + klv->length;
282
    uint64_t size;
283
    uint64_t orig_size;
284
    uint64_t plaintext_size;
285
    uint8_t ivec[16];
286
    uint8_t tmpbuf[16];
287
    int index;
288
289
    if (!mxf->aesc && s->key && s->keylen == 16) {
290
        mxf->aesc = av_malloc(av_aes_size);
291
        av_aes_init(mxf->aesc, s->key, 128, 1);
292
    }
293
    // crypto context
294
    url_fskip(pb, klv_decode_ber_length(pb));
295
    // plaintext offset
296
    klv_decode_ber_length(pb);
297
    plaintext_size = get_be64(pb);
298
    // source klv key
299
    klv_decode_ber_length(pb);
300
    get_buffer(pb, klv->key, 16);
301
    if (!IS_KLV_KEY(klv, mxf_essence_element_key)) goto err_out;
302
    index = mxf_get_stream_index(s, klv);
303
    if (index < 0) goto err_out;
304
    // source size
305
    klv_decode_ber_length(pb);
306
    orig_size = get_be64(pb);
307
    if (orig_size < plaintext_size) goto err_out;
308
    // enc. code
309
    size = klv_decode_ber_length(pb);
310
    if (size < 32 || size - 32 < orig_size) goto err_out;
311
    get_buffer(pb, ivec, 16);
312
    get_buffer(pb, tmpbuf, 16);
313
    if (mxf->aesc)
314
        av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
315
    if (memcmp(tmpbuf, checkv, 16))
316
        av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
317
    size -= 32;
318
    av_get_packet(pb, pkt, size);
319
    size -= plaintext_size;
320
    if (mxf->aesc)
321
        av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
322
                     &pkt->data[plaintext_size], size >> 4, ivec, 1);
323
    pkt->size = orig_size;
324
    pkt->stream_index = index;
325
    url_fskip(pb, end - url_ftell(pb));
326
    return 0;
327
328
err_out:
329
    url_fskip(pb, end - url_ftell(pb));
330
    return -1;
331
}
332
333 07bf2af8 Baptiste Coudurier
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
334
{
335 86074ce3 Reimar Döffinger
    MXFContext *mxf = s->priv_data;
336 07bf2af8 Baptiste Coudurier
    KLVPacket klv;
337
338
    while (!url_feof(&s->pb)) {
339 b7889fce Baptiste Coudurier
        if (klv_read_packet(&klv, &s->pb) < 0)
340 07bf2af8 Baptiste Coudurier
            return -1;
341 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
342 318c5e05 Michel Bardiaux
        PRINT_KEY(s, "read packet", klv.key);
343 6d0c3beb Baptiste Coudurier
#endif
344 86074ce3 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
345 80a289b9 Reimar Döffinger
            int res = mxf_decrypt_triplet(s, pkt, &klv);
346 86074ce3 Reimar Döffinger
            mxf->sync_key = mxf_encrypted_triplet_key;
347 80a289b9 Reimar Döffinger
            if (res < 0) {
348
                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
349
                return -1;
350
            }
351
            return 0;
352 86074ce3 Reimar Döffinger
        }
353 07bf2af8 Baptiste Coudurier
        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
354 885e691a Baptiste Coudurier
            int index = mxf_get_stream_index(s, &klv);
355
            if (index < 0) {
356
                av_log(s, AV_LOG_ERROR, "error getting stream index\n");
357 4d6ac1a4 Baptiste Coudurier
                url_fskip(&s->pb, klv.length);
358 885e691a Baptiste Coudurier
                return -1;
359
            }
360
            /* check for 8 channels AES3 element */
361
            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
362
                if (mxf_get_d10_aes3_packet(&s->pb, s->streams[index], pkt, klv.length) < 0) {
363
                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
364
                    return -1;
365
                }
366
            } else
367
                av_get_packet(&s->pb, pkt, klv.length);
368
            pkt->stream_index = index;
369
            return 0;
370 07bf2af8 Baptiste Coudurier
        } else
371
            url_fskip(&s->pb, klv.length);
372
    }
373
    return AVERROR_IO;
374
}
375
376 d2cdbd5f Baptiste Coudurier
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
377
{
378
    mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
379
    mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
380
    mxf->metadata_sets_count++;
381
    return 0;
382
}
383
384 80a289b9 Reimar Döffinger
static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag)
385
{
386
    switch(tag) {
387
    case 0xFFFE:
388
        get_buffer(pb, cryptocontext->context_uid, 16);
389
        break;
390
    case 0xFFFD:
391
        get_buffer(pb, cryptocontext->source_container_ul, 16);
392
        break;
393
    }
394
    return 0;
395
}
396
397 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
398 743d772c Baptiste Coudurier
{
399 55de95b9 Baptiste Coudurier
    switch (tag) {
400
    case 0x1901:
401
        mxf->packages_count = get_be32(pb);
402
        if (mxf->packages_count >= UINT_MAX / sizeof(UID))
403
            return -1;
404
        mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
405
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
406
        get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID));
407
        break;
408
    }
409 743d772c Baptiste Coudurier
    return 0;
410
}
411
412 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag)
413 743d772c Baptiste Coudurier
{
414 55de95b9 Baptiste Coudurier
    switch(tag) {
415
    case 0x0202:
416
        source_clip->duration = get_be64(pb);
417
        break;
418
    case 0x1201:
419
        source_clip->start_position = get_be64(pb);
420
        break;
421
    case 0x1101:
422
        /* UMID, only get last 16 bytes */
423
        url_fskip(pb, 16);
424
        get_buffer(pb, source_clip->source_package_uid, 16);
425
        break;
426
    case 0x1102:
427
        source_clip->source_track_id = get_be32(pb);
428
        break;
429
    }
430
    return 0;
431 743d772c Baptiste Coudurier
}
432
433 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_material_package(MXFPackage *package, ByteIOContext *pb, int tag)
434 743d772c Baptiste Coudurier
{
435 55de95b9 Baptiste Coudurier
    switch(tag) {
436
    case 0x4403:
437
        package->tracks_count = get_be32(pb);
438
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
439
            return -1;
440
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
441
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
442
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
443
        break;
444
    }
445
    return 0;
446 743d772c Baptiste Coudurier
}
447
448 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_track(MXFTrack *track, ByteIOContext *pb, int tag)
449 743d772c Baptiste Coudurier
{
450 55de95b9 Baptiste Coudurier
    switch(tag) {
451
    case 0x4801:
452
        track->track_id = get_be32(pb);
453
        break;
454
    case 0x4804:
455
        get_buffer(pb, track->track_number, 4);
456
        break;
457
    case 0x4B01:
458
        track->edit_rate.den = get_be32(pb);
459
        track->edit_rate.num = get_be32(pb);
460
        break;
461
    case 0x4803:
462
        get_buffer(pb, track->sequence_ref, 16);
463
        break;
464
    }
465
    return 0;
466 07bf2af8 Baptiste Coudurier
}
467
468 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag)
469 07bf2af8 Baptiste Coudurier
{
470 55de95b9 Baptiste Coudurier
    switch(tag) {
471
    case 0x0202:
472
        sequence->duration = get_be64(pb);
473
        break;
474
    case 0x0201:
475
        get_buffer(pb, sequence->data_definition_ul, 16);
476
        break;
477
    case 0x1001:
478
        sequence->structural_components_count = get_be32(pb);
479
        if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
480
            return -1;
481
        sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
482
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
483
        get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
484
        break;
485
    }
486
    return 0;
487 07bf2af8 Baptiste Coudurier
}
488
489 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_source_package(MXFPackage *package, ByteIOContext *pb, int tag)
490 07bf2af8 Baptiste Coudurier
{
491 55de95b9 Baptiste Coudurier
    switch(tag) {
492
    case 0x4403:
493
        package->tracks_count = get_be32(pb);
494
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
495
            return -1;
496
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
497
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
498
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
499
        break;
500
    case 0x4401:
501
        /* UMID, only get last 16 bytes */
502
        url_fskip(pb, 16);
503
        get_buffer(pb, package->package_uid, 16);
504
        break;
505
    case 0x4701:
506
        get_buffer(pb, package->descriptor_ref, 16);
507
        break;
508
    }
509
    return 0;
510 07bf2af8 Baptiste Coudurier
}
511
512 59b56738 Baptiste Coudurier
static void mxf_read_metadata_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor)
513
{
514
    int code;
515
516
    do {
517
        code = get_byte(pb);
518 318c5e05 Michel Bardiaux
        dprintf(NULL, "pixel layout: code 0x%x\n", code);
519 59b56738 Baptiste Coudurier
        switch (code) {
520
        case 0x52: /* R */
521
            descriptor->bits_per_sample += get_byte(pb);
522
            break;
523
        case 0x47: /* G */
524
            descriptor->bits_per_sample += get_byte(pb);
525
            break;
526
        case 0x42: /* B */
527
            descriptor->bits_per_sample += get_byte(pb);
528
            break;
529
        default:
530
            get_byte(pb);
531
        }
532
    } while (code != 0); /* SMPTE 377M E.2.46 */
533
}
534
535 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size)
536 743d772c Baptiste Coudurier
{
537 55de95b9 Baptiste Coudurier
    switch(tag) {
538 e6837cfa Baptiste Coudurier
    case 0x3F01:
539
        descriptor->sub_descriptors_count = get_be32(pb);
540
        if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
541
            return -1;
542
        descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
543
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
544
        get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
545
        break;
546 55de95b9 Baptiste Coudurier
    case 0x3004:
547
        get_buffer(pb, descriptor->essence_container_ul, 16);
548
        break;
549
    case 0x3006:
550
        descriptor->linked_track_id = get_be32(pb);
551
        break;
552
    case 0x3201: /* PictureEssenceCoding */
553
        get_buffer(pb, descriptor->essence_codec_ul, 16);
554
        break;
555
    case 0x3203:
556
        descriptor->width = get_be32(pb);
557
        break;
558
    case 0x3202:
559
        descriptor->height = get_be32(pb);
560
        break;
561
    case 0x320E:
562
        descriptor->aspect_ratio.num = get_be32(pb);
563
        descriptor->aspect_ratio.den = get_be32(pb);
564
        break;
565
    case 0x3D03:
566
        descriptor->sample_rate.num = get_be32(pb);
567
        descriptor->sample_rate.den = get_be32(pb);
568
        break;
569
    case 0x3D06: /* SoundEssenceCompression */
570
        get_buffer(pb, descriptor->essence_codec_ul, 16);
571
        break;
572
    case 0x3D07:
573
        descriptor->channels = get_be32(pb);
574
        break;
575
    case 0x3D01:
576
        descriptor->bits_per_sample = get_be32(pb);
577
        break;
578
    case 0x3401:
579
        mxf_read_metadata_pixel_layout(pb, descriptor);
580
        break;
581
    case 0x8201: /* Private tag used by SONY C0023S01.mxf */
582
        descriptor->extradata = av_malloc(size);
583
        descriptor->extradata_size = size;
584
        get_buffer(pb, descriptor->extradata, size);
585
        break;
586
    }
587
    return 0;
588 07bf2af8 Baptiste Coudurier
}
589
590
/* SMPTE RP224 http://www.smpte-ra.org/mdd/index.html */
591 dd202ff6 Baptiste Coudurier
static const MXFDataDefinitionUL mxf_data_definition_uls[] = {
592
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, CODEC_TYPE_VIDEO },
593
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, CODEC_TYPE_AUDIO },
594 1159f634 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x05,0x01,0x03,0x02,0x02,0x02,0x02,0x00,0x00 }, CODEC_TYPE_AUDIO },
595 dd202ff6 Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  CODEC_TYPE_DATA },
596
};
597 743d772c Baptiste Coudurier
598
static const MXFCodecUL mxf_codec_uls[] = {
599
    /* PictureEssenceCoding */
600 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@ML Long GoP */
601 3c6b46d3 Baptiste Coudurier
602
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 30Mbps PAL */
603
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 40Mbps PAL */
604
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 50Mbps PAL */
605
606
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML I-Frame */
607 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML Long GoP */
608 3c6b46d3 Baptiste Coudurier
609 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@HL Long GoP */
610 3c6b46d3 Baptiste Coudurier
611
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL I-Frame */
612
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL Long GoP */
613
614 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 },      CODEC_ID_MPEG4, Frame }, /* XDCAM proxy_pal030926.mxf */
615
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x04 },      CODEC_ID_MPEG4, Frame }, /* XDCAM Proxy C0023S01.mxf */
616 3c6b46d3 Baptiste Coudurier
617 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DV25 IEC PAL */
618 3c6b46d3 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DVCPRO25 PAL */
619
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DVCPRO50 PAL */
620
621 acf36dba Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 },   CODEC_ID_JPEG2000, Frame }, /* JPEG2000 Codestream */
622 3c6b46d3 Baptiste Coudurier
623 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 },   CODEC_ID_RAWVIDEO, Frame }, /* Uncompressed */
624 743d772c Baptiste Coudurier
    /* SoundEssenceCompression */
625 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 },  CODEC_ID_PCM_S16LE, Frame }, /* Uncompressed */
626
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 },  CODEC_ID_PCM_S16LE, Frame },
627
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 },  CODEC_ID_PCM_S16BE, Frame }, /* From Omneon MXF file */
628
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 },   CODEC_ID_PCM_ALAW, Frame },
629
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 },   CODEC_ID_PCM_ALAW, Frame }, /* XDCAM Proxy C0023S01.mxf */
630
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 },        CODEC_ID_AC3, Frame },
631
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 },        CODEC_ID_MP2, Frame }, /* MP2 or MP3 */
632
  //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 },    CODEC_ID_DOLBY_E, Frame }, /* Dolby-E */
633
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
634 07bf2af8 Baptiste Coudurier
};
635
636 8c5002db Baptiste Coudurier
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
637 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MPEG-ES Frame wrapped */
638
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xe0,0x02 }, CODEC_ID_MPEG2VIDEO,  Clip }, /* MPEG-ES Clip wrapped, 0xe0 MPV stream id */
639
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x04,0x61,0x07 }, CODEC_ID_MPEG2VIDEO,  Clip }, /* MPEG-ES Custom wrapped, 0x61 ??? stream id */
640
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
641 8c5002db Baptiste Coudurier
};
642
643
static const MXFCodecUL mxf_sound_essence_container_uls[] = {
644 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 },  CODEC_ID_PCM_S16LE, Frame }, /* BWF Frame wrapped */
645
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },  CODEC_ID_PCM_S16LE, Frame }, /* AES Frame wrapped */
646
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 },        CODEC_ID_MP2, Frame }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */
647
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xc0,0x01 },        CODEC_ID_MP2, Frame }, /* MPEG-ES Frame wrapped, 0xc0 MPA stream id */
648
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xc0,0x02 },        CODEC_ID_MP2,  Clip }, /* MPEG-ES Clip wrapped, 0xc0 MPA stream id */
649 885e691a Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },  CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 30Mbps PAL Extended Template */
650 c4fe61ff Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },  CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 40Mbps PAL Extended Template */
651 885e691a Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },  CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 50Mbps PAL Extended Template */
652 3bb63b82 Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
653 8c5002db Baptiste Coudurier
};
654
655 6982462f Baptiste Coudurier
/*
656
 * Match an uid independently of the version byte and up to len common bytes
657
 * Returns: boolean
658
 */
659
static int mxf_match_uid(const UID key, const UID uid, int len)
660
{
661
    int i;
662
    for (i = 0; i < len; i++) {
663
        if (i != 7 && key[i] != uid[i])
664
            return 0;
665
    }
666
    return 1;
667
}
668
669 3bb63b82 Baptiste Coudurier
static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
670 743d772c Baptiste Coudurier
{
671
    while (uls->id != CODEC_ID_NONE) {
672 6982462f Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, 16))
673 3bb63b82 Baptiste Coudurier
            break;
674 743d772c Baptiste Coudurier
        uls++;
675
    }
676 3bb63b82 Baptiste Coudurier
    return uls;
677 743d772c Baptiste Coudurier
}
678 07bf2af8 Baptiste Coudurier
679 dd202ff6 Baptiste Coudurier
static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
680
{
681
    while (uls->type != CODEC_TYPE_DATA) {
682 6982462f Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, 16))
683 dd202ff6 Baptiste Coudurier
            break;
684
        uls++;
685
    }
686
    return uls->type;
687
}
688
689 2d193b2e Reimar Döffinger
static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
690 d2cdbd5f Baptiste Coudurier
{
691
    int i;
692
693
    if (!strong_ref)
694
        return NULL;
695
    for (i = 0; i < mxf->metadata_sets_count; i++) {
696 2d193b2e Reimar Döffinger
        if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
697 6ac558ee Baptiste Coudurier
            (type == AnyType || mxf->metadata_sets[i]->type == type)) {
698 d2cdbd5f Baptiste Coudurier
            return mxf->metadata_sets[i];
699
        }
700
    }
701
    return NULL;
702
}
703
704 743d772c Baptiste Coudurier
static int mxf_parse_structural_metadata(MXFContext *mxf)
705 07bf2af8 Baptiste Coudurier
{
706 743d772c Baptiste Coudurier
    MXFPackage *material_package = NULL;
707 d2cdbd5f Baptiste Coudurier
    MXFPackage *temp_package = NULL;
708 743d772c Baptiste Coudurier
    int i, j, k;
709
710 318c5e05 Michel Bardiaux
    dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
711 743d772c Baptiste Coudurier
    /* TODO: handle multiple material packages (OP3x) */
712
    for (i = 0; i < mxf->packages_count; i++) {
713 2d193b2e Reimar Döffinger
        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
714
        if (material_package) break;
715 743d772c Baptiste Coudurier
    }
716
    if (!material_package) {
717
        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
718
        return -1;
719
    }
720 07bf2af8 Baptiste Coudurier
721 743d772c Baptiste Coudurier
    for (i = 0; i < material_package->tracks_count; i++) {
722 7f25df4c Baptiste Coudurier
        MXFPackage *source_package = NULL;
723 d2cdbd5f Baptiste Coudurier
        MXFTrack *material_track = NULL;
724 743d772c Baptiste Coudurier
        MXFTrack *source_track = NULL;
725 d2cdbd5f Baptiste Coudurier
        MXFTrack *temp_track = NULL;
726 743d772c Baptiste Coudurier
        MXFDescriptor *descriptor = NULL;
727
        MXFStructuralComponent *component = NULL;
728 80a289b9 Reimar Döffinger
        UID *essence_container_ul = NULL;
729 3bb63b82 Baptiste Coudurier
        const MXFCodecUL *codec_ul = NULL;
730
        const MXFCodecUL *container_ul = NULL;
731 743d772c Baptiste Coudurier
        AVStream *st;
732
733 2d193b2e Reimar Döffinger
        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
734 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
735
            continue;
736
        }
737
738 2d193b2e Reimar Döffinger
        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
739 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
740
            return -1;
741
        }
742
743 743d772c Baptiste Coudurier
        /* TODO: handle multiple source clips */
744
        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
745
            /* TODO: handle timecode component */
746 2d193b2e Reimar Döffinger
            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
747
            if (!component)
748 743d772c Baptiste Coudurier
                continue;
749
750
            for (k = 0; k < mxf->packages_count; k++) {
751 2d193b2e Reimar Döffinger
                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
752
                if (!temp_package)
753
                    continue;
754 d2cdbd5f Baptiste Coudurier
                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
755
                    source_package = temp_package;
756 743d772c Baptiste Coudurier
                    break;
757
                }
758
            }
759
            if (!source_package) {
760
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
761
                break;
762
            }
763
            for (k = 0; k < source_package->tracks_count; k++) {
764 2d193b2e Reimar Döffinger
                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
765 d2cdbd5f Baptiste Coudurier
                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
766
                    return -1;
767
                }
768
                if (temp_track->track_id == component->source_track_id) {
769
                    source_track = temp_track;
770 743d772c Baptiste Coudurier
                    break;
771
                }
772
            }
773
            if (!source_track) {
774
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
775
                break;
776
            }
777
        }
778
        if (!source_track)
779
            continue;
780
781 f03b6426 Baptiste Coudurier
        st = av_new_stream(mxf->fc, source_track->track_id);
782
        st->priv_data = source_track;
783 743d772c Baptiste Coudurier
        st->duration = component->duration;
784
        if (st->duration == -1)
785
            st->duration = AV_NOPTS_VALUE;
786
        st->start_time = component->start_position;
787
        av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
788 d2cdbd5f Baptiste Coudurier
789 2d193b2e Reimar Döffinger
        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
790 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
791
            return -1;
792
        }
793
794 743d772c Baptiste Coudurier
#ifdef DEBUG
795 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
796 743d772c Baptiste Coudurier
#endif
797 dd202ff6 Baptiste Coudurier
        st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
798 743d772c Baptiste Coudurier
799 6ac558ee Baptiste Coudurier
        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
800 743d772c Baptiste Coudurier
        if (source_package->descriptor) {
801 d2cdbd5f Baptiste Coudurier
            if (source_package->descriptor->type == MultipleDescriptor) {
802 743d772c Baptiste Coudurier
                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
803 2d193b2e Reimar Döffinger
                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
804 d2cdbd5f Baptiste Coudurier
805
                    if (!sub_descriptor) {
806
                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
807
                        continue;
808
                    }
809
                    if (sub_descriptor->linked_track_id == source_track->track_id) {
810
                        descriptor = sub_descriptor;
811
                        break;
812 07bf2af8 Baptiste Coudurier
                    }
813
                }
814 6ac558ee Baptiste Coudurier
            } else if (source_package->descriptor->type == Descriptor)
815 743d772c Baptiste Coudurier
                descriptor = source_package->descriptor;
816
        }
817
        if (!descriptor) {
818
            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
819
            continue;
820
        }
821
#ifdef DEBUG
822 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);
823
        PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
824 743d772c Baptiste Coudurier
#endif
825 80a289b9 Reimar Döffinger
        essence_container_ul = &descriptor->essence_container_ul;
826
        /* HACK: replacing the original key with mxf_encrypted_essence_container
827
         * is not allowed according to s429-6, try to find correct information anyway */
828
        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
829
            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
830
            for (k = 0; k < mxf->metadata_sets_count; k++) {
831
                MXFMetadataSet *metadata = mxf->metadata_sets[k];
832
                if (metadata->type == CryptoContext) {
833
                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
834
                    break;
835
                }
836
            }
837
        }
838 3bb63b82 Baptiste Coudurier
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
839
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
840 c2e88054 Baptiste Coudurier
        st->codec->codec_id = codec_ul->id;
841 e1dacee1 Baptiste Coudurier
        if (descriptor->extradata) {
842
            st->codec->extradata = descriptor->extradata;
843
            st->codec->extradata_size = descriptor->extradata_size;
844
        }
845 743d772c Baptiste Coudurier
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
846 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
847 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
848 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
849 743d772c Baptiste Coudurier
            st->codec->width = descriptor->width;
850
            st->codec->height = descriptor->height;
851 59b56738 Baptiste Coudurier
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
852 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
853 743d772c Baptiste Coudurier
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
854 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
855 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
856 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
857 743d772c Baptiste Coudurier
            st->codec->channels = descriptor->channels;
858
            st->codec->bits_per_sample = descriptor->bits_per_sample;
859
            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
860
            /* TODO: implement CODEC_ID_RAWAUDIO */
861
            if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
862
                if (descriptor->bits_per_sample == 24)
863
                    st->codec->codec_id = CODEC_ID_PCM_S24LE;
864
                else if (descriptor->bits_per_sample == 32)
865
                    st->codec->codec_id = CODEC_ID_PCM_S32LE;
866
            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
867
                if (descriptor->bits_per_sample == 24)
868
                    st->codec->codec_id = CODEC_ID_PCM_S24BE;
869
                else if (descriptor->bits_per_sample == 32)
870
                    st->codec->codec_id = CODEC_ID_PCM_S32BE;
871 c74915cd Baptiste Coudurier
                if (descriptor->essence_container_ul[13] == 0x01) /* D-10 Mapping */
872 885e691a Baptiste Coudurier
                    st->codec->channels = 8; /* force channels to 8 */
873 c86ecbb7 Baptiste Coudurier
            } else if (st->codec->codec_id == CODEC_ID_MP2) {
874 57004ff1 Aurelien Jacobs
                st->need_parsing = AVSTREAM_PARSE_FULL;
875 07bf2af8 Baptiste Coudurier
            }
876
        }
877 f0d47292 Baptiste Coudurier
        if (container_ul && container_ul->wrapping == Clip) {
878 318c5e05 Michel Bardiaux
            dprintf(mxf->fc, "stream %d: clip wrapped essence\n", st->index);
879 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_FULL;
880 c2e88054 Baptiste Coudurier
        }
881 07bf2af8 Baptiste Coudurier
    }
882 743d772c Baptiste Coudurier
    return 0;
883 07bf2af8 Baptiste Coudurier
}
884
885 b92c61e0 Baptiste Coudurier
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
886 33bddcdc Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_metadata_content_storage, 0, AnyType },
887
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage },
888
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage },
889
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence },
890
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip },
891 e6837cfa Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
892 33bddcdc Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */
893
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */
894
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */
895
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */
896
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
897
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
898
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Static Track */
899
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_metadata_track, sizeof(MXFTrack), Track }, /* Generic Track */
900 80a289b9 Reimar Döffinger
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_metadata_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
901 33bddcdc Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
902 b92c61e0 Baptiste Coudurier
};
903
904 33bddcdc Baptiste Coudurier
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
905
{
906
    ByteIOContext *pb = &mxf->fc->pb;
907
    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
908
    uint64_t klv_end= url_ftell(pb) + klv->length;
909
910
    while (url_ftell(pb) + 4 < klv_end) {
911
        int tag = get_be16(pb);
912
        int size = get_be16(pb); /* KLV specified by 0x53 */
913
        uint64_t next= url_ftell(pb) + size;
914
915
        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
916
            av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
917
            continue;
918
        }
919
        if(ctx_size && tag == 0x3C0A)
920
            get_buffer(pb, ctx->uid, 16);
921
        else
922
            read_child(ctx, pb, tag, size);
923
924
        url_fseek(pb, next, SEEK_SET);
925
    }
926
    if (ctx_size) ctx->type = type;
927
    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
928
}
929
930 07bf2af8 Baptiste Coudurier
static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
931
{
932
    MXFContext *mxf = s->priv_data;
933
    KLVPacket klv;
934
935 86074ce3 Reimar Döffinger
    mxf->sync_key = mxf_essence_element_key;
936 ee71ef5c Baptiste Coudurier
    if (!mxf_read_sync(&s->pb, mxf_header_partition_pack_key, 14)) {
937
        av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
938
        return -1;
939
    }
940
    url_fseek(&s->pb, -14, SEEK_CUR);
941 07bf2af8 Baptiste Coudurier
    mxf->fc = s;
942
    while (!url_feof(&s->pb)) {
943 975c88e3 Baptiste Coudurier
        const MXFMetadataReadTableEntry *metadata;
944 b92c61e0 Baptiste Coudurier
945 b7889fce Baptiste Coudurier
        if (klv_read_packet(&klv, &s->pb) < 0)
946 07bf2af8 Baptiste Coudurier
            return -1;
947 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
948 318c5e05 Michel Bardiaux
        PRINT_KEY(s, "read header", klv.key);
949 6d0c3beb Baptiste Coudurier
#endif
950 80a289b9 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
951
            IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
952 07bf2af8 Baptiste Coudurier
            /* FIXME avoid seek */
953
            url_fseek(&s->pb, klv.offset, SEEK_SET);
954
            break;
955 5e441e31 Baptiste Coudurier
        }
956 b92c61e0 Baptiste Coudurier
957 975c88e3 Baptiste Coudurier
        for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
958
            if (IS_KLV_KEY(klv.key, metadata->key)) {
959
                if (mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
960 b92c61e0 Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
961
                    return -1;
962
                }
963
                break;
964
            }
965
        }
966 975c88e3 Baptiste Coudurier
        if (!metadata->read)
967 b92c61e0 Baptiste Coudurier
            url_fskip(&s->pb, klv.length);
968 07bf2af8 Baptiste Coudurier
    }
969 743d772c Baptiste Coudurier
    return mxf_parse_structural_metadata(mxf);
970 07bf2af8 Baptiste Coudurier
}
971
972
static int mxf_read_close(AVFormatContext *s)
973
{
974
    MXFContext *mxf = s->priv_data;
975 d2cdbd5f Baptiste Coudurier
    int i;
976 743d772c Baptiste Coudurier
977
    av_freep(&mxf->packages_refs);
978 d2cdbd5f Baptiste Coudurier
    for (i = 0; i < mxf->metadata_sets_count; i++) {
979
        switch (mxf->metadata_sets[i]->type) {
980
        case MultipleDescriptor:
981
            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
982
            break;
983
        case Sequence:
984
            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
985
            break;
986
        case SourcePackage:
987
        case MaterialPackage:
988
            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
989
            break;
990
        default:
991
            break;
992
        }
993
        av_freep(&mxf->metadata_sets[i]);
994
    }
995
    av_freep(&mxf->metadata_sets);
996 80a289b9 Reimar Döffinger
    av_freep(&mxf->aesc);
997 07bf2af8 Baptiste Coudurier
    return 0;
998
}
999
1000
static int mxf_probe(AVProbeData *p) {
1001 ba32c8df Baptiste Coudurier
    uint8_t *bufp = p->buf;
1002
    uint8_t *end = p->buf + p->buf_size;
1003
1004 07bf2af8 Baptiste Coudurier
    if (p->buf_size < sizeof(mxf_header_partition_pack_key))
1005
        return 0;
1006
1007 ba32c8df Baptiste Coudurier
    /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
1008
    end -= sizeof(mxf_header_partition_pack_key);
1009
    for (; bufp < end; bufp++) {
1010 f8503792 Baptiste Coudurier
        if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
1011 ba32c8df Baptiste Coudurier
            return AVPROBE_SCORE_MAX;
1012
    }
1013
    return 0;
1014 07bf2af8 Baptiste Coudurier
}
1015
1016 2f8fe719 Baptiste Coudurier
/* rudimentary byte seek */
1017 3a6ccf4f Baptiste Coudurier
/* XXX: use MXF Index */
1018
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1019
{
1020 86074ce3 Reimar Döffinger
    MXFContext *mxf = s->priv_data;
1021 3a6ccf4f Baptiste Coudurier
    AVStream *st = s->streams[stream_index];
1022
    int64_t seconds;
1023
1024 de9fe002 Baptiste Coudurier
    if (!s->bit_rate)
1025 3a6ccf4f Baptiste Coudurier
        return -1;
1026 de9fe002 Baptiste Coudurier
    if (sample_time < 0)
1027
        sample_time = 0;
1028 3a6ccf4f Baptiste Coudurier
    seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
1029
    url_fseek(&s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
1030 86074ce3 Reimar Döffinger
    if (!mxf_read_sync(&s->pb, mxf->sync_key, 12))
1031 ee71ef5c Baptiste Coudurier
        return -1;
1032
1033
    /* found KLV key */
1034
    url_fseek(&s->pb, -12, SEEK_CUR);
1035
    av_update_cur_dts(s, st, sample_time);
1036
    return 0;
1037 3a6ccf4f Baptiste Coudurier
}
1038 07bf2af8 Baptiste Coudurier
1039
AVInputFormat mxf_demuxer = {
1040
    "mxf",
1041
    "MXF format",
1042
    sizeof(MXFContext),
1043
    mxf_probe,
1044
    mxf_read_header,
1045
    mxf_read_packet,
1046
    mxf_read_close,
1047 3a6ccf4f Baptiste Coudurier
    mxf_read_seek,
1048 07bf2af8 Baptiste Coudurier
};