Statistics
| Branch: | Revision:

ffmpeg / libavformat / mxf.c @ 2b12d6fc

History | View | Annotate | Download (40.5 KB)

1 07bf2af8 Baptiste Coudurier
/*
2
 * MXF demuxer.
3
 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>.
4
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 07bf2af8 Baptiste Coudurier
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 07bf2af8 Baptiste Coudurier
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 07bf2af8 Baptiste Coudurier
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 07bf2af8 Baptiste Coudurier
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/*
23
 * References
24
 * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value
25
 * SMPTE 377M MXF File Format Specifications
26
 * SMPTE 378M Operational Pattern 1a
27
 * SMPTE 379M MXF Generic Container
28
 * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container
29
 * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container
30
 * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container
31
 *
32
 * Principle
33
 * Search for Track numbers which will identify essence element KLV packets.
34
 * Search for SourcePackage which define tracks which contains Track numbers.
35 743d772c Baptiste Coudurier
 * Material Package contains tracks with reference to SourcePackage tracks.
36 07bf2af8 Baptiste Coudurier
 * Search for Descriptors (Picture, Sound) which contains codec info and parameters.
37
 * Assign Descriptors to correct Tracks.
38
 *
39 d2cdbd5f Baptiste Coudurier
 * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext.
40
 * Metadata parsing resolves Strong References to objects.
41 743d772c Baptiste Coudurier
 *
42
 * Simple demuxer, only OP1A supported and some files might not work at all.
43
 * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1
44 07bf2af8 Baptiste Coudurier
 */
45
46 49b6f162 Baptiste Coudurier
//#define DEBUG
47 07bf2af8 Baptiste Coudurier
48
#include "avformat.h"
49 80a289b9 Reimar Döffinger
#include "aes.h"
50 28cf7215 Baptiste Coudurier
#include "bytestream.h"
51 07bf2af8 Baptiste Coudurier
52 f03b6426 Baptiste Coudurier
typedef uint8_t UID[16];
53 4bfff768 Baptiste Coudurier
54 d2cdbd5f Baptiste Coudurier
enum MXFMetadataSetType {
55 6ac558ee Baptiste Coudurier
    AnyType,
56 743d772c Baptiste Coudurier
    MaterialPackage,
57
    SourcePackage,
58
    SourceClip,
59 d2cdbd5f Baptiste Coudurier
    TimecodeComponent,
60
    Sequence,
61
    MultipleDescriptor,
62
    Descriptor,
63
    Track,
64 80a289b9 Reimar Döffinger
    CryptoContext,
65 743d772c Baptiste Coudurier
};
66
67 1b481845 Baptiste Coudurier
typedef struct {
68 80a289b9 Reimar Döffinger
    UID uid;
69
    enum MXFMetadataSetType type;
70
    UID 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
                av_log(s, AV_LOG_ERROR, "error getting stream index\n");
353 899681cd Björn Axelsson
                url_fskip(s->pb, klv.length);
354 885e691a Baptiste Coudurier
                return -1;
355
            }
356
            /* check for 8 channels AES3 element */
357
            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
358 899681cd Björn Axelsson
                if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
359 885e691a Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
360
                    return -1;
361
                }
362
            } else
363 899681cd Björn Axelsson
                av_get_packet(s->pb, pkt, klv.length);
364 885e691a Baptiste Coudurier
            pkt->stream_index = index;
365 28b9f986 Baptiste Coudurier
            pkt->pos = klv.offset;
366 885e691a Baptiste Coudurier
            return 0;
367 07bf2af8 Baptiste Coudurier
        } else
368 899681cd Björn Axelsson
            url_fskip(s->pb, klv.length);
369 07bf2af8 Baptiste Coudurier
    }
370 6f3e0b21 Panagiotis Issaris
    return AVERROR(EIO);
