mxf.c 40.5 KB
Newer Older
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1 2 3 4
/*
 * MXF demuxer.
 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>.
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
Baptiste Coudurier's avatar
Baptiste Coudurier committed
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Baptiste Coudurier's avatar
Baptiste Coudurier committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Baptiste Coudurier's avatar
Baptiste Coudurier committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
Baptiste Coudurier's avatar
Baptiste Coudurier committed
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/*
 * References
 * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
 * SMPTE 377M MXF File Format Specifications
 * SMPTE 378M Operational Pattern 1a
 * SMPTE 379M MXF Generic Container
 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
 * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
 * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
 *
 * Principle
 * Search for Track numbers which will identify essence element KLV packets.
 * Search for SourcePackage which define tracks which contains Track numbers.
35
 * Material Package contains tracks with reference to SourcePackage tracks.
Baptiste Coudurier's avatar
Baptiste Coudurier committed
36 37 38
 * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
 * Assign Descriptors to correct Tracks.
 *
39 40
 * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
 * Metadata parsing resolves Strong References to objects.
41 42 43
 *
 * Simple demuxer, only OP1A supported and some files might not work at all.
 * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
Baptiste Coudurier's avatar
Baptiste Coudurier committed
44 45
 */

46
//#define DEBUG
Baptiste Coudurier's avatar
Baptiste Coudurier committed
47 48

#include "avformat.h"
49
#include "aes.h"
50
#include "bytestream.h"
Baptiste Coudurier's avatar
Baptiste Coudurier committed
51

52
typedef uint8_t UID[16];
53

54
enum MXFMetadataSetType {
55
    AnyType,
56 57 58
    MaterialPackage,
    SourcePackage,
    SourceClip,
59 60 61 62 63
    TimecodeComponent,
    Sequence,
    MultipleDescriptor,
    Descriptor,
    Track,
64
    CryptoContext,
65 66
};

67
typedef struct {
68 69 70 71 72
    UID uid;
    enum MXFMetadataSetType type;
    UID source_container_ul;
} MXFCryptoContext;

73
typedef struct {
74
    UID uid;
75
    enum MXFMetadataSetType type;
76 77 78 79 80 81 82
    UID source_package_uid;
    UID data_definition_ul;
    int64_t duration;
    int64_t start_position;
    int source_track_id;
} MXFStructuralComponent;

83
typedef struct {
84
    UID uid;
85
    enum MXFMetadataSetType type;
86 87 88 89 90 91
    UID data_definition_ul;
    UID *structural_components_refs;
    int structural_components_count;
    int64_t duration;
} MXFSequence;

92
typedef struct {
93
    UID uid;
94
    enum MXFMetadataSetType type;
95 96
    MXFSequence *sequence; /* mandatory, and only one */
    UID sequence_ref;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
97
    int track_id;
98
    uint8_t track_number[4];
99
    AVRational edit_rate;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
100 101
} MXFTrack;

102
typedef struct {
103
    UID uid;
104
    enum MXFMetadataSetType type;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
105 106
    UID essence_container_ul;
    UID essence_codec_ul;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
107 108 109 110 111 112
    AVRational sample_rate;
    AVRational aspect_ratio;
    int width;
    int height;
    int channels;
    int bits_per_sample;
113 114
    UID *sub_descriptors_refs;
    int sub_descriptors_count;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
115
    int linked_track_id;
116 117
    uint8_t *extradata;
    int extradata_size;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
118 119
} MXFDescriptor;

120
typedef struct {
121
    UID uid;
122
    enum MXFMetadataSetType type;
123 124
    UID package_uid;
    UID *tracks_refs;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
125
    int tracks_count;
126 127 128 129
    MXFDescriptor *descriptor; /* only one */
    UID descriptor_ref;
} MXFPackage;

130 131 132 133 134
typedef struct {
    UID uid;
    enum MXFMetadataSetType type;
} MXFMetadataSet;

135
typedef struct {
136 137
    UID *packages_refs;
    int packages_count;
138 139
    MXFMetadataSet **metadata_sets;
    int metadata_sets_count;
140
    AVFormatContext *fc;
141
    struct AVAES *aesc;
142 143
    uint8_t *local_tags;
    int local_tags_count;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
144 145
} MXFContext;

