Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 7e1720de

History | View | Annotate | Download (41.5 KB)

1 07bf2af8 Baptiste Coudurier
/*
2
 * MXF demuxer.
3
 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>.
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 07bf2af8 Baptiste Coudurier
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 07bf2af8 Baptiste Coudurier
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 07bf2af8 Baptiste Coudurier
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 07bf2af8 Baptiste Coudurier
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/*
23
 * References
24
 * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
25
 * SMPTE 377M MXF File Format Specifications
26
 * SMPTE 378M Operational Pattern 1a
27
 * SMPTE 379M MXF Generic Container
28
 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
29
 * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
30
 * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
31
 *
32
 * Principle
33
 * Search for Track numbers which will identify essence element KLV packets.
34
 * Search for SourcePackage which define tracks which contains Track numbers.
35 743d772c Baptiste Coudurier
 * Material Package contains tracks with reference to SourcePackage tracks.
36 07bf2af8 Baptiste Coudurier
 * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
37
 * Assign Descriptors to correct Tracks.
38
 *
39 d2cdbd5f Baptiste Coudurier
 * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
40
 * Metadata parsing resolves Strong References to objects.
41 743d772c Baptiste Coudurier
 *
42
 * Simple demuxer, only OP1A supported and some files might not work at all.
43
 * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
44 07bf2af8 Baptiste Coudurier
 */