371 07bf2af8 Baptiste Coudurier
}
372
373 7ee7f6f9 Baptiste Coudurier
static int mxf_read_primer_pack(MXFContext *mxf)
374
{
375
    ByteIOContext *pb = mxf->fc->pb;
376
    int item_num = get_be32(pb);
377
    int item_len = get_be32(pb);
378
379
    if (item_len != 18) {
380
        av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n");
381
        return -1;
382
    }
383
    if (item_num > UINT_MAX / item_len)
384
        return -1;
385
    mxf->local_tags_count = item_num;
386
    mxf->local_tags = av_malloc(item_num*item_len);
387
    if (!mxf->local_tags)
388
        return -1;
389
    get_buffer(pb, mxf->local_tags, item_num*item_len);
390
    return 0;
391
}
392
393 d2cdbd5f Baptiste Coudurier
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
394
{
395
    mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
396 57810910 Baptiste Coudurier
    if (!mxf->metadata_sets)
397
        return -1;
398 d2cdbd5f Baptiste Coudurier
    mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
399
    mxf->metadata_sets_count++;
400
    return 0;
401
}
402
403 4de5906f Baptiste Coudurier
static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid)
404 80a289b9 Reimar Döffinger
{
405 7ee7f6f9 Baptiste Coudurier
    if (size != 16)
406
        return -1;
407 3a9c08be Baptiste Coudurier
    if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
408 80a289b9 Reimar Döffinger
        get_buffer(pb, cryptocontext->source_container_ul, 16);
409
    return 0;
410
}
411
412 4de5906f Baptiste Coudurier
static int mxf_read_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
413 743d772c Baptiste Coudurier
{
414 55de95b9 Baptiste Coudurier
    switch (tag) {
415
    case 0x1901:
416
        mxf->packages_count = get_be32(pb);
417
        if (mxf->packages_count >= UINT_MAX / sizeof(UID))
418
            return -1;
419
        mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
420 57810910 Baptiste Coudurier
        if (!mxf->packages_refs)
421
            return -1;
422 55de95b9 Baptiste Coudurier
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
423
        get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID));
424
        break;
425
    }
426 743d772c Baptiste Coudurier
    return 0;