146
typedef struct {
147
    UID key;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
148 149 150 151
    offset_t offset;
    uint64_t length;
} KLVPacket;

152 153 154 155 156
enum MXFWrappingScheme {
    Frame,
    Clip,
};

157
typedef struct {
158
    UID uid;
159
    unsigned matching_len;
160 161 162
    enum CodecID id;
} MXFCodecUL;

163
typedef struct {
164 165 166 167
    UID uid;
    enum CodecType type;
} MXFDataDefinitionUL;

168
typedef struct {
169
    const UID key;
170 171 172
    int (*read)();
    int ctx_size;
    enum MXFMetadataSetType type;
173
} MXFMetadataReadTableEntry;
174 175

/* partial keys to match */
Baptiste Coudurier's avatar
Baptiste Coudurier committed
176
static const uint8_t mxf_header_partition_pack_key[]       = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
177
static const uint8_t mxf_essence_element_key[]             = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
178
static const uint8_t mxf_klv_key[]                         = { 0x06,0x0e,0x2b,0x34 };
179
/* complete keys to match */
180
static const uint8_t mxf_crypto_source_container_ul[]      = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
181
static const uint8_t mxf_encrypted_triplet_key[]           = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
182
static const uint8_t mxf_encrypted_essence_container[]     = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
183
static const uint8_t mxf_sony_mpeg4_extradata[]            = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
Baptiste Coudurier's avatar
Baptiste Coudurier committed
184 185 186

#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))

187
#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, \
188
                             (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])
Baptiste Coudurier's avatar
Baptiste Coudurier committed
189 190 191

static int64_t klv_decode_ber_length(ByteIOContext *pb)
{
192 193 194
    uint64_t size = get_byte(pb);
    if (size & 0x80) { /* long form */
        int bytes_num = size & 0x7f;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
195 196 197
        /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */
        if (bytes_num > 8)
            return -1;
198
        size = 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
199 200 201 202 203 204
        while (bytes_num--)
            size = size << 8 | get_byte(pb);
    }
    return size;
}

205 206 207 208 209 210 211 212 213 214 215 216 217
static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
{
    int i, b;
    for (i = 0; i < size && !url_feof(pb); i++) {
        b = get_byte(pb);
        if (b == key[0])
            i = 0;
        else if (b != key[i])
            i = -1;
    }
    return i == size;
}

Baptiste Coudurier's avatar
Baptiste Coudurier committed
218 219
static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb)
{
220 221 222 223 224
    if (!mxf_read_sync(pb, mxf_klv_key, 4))
        return -1;
    klv->offset = url_ftell(pb) - 4;
    memcpy(klv->key, mxf_klv_key, 4);
    get_buffer(pb, klv->key + 4, 12);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
225
    klv->length = klv_decode_ber_length(pb);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
226
    return klv->length == -1 ? -1 : 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
227 228 229 230 231 232 233
}

static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
{
    int i;

    for (i = 0; i < s->nb_streams; i++) {
234
        MXFTrack *track = s->streams[i]->priv_data;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
235
        /* SMPTE 379M 7.3 */
236
        if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
Baptiste Coudurier's avatar
Baptiste Coudurier committed
237 238
            return i;
    }
239 240
    /* return 0 if only one stream, for OP Atom files with 0 as track number */
    return s->nb_streams == 1 ? 0 : -1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
241 242
}

243 244 245 246
/* XXX: use AVBitStreamFilter */
static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
{
    uint8_t buffer[61444];
Baptiste Coudurier's avatar
Baptiste Coudurier committed
247 248
    const uint8_t *buf_ptr, *end_ptr;
    uint8_t *data_ptr;
249
    int i;
250 251 252 253 254 255 256 257

    if (length > 61444) /* worst case PAL 1920 samples 8 channels */
        return -1;
    get_buffer(pb, buffer, length);
    av_new_packet(pkt, length);
    data_ptr = pkt->data;
    end_ptr = buffer + length;
    buf_ptr = buffer + 4; /* skip SMPTE 331M header */
258 259 260 261 262 263 264
    for (; buf_ptr < end_ptr; ) {
        for (i = 0; i < st->codec->channels; i++) {
            uint32_t sample = bytestream_get_le32(&buf_ptr);
            if (st->codec->bits_per_sample == 24)
                bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
            else
                bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
265
        }
266
        buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
267 268 269 270 271
    }
    pkt->size = data_ptr - pkt->data;
    return 0;
}

