Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 1d7d9935

History | View | Annotate | Download (40.8 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 86074ce3 Reimar Döffinger
/* complete keys to match */
185
static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
186 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 };
187 07bf2af8 Baptiste Coudurier
188
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
189
190 996c9ad0 Baptiste Coudurier
#define PRINT_KEY(s, x) dprintf("%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \
191 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])
192 07bf2af8 Baptiste Coudurier
193
static int64_t klv_decode_ber_length(ByteIOContext *pb)
194
{
195 1fe68f0e Reimar Döffinger
    uint64_t size = get_byte(pb);
196
    if (size & 0x80) { /* long form */
197
        int bytes_num = size & 0x7f;
198 07bf2af8 Baptiste Coudurier
        /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
199
        if (bytes_num > 8)
200
            return -1;
201 1fe68f0e Reimar Döffinger
        size = 0;
202 07bf2af8 Baptiste Coudurier
        while (bytes_num--)
203
            size = size << 8 | get_byte(pb);
204
    }
205
    return size;
206
}
207
208
static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb)
209
{
210
    klv->offset = url_ftell(pb);
211
    get_buffer(pb, klv->key, 16);
212
    klv->length = klv_decode_ber_length(pb);
213 b7522224 Baptiste Coudurier
    return klv->length == -1 ? -1 : 0;
214 07bf2af8 Baptiste Coudurier
}
215
216
static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
217
{
218
    int i;
219
220
    for (i = 0; i < s->nb_streams; i++) {
221 f03b6426 Baptiste Coudurier
        MXFTrack *track = s->streams[i]->priv_data;
222 55de95b9 Baptiste Coudurier
        /* SMPTE 379M 7.3 */
223 f03b6426 Baptiste Coudurier
        if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
224 07bf2af8 Baptiste Coudurier
            return i;
225
    }
226 03da8726 Baptiste Coudurier
    /* return 0 if only one stream, for OP Atom files with 0 as track number */
227
    return s->nb_streams == 1 ? 0 : -1;
228 07bf2af8 Baptiste Coudurier
}
229
230 885e691a Baptiste Coudurier
/* XXX: use AVBitStreamFilter */
231
static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
232
{
233
    uint8_t buffer[61444];
234
    uint8_t *buf_ptr, *end_ptr, *data_ptr;
235
236
    if (length > 61444) /* worst case PAL 1920 samples 8 channels */
237
        return -1;
238
    get_buffer(pb, buffer, length);
239
    av_new_packet(pkt, length);
240
    data_ptr = pkt->data;
241
    end_ptr = buffer + length;
242
    buf_ptr = buffer + 4; /* skip SMPTE 331M header */
243
    for (; buf_ptr < end_ptr; buf_ptr += 4) {
244
        if (st->codec->bits_per_sample == 24) {
245
            data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4);
246
            data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4);
247
            data_ptr[2] = (buf_ptr[0] >> 4) | ((buf_ptr[1] & 0x0f) << 4);
248
            data_ptr += 3;
249
        } else {
250
            data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4);
251
            data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4);
252
            data_ptr += 2;
253
        }
254
    }
255
    pkt->size = data_ptr - pkt->data;
256
    return 0;
257
}
258
259 80a289b9 Reimar Döffinger
static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
260
{
261
    static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
262
    MXFContext *mxf = s->priv_data;
263
    ByteIOContext *pb = &s->pb;
264
    offset_t end = url_ftell(pb) + klv->length;
265
    uint64_t size;
266
    uint64_t orig_size;
267
    uint64_t plaintext_size;
268
    uint8_t ivec[16];
269
    uint8_t tmpbuf[16];
270
    int index;
271
272
    if (!mxf->aesc && s->key && s->keylen == 16) {
273
        mxf->aesc = av_malloc(av_aes_size);
274
        av_aes_init(mxf->aesc, s->key, 128, 1);
275
    }
276
    // crypto context
277
    url_fskip(pb, klv_decode_ber_length(pb));
278
    // plaintext offset
279
    klv_decode_ber_length(pb);
280
    plaintext_size = get_be64(pb);
281
    // source klv key
282
    klv_decode_ber_length(pb);
283
    get_buffer(pb, klv->key, 16);
284
    if (!IS_KLV_KEY(klv, mxf_essence_element_key)) goto err_out;
285
    index = mxf_get_stream_index(s, klv);
286
    if (index < 0) goto err_out;
287
    // source size
288
    klv_decode_ber_length(pb);
289
    orig_size = get_be64(pb);
290
    if (orig_size < plaintext_size) goto err_out;
291
    // enc. code
292
    size = klv_decode_ber_length(pb);
293
    if (size < 32 || size - 32 < orig_size) goto err_out;
294
    get_buffer(pb, ivec, 16);
295
    get_buffer(pb, tmpbuf, 16);
296
    if (mxf->aesc)
297
        av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
298
    if (memcmp(tmpbuf, checkv, 16))
299
        av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
300
    size -= 32;
301
    av_get_packet(pb, pkt, size);
302
    size -= plaintext_size;
303
    if (mxf->aesc)
304
        av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
305
                     &pkt->data[plaintext_size], size >> 4, ivec, 1);