427
}
428
429 4de5906f Baptiste Coudurier
static int mxf_read_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag)
430 743d772c Baptiste Coudurier
{
431 55de95b9 Baptiste Coudurier
    switch(tag) {
432
    case 0x0202:
433
        source_clip->duration = get_be64(pb);
434
        break;
435
    case 0x1201:
436
        source_clip->start_position = get_be64(pb);
437
        break;
438
    case 0x1101:
439
        /* UMID, only get last 16 bytes */
440
        url_fskip(pb, 16);
441
        get_buffer(pb, source_clip->source_package_uid, 16);
442
        break;
443
    case 0x1102:
444
        source_clip->source_track_id = get_be32(pb);
445
        break;
446
    }
447
    return 0;
448 743d772c Baptiste Coudurier
}
449
450 4de5906f Baptiste Coudurier
static int mxf_read_material_package(MXFPackage *package, ByteIOContext *pb, int tag)
451 743d772c Baptiste Coudurier
{
452 55de95b9 Baptiste Coudurier
    switch(tag) {
453
    case 0x4403:
454
        package->tracks_count = get_be32(pb);
455
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
456
            return -1;
457
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
458 57810910 Baptiste Coudurier
        if (!package->tracks_refs)
459
            return -1;
460 55de95b9 Baptiste Coudurier
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
461
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
462
        break;
463
    }
464
    return 0;
465 743d772c Baptiste Coudurier
}
466
467 4de5906f Baptiste Coudurier
static int mxf_read_track(MXFTrack *track, ByteIOContext *pb, int tag)
468 743d772c Baptiste Coudurier
{
469 55de95b9 Baptiste Coudurier
    switch(tag) {
470
    case 0x4801:
471
        track->track_id = get_be32(pb);
472
        break;
473
    case 0x4804:
474
        get_buffer(pb, track->track_number, 4);
475
        break;
476
    case 0x4B01:
477
        track->edit_rate.den = get_be32(pb);
478
        track->edit_rate.num = get_be32(pb);
479
        break;
480
    case 0x4803:
481
        get_buffer(pb, track->sequence_ref, 16);
482
        break;
483
    }
484
    return 0;
485 07bf2af8 Baptiste Coudurier
}
486
487 4de5906f Baptiste Coudurier
static int mxf_read_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag)
488 07bf2af8 Baptiste Coudurier
{
489 55de95b9 Baptiste Coudurier
    switch(tag) {
490
    case 0x0202:
491
        sequence->duration = get_be64(pb);
492
        break;
493
    case 0x0201:
494
        get_buffer(pb, sequence->data_definition_ul, 16);
495
        break;
496
    case 0x1001:
497
        sequence->structural_components_count = get_be32(pb);
498
        if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
499
            return -1;
500
        sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
501 57810910 Baptiste Coudurier
        if (!sequence->structural_components_refs)
502
            return -1;
503 55de95b9 Baptiste Coudurier
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
504
        get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
505
        break;
506
    }
507
    return 0;
508 07bf2af8 Baptiste Coudurier
}
509
510 4de5906f Baptiste Coudurier
static int mxf_read_source_package(MXFPackage *package, ByteIOContext *pb, int tag)
511 07bf2af8 Baptiste Coudurier
{
512 55de95b9 Baptiste Coudurier
    switch(tag) {
513
    case 0x4403:
514
        package->tracks_count = get_be32(pb);
515
        if (package->tracks_count >= UINT_MAX / sizeof(UID))
516
            return -1;
517
        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
518 57810910 Baptiste Coudurier
        if (!package->tracks_refs)
519
            return -1;
520 55de95b9 Baptiste Coudurier
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
521
        get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
522
        break;
523
    case 0x4401:
524
        /* UMID, only get last 16 bytes */
525
        url_fskip(pb, 16);
526
        get_buffer(pb, package->package_uid, 16);
527
        break;
528
    case 0x4701:
529
        get_buffer(pb, package->descriptor_ref, 16);
530
        break;
531
    }
532
    return 0;
533 07bf2af8 Baptiste Coudurier
}
534
535 4de5906f Baptiste Coudurier
static void mxf_read_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor)
536 59b56738 Baptiste Coudurier
{
537
    int code;
538
539
    do {
540
        code = get_byte(pb);
541 318c5e05 Michel Bardiaux
        dprintf(NULL, "pixel layout: code 0x%x\n", code);
542 59b56738 Baptiste Coudurier
        switch (code) {
543
        case 0x52: /* R */
544
            descriptor->bits_per_sample += get_byte(pb);
545
            break;
546
        case 0x47: /* G */
547
            descriptor->bits_per_sample += get_byte(pb);
548
            break;
549
        case 0x42: /* B */
550
            descriptor->bits_per_sample += get_byte(pb);
551
            break;
552
        default:
553
            get_byte(pb);
554
        }
555
    } while (code != 0); /* SMPTE 377M E.2.46 */
556
}
557
558 bb085dd6 Baptiste Coudurier
static int mxf_read_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size, UID uid)
559 743d772c Baptiste Coudurier
{
560 55de95b9 Baptiste Coudurier
    switch(tag) {
561 e6837cfa Baptiste Coudurier
    case 0x3F01:
562
        descriptor->sub_descriptors_count = get_be32(pb);
563
        if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
564
            return -1;
565
        descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
566 57810910 Baptiste Coudurier
        if (!descriptor->sub_descriptors_refs)
567
            return -1;
568 e6837cfa Baptiste Coudurier
        url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */
569
        get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
570
        break;
571 55de95b9 Baptiste Coudurier
    case 0x3004:
572
        get_buffer(pb, descriptor->essence_container_ul, 16);
573
        break;
574
    case 0x3006:
575
        descriptor->linked_track_id = get_be32(pb);
576
        break;
577
    case 0x3201: /* PictureEssenceCoding */
578
        get_buffer(pb, descriptor->essence_codec_ul, 16);
579
        break;
580
    case 0x3203:
581
        descriptor->width = get_be32(pb);
582
        break;
583
    case 0x3202:
584
        descriptor->height = get_be32(pb);
585
        break;
586
    case 0x320E:
587
        descriptor->aspect_ratio.num = get_be32(pb);
588
        descriptor->aspect_ratio.den = get_be32(pb);
589
        break;
590
    case 0x3D03:
591
        descriptor->sample_rate.num = get_be32(pb);
592
        descriptor->sample_rate.den = get_be32(pb);
593
        break;
594
    case 0x3D06: /* SoundEssenceCompression */
595
        get_buffer(pb, descriptor->essence_codec_ul, 16);
596
        break;
597
    case 0x3D07:
598
        descriptor->channels = get_be32(pb);
599
        break;
600
    case 0x3D01:
601
        descriptor->bits_per_sample = get_be32(pb);
602
        break;
603
    case 0x3401:
604 4de5906f Baptiste Coudurier
        mxf_read_pixel_layout(pb, descriptor);
605 55de95b9 Baptiste Coudurier
        break;
606 bb085dd6 Baptiste Coudurier
    default:
607
        /* Private uid used by SONY C0023S01.mxf */
608
        if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
609 e20c865a Baptiste Coudurier
            descriptor->extradata = av_malloc(size);
610
            if (!descriptor->extradata)
611
                return -1;
612
            descriptor->extradata_size = size;
613
            get_buffer(pb, descriptor->extradata, size);
614 bb085dd6 Baptiste Coudurier
        }
615 55de95b9 Baptiste Coudurier
        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 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 */
631
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* 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 }, /* 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 }, /* 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 }, /* 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 }, /* DV25 IEC PAL */
636
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
637
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,   CODEC_ID_RAWVIDEO }, /* Uncompressed */
638 743d772c Baptiste Coudurier
    /* SoundEssenceCompression */