272 273 274 275
static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
{
    static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
    MXFContext *mxf = s->priv_data;
276
    ByteIOContext *pb = s->pb;
277 278 279 280 281 282 283 284 285 286
    offset_t end = url_ftell(pb) + klv->length;
    uint64_t size;
    uint64_t orig_size;
    uint64_t plaintext_size;
    uint8_t ivec[16];
    uint8_t tmpbuf[16];
    int index;

    if (!mxf->aesc && s->key && s->keylen == 16) {
        mxf->aesc = av_malloc(av_aes_size);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
287 288
        if (!mxf->aesc)
            return -1;
289 290 291 292 293 294 295 296 297 298
        av_aes_init(mxf->aesc, s->key, 128, 1);
    }
    // crypto context
    url_fskip(pb, klv_decode_ber_length(pb));
    // plaintext offset
    klv_decode_ber_length(pb);
    plaintext_size = get_be64(pb);
    // source klv key
    klv_decode_ber_length(pb);
    get_buffer(pb, klv->key, 16);
299 300
    if (!IS_KLV_KEY(klv, mxf_essence_element_key))
        return -1;
301
    index = mxf_get_stream_index(s, klv);
302 303
    if (index < 0)
        return -1;
304 305 306
    // source size
    klv_decode_ber_length(pb);
    orig_size = get_be64(pb);
307 308
    if (orig_size < plaintext_size)
        return -1;
309 310
    // enc. code
    size = klv_decode_ber_length(pb);
311 312
    if (size < 32 || size - 32 < orig_size)
        return -1;
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
    get_buffer(pb, ivec, 16);
    get_buffer(pb, tmpbuf, 16);
    if (mxf->aesc)
        av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
    if (memcmp(tmpbuf, checkv, 16))
        av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
    size -= 32;
    av_get_packet(pb, pkt, size);
    size -= plaintext_size;
    if (mxf->aesc)
        av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
                     &pkt->data[plaintext_size], size >> 4, ivec, 1);
    pkt->size = orig_size;
    pkt->stream_index = index;
    url_fskip(pb, end - url_ftell(pb));
    return 0;
}

Baptiste Coudurier's avatar
Baptiste Coudurier committed
331 332 333 334
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    KLVPacket klv;

335 336
    while (!url_feof(s->pb)) {
        if (klv_read_packet(&klv, s->pb) < 0)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
337
            return -1;
338
#ifdef DEBUG
339
        PRINT_KEY(s, "read packet", klv.key);
340
#endif
341
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
342 343 344 345 346 347
            int res = mxf_decrypt_triplet(s, pkt, &klv);
            if (res < 0) {
                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
                return -1;
            }
            return 0;
348
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
349
        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
350 351 352
            int index = mxf_get_stream_index(s, &klv);
            if (index < 0) {
                av_log(s, AV_LOG_ERROR, "error getting stream index\n");
353
                url_fskip(s->pb, klv.length);
354 355 356 357
                return -1;
            }
            /* check for 8 channels AES3 element */
            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
358
                if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
359 360 361 362
                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
                    return -1;
                }
            } else
363
                av_get_packet(s->pb, pkt, klv.length);
364
            pkt->stream_index = index;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
365
            pkt->pos = klv.offset;
366
            return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
367
        } else
368
            url_fskip(s->pb, klv.length);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
369
    }
370
    return AVERROR(EIO);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
371 372
}

373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
static int mxf_read_primer_pack(MXFContext *mxf)
{
    ByteIOContext *pb = mxf->fc->pb;
    int item_num = get_be32(pb);
    int item_len = get_be32(pb);

    if (item_len != 18) {
        av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n");
        return -1;
    }
    if (item_num > UINT_MAX / item_len)
        return -1;
    mxf->local_tags_count = item_num;
    mxf->local_tags = av_malloc(item_num*item_len);
    if (!mxf->local_tags)
        return -1;
    get_buffer(pb, mxf->local_tags, item_num*item_len);
    return 0;
}

