Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 7ee7f6f9

History | View | Annotate | Download (41.8 KB)

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