X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmxf.c;h=4d4bcbb35d1a78948719faa87658fc38d213fe0d;hb=61559562f52f9cfaf050500342c5bbba9ece3ce9;hp=7b4246392fb333fa90a86cfd9ea55d786dce6f4e;hpb=01dfc6466907642b82c24fb9768d62cd49099a18;p=ffmpeg diff --git a/libavformat/mxf.c b/libavformat/mxf.c index 7b4246392fb..4d4bcbb35d1 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -47,6 +47,7 @@ #include "avformat.h" #include "aes.h" +#include "bytestream.h" typedef uint8_t UID[16]; @@ -60,18 +61,16 @@ enum MXFMetadataSetType { MultipleDescriptor, Descriptor, Track, - EssenceContainerData, CryptoContext, }; -typedef struct MXFCryptoContext { +typedef struct { UID uid; enum MXFMetadataSetType type; - UID context_uid; UID source_container_ul; } MXFCryptoContext; -typedef struct MXFStructuralComponent { +typedef struct { UID uid; enum MXFMetadataSetType type; UID source_package_uid; @@ -81,7 +80,7 @@ typedef struct MXFStructuralComponent { int source_track_id; } MXFStructuralComponent; -typedef struct MXFSequence { +typedef struct { UID uid; enum MXFMetadataSetType type; UID data_definition_ul; @@ -90,7 +89,7 @@ typedef struct MXFSequence { int64_t duration; } MXFSequence; -typedef struct MXFTrack { +typedef struct { UID uid; enum MXFMetadataSetType type; MXFSequence *sequence; /* mandatory, and only one */ @@ -100,7 +99,7 @@ typedef struct MXFTrack { AVRational edit_rate; } MXFTrack; -typedef struct MXFDescriptor { +typedef struct { UID uid; enum MXFMetadataSetType type; UID essence_container_ul; @@ -118,7 +117,7 @@ typedef struct MXFDescriptor { int extradata_size; } MXFDescriptor; -typedef struct MXFPackage { +typedef struct { UID uid; enum MXFMetadataSetType type; UID package_uid; @@ -128,27 +127,23 @@ typedef struct MXFPackage { UID descriptor_ref; } MXFPackage; -typedef struct MXFEssenceContainerData { - UID uid; - enum MXFMetadataSetType type; - UID linked_package_uid; -} MXFEssenceContainerData; - typedef struct { UID uid; enum MXFMetadataSetType type; } MXFMetadataSet; -typedef struct MXFContext { +typedef struct { UID *packages_refs; int packages_count; MXFMetadataSet **metadata_sets; int metadata_sets_count; AVFormatContext *fc; struct AVAES *aesc; + uint8_t *local_tags; + int local_tags_count; } MXFContext; -typedef struct KLVPacket { +typedef struct { UID key; offset_t offset; uint64_t length; @@ -159,18 +154,18 @@ enum MXFWrappingScheme { Clip, }; -typedef struct MXFCodecUL { +typedef struct { UID uid; + unsigned matching_len; enum CodecID id; - enum MXFWrappingScheme wrapping; } MXFCodecUL; -typedef struct MXFDataDefinitionUL { +typedef struct { UID uid; enum CodecType type; } MXFDataDefinitionUL; -typedef struct MXFMetadataReadTableEntry { +typedef struct { const UID key; int (*read)(); int ctx_size; @@ -182,8 +177,10 @@ static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; /* complete keys to match */ +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 }; static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; +static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) @@ -247,7 +244,9 @@ static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv) static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length) { uint8_t buffer[61444]; - uint8_t *buf_ptr, *end_ptr, *data_ptr; + const uint8_t *buf_ptr, *end_ptr; + uint8_t *data_ptr; + int i; if (length > 61444) /* worst case PAL 1920 samples 8 channels */ return -1; @@ -256,17 +255,15 @@ static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pk data_ptr = pkt->data; end_ptr = buffer + length; buf_ptr = buffer + 4; /* skip SMPTE 331M header */ - for (; buf_ptr < end_ptr; buf_ptr += 4) { - if (st->codec->bits_per_sample == 24) { - data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4); - data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4); - data_ptr[2] = (buf_ptr[0] >> 4) | ((buf_ptr[1] & 0x0f) << 4); - data_ptr += 3; - } else { - data_ptr[0] = (buf_ptr[2] >> 4) | ((buf_ptr[3] & 0x0f) << 4); - data_ptr[1] = (buf_ptr[1] >> 4) | ((buf_ptr[2] & 0x0f) << 4); - data_ptr += 2; + for (; buf_ptr < end_ptr; ) { + for (i = 0; i < st->codec->channels; i++) { + uint32_t sample = bytestream_get_le32(&buf_ptr); + if (st->codec->bits_per_sample == 24) + bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff); + else + bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff); } + buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M } pkt->size = data_ptr - pkt->data; return 0; @@ -276,7 +273,7 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv { static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b}; MXFContext *mxf = s->priv_data; - ByteIOContext *pb = &s->pb; + ByteIOContext *pb = s->pb; offset_t end = url_ftell(pb) + klv->length; uint64_t size; uint64_t orig_size; @@ -287,6 +284,8 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv if (!mxf->aesc && s->key && s->keylen == 16) { mxf->aesc = av_malloc(av_aes_size); + if (!mxf->aesc) + return -1; av_aes_init(mxf->aesc, s->key, 128, 1); } // crypto context @@ -297,16 +296,20 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv // source klv key klv_decode_ber_length(pb); get_buffer(pb, klv->key, 16); - if (!IS_KLV_KEY(klv, mxf_essence_element_key)) goto err_out; + if (!IS_KLV_KEY(klv, mxf_essence_element_key)) + return -1; index = mxf_get_stream_index(s, klv); - if (index < 0) goto err_out; + if (index < 0) + return -1; // source size klv_decode_ber_length(pb); orig_size = get_be64(pb); - if (orig_size < plaintext_size) goto err_out; + if (orig_size < plaintext_size) + return -1; // enc. code size = klv_decode_ber_length(pb); - if (size < 32 || size - 32 < orig_size) goto err_out; + if (size < 32 || size - 32 < orig_size) + return -1; get_buffer(pb, ivec, 16); get_buffer(pb, tmpbuf, 16); if (mxf->aesc) @@ -323,18 +326,14 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv pkt->stream_index = index; url_fskip(pb, end - url_ftell(pb)); return 0; - -err_out: - url_fskip(pb, end - url_ftell(pb)); - return -1; } static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) { KLVPacket klv; - while (!url_feof(&s->pb)) { - if (klv_read_packet(&klv, &s->pb) < 0) + while (!url_feof(s->pb)) { + if (klv_read_packet(&klv, s->pb) < 0) return -1; #ifdef DEBUG PRINT_KEY(s, "read packet", klv.key); @@ -351,48 +350,68 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) int index = mxf_get_stream_index(s, &klv); if (index < 0) { av_log(s, AV_LOG_ERROR, "error getting stream index\n"); - url_fskip(&s->pb, klv.length); - return -1; + goto skip; } + if (s->streams[index]->discard == AVDISCARD_ALL) + goto skip; /* check for 8 channels AES3 element */ if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) { - if (mxf_get_d10_aes3_packet(&s->pb, s->streams[index], pkt, klv.length) < 0) { + if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) { av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); return -1; } } else - av_get_packet(&s->pb, pkt, klv.length); + av_get_packet(s->pb, pkt, klv.length); pkt->stream_index = index; pkt->pos = klv.offset; return 0; } else - url_fskip(&s->pb, klv.length); + skip: + url_fskip(s->pb, klv.length); + } + return AVERROR(EIO); +} + +static int mxf_read_primer_pack(MXFContext *mxf) +{ + ByteIOContext *pb = mxf->fc->pb; + int item_num = get_be32(pb); + int item_len = get_be32(pb); + + if (item_len != 18) { + av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n"); + return -1; } - return AVERROR_IO; + if (item_num > UINT_MAX / item_len) + return -1; + mxf->local_tags_count = item_num; + mxf->local_tags = av_malloc(item_num*item_len); + if (!mxf->local_tags) + return -1; + get_buffer(pb, mxf->local_tags, item_num*item_len); + return 0; } static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) { mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); + if (!mxf->metadata_sets) + return -1; mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; mxf->metadata_sets_count++; return 0; } -static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag) +static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid) { - switch(tag) { - case 0xFFFE: - get_buffer(pb, cryptocontext->context_uid, 16); - break; - case 0xFFFD: + if (size != 16) + return -1; + if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul)) get_buffer(pb, cryptocontext->source_container_ul, 16); - break; - } return 0; } -static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag) +static int mxf_read_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag) { switch (tag) { case 0x1901: @@ -400,6 +419,8 @@ static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, if (mxf->packages_count >= UINT_MAX / sizeof(UID)) return -1; mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID)); + if (!mxf->packages_refs) + return -1; url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID)); break; @@ -407,7 +428,7 @@ static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, return 0; } -static int mxf_read_metadata_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag) +static int mxf_read_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag) { switch(tag) { case 0x0202: @@ -428,7 +449,7 @@ static int mxf_read_metadata_source_clip(MXFStructuralComponent *source_clip, By return 0; } -static int mxf_read_metadata_material_package(MXFPackage *package, ByteIOContext *pb, int tag) +static int mxf_read_material_package(MXFPackage *package, ByteIOContext *pb, int tag) { switch(tag) { case 0x4403: @@ -436,6 +457,8 @@ static int mxf_read_metadata_material_package(MXFPackage *package, ByteIOContext if (package->tracks_count >= UINT_MAX / sizeof(UID)) return -1; package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID)); + if (!package->tracks_refs) + return -1; url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); break; @@ -443,7 +466,7 @@ static int mxf_read_metadata_material_package(MXFPackage *package, ByteIOContext return 0; } -static int mxf_read_metadata_track(MXFTrack *track, ByteIOContext *pb, int tag) +static int mxf_read_track(MXFTrack *track, ByteIOContext *pb, int tag) { switch(tag) { case 0x4801: @@ -463,7 +486,7 @@ static int mxf_read_metadata_track(MXFTrack *track, ByteIOContext *pb, int tag) return 0; } -static int mxf_read_metadata_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag) +static int mxf_read_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag) { switch(tag) { case 0x0202: @@ -477,6 +500,8 @@ static int mxf_read_metadata_sequence(MXFSequence *sequence, ByteIOContext *pb, if (sequence->structural_components_count >= UINT_MAX / sizeof(UID)) return -1; sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID)); + if (!sequence->structural_components_refs) + return -1; url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID)); break; @@ -484,7 +509,7 @@ static int mxf_read_metadata_sequence(MXFSequence *sequence, ByteIOContext *pb, return 0; } -static int mxf_read_metadata_source_package(MXFPackage *package, ByteIOContext *pb, int tag) +static int mxf_read_source_package(MXFPackage *package, ByteIOContext *pb, int tag) { switch(tag) { case 0x4403: @@ -492,6 +517,8 @@ static int mxf_read_metadata_source_package(MXFPackage *package, ByteIOContext * if (package->tracks_count >= UINT_MAX / sizeof(UID)) return -1; package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID)); + if (!package->tracks_refs) + return -1; url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); break; @@ -507,7 +534,7 @@ static int mxf_read_metadata_source_package(MXFPackage *package, ByteIOContext * return 0; } -static void mxf_read_metadata_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor) +static void mxf_read_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor) { int code; @@ -530,7 +557,7 @@ static void mxf_read_metadata_pixel_layout(ByteIOContext *pb, MXFDescriptor *des } while (code != 0); /* SMPTE 377M E.2.46 */ } -static int mxf_read_metadata_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size) +static int mxf_read_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size, UID uid) { switch(tag) { case 0x3F01: @@ -538,6 +565,8 @@ static int mxf_read_metadata_generic_descriptor(MXFDescriptor *descriptor, ByteI if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID)) return -1; descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID)); + if (!descriptor->sub_descriptors_refs) + return -1; url_fskip(pb, 4); /* useless size of objects, always 16 according to specs */ get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID)); break; @@ -574,12 +603,17 @@ static int mxf_read_metadata_generic_descriptor(MXFDescriptor *descriptor, ByteI descriptor->bits_per_sample = get_be32(pb); break; case 0x3401: - mxf_read_metadata_pixel_layout(pb, descriptor); + mxf_read_pixel_layout(pb, descriptor); break; - case 0x8201: /* Private tag used by SONY C0023S01.mxf */ - descriptor->extradata = av_malloc(size); - descriptor->extradata_size = size; - get_buffer(pb, descriptor->extradata, size); + default: + /* Private uid used by SONY C0023S01.mxf */ + if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) { + descriptor->extradata = av_malloc(size); + if (!descriptor->extradata) + return -1; + descriptor->extradata_size = size; + get_buffer(pb, descriptor->extradata, size); + } break; } return 0; @@ -595,58 +629,36 @@ static const MXFDataDefinitionUL mxf_data_definition_uls[] = { static const MXFCodecUL mxf_codec_uls[] = { /* PictureEssenceCoding */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@ML Long GoP */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 30Mbps PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 40Mbps PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, CODEC_ID_MPEG2VIDEO, Frame }, /* D-10 50Mbps PAL */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML I-Frame */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@ML Long GoP */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MP@HL Long GoP */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL I-Frame */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, CODEC_ID_MPEG2VIDEO, Frame }, /* 422P@HL Long GoP */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, CODEC_ID_MPEG4, Frame }, /* XDCAM proxy_pal030926.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x04 }, CODEC_ID_MPEG4, Frame }, /* XDCAM Proxy C0023S01.mxf */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, CODEC_ID_DVVIDEO, Frame }, /* DV25 IEC PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 }, CODEC_ID_DVVIDEO, Frame }, /* DVCPRO25 PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 }, CODEC_ID_DVVIDEO, Frame }, /* DVCPRO50 PAL */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, CODEC_ID_JPEG2000, Frame }, /* JPEG2000 Codestream */ - - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, CODEC_ID_RAWVIDEO, Frame }, /* Uncompressed */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@ML Long GoP */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* D-10 50Mbps PAL */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* MP@HL Long GoP */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, CODEC_ID_MPEG2VIDEO }, /* 422P@HL I-Frame */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14, CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_RAWVIDEO }, /* Uncompressed */ /* SoundEssenceCompression */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, CODEC_ID_PCM_S16LE, Frame }, /* Uncompressed */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, CODEC_ID_PCM_S16LE, Frame }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, CODEC_ID_PCM_S16BE, Frame }, /* From Omneon MXF file */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, CODEC_ID_PCM_ALAW, Frame }, /* XDCAM Proxy C0023S01.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, CODEC_ID_AC3, Frame }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, CODEC_ID_MP2, Frame }, /* MP2 or MP3 */ - //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, CODEC_ID_DOLBY_E, Frame }, /* Dolby-E */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, CODEC_ID_NONE, Frame }, + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, /* Uncompressed */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE }, + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16BE }, /* From Omneon MXF file */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15, CODEC_ID_PCM_ALAW }, /* XDCAM Proxy C0023S01.mxf */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15, CODEC_ID_AC3 }, + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15, CODEC_ID_MP2 }, /* MP2 or MP3 */ + //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15, CODEC_ID_DOLBY_E }, /* Dolby-E */ + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE }, }; static const MXFCodecUL mxf_picture_essence_container_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, CODEC_ID_MPEG2VIDEO, Frame }, /* MPEG-ES Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xe0,0x02 }, CODEC_ID_MPEG2VIDEO, Clip }, /* MPEG-ES Clip wrapped, 0xe0 MPV stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x04,0x61,0x07 }, CODEC_ID_MPEG2VIDEO, Clip }, /* MPEG-ES Custom wrapped, 0x61 ??? stream id */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, CODEC_ID_NONE, Frame }, + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, CODEC_ID_DVVIDEO }, /* DV 625 25mbps */ + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE }, }; static const MXFCodecUL mxf_sound_essence_container_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, CODEC_ID_PCM_S16LE, Frame }, /* BWF Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 }, CODEC_ID_PCM_S16LE, Frame }, /* AES Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, CODEC_ID_MP2, Frame }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xc0,0x01 }, CODEC_ID_MP2, Frame }, /* MPEG-ES Frame wrapped, 0xc0 MPA stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0xc0,0x02 }, CODEC_ID_MP2, Clip }, /* MPEG-ES Clip wrapped, 0xc0 MPA stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 }, CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 30Mbps PAL Extended Template */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 }, CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 40Mbps PAL Extended Template */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, CODEC_ID_PCM_S16BE, Frame }, /* D-10 Mapping 50Mbps PAL Extended Template */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, CODEC_ID_NONE, Frame }, + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */ + { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */ + { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE }, }; /* @@ -666,7 +678,7 @@ static int mxf_match_uid(const UID key, const UID uid, int len) static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid) { while (uls->id != CODEC_ID_NONE) { - if(mxf_match_uid(uls->uid, *uid, 16)) + if(mxf_match_uid(uls->uid, *uid, uls->matching_len)) break; uls++; } @@ -776,6 +788,10 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) continue; st = av_new_stream(mxf->fc, source_track->track_id); + if (!st) { + av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n"); + return -1; + } st->priv_data = source_track; st->duration = component->duration; if (st->duration == -1) @@ -865,14 +881,12 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codec->codec_id = CODEC_ID_PCM_S24BE; else if (descriptor->bits_per_sample == 32) st->codec->codec_id = CODEC_ID_PCM_S32BE; - if (descriptor->essence_container_ul[13] == 0x01) /* D-10 Mapping */ - st->codec->channels = 8; /* force channels to 8 */ } else if (st->codec->codec_id == CODEC_ID_MP2) { st->need_parsing = AVSTREAM_PARSE_FULL; } } - if (container_ul && container_ul->wrapping == Clip) { - dprintf(mxf->fc, "stream %d: clip wrapped essence\n", st->index); + if (st->codec->codec_type != CODEC_TYPE_DATA && (*essence_container_ul)[15] > 0x01) { + av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n"); st->need_parsing = AVSTREAM_PARSE_FULL; } } @@ -880,43 +894,60 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) } static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_metadata_content_storage, 0, AnyType }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_metadata_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor }, - { { 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 */ - { { 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 */ - { { 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 */ - { { 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 */ - { { 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 */ - { { 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 */ - { { 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 */ - { { 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 */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_metadata_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor }, + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */ + { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext }, { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType }, }; static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type) { - ByteIOContext *pb = &mxf->fc->pb; + ByteIOContext *pb = mxf->fc->pb; MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf; - uint64_t klv_end= url_ftell(pb) + klv->length; + uint64_t klv_end = url_ftell(pb) + klv->length; + if (!ctx) + return -1; while (url_ftell(pb) + 4 < klv_end) { int tag = get_be16(pb); int size = get_be16(pb); /* KLV specified by 0x53 */ - uint64_t next= url_ftell(pb) + size; + uint64_t next = url_ftell(pb) + size; + UID uid = {0}; if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */ av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag); continue; } - if(ctx_size && tag == 0x3C0A) + if (tag > 0x7FFF) { /* dynamic tag */ + int i; + for (i = 0; i < mxf->local_tags_count; i++) { + int local_tag = AV_RB16(mxf->local_tags+i*18); + if (local_tag == tag) { + memcpy(uid, mxf->local_tags+i*18+2, 16); + dprintf(mxf->fc, "local tag 0x%04X\n", local_tag); +#ifdef DEBUG + PRINT_KEY(mxf->fc, "uid", uid); +#endif + } + } + } + if (ctx_size && tag == 0x3C0A) get_buffer(pb, ctx->uid, 16); - else - read_child(ctx, pb, tag, size); + else if (read_child(ctx, pb, tag, size, uid) < 0) + return -1; url_fseek(pb, next, SEEK_SET); } @@ -929,16 +960,16 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) MXFContext *mxf = s->priv_data; KLVPacket klv; - if (!mxf_read_sync(&s->pb, mxf_header_partition_pack_key, 14)) { + if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) { av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n"); return -1; } - url_fseek(&s->pb, -14, SEEK_CUR); + url_fseek(s->pb, -14, SEEK_CUR); mxf->fc = s; - while (!url_feof(&s->pb)) { + while (!url_feof(s->pb)) { const MXFMetadataReadTableEntry *metadata; - if (klv_read_packet(&klv, &s->pb) < 0) + if (klv_read_packet(&klv, s->pb) < 0) return -1; #ifdef DEBUG PRINT_KEY(s, "read header", klv.key); @@ -946,13 +977,14 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) || IS_KLV_KEY(klv.key, mxf_essence_element_key)) { /* FIXME avoid seek */ - url_fseek(&s->pb, klv.offset, SEEK_SET); + url_fseek(s->pb, klv.offset, SEEK_SET); break; } for (metadata = mxf_metadata_read_table; metadata->read; metadata++) { if (IS_KLV_KEY(klv.key, metadata->key)) { - if (mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) { + int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read; + if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) { av_log(s, AV_LOG_ERROR, "error reading header metadata\n"); return -1; } @@ -960,7 +992,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) } } if (!metadata->read) - url_fskip(&s->pb, klv.length); + url_fskip(s->pb, klv.length); } return mxf_parse_structural_metadata(mxf); } @@ -990,6 +1022,7 @@ static int mxf_read_close(AVFormatContext *s) } av_freep(&mxf->metadata_sets); av_freep(&mxf->aesc); + av_freep(&mxf->local_tags); return 0; } @@ -1021,7 +1054,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if (sample_time < 0) sample_time = 0; seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); - url_fseek(&s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET); + url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET); av_update_cur_dts(s, st, sample_time); return 0; }