639 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 */
640
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,  CODEC_ID_PCM_S16LE },
641
    { { 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 */
642
    { { 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 */
643
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15,        CODEC_ID_AC3 },
644
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15,        CODEC_ID_MP2 }, /* 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 }, /* Dolby-E */
646
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       CODEC_ID_NONE },
647 07bf2af8 Baptiste Coudurier
};
648
649 8c5002db Baptiste Coudurier
static const MXFCodecUL mxf_picture_essence_container_uls[] = {
650 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 */
651
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,    CODEC_ID_DVVIDEO }, /* DV 625 25mbps */
652
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,       CODEC_ID_NONE },
653 8c5002db Baptiste Coudurier
};
654
655
static const MXFCodecUL mxf_sound_essence_container_uls[] = {
656 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 */
657
    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,       CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */
658 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 */
659
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },  0,      CODEC_ID_NONE },
660 8c5002db Baptiste Coudurier
};
661
662 6982462f Baptiste Coudurier
/*
663
 * Match an uid independently of the version byte and up to len common bytes
664
 * Returns: boolean
665
 */
666
static int mxf_match_uid(const UID key, const UID uid, int len)
667
{
668
    int i;
669
    for (i = 0; i < len; i++) {
670
        if (i != 7 && key[i] != uid[i])
671
            return 0;
672
    }
673
    return 1;
674
}
675
676 3bb63b82 Baptiste Coudurier
static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
677 743d772c Baptiste Coudurier
{
678
    while (uls->id != CODEC_ID_NONE) {
679 c9c55a56 Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
680 3bb63b82 Baptiste Coudurier
            break;
681 743d772c Baptiste Coudurier
        uls++;
682
    }
683 3bb63b82 Baptiste Coudurier
    return uls;
684 743d772c Baptiste Coudurier
}
685 07bf2af8 Baptiste Coudurier
686 dd202ff6 Baptiste Coudurier
static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
687
{
688
    while (uls->type != CODEC_TYPE_DATA) {
689 6982462f Baptiste Coudurier
        if(mxf_match_uid(uls->uid, *uid, 16))
690 dd202ff6 Baptiste Coudurier
            break;
691
        uls++;
692
    }
693
    return uls->type;
694
}
695
696 2d193b2e Reimar Döffinger
static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
697 d2cdbd5f Baptiste Coudurier
{
698
    int i;
699
700
    if (!strong_ref)
701
        return NULL;
702
    for (i = 0; i < mxf->metadata_sets_count; i++) {
703 2d193b2e Reimar Döffinger
        if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
704 6ac558ee Baptiste Coudurier
            (type == AnyType || mxf->metadata_sets[i]->type == type)) {
705 d2cdbd5f Baptiste Coudurier
            return mxf->metadata_sets[i];
706
        }
707
    }
708
    return NULL;