393 394 395
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
{
    mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
396 397
    if (!mxf->metadata_sets)
        return -1;
398 399 400 401 402
    mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
    mxf->metadata_sets_count++;
    return 0;
}

403
static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid)
404
{
405 406
    if (size != 16)
        return -1;
407
    if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
408 409 410 411
        get_buffer(pb, cryptocontext->source_container_ul, 16);
    return 0;
}

412
static int mxf_read_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
413
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
414 415 416 417 418 419
    switch (tag) {
    case 0x1901:
        mxf->packages_count = get_be32(pb);
        if (mxf->packages_count >= UINT_MAX / sizeof(UID))
            return -1;
        mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
420 421
        if (!mxf->packages_refs)
            return -1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
422 423 424 425
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
        get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID));
        break;
    }
426 427 428
    return 0;
}

429
static int mxf_read_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag)
430
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
    switch(tag) {
    case 0x0202:
        source_clip->duration = get_be64(pb);
        break;
    case 0x1201:
        source_clip->start_position = get_be64(pb);
        break;
    case 0x1101:
        /* UMID, only get last 16 bytes */
        url_fskip(pb, 16);
        get_buffer(pb, source_clip->source_package_uid, 16);
        break;
    case 0x1102:
        source_clip->source_track_id = get_be32(pb);
        break;
    }
    return 0;
448 449
}

450
static int mxf_read_material_package(MXFPackage *package, ByteIOContext *pb, int tag)
451
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
452 453 454 455 456 457
    switch(tag) {
    case 0x4403:
        package->tracks_count = get_be32(pb);
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
            return -1;
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
458 459
        if (!package->tracks_refs)
            return -1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
460 461 462 463 464
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
        break;
    }
    return 0;
465 466
}

467
static int mxf_read_track(MXFTrack *track, ByteIOContext *pb, int tag)
468
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
    switch(tag) {
    case 0x4801:
        track->track_id = get_be32(pb);
        break;
    case 0x4804:
        get_buffer(pb, track->track_number, 4);
        break;
    case 0x4B01:
        track->edit_rate.den = get_be32(pb);
        track->edit_rate.num = get_be32(pb);
        break;
    case 0x4803:
        get_buffer(pb, track->sequence_ref, 16);
        break;
    }
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
485 486
}

487
static int mxf_read_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
488
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
489 490 491 492 493 494 495 496 497 498 499 500
    switch(tag) {
    case 0x0202:
        sequence->duration = get_be64(pb);
        break;
    case 0x0201:
        get_buffer(pb, sequence->data_definition_ul, 16);
        break;
    case 0x1001:
        sequence->structural_components_count = get_be32(pb);
        if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
            return -1;
        sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
501 502
        if (!sequence->structural_components_refs)
            return -1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
503 504 505 506 507
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
        get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
        break;
    }
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
508 509
}

510
static int mxf_read_source_package(MXFPackage *package, ByteIOContext *pb, int tag)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
511
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
512 513 514 515 516 517
    switch(tag) {
    case 0x4403:
        package->tracks_count = get_be32(pb);
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
            return -1;
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
518 519
        if (!package->tracks_refs)
            return -1;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
520 521 522 523 524 525 526 527 528 529 530 531 532
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
        break;
    case 0x4401:
        /* UMID, only get last 16 bytes */
        url_fskip(pb, 16);
        get_buffer(pb, package->package_uid, 16);
        break;
    case 0x4701:
        get_buffer(pb, package->descriptor_ref, 16);
        break;
    }
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
533 534
}

535
static void mxf_read_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor)
536 537 538 539 540
{
    int code;

    do {
        code = get_byte(pb);
541
        dprintf(NULL, "pixel layout: code 0x%x\n", code);
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
        switch (code) {
        case 0x52: /* R */
            descriptor->bits_per_sample += get_byte(pb);
            break;
        case 0x47: /* G */
            descriptor->bits_per_sample += get_byte(pb);
            break;
        case 0x42: /* B */
            descriptor->bits_per_sample += get_byte(pb);
            break;
        default:
            get_byte(pb);
        }
    } while (code != 0); /* SMPTE 377M E.2.46 */
}