45
46 49b6f162 Baptiste Coudurier
//#define DEBUG
47 07bf2af8 Baptiste Coudurier
48
#include "avformat.h"
49 80a289b9 Reimar Döffinger
#include "aes.h"
50 28cf7215 Baptiste Coudurier
#include "bytestream.h"
51 07bf2af8 Baptiste Coudurier
52 f03b6426 Baptiste Coudurier
typedef uint8_t UID[16];
53 4bfff768 Baptiste Coudurier
54 d2cdbd5f Baptiste Coudurier
enum MXFMetadataSetType {
55 6ac558ee Baptiste Coudurier
    AnyType,
56 743d772c Baptiste Coudurier
    MaterialPackage,
57
    SourcePackage,
58
    SourceClip,
59 d2cdbd5f Baptiste Coudurier
    TimecodeComponent,
60
    Sequence,
61
    MultipleDescriptor,
62
    Descriptor,
63
    Track,
64 80a289b9 Reimar Döffinger
    CryptoContext,
65 743d772c Baptiste Coudurier
};
66
67 1b481845 Baptiste Coudurier
typedef struct {
68 80a289b9 Reimar Döffinger
    UID uid;
69
    enum MXFMetadataSetType type;
70
    UID context_uid;
71
    UID source_container_ul;
72
} MXFCryptoContext;
73
74 1b481845 Baptiste Coudurier
typedef struct {
75 743d772c Baptiste Coudurier
    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 1b481845 Baptiste Coudurier
typedef struct {
85 743d772c Baptiste Coudurier
    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 1b481845 Baptiste Coudurier
typedef struct {
94 743d772c Baptiste Coudurier
    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 1b481845 Baptiste Coudurier
typedef struct {
104 743d772c Baptiste Coudurier
    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 1b481845 Baptiste Coudurier
typedef struct {
122 743d772c Baptiste Coudurier
    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 d2cdbd5f Baptiste Coudurier
typedef struct {
132
    UID uid;
133
    enum MXFMetadataSetType type;
134
} MXFMetadataSet;
135
136 1b481845 Baptiste Coudurier
typedef struct {
137 743d772c Baptiste Coudurier
    UID *packages_refs;
138
    int packages_count;
139 d2cdbd5f Baptiste Coudurier
    MXFMetadataSet **metadata_sets;
140
    int metadata_sets_count;
141 743d772c Baptiste Coudurier
    AVFormatContext *fc;
142 80a289b9 Reimar Döffinger
    struct AVAES *aesc;
143 07bf2af8 Baptiste Coudurier
} MXFContext;
144
145 1b481845 Baptiste Coudurier
typedef struct {
146 4bfff768 Baptiste Coudurier
    UID key;
147 07bf2af8 Baptiste Coudurier
    offset_t offset;
148
    uint64_t length;
149
} KLVPacket;
150
151 3bb63b82 Baptiste Coudurier
enum MXFWrappingScheme {
152
    Frame,
153
    Clip,
154
};
155
156 1b481845 Baptiste Coudurier
typedef struct {
157 743d772c Baptiste Coudurier
    UID uid;
158
    enum CodecID id;
159 3bb63b82 Baptiste Coudurier
    enum MXFWrappingScheme wrapping;
160 743d772c Baptiste Coudurier
} MXFCodecUL;
161
162 1b481845 Baptiste Coudurier
typedef struct {
163 dd202ff6 Baptiste Coudurier
    UID uid;
164
    enum CodecType type;
165
} MXFDataDefinitionUL;
166
167 1b481845 Baptiste Coudurier
typedef struct {
168 b92c61e0 Baptiste Coudurier
    const UID key;
169 33bddcdc Baptiste Coudurier
    int (*read)();
170
    int ctx_size;
171
    enum MXFMetadataSetType type;
172 b92c61e0 Baptiste Coudurier
} MXFMetadataReadTableEntry;
173 4bfff768 Baptiste Coudurier
174
/* partial keys to match */
175 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 };
176 f03b6426 Baptiste Coudurier
static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
177 cabe2527 Baptiste Coudurier
static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
178 86074ce3 Reimar Döffinger
/* complete keys to match */
179
static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
180 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 };
181 07bf2af8 Baptiste Coudurier
182
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
183
184 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, \
185 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])
186 07bf2af8 Baptiste Coudurier
187
static int64_t klv_decode_ber_length(ByteIOContext *pb)
188
{
189 1fe68f0e Reimar Döffinger
    uint64_t size = get_byte(pb);
190
    if (size & 0x80) { /* long form */
191
        int bytes_num = size & 0x7f;
192 07bf2af8 Baptiste Coudurier
        /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
193
        if (bytes_num > 8)
194
            return -1;
195 1fe68f0e Reimar Döffinger
        size = 0;
196 07bf2af8 Baptiste Coudurier
        while (bytes_num--)
197
            size = size << 8 | get_byte(pb);
198
    }
199
    return size;
200
}
201
202 cabe2527 Baptiste Coudurier
static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
203
{
204
    int i, b;
205
    for (i = 0; i < size && !url_feof(pb); i++) {
206
        b = get_byte(pb);
207
        if (b == key[0])
208
            i = 0;
209
        else if (b != key[i])
210
            i = -1;
211
    }
212
    return i == size;
213
}
214
215 07bf2af8 Baptiste Coudurier
static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb)
216
{
217 cabe2527 Baptiste Coudurier
    if (!mxf_read_sync(pb, mxf_klv_key, 4))
218
        return -1;
219
    klv->offset = url_ftell(pb) - 4;
220
    memcpy(klv->key, mxf_klv_key, 4);
221
    get_buffer(pb, klv->key + 4, 12);
222 07bf2af8 Baptiste Coudurier
    klv->length = klv_decode_ber_length(pb);
223 b7522224 Baptiste Coudurier
    return klv->length == -1 ? -1 : 0;
224 07bf2af8 Baptiste Coudurier
}
225
226
static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
227
{
228
    int i;
229
230
    for (i = 0; i < s->nb_streams; i++) {
231 f03b6426 Baptiste Coudurier
        MXFTrack *track = s->streams[i]->priv_data;
232 55de95b9 Baptiste Coudurier
        /* SMPTE 379M 7.3 */
233 f03b6426 Baptiste Coudurier
        if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
234 07bf2af8 Baptiste Coudurier
            return i;
235
    }
236 03da8726 Baptiste Coudurier
    /* return 0 if only one stream, for OP Atom files with 0 as track number */
237
    return s->nb_streams == 1 ? 0 : -1;
238 07bf2af8 Baptiste Coudurier
}
239
240 885e691a Baptiste Coudurier
/* XXX: use AVBitStreamFilter */
241
static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
242
{
243
    uint8_t buffer[61444];
244
    uint8_t *buf_ptr, *end_ptr, *data_ptr;
245 28cf7215 Baptiste Coudurier
    int i;
246 885e691a Baptiste Coudurier
247
    if (length > 61444) /* worst case PAL 1920 samples 8 channels */
248
        return -1;
249
    get_buffer(pb, buffer, length);
250
    av_new_packet(pkt, length);
251
    data_ptr = pkt->data;
252
    end_ptr = buffer + length;
253
    buf_ptr = buffer + 4; /* skip SMPTE 331M header */
254 28cf7215 Baptiste Coudurier
    for (; buf_ptr < end_ptr; ) {
255
        for (i = 0; i < st->codec->channels; i++) {
256
            uint32_t sample = bytestream_get_le32(&buf_ptr);
257
            if (st->codec->bits_per_sample == 24)
258
                bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
259
            else
260
                bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
261 885e691a Baptiste Coudurier
        }
262 28cf7215 Baptiste Coudurier
        buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
263 885e691a Baptiste Coudurier
    }
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 899681cd Björn Axelsson
    ByteIOContext *pb = s->pb;
273 80a289b9 Reimar Döffinger
    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 899681cd Björn Axelsson
    while (!url_feof(s->pb)) {
330
        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 899681cd Björn Axelsson
                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 899681cd Björn Axelsson
                if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
353 885e691a Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
354
                    return -1;
355
                }
356
            } else
