Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 9184d53a

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