558
static int mxf_read_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size, UID uid)
559
{
Baptiste Coudurier's avatar
Baptiste Coudurier committed
560
    switch(tag) {
561 562 563 564 565
    case 0x3F01:
        descriptor->sub_descriptors_count = get_be32(pb);
        if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
            return -1;
        descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
Baptiste Coudurier's avatar
Baptiste Coudurier committed
566 567
        if (!descriptor->sub_descriptors_refs)
            return -1;
568 569 570
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
        get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
        break;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603
    case 0x3004:
        get_buffer(pb, descriptor->essence_container_ul, 16);
        break;
    case 0x3006:
        descriptor->linked_track_id = get_be32(pb);
        break;
    case 0x3201: /* PictureEssenceCoding */
        get_buffer(pb, descriptor->essence_codec_ul, 16);
        break;
    case 0x3203:
        descriptor->width = get_be32(pb);
        break;
    case 0x3202:
        descriptor->height = get_be32(pb);
        break;
    case 0x320E:
        descriptor->aspect_ratio.num = get_be32(pb);
        descriptor->aspect_ratio.den = get_be32(pb);
        break;
    case 0x3D03:
        descriptor->sample_rate.num = get_be32(pb);
        descriptor->sample_rate.den = get_be32(pb);
        break;
    case 0x3D06: /* SoundEssenceCompression */
        get_buffer(pb, descriptor->essence_codec_ul, 16);
        break;
    case 0x3D07:
        descriptor->channels = get_be32(pb);
        break;
    case 0x3D01:
        descriptor->bits_per_sample = get_be32(pb);
        break;
    case 0x3401:
604
        mxf_read_pixel_layout(pb, descriptor);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
605
        break;
606 607 608
    default:
        /* Private uid used by SONY C0023S01.mxf */
        if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
Baptiste Coudurier's avatar
Baptiste Coudurier committed
609 610 611 612 613
            descriptor->extradata = av_malloc(size);
            if (!descriptor->extradata)
                return -1;
            descriptor->extradata_size = size;
            get_buffer(pb, descriptor->extradata, size);
614
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
615 616 617
        break;
    }
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
618 619 620
}

/* SMPTE RP224 http://www.smpte-ra.org/mdd/index.html */
621 622 623
static const MXFDataDefinitionUL mxf_data_definition_uls[] = {
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, CODEC_TYPE_VIDEO },
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, CODEC_TYPE_AUDIO },
624
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x05,0x01,0x03,0x02,0x02,0x02,0x02,0x00,0x00 }, CODEC_TYPE_AUDIO },
625 626
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  CODEC_TYPE_DATA },
};
627 628 629

static const MXFCodecUL mxf_codec_uls[] = {
    /* PictureEssenceCoding */
630 631 632 633 634 635 636 637
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@ML Long GoP */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* D-10 50Mbps PAL */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@HL Long GoP */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* 422P@HL I-Frame */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14,      CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13,    CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,   CODEC_ID_RAWVIDEO }, /* Uncompressed */
638
    /* SoundEssenceCompression */
639 640 641 642 643 644 645 646
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13,  CODEC_ID_PCM_S16LE }, /* Uncompressed */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,  CODEC_ID_PCM_S16LE },
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13,  CODEC_ID_PCM_S16BE }, /* From Omneon MXF file */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15,   CODEC_ID_PCM_ALAW }, /* XDCAM Proxy C0023S01.mxf */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15,        CODEC_ID_AC3 },
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15,        CODEC_ID_MP2 }, /* MP2 or MP3 */
  //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15,    CODEC_ID_DOLBY_E }, /* Dolby-E */
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       CODEC_ID_NONE },
Baptiste Coudurier's avatar
Baptiste Coudurier committed
647 648
};

649
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
650 651 652
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,    CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       CODEC_ID_NONE },
653 654 655
};