357 899681cd Björn Axelsson
                av_get_packet(s->pb, pkt, klv.length);
358 885e691a Baptiste Coudurier
            pkt->stream_index = index;
359 28b9f986 Baptiste Coudurier
            pkt->pos = klv.offset;
360 885e691a Baptiste Coudurier
            return 0;
361 07bf2af8 Baptiste Coudurier
        } else
362 899681cd Björn Axelsson
            url_fskip(s->pb, klv.length);
363 07bf2af8 Baptiste Coudurier
    }
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 3a319ab6 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 30Mbps NTSC */
597
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 40Mbps NTSC */
598
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 50Mbps NTSC */
599 3c6b46d3 Baptiste Coudurier
600
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML I-Frame */
601 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 */
602 3c6b46d3 Baptiste Coudurier
603 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 */
604 3c6b46d3 Baptiste Coudurier
605
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL I-Frame */
606
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL Long GoP */
607
608 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 */
609
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x04 },      CODEC_ID_MPEG4, Frame }, /* XDCAM Proxy C0023S01.mxf */
610 3c6b46d3 Baptiste Coudurier
611 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 */
612 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 */
613
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 },    CODEC_ID_DVVIDEO, Frame }, /* DVCPRO50 PAL */
614
615 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 */
616 3c6b46d3 Baptiste Coudurier
617 3bb63b82 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 },   CODEC_ID_RAWVIDEO, Frame }, /* Uncompressed */
618 743d772c Baptiste Coudurier
    /* SoundEssenceCompression */
619 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 */
620
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 },  CODEC_ID_PCM_S16LE, Frame },
621
    { { 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 */
622
    { { 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 */
623
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 },        CODEC_ID_AC3, Frame },
624
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 },        CODEC_ID_MP2, Frame }, /* MP2 or MP3 */
625
  //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 },    CODEC_ID_DOLBY_E, Frame }, /* Dolby-E */