306
    pkt->size = orig_size;
307
    pkt->stream_index = index;
308
    url_fskip(pb, end - url_ftell(pb));
309
    return 0;
310
311
err_out:
312
    url_fskip(pb, end - url_ftell(pb));
313
    return -1;
314
}
315
316 07bf2af8 Baptiste Coudurier
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
317
{
318 86074ce3 Reimar Döffinger
    MXFContext *mxf = s->priv_data;
319 07bf2af8 Baptiste Coudurier
    KLVPacket klv;
320
321
    while (!url_feof(&s->pb)) {
322 5e441e31 Baptiste Coudurier
        if (klv_read_packet(&klv, &s->pb) < 0) {
323
            av_log(s, AV_LOG_ERROR, "error reading KLV packet\n");
324 07bf2af8 Baptiste Coudurier
            return -1;
325 5e441e31 Baptiste Coudurier
        }
326 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
327 996c9ad0 Baptiste Coudurier
        PRINT_KEY("read packet", klv.key);
328 6d0c3beb Baptiste Coudurier
#endif
329 86074ce3 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
330 80a289b9 Reimar Döffinger
            int res = mxf_decrypt_triplet(s, pkt, &klv);
331 86074ce3 Reimar Döffinger
            mxf->sync_key = mxf_encrypted_triplet_key;
332 80a289b9 Reimar Döffinger
            if (res < 0) {
333
                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
334
                return -1;
335
            }
336
            return 0;
337 86074ce3 Reimar Döffinger
        }
338 07bf2af8 Baptiste Coudurier
        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
339 885e691a Baptiste Coudurier
            int index = mxf_get_stream_index(s, &klv);
340
            if (index < 0) {
341
                av_log(s, AV_LOG_ERROR, "error getting stream index\n");
342 4d6ac1a4 Baptiste Coudurier
                url_fskip(&s->pb, klv.length);
343 885e691a Baptiste Coudurier
                return -1;
344
            }
345
            /* check for 8 channels AES3 element */
346
            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
347
                if (mxf_get_d10_aes3_packet(&s->pb, s->streams[index], pkt, klv.length) < 0) {
348
                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
349
                    return -1;
350
                }
351
            } else
352
                av_get_packet(&s->pb, pkt, klv.length);
353
            pkt->stream_index = index;
354
            return 0;
355 07bf2af8 Baptiste Coudurier
        } else
356
            url_fskip(&s->pb, klv.length);
357
    }
358
    return AVERROR_IO;
359
}
360
361 d2cdbd5f Baptiste Coudurier
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
362
{
363
    mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
364
    mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
365
    mxf->metadata_sets_count++;
366
    return 0;
367
}
368
369 80a289b9 Reimar Döffinger
static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag)
370
{
371
    switch(tag) {
372
    case 0xFFFE:
373
        get_buffer(pb, cryptocontext->context_uid, 16);
374
        break;
375
    case 0xFFFD:
376
        get_buffer(pb, cryptocontext->source_container_ul, 16);
377
        break;
378
    }
379
    return 0;
380
}
381
382 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
383 743d772c Baptiste Coudurier
{
384 55de95b9 Baptiste Coudurier
    switch (tag) {
385
    case 0x1901:
386
        mxf->packages_count = get_be32(pb);
387
        if (mxf->packages_count >= UINT_MAX / sizeof(UID))
388
            return -1;
389
        mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
390
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
391
        get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID));
392
        break;
393
    }
394 743d772c Baptiste Coudurier
    return 0;