709
}
710
711 743d772c Baptiste Coudurier
static int mxf_parse_structural_metadata(MXFContext *mxf)
712 07bf2af8 Baptiste Coudurier
{
713 743d772c Baptiste Coudurier
    MXFPackage *material_package = NULL;
714 d2cdbd5f Baptiste Coudurier
    MXFPackage *temp_package = NULL;
715 743d772c Baptiste Coudurier
    int i, j, k;
716
717 318c5e05 Michel Bardiaux
    dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
718 743d772c Baptiste Coudurier
    /* TODO: handle multiple material packages (OP3x) */
719
    for (i = 0; i < mxf->packages_count; i++) {
720 2d193b2e Reimar Döffinger
        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
721
        if (material_package) break;
722 743d772c Baptiste Coudurier
    }
723
    if (!material_package) {
724
        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
725
        return -1;
726
    }
727 07bf2af8 Baptiste Coudurier
728 743d772c Baptiste Coudurier
    for (i = 0; i < material_package->tracks_count; i++) {
729 7f25df4c Baptiste Coudurier
        MXFPackage *source_package = NULL;
730 d2cdbd5f Baptiste Coudurier
        MXFTrack *material_track = NULL;
731 743d772c Baptiste Coudurier
        MXFTrack *source_track = NULL;
732 d2cdbd5f Baptiste Coudurier
        MXFTrack *temp_track = NULL;
733 743d772c Baptiste Coudurier
        MXFDescriptor *descriptor = NULL;
734
        MXFStructuralComponent *component = NULL;
735 80a289b9 Reimar Döffinger
        UID *essence_container_ul = NULL;
736 3bb63b82 Baptiste Coudurier
        const MXFCodecUL *codec_ul = NULL;
737
        const MXFCodecUL *container_ul = NULL;
738 743d772c Baptiste Coudurier
        AVStream *st;
739
740 2d193b2e Reimar Döffinger
        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
741 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
742
            continue;
743
        }
744
745 2d193b2e Reimar Döffinger
        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
746 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
747
            return -1;
748
        }
749
750 743d772c Baptiste Coudurier
        /* TODO: handle multiple source clips */
751
        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
752
            /* TODO: handle timecode component */
753 2d193b2e Reimar Döffinger
            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
754
            if (!component)
755 743d772c Baptiste Coudurier
                continue;
756
757
            for (k = 0; k < mxf->packages_count; k++) {
758 2d193b2e Reimar Döffinger
                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
759
                if (!temp_package)
760
                    continue;
761 d2cdbd5f Baptiste Coudurier
                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
762
                    source_package = temp_package;
763 743d772c Baptiste Coudurier
                    break;
764
                }
765
            }
766
            if (!source_package) {
767
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
768
                break;
769
            }
770
            for (k = 0; k < source_package->tracks_count; k++) {
771 2d193b2e Reimar Döffinger
                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
772 d2cdbd5f Baptiste Coudurier
                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
773
                    return -1;
774
                }
775
                if (temp_track->track_id == component->source_track_id) {
776
                    source_track = temp_track;
777 743d772c Baptiste Coudurier
                    break;
778
                }
779
            }
780
            if (!source_track) {
781
                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
782
                break;
783
            }
784
        }
785
        if (!source_track)
786
            continue;
787
788 f03b6426 Baptiste Coudurier
        st = av_new_stream(mxf->fc, source_track->track_id);
789 ebbe25d2 Baptiste Coudurier
        if (!st) {
790
            av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
791
            return -1;
792
        }
793 f03b6426 Baptiste Coudurier
        st->priv_data = source_track;
794 743d772c Baptiste Coudurier
        st->duration = component->duration;
795
        if (st->duration == -1)
796
            st->duration = AV_NOPTS_VALUE;
797
        st->start_time = component->start_position;
798
        av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
799 d2cdbd5f Baptiste Coudurier
800 2d193b2e Reimar Döffinger
        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
801 d2cdbd5f Baptiste Coudurier
            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
802
            return -1;
803
        }
804
805 743d772c Baptiste Coudurier
#ifdef DEBUG
806 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);
807 743d772c Baptiste Coudurier
#endif
808 dd202ff6 Baptiste Coudurier
        st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
809 743d772c Baptiste Coudurier
810 6ac558ee Baptiste Coudurier
        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