626
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
627 07bf2af8 Baptiste Coudurier
};
628
629 8c5002db Baptiste Coudurier
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
630 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 */
631
    { { 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 */
632
    { { 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 */
633
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
634 8c5002db Baptiste Coudurier
};
635
636
static const MXFCodecUL mxf_sound_essence_container_uls[] = {
637 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 */
638
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 },  CODEC_ID_PCM_S16LE, Frame }, /* AES Frame wrapped */
639
    { { 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 */
640
    { { 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 */
641
    { { 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 */
642 28cf7215 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 30Mbps PAL Extended Template */
643
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 40Mbps PAL Extended Template */
644
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 50Mbps PAL Extended Template */
645 3a319ab6 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 30Mbps NTSC Extended Template */
646
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 40Mbps NTSC Extended Template */
647
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 },  CODEC_ID_PCM_S16LE, Frame }, /* D-10 Mapping 50Mbps NTSC Extended Template */
648 3bb63b82 Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },       CODEC_ID_NONE, Frame },
649 8c5002db Baptiste Coudurier
};
650
651 6982462f Baptiste Coudurier
/*
652
 * Match an uid independently of the version byte and up to len common bytes
653
 * Returns: boolean
654
 */
655
static int mxf_match_uid(const UID key, const UID uid, int len)
656
{
657
    int i;
658
    for (i = 0; i < len; i++) {
659
        if (i != 7 && key[i] != uid[i])
660
            return 0;
661
    }
662
    return 1;
663
}
664
665 3bb63b82 Baptiste Coudurier
static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
666 743d772c Baptiste Coudurier
{
667
    while (uls->id != CODEC_ID_NONE) {
668 6982462f Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, 16))
669 3bb63b82 Baptiste Coudurier
            break;
670 743d772c Baptiste Coudurier
        uls++;
671
    }
672 3bb63b82 Baptiste Coudurier
    return uls;
673 743d772c Baptiste Coudurier
}
674 07bf2af8 Baptiste Coudurier
675 dd202ff6 Baptiste Coudurier
static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
676
{
677
    while (uls->type != CODEC_TYPE_DATA) {
678 6982462f Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, 16))
679 dd202ff6 Baptiste Coudurier
            break;
680
        uls++;
681
    }
682
    return uls->type;
683
}
684
685 2d193b2e Reimar Döffinger
static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
686 d2cdbd5f Baptiste Coudurier
{
687
    int i;
688
689
    if (!strong_ref)
690
        return NULL;
691
    for (i = 0; i < mxf->metadata_sets_count; i++) {
692 2d193b2e Reimar Döffinger
        if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
693 6ac558ee Baptiste Coudurier
            (type == AnyType || mxf->metadata_sets[i]->type == type)) {
694 d2cdbd5f Baptiste Coudurier
            return mxf->metadata_sets[i];
695
        }
696
    }
697
    return NULL;
698
}
699
700 743d772c Baptiste Coudurier
static int mxf_parse_structural_metadata(MXFContext *mxf)
701 07bf2af8 Baptiste Coudurier
{
702 743d772c Baptiste Coudurier
    MXFPackage *material_package = NULL;
703 d2cdbd5f Baptiste Coudurier
    MXFPackage *temp_package = NULL;
704 743d772c Baptiste Coudurier
    int i, j, k;
705
706 318c5e05 Michel Bardiaux
    dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
707 743d772c Baptiste Coudurier
    /* TODO: handle multiple material packages (OP3x) */
708
    for (i = 0; i < mxf->packages_count; i++) {
709 2d193b2e Reimar Döffinger
        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
710
        if (material_package) break;
711 743d772c Baptiste Coudurier
    }
712
    if (!material_package) {
713
        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
714
        return -1;
715
    }
716 07bf2af8 Baptiste Coudurier
717 743d772c Baptiste Coudurier
    for (i = 0; i < material_package->tracks_count; i++) {
718 7f25df4c Baptiste Coudurier
        MXFPackage *source_package = NULL;
719 d2cdbd5f Baptiste Coudurier
        MXFTrack *material_track = NULL;
720 743d772c Baptiste Coudurier
        MXFTrack *source_track = NULL;
721 d2cdbd5f Baptiste Coudurier
        MXFTrack *temp_track = NULL;
722 743d772c Baptiste Coudurier
        MXFDescriptor *descriptor = NULL;
723
        MXFStructuralComponent *component = NULL;
724 80a289b9 Reimar Döffinger
        UID *essence_container_ul = NULL;
725 3bb63b82 Baptiste Coudurier
        const MXFCodecUL *codec_ul = NULL;
726
        const MXFCodecUL *container_ul = NULL;
727 743d772c Baptiste Coudurier
        AVStream *st;
728
729 2d193b2e Reimar Döffinger
        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
730 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
731
            continue;
732
        }
733
734 2d193b2e Reimar Döffinger
        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
735 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
736
            return -1;
737
        }
738
739 743d772c Baptiste Coudurier
        /* TODO: handle multiple source clips */
740
        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
741
            /* TODO: handle timecode component */
