Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 0a5790d1

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