static const MXFCodecUL mxf_sound_essence_container_uls[] = {
656 657
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,       CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */
658 659
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,      CODEC_ID_NONE },
660 661
};

662 663 664 665 666 667 668 669 670 671 672 673 674 675
/*
 * Match an uid independently of the version byte and up to len common bytes
 * Returns: boolean
 */
static int mxf_match_uid(const UID key, const UID uid, int len)
{
    int i;
    for (i = 0; i < len; i++) {
        if (i != 7 && key[i] != uid[i])
            return 0;
    }
    return 1;
}

676
static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
677 678
{
    while (uls->id != CODEC_ID_NONE) {
679
        if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
680
            break;
681 682
        uls++;
    }
683
    return uls;
684
}
Baptiste Coudurier's avatar
Baptiste Coudurier committed
685

686 687 688
static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
{
    while (uls->type != CODEC_TYPE_DATA) {
689
        if(mxf_match_uid(uls->uid, *uid, 16))
690 691 692 693 694 695
            break;
        uls++;
    }
    return uls->type;
}

696
static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
697 698 699 700 701 702
{
    int i;

    if (!strong_ref)
        return NULL;
    for (i = 0; i < mxf->metadata_sets_count; i++) {
703
        if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
704
            (type == AnyType || mxf->metadata_sets[i]->type == type)) {
705 706 707 708 709 710
            return mxf->metadata_sets[i];
        }
    }
    return NULL;
}

711
static int mxf_parse_structural_metadata(MXFContext *mxf)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
712
{
713
    MXFPackage *material_package = NULL;
714
    MXFPackage *temp_package = NULL;
715 716
    int i, j, k;

717
    dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
718 719
    /* TODO: handle multiple material packages (OP3x) */
    for (i = 0; i < mxf->packages_count; i++) {
720 721
        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
        if (material_package) break;
722 723 724 725 726
    }
    if (!material_package) {
        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
        return -1;
    }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
727

728
    for (i = 0; i < material_package->tracks_count; i++) {
729
        MXFPackage *source_package = NULL;
730
        MXFTrack *material_track = NULL;
731
        MXFTrack *source_track = NULL;
732
        MXFTrack *temp_track = NULL;
733 734
        MXFDescriptor *descriptor = NULL;
        MXFStructuralComponent *component = NULL;
735
        UID *essence_container_ul = NULL;
736 737
        const MXFCodecUL *codec_ul = NULL;
        const MXFCodecUL *container_ul = NULL;
738 739
        AVStream *st;

740
        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
741 742 743 744
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
            continue;
        }

745
        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
746 747 748 749
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
            return -1;
        }

750 751 752
        /* TODO: handle multiple source clips */
        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
            /* TODO: handle timecode component */
753 754
            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
            if (!component)
755 756 757
                continue;

            for (k = 0; k < mxf->packages_count; k++) {
758 759 760
                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
                if (!temp_package)
                    continue;
761 762
                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
                    source_package = temp_package;
763 764 765 766 767 768 769 770
                    break;
                }
            }
            if (!source_package) {
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
                break;
            }
            for (k = 0; k < source_package->tracks_count; k++) {
771
                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
772 773 774 775 776
                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
                    return -1;
                }
                if (temp_track->track_id == component->source_track_id) {
                    source_track = temp_track;
777 778 779 780 781 782 783 784 785 786 787
                    break;
                }
            }
            if (!source_track) {
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
                break;
            }
        }
        if (!source_track)
            continue;

788
        st = av_new_stream(mxf->fc, source_track->track_id);
789 790 791 792
        if (!st) {
            av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
            return -1;
        }
793
        st->priv_data = source_track;
794 795 796 797 798
        st->duration = component->duration;
        if (st->duration == -1)
            st->duration = AV_NOPTS_VALUE;
        st->start_time = component->start_position;
        av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
799

800
        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
801 802 803 804
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
            return -1;
        }

805
#ifdef DEBUG
806
        PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
807
#endif
808
        st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
809

810
        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