742 2d193b2e Reimar Döffinger
            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
743
            if (!component)
744 743d772c Baptiste Coudurier
                continue;
745
746
            for (k = 0; k < mxf->packages_count; k++) {
747 2d193b2e Reimar Döffinger
                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
748
                if (!temp_package)
749
                    continue;
750 d2cdbd5f Baptiste Coudurier
                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
751
                    source_package = temp_package;
752 743d772c Baptiste Coudurier
                    break;
753
                }
754
            }
755
            if (!source_package) {
756
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
757
                break;
758
            }
759
            for (k = 0; k < source_package->tracks_count; k++) {
760 2d193b2e Reimar Döffinger
                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
761 d2cdbd5f Baptiste Coudurier
                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
762
                    return -1;
763
                }
764
                if (temp_track->track_id == component->source_track_id) {
765
                    source_track = temp_track;
766 743d772c Baptiste Coudurier
                    break;
767
                }
768
            }
769
            if (!source_track) {
770
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
771
                break;
772
            }
773
        }
774
        if (!source_track)
775
            continue;
776
777 f03b6426 Baptiste Coudurier
        st = av_new_stream(mxf->fc, source_track->track_id);
778
        st->priv_data = source_track;
779 743d772c Baptiste Coudurier
        st->duration = component->duration;
780
        if (st->duration == -1)
781
            st->duration = AV_NOPTS_VALUE;
782
        st->start_time = component->start_position;
783
        av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
784 d2cdbd5f Baptiste Coudurier
785 2d193b2e Reimar Döffinger
        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
786 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
787
            return -1;
788
        }
789
790 743d772c Baptiste Coudurier
#ifdef DEBUG
791 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
792 743d772c Baptiste Coudurier
#endif
793 dd202ff6 Baptiste Coudurier
        st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
794 743d772c Baptiste Coudurier
795 6ac558ee Baptiste Coudurier
        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
796 743d772c Baptiste Coudurier
        if (source_package->descriptor) {
797 d2cdbd5f Baptiste Coudurier
            if (source_package->descriptor->type == MultipleDescriptor) {
798 743d772c Baptiste Coudurier
                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
799 2d193b2e Reimar Döffinger
                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
800 d2cdbd5f Baptiste Coudurier
801
                    if (!sub_descriptor) {
802
                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
803
                        continue;
804
                    }
805
                    if (sub_descriptor->linked_track_id == source_track->track_id) {
806
                        descriptor = sub_descriptor;
807
                        break;
808 07bf2af8 Baptiste Coudurier
                    }
809
                }
810 6ac558ee Baptiste Coudurier
            } else if (source_package->descriptor->type == Descriptor)
811 743d772c Baptiste Coudurier
                descriptor = source_package->descriptor;
812
        }
813
        if (!descriptor) {
814
            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
815
            continue;
816
        }
817
#ifdef DEBUG
818 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);
819
        PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
820 743d772c Baptiste Coudurier
#endif
821 80a289b9 Reimar Döffinger
        essence_container_ul = &descriptor->essence_container_ul;
822
        /* HACK: replacing the original key with mxf_encrypted_essence_container
823
         * is not allowed according to s429-6, try to find correct information anyway */
824
        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
825
            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
826
            for (k = 0; k < mxf->metadata_sets_count; k++) {
827
                MXFMetadataSet *metadata = mxf->metadata_sets[k];
828
                if (metadata->type == CryptoContext) {
829
                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
830
                    break;
831
                }
832
            }
833
        }
834 3bb63b82 Baptiste Coudurier
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
835
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
836 c2e88054 Baptiste Coudurier
        st->codec->codec_id = codec_ul->id;
837 e1dacee1 Baptiste Coudurier
        if (descriptor->extradata) {
838
            st->codec->extradata = descriptor->extradata;
839
            st->codec->extradata_size = descriptor->extradata_size;
840
        }
841 743d772c Baptiste Coudurier
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
842 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
843 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
844 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
845 743d772c Baptiste Coudurier
            st->codec->width = descriptor->width;
846
            st->codec->height = descriptor->height;