395
}
396
397 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag)
398 743d772c Baptiste Coudurier
{
399 55de95b9 Baptiste Coudurier
    switch(tag) {
400
    case 0x0202:
401
        source_clip->duration = get_be64(pb);
402
        break;
403
    case 0x1201:
404
        source_clip->start_position = get_be64(pb);
405
        break;
406
    case 0x1101:
407
        /* UMID, only get last 16 bytes */
408
        url_fskip(pb, 16);
409
        get_buffer(pb, source_clip->source_package_uid, 16);
410
        break;
411
    case 0x1102:
412
        source_clip->source_track_id = get_be32(pb);
413
        break;
414
    }
415
    return 0;
416 743d772c Baptiste Coudurier
}
417
418 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_material_package(MXFPackage *package, ByteIOContext *pb, int tag)
419 743d772c Baptiste Coudurier
{
420 55de95b9 Baptiste Coudurier
    switch(tag) {
421
    case 0x4403:
422
        package->tracks_count = get_be32(pb);
423
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
424
            return -1;
425
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
426
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
427
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
428
        break;
429
    }
430
    return 0;
431 743d772c Baptiste Coudurier
}
432
433 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_track(MXFTrack *track, ByteIOContext *pb, int tag)
434 743d772c Baptiste Coudurier
{
435 55de95b9 Baptiste Coudurier
    switch(tag) {
436
    case 0x4801:
437
        track->track_id = get_be32(pb);
438
        break;
439
    case 0x4804:
440
        get_buffer(pb, track->track_number, 4);
441
        break;
442
    case 0x4B01:
443
        track->edit_rate.den = get_be32(pb);
444
        track->edit_rate.num = get_be32(pb);
445
        break;
446
    case 0x4803:
447
        get_buffer(pb, track->sequence_ref, 16);
448
        break;
449
    }
450
    return 0;
451 07bf2af8 Baptiste Coudurier
}
452
453 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag)
454 07bf2af8 Baptiste Coudurier
{
455 55de95b9 Baptiste Coudurier
    switch(tag) {
456
    case 0x0202:
457
        sequence->duration = get_be64(pb);
458
        break;
459
    case 0x0201:
460
        get_buffer(pb, sequence->data_definition_ul, 16);
461
        break;
462
    case 0x1001:
463
        sequence->structural_components_count = get_be32(pb);
464
        if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
465
            return -1;
466
        sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
467
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
468
        get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
469
        break;
470
    }
471
    return 0;
472 07bf2af8 Baptiste Coudurier
}
473
474 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_source_package(MXFPackage *package, ByteIOContext *pb, int tag)
475 07bf2af8 Baptiste Coudurier
{
476 55de95b9 Baptiste Coudurier
    switch(tag) {
477
    case 0x4403:
478
        package->tracks_count = get_be32(pb);
479
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
480
            return -1;
481
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
482
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
483
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
484
        break;
485
    case 0x4401:
486
        /* UMID, only get last 16 bytes */
487
        url_fskip(pb, 16);
488
        get_buffer(pb, package->package_uid, 16);
489
        break;
490
    case 0x4701:
491
        get_buffer(pb, package->descriptor_ref, 16);
492
        break;
493
    }
494
    return 0;
495 07bf2af8 Baptiste Coudurier
}
496
497 59b56738 Baptiste Coudurier
static void mxf_read_metadata_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor)
498
{
499
    int code;
500
501
    do {
502
        code = get_byte(pb);
503
        dprintf("pixel layout: code 0x%x\n", code);
504
        switch (code) {
505
        case 0x52: /* R */
506
            descriptor->bits_per_sample += get_byte(pb);
507
            break;
508
        case 0x47: /* G */
509
            descriptor->bits_per_sample += get_byte(pb);
510
            break;
511
        case 0x42: /* B */
512
            descriptor->bits_per_sample += get_byte(pb);
513
            break;
514
        default:
515
            get_byte(pb);
516
        }
517
    } while (code != 0); /* SMPTE 377M E.2.46 */
518
}
519
520 33bddcdc Baptiste Coudurier
static int mxf_read_metadata_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size)
521 743d772c Baptiste Coudurier
{
522 55de95b9 Baptiste Coudurier
    switch(tag) {
523 e6837cfa Baptiste Coudurier
    case 0x3F01:
524
        descriptor->sub_descriptors_count = get_be32(pb);
525
        if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
526
            return -1;
527
        descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
528
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
529
        get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
530
        break;
531 55de95b9 Baptiste Coudurier
    case 0x3004:
532
        get_buffer(pb, descriptor->essence_container_ul, 16);
533
        break;
534
    case 0x3006:
535
        descriptor->linked_track_id = get_be32(pb);
536
        break;
537
    case 0x3201: /* PictureEssenceCoding */
538
        get_buffer(pb, descriptor->essence_codec_ul, 16);
539
        break;
540
    case 0x3203:
541
        descriptor->width = get_be32(pb);
542
        break;
543
    case 0x3202:
544
        descriptor->height = get_be32(pb);
545
        break;
546
    case 0x320E:
547
        descriptor->aspect_ratio.num = get_be32(pb);
548
        descriptor->aspect_ratio.den = get_be32(pb);
549
        break;
550
    case 0x3D03:
551
        descriptor->sample_rate.num = get_be32(pb);
552
        descriptor->sample_rate.den = get_be32(pb);
553
        break;
554
    case 0x3D06: /* SoundEssenceCompression */
555
        get_buffer(pb, descriptor->essence_codec_ul, 16);
556
        break;
557
    case 0x3D07:
558
        descriptor->channels = get_be32(pb);
559
        break;
560
    case 0x3D01:
561
        descriptor->bits_per_sample = get_be32(pb);
562
        break;
563
    case 0x3401:
564
        mxf_read_metadata_pixel_layout(pb, descriptor);
565
        break;
566
    case 0x8201: /* Private tag used by SONY C0023S01.mxf */
567
        descriptor->extradata = av_malloc(size);
568
        descriptor->extradata_size = size;
569
        get_buffer(pb, descriptor->extradata, size);
570
        break;
571
    }
572
    return 0;
573 07bf2af8 Baptiste Coudurier
}
574
575
/* SMPTE RP224 http://www.smpte-ra.org/mdd/index.html */
576 dd202ff6 Baptiste Coudurier
static const MXFDataDefinitionUL mxf_data_definition_uls[] = {
577
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, CODEC_TYPE_VIDEO },
578
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, CODEC_TYPE_AUDIO },
579 1159f634 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x05,0x01,0x03,0x02,0x02,0x02,0x02,0x00,0x00 }, CODEC_TYPE_AUDIO },
580 dd202ff6 Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  CODEC_TYPE_DATA },
581
};
582 743d772c Baptiste Coudurier
583
static const MXFCodecUL mxf_codec_uls[] = {
584
    /* PictureEssenceCoding */
585 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML I-Frame */
586 1fc17d15 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL I-Frame */
587 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL Long GoP */
588
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@ML Long GoP */
589
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML Long GoP */
590
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@HL Long GoP */
591
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 },      CODEC_ID_MPEG4, Frame }, /* XDCAM proxy_pal030926.mxf */
592
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x04 },      CODEC_ID_MPEG4, Frame }, /* XDCAM Proxy C0023S01.mxf */
593
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 30Mbps PAL */
594
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 50Mbps PAL */
595
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DVCPRO50 PAL */
596
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DVCPRO25 PAL */
597
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DV25 IEC PAL */
598 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 */
599 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 },   CODEC_ID_RAWVIDEO, Frame }, /* Uncompressed */
600 743d772c Baptiste Coudurier
    /* SoundEssenceCompression */