811 743d772c Baptiste Coudurier
        if (source_package->descriptor) {
812 d2cdbd5f Baptiste Coudurier
            if (source_package->descriptor->type == MultipleDescriptor) {
813 743d772c Baptiste Coudurier
                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
814 2d193b2e Reimar Döffinger
                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
815 d2cdbd5f Baptiste Coudurier
816
                    if (!sub_descriptor) {
817
                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
818
                        continue;
819
                    }
820
                    if (sub_descriptor->linked_track_id == source_track->track_id) {
821
                        descriptor = sub_descriptor;
822
                        break;
823 07bf2af8 Baptiste Coudurier
                    }
824
                }
825 6ac558ee Baptiste Coudurier
            } else if (source_package->descriptor->type == Descriptor)
826 743d772c Baptiste Coudurier
                descriptor = source_package->descriptor;
827
        }
828
        if (!descriptor) {
829
            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
830
            continue;
831
        }
832
#ifdef DEBUG
833 318c5e05 Michel Bardiaux
        PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);
834
        PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
835 743d772c Baptiste Coudurier
#endif
836 80a289b9 Reimar Döffinger
        essence_container_ul = &descriptor->essence_container_ul;
837
        /* HACK: replacing the original key with mxf_encrypted_essence_container
838
         * is not allowed according to s429-6, try to find correct information anyway */
839
        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
840
            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
841
            for (k = 0; k < mxf->metadata_sets_count; k++) {
842
                MXFMetadataSet *metadata = mxf->metadata_sets[k];
843
                if (metadata->type == CryptoContext) {
844
                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
845
                    break;
846
                }
847
            }
848
        }
849 3bb63b82 Baptiste Coudurier
        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */
850
        codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
851 c2e88054 Baptiste Coudurier
        st->codec->codec_id = codec_ul->id;
852 e1dacee1 Baptiste Coudurier
        if (descriptor->extradata) {
853
            st->codec->extradata = descriptor->extradata;
854
            st->codec->extradata_size = descriptor->extradata_size;
855
        }
856 743d772c Baptiste Coudurier
        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
857 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
858 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
859 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
860 743d772c Baptiste Coudurier
            st->codec->width = descriptor->width;
861
            st->codec->height = descriptor->height;
862 59b56738 Baptiste Coudurier
            st->codec->bits_per_sample = descriptor->bits_per_sample; /* Uncompressed */
863 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
864 743d772c Baptiste Coudurier
        } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
865 80a289b9 Reimar Döffinger
            container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
866 8c5002db Baptiste Coudurier
            if (st->codec->codec_id == CODEC_ID_NONE)
867 3bb63b82 Baptiste Coudurier
                st->codec->codec_id = container_ul->id;
868 743d772c Baptiste Coudurier
            st->codec->channels = descriptor->channels;
869
            st->codec->bits_per_sample = descriptor->bits_per_sample;
870
            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
871
            /* TODO: implement CODEC_ID_RAWAUDIO */
872
            if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
873
                if (descriptor->bits_per_sample == 24)
874
                    st->codec->codec_id = CODEC_ID_PCM_S24LE;
875
                else if (descriptor->bits_per_sample == 32)
876
                    st->codec->codec_id = CODEC_ID_PCM_S32LE;
877
            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
878
                if (descriptor->bits_per_sample == 24)
879
                    st->codec->codec_id = CODEC_ID_PCM_S24BE;
880
                else if (descriptor->bits_per_sample == 32)
881
                    st->codec->codec_id = CODEC_ID_PCM_S32BE;
882 c86ecbb7 Baptiste Coudurier
            } else if (st->codec->codec_id == CODEC_ID_MP2) {
883 57004ff1 Aurelien Jacobs
                st->need_parsing = AVSTREAM_PARSE_FULL;
884 07bf2af8 Baptiste Coudurier
            }
885
        }
886 51169b61 Baptiste Coudurier
        if (st->codec->codec_type != CODEC_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
887
            av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");
888 57004ff1 Aurelien Jacobs
            st->need_parsing = AVSTREAM_PARSE_FULL;
889 c2e88054 Baptiste Coudurier
        }
