Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 71e445fc

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