847 59b56738 Baptiste Coudurier
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
848 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
849 743d772c Baptiste Coudurier
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
850 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
851 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
852 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
853 743d772c Baptiste Coudurier
            st->codec->channels = descriptor->channels;
854
            st->codec->bits_per_sample = descriptor->bits_per_sample;
855
            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
856
            /* TODO: implement CODEC_ID_RAWAUDIO */
857
            if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
858
                if (descriptor->bits_per_sample == 24)
859
                    st->codec->codec_id = CODEC_ID_PCM_S24LE;
860
                else if (descriptor->bits_per_sample == 32)
861
                    st->codec->codec_id = CODEC_ID_PCM_S32LE;
862
            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
863
                if (descriptor->bits_per_sample == 24)
864
                    st->codec->codec_id = CODEC_ID_PCM_S24BE;
865
                else if (descriptor->bits_per_sample == 32)
866
                    st->codec->codec_id = CODEC_ID_PCM_S32BE;
867 c86ecbb7 Baptiste Coudurier
            } else if (st->codec->codec_id == CODEC_ID_MP2) {
868 57004ff1 Aurelien Jacobs
                st->need_parsing = AVSTREAM_PARSE_FULL;
869 07bf2af8 Baptiste Coudurier
            }
870
        }
871 f0d47292 Baptiste Coudurier
        if (container_ul && container_ul->wrapping == Clip) {
872 318c5e05 Michel Bardiaux
            dprintf(mxf->fc, "stream %d: clip wrapped essence\n", st->index);
873 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_FULL;
874 c2e88054 Baptiste Coudurier
        }
875 07bf2af8 Baptiste Coudurier
    }
876 743d772c Baptiste Coudurier
    return 0;