890 07bf2af8 Baptiste Coudurier
    }
891 743d772c Baptiste Coudurier
    return 0;
892 07bf2af8 Baptiste Coudurier
}
893
894 b92c61e0 Baptiste Coudurier
static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
895 7ee7f6f9 Baptiste Coudurier
    { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
896 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 },
897
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
898
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
899
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
900
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
901
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
902
    { { 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 */
903
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */
904
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */
905
    { { 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 */
906
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */
907
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
908
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
909
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
910
    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
911 33bddcdc Baptiste Coudurier
    { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
912 b92c61e0 Baptiste Coudurier
};
913
914 33bddcdc Baptiste Coudurier
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
915
{
916 899681cd Björn Axelsson
    ByteIOContext *pb = mxf->fc->pb;
917 33bddcdc Baptiste Coudurier
    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
918 3f2d859b Baptiste Coudurier
    uint64_t klv_end = url_ftell(pb) + klv->length;
919 33bddcdc Baptiste Coudurier
920 57810910 Baptiste Coudurier
    if (!ctx)
921
        return -1;
922 33bddcdc Baptiste Coudurier
    while (url_ftell(pb) + 4 < klv_end) {
923
        int tag = get_be16(pb);
924
        int size = get_be16(pb); /* KLV specified by 0x53 */
925 3f2d859b Baptiste Coudurier
        uint64_t next = url_ftell(pb) + size;
926 76e48645 Baptiste Coudurier
        UID uid = {0};
927 33bddcdc Baptiste Coudurier
928
        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
929
            av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
930
            continue;
931
        }
932 7ee7f6f9 Baptiste Coudurier
        if (tag > 0x7FFF) { /* dynamic tag */
933
            int i;
934
            for (i = 0; i < mxf->local_tags_count; i++) {
935
                int local_tag = AV_RB16(mxf->local_tags+i*18);
936
                if (local_tag == tag) {
937
                    memcpy(uid, mxf->local_tags+i*18+2, 16);
938
                    dprintf(mxf->fc, "local tag 0x%04X\n", local_tag);
939
#ifdef DEBUG
940
                    PRINT_KEY(mxf->fc, "uid", uid);
941
#endif
942
                }
943
            }
944
        }
945 3f2d859b Baptiste Coudurier
        if (ctx_size && tag == 0x3C0A)
946 33bddcdc Baptiste Coudurier
            get_buffer(pb, ctx->uid, 16);
947 6e3ea446 Baptiste Coudurier
        else if (read_child(ctx, pb, tag, size, uid) < 0)
948
            return -1;
949 33bddcdc Baptiste Coudurier
950
        url_fseek(pb, next, SEEK_SET);
951
    }
952
    if (ctx_size) ctx->type = type;
953
    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
954
}
955
956 07bf2af8 Baptiste Coudurier
static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
957
{
958
    MXFContext *mxf = s->priv_data;
959
    KLVPacket klv;
960
961 899681cd Björn Axelsson
    if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
962 ee71ef5c Baptiste Coudurier
        av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
963
        return -1;
964
    }
965 899681cd Björn Axelsson
    url_fseek(s->pb, -14, SEEK_CUR);
966 07bf2af8 Baptiste Coudurier
    mxf->fc = s;
967 899681cd Björn Axelsson
    while (!url_feof(s->pb)) {
968 975c88e3 Baptiste Coudurier
        const MXFMetadataReadTableEntry *metadata;
969 b92c61e0 Baptiste Coudurier
970 899681cd Björn Axelsson
        if (klv_read_packet(&klv, s->pb) < 0)
971 07bf2af8 Baptiste Coudurier
            return -1;
972 6d0c3beb Baptiste Coudurier
#ifdef DEBUG
973 318c5e05 Michel Bardiaux
        PRINT_KEY(s, "read header", klv.key);
974 6d0c3beb Baptiste Coudurier
#endif
975 80a289b9 Reimar Döffinger
        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
976
            IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
977 07bf2af8 Baptiste Coudurier
            /* FIXME avoid seek */
978 899681cd Björn Axelsson
            url_fseek(s->pb, klv.offset, SEEK_SET);
979 07bf2af8 Baptiste Coudurier
            break;
980 5e441e31 Baptiste Coudurier
        }
981 b92c61e0 Baptiste Coudurier
982 975c88e3 Baptiste Coudurier
        for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
983
            if (IS_KLV_KEY(klv.key, metadata->key)) {
984 7ee7f6f9 Baptiste Coudurier
                int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read;
985
                if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
986 b92c61e0 Baptiste Coudurier
                    av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
987
                    return -1;
988
                }
989
                break;
990
            }
991
        }
992 975c88e3 Baptiste Coudurier
        if (!metadata->read)
993 899681cd Björn Axelsson
            url_fskip(s->pb, klv.length);
994 07bf2af8 Baptiste Coudurier
    }