601 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 */
602
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 },  CODEC_ID_PCM_S16LE, Frame },
603
    { { 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 */
604
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 },   CODEC_ID_PCM_ALAW, Frame },
605
    { { 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 */
606
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 },        CODEC_ID_AC3, Frame },
607
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 },        CODEC_ID_MP2, Frame }, /* MP2 or MP3 */
608
  //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 },    CODEC_ID_DOLBY_E, Frame }, /* Dolby-E */
609
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
610 07bf2af8 Baptiste Coudurier
};
611
612 8c5002db Baptiste Coudurier
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
613 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 */
614
    { { 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 */
615
    { { 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 */
616
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
617 8c5002db Baptiste Coudurier
};
618
619
static const MXFCodecUL mxf_sound_essence_container_uls[] = {
620 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 */
621
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },  CODEC_ID_PCM_S16LE, Frame }, /* AES Frame wrapped */
622
    { { 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 */
623
    { { 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 */
624
    { { 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 */
625 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 */
626
    { { 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 */
627 3bb63b82 Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
628 8c5002db Baptiste Coudurier
};
629
630 3bb63b82 Baptiste Coudurier
static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
631 743d772c Baptiste Coudurier
{
632
    while (uls->id != CODEC_ID_NONE) {
633
        if(!memcmp(uls->uid, *uid, 16))
634 3bb63b82 Baptiste Coudurier
            break;
635 743d772c Baptiste Coudurier
        uls++;
636
    }
637 3bb63b82 Baptiste Coudurier
    return uls;
638 743d772c Baptiste Coudurier
}
639 07bf2af8 Baptiste Coudurier
640 dd202ff6 Baptiste Coudurier
static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
641
{
642
    while (uls->type != CODEC_TYPE_DATA) {
643
        if(!memcmp(uls->uid, *uid, 16))
644
            break;
645
        uls++;
646
    }
647
    return uls->type;
648
}
649
650 2d193b2e Reimar Döffinger
static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
651 d2cdbd5f Baptiste Coudurier
{
652
    int i;
653
654
    if (!strong_ref)
655
        return NULL;
656
    for (i = 0; i < mxf->metadata_sets_count; i++) {
657 2d193b2e Reimar Döffinger
        if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
658 6ac558ee Baptiste Coudurier
            (type == AnyType || mxf->metadata_sets[i]->type == type)) {
659 d2cdbd5f Baptiste Coudurier
            return mxf->metadata_sets[i];
660
        }
661
    }
662
    return NULL;
663
}
664
665 743d772c Baptiste Coudurier
static int mxf_parse_structural_metadata(MXFContext *mxf)
666 07bf2af8 Baptiste Coudurier
{
667 743d772c Baptiste Coudurier
    MXFPackage *material_package = NULL;
668 d2cdbd5f Baptiste Coudurier
    MXFPackage *temp_package = NULL;
669 743d772c Baptiste Coudurier
    int i, j, k;
670
671 d2cdbd5f Baptiste Coudurier
    dprintf("metadata sets count %d\n", mxf->metadata_sets_count);
672 743d772c Baptiste Coudurier
    /* TODO: handle multiple material packages (OP3x) */
673
    for (i = 0; i < mxf->packages_count; i++) {
674 2d193b2e Reimar Döffinger
        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
675
        if (material_package) break;
676 743d772c Baptiste Coudurier
    }
677
    if (!material_package) {
678
        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
679
        return -1;
680
    }
681 07bf2af8 Baptiste Coudurier
682 743d772c Baptiste Coudurier
    for (i = 0; i < material_package->tracks_count; i++) {
683 7f25df4c Baptiste Coudurier
        MXFPackage *source_package = NULL;
684 d2cdbd5f Baptiste Coudurier
        MXFTrack *material_track = NULL;
685 743d772c Baptiste Coudurier
        MXFTrack *source_track = NULL;
686 d2cdbd5f Baptiste Coudurier
        MXFTrack *temp_track = NULL;
687 743d772c Baptiste Coudurier
        MXFDescriptor *descriptor = NULL;
688
        MXFStructuralComponent *component = NULL;
689 80a289b9 Reimar Döffinger
        UID *essence_container_ul = NULL;
690 3bb63b82 Baptiste Coudurier
        const MXFCodecUL *codec_ul = NULL;
691
        const MXFCodecUL *container_ul = NULL;
692 743d772c Baptiste Coudurier
        AVStream *st;
693
694 2d193b2e Reimar Döffinger
        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
695 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
696
            continue;
697
        }
698
699 2d193b2e Reimar Döffinger
        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
700 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
701
            return -1;
702
        }
703
704 743d772c Baptiste Coudurier
        /* TODO: handle multiple source clips */
705
        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
706
            /* TODO: handle timecode component */
707 2d193b2e Reimar Döffinger
            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
708
            if (!component)
709 743d772c Baptiste Coudurier
                continue;
710
711
            for (k = 0; k < mxf->packages_count; k++) {
712 2d193b2e Reimar Döffinger
                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
713
                if (!temp_package)
714
                    continue;
715 d2cdbd5f Baptiste Coudurier
                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
716
                    source_package = temp_package;
717 743d772c Baptiste Coudurier
                    break;
718
                }
719
            }
720
            if (!source_package) {
721
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
722
                break;
723
            }
724
            for (k = 0; k < source_package->tracks_count; k++) {
725 2d193b2e Reimar Döffinger
                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
726 d2cdbd5f Baptiste Coudurier
                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
727
                    return -1;
728
                }
729
                if (temp_track->track_id == component->source_track_id) {
730
                    source_track = temp_track;
731 743d772c Baptiste Coudurier
                    break;
732
                }
733
            }
734
            if (!source_track) {
735
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
736
                break;
737
            }
738
        }
739
        if (!source_track)
740
            continue;
741
742 f03b6426 Baptiste Coudurier
        st = av_new_stream(mxf->fc, source_track->track_id);
743
        st->priv_data = source_track;
744 743d772c Baptiste Coudurier
        st->duration = component->duration;
745
        if (st->duration == -1)
746
            st->duration = AV_NOPTS_VALUE;
747
        st->start_time = component->start_position;
748
        av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
749 d2cdbd5f Baptiste Coudurier
750 2d193b2e Reimar Döffinger
        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
751 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
752
            return -1;
753
        }
754
755 743d772c Baptiste Coudurier
#ifdef DEBUG
756 996c9ad0 Baptiste Coudurier
        PRINT_KEY("data definition   ul", source_track->sequence->data_definition_ul);
757 743d772c Baptiste Coudurier
#endif
758 dd202ff6 Baptiste Coudurier
        st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
759 743d772c Baptiste Coudurier
760 6ac558ee Baptiste Coudurier
        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
761 743d772c Baptiste Coudurier
        if (source_package->descriptor) {
762 d2cdbd5f Baptiste Coudurier
            if (source_package->descriptor->type == MultipleDescriptor) {
763 743d772c Baptiste Coudurier
                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
764 2d193b2e Reimar Döffinger
                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
765 d2cdbd5f Baptiste Coudurier
766
                    if (!sub_descriptor) {
767
                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
768
                        continue;
769
                    }
770
                    if (sub_descriptor->linked_track_id == source_track->track_id) {
771
                        descriptor = sub_descriptor;
772
                        break;
773 07bf2af8 Baptiste Coudurier
                    }
774
                }
775 6ac558ee Baptiste Coudurier
            } else if (source_package->descriptor->type == Descriptor)
776 743d772c Baptiste Coudurier
                descriptor = source_package->descriptor;
777
        }
778
        if (!descriptor) {
779
            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
780
            continue;
781
        }
782
#ifdef DEBUG
783 996c9ad0 Baptiste Coudurier
        PRINT_KEY("essence codec     ul", descriptor->essence_codec_ul);
784
        PRINT_KEY("essence container ul", descriptor->essence_container_ul);
785 743d772c Baptiste Coudurier
#endif
786 80a289b9 Reimar Döffinger
        essence_container_ul = &descriptor->essence_container_ul;
787
        /* HACK: replacing the original key with mxf_encrypted_essence_container
788
         * is not allowed according to s429-6, try to find correct information anyway */
789
        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
790
            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
791
            for (k = 0; k < mxf->metadata_sets_count; k++) {
792
                MXFMetadataSet *metadata = mxf->metadata_sets[k];
793
                if (metadata->type == CryptoContext) {
794
                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
795
                    break;
796
                }
797
            }
798
        }
799 3bb63b82 Baptiste Coudurier
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
800
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
801 c2e88054 Baptiste Coudurier
        st->codec->codec_id = codec_ul->id;
802 e1dacee1 Baptiste Coudurier
        if (descriptor->extradata) {
803
            st->codec->extradata = descriptor->extradata;
804
            st->codec->extradata_size = descriptor->extradata_size;
805
        }
806 743d772c Baptiste Coudurier
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
807 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
808 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
809 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
810 743d772c Baptiste Coudurier
            st->codec->width = descriptor->width;
811
            st->codec->height = descriptor->height;
812 59b56738 Baptiste Coudurier
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
813 550f6f97 Baptiste Coudurier
            st->need_parsing = 2; /* only parse headers */
814 743d772c Baptiste Coudurier
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
815 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
816 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
817 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
818 743d772c Baptiste Coudurier
            st->codec->channels = descriptor->channels;
819
            st->codec->bits_per_sample = descriptor->bits_per_sample;
820
            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
821
            /* TODO: implement CODEC_ID_RAWAUDIO */
822
            if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
823
                if (descriptor->bits_per_sample == 24)
824
                    st->codec->codec_id = CODEC_ID_PCM_S24LE;
825
                else if (descriptor->bits_per_sample == 32)
826
                    st->codec->codec_id = CODEC_ID_PCM_S32LE;
827
            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
828
                if (descriptor->bits_per_sample == 24)
829
                    st->codec->codec_id = CODEC_ID_PCM_S24BE;
830
                else if (descriptor->bits_per_sample == 32)
831
                    st->codec->codec_id = CODEC_ID_PCM_S32BE;
832 c74915cd Baptiste Coudurier
                if (descriptor->essence_container_ul[13] == 0x01) /* D-10 Mapping */
833 885e691a Baptiste Coudurier
                    st->codec->channels = 8; /* force channels to 8 */
834 c86ecbb7 Baptiste Coudurier
            } else if (st->codec->codec_id == CODEC_ID_MP2) {
835
                st->need_parsing = 1;
836 07bf2af8 Baptiste Coudurier
            }
837
        }