811
        if (source_package->descriptor) {
812
            if (source_package->descriptor->type == MultipleDescriptor) {
813
                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
814
                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
815 816 817 818 819 820 821 822

                    if (!sub_descriptor) {
                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
                        continue;
                    }
                    if (sub_descriptor->linked_track_id == source_track->track_id) {
                        descriptor = sub_descriptor;
                        break;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
823 824
                    }
                }
825
            } else if (source_package->descriptor->type == Descriptor)
826 827 828 829 830 831 832
                descriptor = source_package->descriptor;
        }
        if (!descriptor) {
            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
            continue;
        }
#ifdef DEBUG
833 834
        PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);
        PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
835
#endif
836 837 838 839 840 841 842 843 844 845 846 847 848
        essence_container_ul = &descriptor->essence_container_ul;
        /* HACK: replacing the original key with mxf_encrypted_essence_container
         * is not allowed according to s429-6, try to find correct information anyway */
        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
            for (k = 0; k < mxf->metadata_sets_count; k++) {
                MXFMetadataSet *metadata = mxf->metadata_sets[k];
                if (metadata->type == CryptoContext) {
                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
                    break;
                }
            }
        }
849 850
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
851
        st->codec->codec_id = codec_ul->id;
852 853 854 855
        if (descriptor->extradata) {
            st->codec->extradata = descriptor->extradata;
            st->codec->extradata_size = descriptor->extradata_size;
        }
856
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
857
            container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
858
            if (st->codec->codec_id == CODEC_ID_NONE)
859
                st->codec->codec_id = container_ul->id;
860 861
            st->codec->width = descriptor->width;
            st->codec->height = descriptor->height;
862
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
863
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
864
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
865
            container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
866
            if (st->codec->codec_id == CODEC_ID_NONE)
867
                st->codec->codec_id = container_ul->id;
868 869 870 871 872 873 874 875 876 877 878 879 880 881
            st->codec->channels = descriptor->channels;
            st->codec->bits_per_sample = descriptor->bits_per_sample;
            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
            /* TODO: implement CODEC_ID_RAWAUDIO */
            if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
                if (descriptor->bits_per_sample == 24)
                    st->codec->codec_id = CODEC_ID_PCM_S24LE;
                else if (descriptor->bits_per_sample == 32)
                    st->codec->codec_id = CODEC_ID_PCM_S32LE;
            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
                if (descriptor->bits_per_sample == 24)
                    st->codec->codec_id = CODEC_ID_PCM_S24BE;
                else if (descriptor->bits_per_sample == 32)
                    st->codec->codec_id = CODEC_ID_PCM_S32BE;
882
            } else if (st->codec->codec_id == CODEC_ID_MP2) {
883
                st->need_parsing = AVSTREAM_PARSE_FULL;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
884 885
            }
        }
886 887
        if (st->codec->codec_type != CODEC_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
            av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");
888
            st->need_parsing = AVSTREAM_PARSE_FULL;
889
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
890
    }
891
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
892 893
}

894
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
895
    { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
911
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
912 913
};

914 915
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
{
916
    ByteIOContext *pb = mxf->fc->pb;
917
    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
918
    uint64_t klv_end = url_ftell(pb) + klv->length;
919

Baptiste Coudurier's avatar
Baptiste Coudurier committed
920 921
    if (!ctx)
        return -1;
922 923 924
    while (url_ftell(pb) + 4 < klv_end) {
        int tag = get_be16(pb);
        int size = get_be16(pb); /* KLV specified by 0x53 */
Baptiste Coudurier's avatar
Baptiste Coudurier committed
925
        uint64_t next = url_ftell(pb) + size;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
926
        UID uid = {0};
927 928 929 930 931

        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
            av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
            continue;
        }
932 933 934 935 936 937 938 939 940 941 942 943 944
        if (tag > 0x7FFF) { /* dynamic tag */
            int i;
            for (i = 0; i < mxf->local_tags_count; i++) {
                int local_tag = AV_RB16(mxf->local_tags+i*18);
                if (local_tag == tag) {
                    memcpy(uid, mxf->local_tags+i*18+2, 16);
                    dprintf(mxf->fc, "local tag 0x%04X\n", local_tag);
#ifdef DEBUG
                    PRINT_KEY(mxf->fc, "uid", uid);
#endif
                }
            }
        }
Baptiste Coudurier's avatar
Baptiste Coudurier committed
945
        if (ctx_size && tag == 0x3C0A)
946
            get_buffer(pb, ctx->uid, 16);
947 948
        else if (read_child(ctx, pb, tag, size, uid) < 0)
            return -1;
949 950 951 952 953 954 955

        url_fseek(pb, next, SEEK_SET);
    }
    if (ctx_size) ctx->type = type;
    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
}