877 07bf2af8 Baptiste Coudurier
}
878
879 b92c61e0 Baptiste Coudurier
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
880 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 },
881
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage },
882
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage },
883
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence },
884
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip },
885 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 },
886 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 */
887
    { { 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 */
888
    { { 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 */
889
    { { 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 */
890
    { { 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 */
891
    { { 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 */
892
    { { 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 */
893
    { { 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 */
894 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 },
895 33bddcdc Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
896 b92c61e0 Baptiste Coudurier
};
897
898 33bddcdc Baptiste Coudurier
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
899
{
900 899681cd Björn Axelsson
    ByteIOContext *pb = mxf->fc->pb;
901 33bddcdc Baptiste Coudurier
    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
902
    uint64_t klv_end= url_ftell(pb) + klv->length;
903
904
    while (url_ftell(pb) + 4 < klv_end) {
905
        int tag = get_be16(pb);
906
        int size = get_be16(pb); /* KLV specified by 0x53 */
907
        uint64_t next= url_ftell(pb) + size;
908
909
        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
910
            av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
911
            continue;
912
        }
913
        if(ctx_size && tag == 0x3C0A)
914
            get_buffer(pb, ctx->uid, 16);
915
        else
916
            read_child(ctx, pb, tag, size);
917
918
        url_fseek(pb, next, SEEK_SET);
919
    }
920
    if (ctx_size) ctx->type = type;
921
    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
922
}
923
924 07bf2af8 Baptiste Coudurier
static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
925
{
926
    MXFContext *mxf = s->priv_data;
927
    KLVPacket klv;
928
929 899681cd Björn Axelsson
    if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
930 ee71ef5c Baptiste Coudurier
        av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
931
        return -1;
932
    }
933 899681cd Björn Axelsson
    url_fseek(s->pb, -14, SEEK_CUR);
934 07bf2af8 Baptiste Coudurier
    mxf->fc = s;
935 899681cd Björn Axelsson
    while (!url_feof(s->pb)) {
936 975c88e3 Baptiste Coudurier
        const MXFMetadataReadTableEntry *metadata;
937 b92c61e0 Baptiste Coudurier
938 899681cd Björn Axelsson
        if (klv_read_packet(&klv, s->pb) < 0)
939 07bf2af8 Baptiste Coudurier
            return -1;
940 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
941 318c5e05 Michel Bardiaux
        PRINT_KEY(s, "read header", klv.key);
942 6d0c3beb Baptiste Coudurier
#endif
943 80a289b9 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
944
            IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
945 07bf2af8 Baptiste Coudurier
            /* FIXME avoid seek */
946 899681cd Björn Axelsson
            url_fseek(s->pb, klv.offset, SEEK_SET);
947 07bf2af8 Baptiste Coudurier
            break;
948 5e441e31 Baptiste Coudurier
        }
949 b92c61e0 Baptiste Coudurier
950 975c88e3 Baptiste Coudurier
        for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
951
            if (IS_KLV_KEY(klv.key, metadata->key)) {
952
                if (mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
953 b92c61e0 Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
954
                    return -1;
955
                }
956
                break;
957
            }
958
        }
959 975c88e3 Baptiste Coudurier
        if (!metadata->read)
960 899681cd Björn Axelsson
            url_fskip(s->pb, klv.length);
961 07bf2af8 Baptiste Coudurier
    }
962 743d772c Baptiste Coudurier
    return mxf_parse_structural_metadata(mxf);
963 07bf2af8 Baptiste Coudurier
}
964
965
static int mxf_read_close(AVFormatContext *s)
966
{
967
    MXFContext *mxf = s->priv_data;
968 d2cdbd5f Baptiste Coudurier
    int i;
969 743d772c Baptiste Coudurier
970
    av_freep(&mxf->packages_refs);
971 d2cdbd5f Baptiste Coudurier
    for (i = 0; i < mxf->metadata_sets_count; i++) {
972
        switch (mxf->metadata_sets[i]->type) {
973
        case MultipleDescriptor:
974
            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
975
            break;
976
        case Sequence:
977
            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
978
            break;
979
        case SourcePackage:
980
        case MaterialPackage:
981
            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
982
            break;
983
        default:
984
            break;
985
        }
986
        av_freep(&mxf->metadata_sets[i]);
987
    }
988
    av_freep(&mxf->metadata_sets);
989 80a289b9 Reimar Döffinger
    av_freep(&mxf->aesc);
990 07bf2af8 Baptiste Coudurier
    return 0;
991
}
992
993
static int mxf_probe(AVProbeData *p) {
994 ba32c8df Baptiste Coudurier
    uint8_t *bufp = p->buf;
995
    uint8_t *end = p->buf + p->buf_size;
996
997 07bf2af8 Baptiste Coudurier
    if (p->buf_size < sizeof(mxf_header_partition_pack_key))
998
        return 0;
999
1000 ba32c8df Baptiste Coudurier
    /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
1001
    end -= sizeof(mxf_header_partition_pack_key);
1002
    for (; bufp < end; bufp++) {
1003 f8503792 Baptiste Coudurier
        if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
1004 ba32c8df Baptiste Coudurier
            return AVPROBE_SCORE_MAX;
1005
    }
1006
    return 0;
1007 07bf2af8 Baptiste Coudurier
}
1008
1009 2f8fe719 Baptiste Coudurier
/* rudimentary byte seek */
1010 3a6ccf4f Baptiste Coudurier
/* XXX: use MXF Index */
1011
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1012
{
1013
    AVStream *st = s->streams[stream_index];
1014
    int64_t seconds;
1015
1016 de9fe002 Baptiste Coudurier
    if (!s->bit_rate)
1017 3a6ccf4f Baptiste Coudurier
        return -1;
1018 de9fe002 Baptiste Coudurier
    if (sample_time < 0)
1019
        sample_time = 0;
1020 3a6ccf4f Baptiste Coudurier
    seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
1021 899681cd Björn Axelsson
    url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
1022 ee71ef5c Baptiste Coudurier
    av_update_cur_dts(s, st, sample_time);
1023
    return 0;
1024 3a6ccf4f Baptiste Coudurier
}
1025 07bf2af8 Baptiste Coudurier
1026
AVInputFormat mxf_demuxer = {
1027
    "mxf",
1028
    "MXF format",
1029
    sizeof(MXFContext),
1030
    mxf_probe,
1031
    mxf_read_header,
1032
    mxf_read_packet,
1033
    mxf_read_close,
1034 3a6ccf4f Baptiste Coudurier
    mxf_read_seek,
1035 07bf2af8 Baptiste Coudurier
};