838 f0d47292 Baptiste Coudurier
        if (container_ul && container_ul->wrapping == Clip) {
839 c2e88054 Baptiste Coudurier
            dprintf("stream %d: clip wrapped essence\n", st->index);
840
            st->need_parsing = 1;
841
        }
842 07bf2af8 Baptiste Coudurier
    }
843 743d772c Baptiste Coudurier
    return 0;
844 07bf2af8 Baptiste Coudurier
}
845
846 b92c61e0 Baptiste Coudurier
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
847 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 },
848
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage },
849
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage },
850
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence },
851
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip },
852 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 },
853 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 */
854
    { { 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 */
855
    { { 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 */
856
    { { 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 */
857
    { { 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 */
858
    { { 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 */
859
    { { 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 */
860
    { { 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 */
861 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 },
862 33bddcdc Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
863 b92c61e0 Baptiste Coudurier
};
864
865 ee71ef5c Baptiste Coudurier
static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
866
{
867
    int i, b;
868
    for (i = 0; i < size && !url_feof(pb); i++) {
869
        b = get_byte(pb);
870
        if (b == key[0])
871
            i = 0;
872
        else if (b != key[i])
873
            i = -1;
874
    }
875
    return i == size;
876
}
877
878 33bddcdc Baptiste Coudurier
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
879
{
880
    ByteIOContext *pb = &mxf->fc->pb;
881
    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
882
    uint64_t klv_end= url_ftell(pb) + klv->length;
883
884
    while (url_ftell(pb) + 4 < klv_end) {
885
        int tag = get_be16(pb);
886
        int size = get_be16(pb); /* KLV specified by 0x53 */
887
        uint64_t next= url_ftell(pb) + size;
888
889
        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
890
            av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
891
            continue;
892
        }
893
        if(ctx_size && tag == 0x3C0A)
894
            get_buffer(pb, ctx->uid, 16);
895
        else
896
            read_child(ctx, pb, tag, size);
897
898
        url_fseek(pb, next, SEEK_SET);
899
    }
900
    if (ctx_size) ctx->type = type;
901
    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
902
}
903
904 07bf2af8 Baptiste Coudurier
static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
905
{
906
    MXFContext *mxf = s->priv_data;
907
    KLVPacket klv;
908
909 86074ce3 Reimar Döffinger
    mxf->sync_key = mxf_essence_element_key;
910 ee71ef5c Baptiste Coudurier
    if (!mxf_read_sync(&s->pb, mxf_header_partition_pack_key, 14)) {
911
        av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
912
        return -1;
913
    }
914
    url_fseek(&s->pb, -14, SEEK_CUR);
915 07bf2af8 Baptiste Coudurier
    mxf->fc = s;
916
    while (!url_feof(&s->pb)) {
917 975c88e3 Baptiste Coudurier
        const MXFMetadataReadTableEntry *metadata;
918 b92c61e0 Baptiste Coudurier
919 5e441e31 Baptiste Coudurier
        if (klv_read_packet(&klv, &s->pb) < 0) {
920
            av_log(s, AV_LOG_ERROR, "error reading KLV packet\n");
921 07bf2af8 Baptiste Coudurier
            return -1;
922 5e441e31 Baptiste Coudurier
        }
923 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
924 996c9ad0 Baptiste Coudurier
        PRINT_KEY("read header", klv.key);
925 6d0c3beb Baptiste Coudurier
#endif
926 80a289b9 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
927
            IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
928 07bf2af8 Baptiste Coudurier
            /* FIXME avoid seek */
929
            url_fseek(&s->pb, klv.offset, SEEK_SET);
930
            break;
931 5e441e31 Baptiste Coudurier
        }
932 b92c61e0 Baptiste Coudurier
933 975c88e3 Baptiste Coudurier
        for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
934
            if (IS_KLV_KEY(klv.key, metadata->key)) {
935
                if (mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
936 b92c61e0 Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
937
                    return -1;
938
                }
939
                break;
940
            }
941
        }
942 975c88e3 Baptiste Coudurier
        if (!metadata->read)
943 b92c61e0 Baptiste Coudurier
            url_fskip(&s->pb, klv.length);
944 07bf2af8 Baptiste Coudurier
    }
945 743d772c Baptiste Coudurier
    return mxf_parse_structural_metadata(mxf);
946 07bf2af8 Baptiste Coudurier
}
947
948
static int mxf_read_close(AVFormatContext *s)
949
{
950
    MXFContext *mxf = s->priv_data;
951 d2cdbd5f Baptiste Coudurier
    int i;
952 743d772c Baptiste Coudurier
953
    av_freep(&mxf->packages_refs);
954 d2cdbd5f Baptiste Coudurier
    for (i = 0; i < mxf->metadata_sets_count; i++) {
955
        switch (mxf->metadata_sets[i]->type) {
956
        case MultipleDescriptor:
957
            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
958
            break;
959
        case Sequence:
960
            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
961
            break;
962
        case SourcePackage:
963
        case MaterialPackage:
964
            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
965
            break;
966
        default:
967
            break;
968
        }
969
        av_freep(&mxf->metadata_sets[i]);
970
    }
971
    av_freep(&mxf->metadata_sets);
972 80a289b9 Reimar Döffinger
    av_freep(&mxf->aesc);
973 07bf2af8 Baptiste Coudurier
    return 0;
974
}
975
976
static int mxf_probe(AVProbeData *p) {
977 ba32c8df Baptiste Coudurier
    uint8_t *bufp = p->buf;
978
    uint8_t *end = p->buf + p->buf_size;
979
980 07bf2af8 Baptiste Coudurier
    if (p->buf_size < sizeof(mxf_header_partition_pack_key))
981
        return 0;
982
983 ba32c8df Baptiste Coudurier
    /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
984
    end -= sizeof(mxf_header_partition_pack_key);
985
    for (; bufp < end; bufp++) {
986 f8503792 Baptiste Coudurier
        if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
987 ba32c8df Baptiste Coudurier
            return AVPROBE_SCORE_MAX;
988
    }
989
    return 0;
990 07bf2af8 Baptiste Coudurier
}
991
992 3a6ccf4f Baptiste Coudurier
/* rudimentary binary seek */
993
/* XXX: use MXF Index */
994
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
995
{
996 86074ce3 Reimar Döffinger
    MXFContext *mxf = s->priv_data;
997 3a6ccf4f Baptiste Coudurier
    AVStream *st = s->streams[stream_index];
998
    int64_t seconds;
999
1000 de9fe002 Baptiste Coudurier
    if (!s->bit_rate)
1001 3a6ccf4f Baptiste Coudurier
        return -1;
1002 de9fe002 Baptiste Coudurier
    if (sample_time < 0)
1003
        sample_time = 0;
1004 3a6ccf4f Baptiste Coudurier
    seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
1005
    url_fseek(&s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
1006 86074ce3 Reimar Döffinger
    if (!mxf_read_sync(&s->pb, mxf->sync_key, 12))
1007 ee71ef5c Baptiste Coudurier
        return -1;
1008
1009
    /* found KLV key */
1010
    url_fseek(&s->pb, -12, SEEK_CUR);
1011
    av_update_cur_dts(s, st, sample_time);
1012
    return 0;
1013 3a6ccf4f Baptiste Coudurier
}
1014 07bf2af8 Baptiste Coudurier
1015
AVInputFormat mxf_demuxer = {
1016
    "mxf",
1017
    "MXF format",
1018
    sizeof(MXFContext),
1019
    mxf_probe,
1020
    mxf_read_header,
1021
    mxf_read_packet,
1022
    mxf_read_close,
1023 3a6ccf4f Baptiste Coudurier
    mxf_read_seek,
1024 07bf2af8 Baptiste Coudurier
};