Baptiste Coudurier's avatar
Baptiste Coudurier committed
956 957 958 959 960
static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    MXFContext *mxf = s->priv_data;
    KLVPacket klv;

961
    if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
962 963 964
        av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
        return -1;
    }
965
    url_fseek(s->pb, -14, SEEK_CUR);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
966
    mxf->fc = s;
967
    while (!url_feof(s->pb)) {
968
        const MXFMetadataReadTableEntry *metadata;
969

970
        if (klv_read_packet(&klv, s->pb) < 0)
Baptiste Coudurier's avatar
Baptiste Coudurier committed
971
            return -1;
972
#ifdef DEBUG
973
        PRINT_KEY(s, "read header", klv.key);
974
#endif
975 976
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
            IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
Baptiste Coudurier's avatar
Baptiste Coudurier committed
977
            /* FIXME avoid seek */
978
            url_fseek(s->pb, klv.offset, SEEK_SET);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
979
            break;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
980
        }
981

982 983
        for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
            if (IS_KLV_KEY(klv.key, metadata->key)) {
984 985
                int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read;
                if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
986 987 988 989 990 991
                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
                    return -1;
                }
                break;
            }
        }
992
        if (!metadata->read)
993
            url_fskip(s->pb, klv.length);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
994
    }
995
    return mxf_parse_structural_metadata(mxf);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
996 997 998 999 1000
}

static int mxf_read_close(AVFormatContext *s)
{
    MXFContext *mxf = s->priv_data;
1001
    int i;
1002 1003

    av_freep(&mxf->packages_refs);
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021
    for (i = 0; i < mxf->metadata_sets_count; i++) {
        switch (mxf->metadata_sets[i]->type) {
        case MultipleDescriptor:
            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
            break;
        case Sequence:
            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
            break;
        case SourcePackage:
        case MaterialPackage:
            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
            break;
        default:
            break;
        }
        av_freep(&mxf->metadata_sets[i]);
    }
    av_freep(&mxf->metadata_sets);
1022
    av_freep(&mxf->aesc);
1023
    av_freep(&mxf->local_tags);
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1024 1025 1026 1027
    return 0;
}

static int mxf_probe(AVProbeData *p) {
1028 1029 1030
    uint8_t *bufp = p->buf;
    uint8_t *end = p->buf + p->buf_size;

Baptiste Coudurier's avatar
Baptiste Coudurier committed
1031 1032 1033
    if (p->buf_size < sizeof(mxf_header_partition_pack_key))
        return 0;

1034 1035 1036
    /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
    end -= sizeof(mxf_header_partition_pack_key);
    for (; bufp < end; bufp++) {
1037
        if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
1038 1039 1040
            return AVPROBE_SCORE_MAX;
    }
    return 0;
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1041 1042
}

1043
/* rudimentary byte seek */
1044 1045 1046 1047 1048 1049
/* XXX: use MXF Index */
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
{
    AVStream *st = s->streams[stream_index];
    int64_t seconds;

1050
    if (!s->bit_rate)
1051
        return -1;
1052 1053
    if (sample_time < 0)
        sample_time = 0;
1054
    seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
1055
    url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
1056 1057
    av_update_cur_dts(s, st, sample_time);
    return 0;
1058
}
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1059 1060 1061 1062 1063 1064 1065 1066 1067

AVInputFormat mxf_demuxer = {
    "mxf",
    "MXF format",
    sizeof(MXFContext),
    mxf_probe,
    mxf_read_header,
    mxf_read_packet,
    mxf_read_close,
1068
    mxf_read_seek,
Baptiste Coudurier's avatar
Baptiste Coudurier committed
1069
};