995 743d772c Baptiste Coudurier
    return mxf_parse_structural_metadata(mxf);
996 07bf2af8 Baptiste Coudurier
}
997
998
static int mxf_read_close(AVFormatContext *s)
999
{
1000
    MXFContext *mxf = s->priv_data;
1001 d2cdbd5f Baptiste Coudurier
    int i;
1002 743d772c Baptiste Coudurier
1003
    av_freep(&mxf->packages_refs);
1004 d2cdbd5f Baptiste Coudurier
    for (i = 0; i < mxf->metadata_sets_count; i++) {
1005
        switch (mxf->metadata_sets[i]->type) {
1006
        case MultipleDescriptor:
1007
            av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
1008
            break;
1009
        case Sequence:
1010
            av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
1011
            break;
1012
        case SourcePackage:
1013
        case MaterialPackage:
1014
            av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
1015
            break;
1016
        default:
1017
            break;
1018
        }
1019
        av_freep(&mxf->metadata_sets[i]);
1020
    }
1021
    av_freep(&mxf->metadata_sets);
1022 80a289b9 Reimar Döffinger
    av_freep(&mxf->aesc);
1023 7ee7f6f9 Baptiste Coudurier
    av_freep(&mxf->local_tags);
1024 07bf2af8 Baptiste Coudurier
    return 0;
1025
}
1026
1027
static int mxf_probe(AVProbeData *p) {
1028 ba32c8df Baptiste Coudurier
    uint8_t *bufp = p->buf;
1029
    uint8_t *end = p->buf + p->buf_size;
1030
1031 07bf2af8 Baptiste Coudurier
    if (p->buf_size < sizeof(mxf_header_partition_pack_key))
1032
        return 0;
1033
1034 ba32c8df Baptiste Coudurier
    /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */
1035
    end -= sizeof(mxf_header_partition_pack_key);
1036
    for (; bufp < end; bufp++) {
1037 f8503792 Baptiste Coudurier
        if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
1038 ba32c8df Baptiste Coudurier
            return AVPROBE_SCORE_MAX;
1039
    }
1040
    return 0;
1041 07bf2af8 Baptiste Coudurier
}
1042
1043 2f8fe719 Baptiste Coudurier
/* rudimentary byte seek */
1044 3a6ccf4f Baptiste Coudurier
/* XXX: use MXF Index */
1045
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1046
{
1047
    AVStream *st = s->streams[stream_index];
1048
    int64_t seconds;
1049
1050 de9fe002 Baptiste Coudurier
    if (!s->bit_rate)
1051 3a6ccf4f Baptiste Coudurier
        return -1;
1052 de9fe002 Baptiste Coudurier
    if (sample_time < 0)
1053
        sample_time = 0;
1054 3a6ccf4f Baptiste Coudurier
    seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
1055 899681cd Björn Axelsson
    url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
1056 ee71ef5c Baptiste Coudurier
    av_update_cur_dts(s, st, sample_time);
1057
    return 0;
1058 3a6ccf4f Baptiste Coudurier
}
1059 07bf2af8 Baptiste Coudurier
1060
AVInputFormat mxf_demuxer = {
1061
    "mxf",
1062
    "MXF format",
1063
    sizeof(MXFContext),
1064
    mxf_probe,
1065
    mxf_read_header,
1066
    mxf_read_packet,
1067
    mxf_read_close,
1068 3a6ccf4f Baptiste Coudurier
    mxf_read_seek,
1069 07bf2af8 Baptiste Coudurier
};