00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "avformat.h"
00049 #include "aes.h"
00050 #include "bytestream.h"
00051
00052 typedef uint8_t UID[16];
00053
00054 enum MXFMetadataSetType {
00055 AnyType,
00056 MaterialPackage,
00057 SourcePackage,
00058 SourceClip,
00059 TimecodeComponent,
00060 Sequence,
00061 MultipleDescriptor,
00062 Descriptor,
00063 Track,
00064 CryptoContext,
00065 };
00066
00067 typedef struct {
00068 UID uid;
00069 enum MXFMetadataSetType type;
00070 UID source_container_ul;
00071 } MXFCryptoContext;
00072
00073 typedef struct {
00074 UID uid;
00075 enum MXFMetadataSetType type;
00076 UID source_package_uid;
00077 UID data_definition_ul;
00078 int64_t duration;
00079 int64_t start_position;
00080 int source_track_id;
00081 } MXFStructuralComponent;
00082
00083 typedef struct {
00084 UID uid;
00085 enum MXFMetadataSetType type;
00086 UID data_definition_ul;
00087 UID *structural_components_refs;
00088 int structural_components_count;
00089 int64_t duration;
00090 } MXFSequence;
00091
00092 typedef struct {
00093 UID uid;
00094 enum MXFMetadataSetType type;
00095 MXFSequence *sequence;
00096 UID sequence_ref;
00097 int track_id;
00098 uint8_t track_number[4];
00099 AVRational edit_rate;
00100 } MXFTrack;
00101
00102 typedef struct {
00103 UID uid;
00104 enum MXFMetadataSetType type;
00105 UID essence_container_ul;
00106 UID essence_codec_ul;
00107 AVRational sample_rate;
00108 AVRational aspect_ratio;
00109 int width;
00110 int height;
00111 int channels;
00112 int bits_per_sample;
00113 UID *sub_descriptors_refs;
00114 int sub_descriptors_count;
00115 int linked_track_id;
00116 uint8_t *extradata;
00117 int extradata_size;
00118 } MXFDescriptor;
00119
00120 typedef struct {
00121 UID uid;
00122 enum MXFMetadataSetType type;
00123 UID package_uid;
00124 UID *tracks_refs;
00125 int tracks_count;
00126 MXFDescriptor *descriptor;
00127 UID descriptor_ref;
00128 } MXFPackage;
00129
00130 typedef struct {
00131 UID uid;
00132 enum MXFMetadataSetType type;
00133 } MXFMetadataSet;
00134
00135 typedef struct {
00136 UID *packages_refs;
00137 int packages_count;
00138 MXFMetadataSet **metadata_sets;
00139 int metadata_sets_count;
00140 AVFormatContext *fc;
00141 struct AVAES *aesc;
00142 uint8_t *local_tags;
00143 int local_tags_count;
00144 } MXFContext;
00145
00146 typedef struct {
00147 UID key;
00148 offset_t offset;
00149 uint64_t length;
00150 } KLVPacket;
00151
00152 enum MXFWrappingScheme {
00153 Frame,
00154 Clip,
00155 };
00156
00157 typedef struct {
00158 UID uid;
00159 unsigned matching_len;
00160 enum CodecID id;
00161 } MXFCodecUL;
00162
00163 typedef struct {
00164 UID uid;
00165 enum CodecType type;
00166 } MXFDataDefinitionUL;
00167
00168 typedef struct {
00169 const UID key;
00170 int (*read)();
00171 int ctx_size;
00172 enum MXFMetadataSetType type;
00173 } MXFMetadataReadTableEntry;
00174
00175
00176 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
00177 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
00178 static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 };
00179
00180 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 };
00181 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
00182 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
00183 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
00184
00185 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
00186
00187 #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, \
00188 (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])
00189
00190 static int64_t klv_decode_ber_length(ByteIOContext *pb)
00191 {
00192 uint64_t size = get_byte(pb);
00193 if (size & 0x80) {
00194 int bytes_num = size & 0x7f;
00195
00196 if (bytes_num > 8)
00197 return -1;
00198 size = 0;
00199 while (bytes_num--)
00200 size = size << 8 | get_byte(pb);
00201 }
00202 return size;
00203 }
00204
00205 static int mxf_read_sync(ByteIOContext *pb, const uint8_t *key, unsigned size)
00206 {
00207 int i, b;
00208 for (i = 0; i < size && !url_feof(pb); i++) {
00209 b = get_byte(pb);
00210 if (b == key[0])
00211 i = 0;
00212 else if (b != key[i])
00213 i = -1;
00214 }
00215 return i == size;
00216 }
00217
00218 static int klv_read_packet(KLVPacket *klv, ByteIOContext *pb)
00219 {
00220 if (!mxf_read_sync(pb, mxf_klv_key, 4))
00221 return -1;
00222 klv->offset = url_ftell(pb) - 4;
00223 memcpy(klv->key, mxf_klv_key, 4);
00224 get_buffer(pb, klv->key + 4, 12);
00225 klv->length = klv_decode_ber_length(pb);
00226 return klv->length == -1 ? -1 : 0;
00227 }
00228
00229 static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
00230 {
00231 int i;
00232
00233 for (i = 0; i < s->nb_streams; i++) {
00234 MXFTrack *track = s->streams[i]->priv_data;
00235
00236 if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number)))
00237 return i;
00238 }
00239
00240 return s->nb_streams == 1 ? 0 : -1;
00241 }
00242
00243
00244 static int mxf_get_d10_aes3_packet(ByteIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
00245 {
00246 uint8_t buffer[61444];
00247 const uint8_t *buf_ptr, *end_ptr;
00248 uint8_t *data_ptr;
00249 int i;
00250
00251 if (length > 61444)
00252 return -1;
00253 get_buffer(pb, buffer, length);
00254 av_new_packet(pkt, length);
00255 data_ptr = pkt->data;
00256 end_ptr = buffer + length;
00257 buf_ptr = buffer + 4;
00258 for (; buf_ptr < end_ptr; ) {
00259 for (i = 0; i < st->codec->channels; i++) {
00260 uint32_t sample = bytestream_get_le32(&buf_ptr);
00261 if (st->codec->bits_per_sample == 24)
00262 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
00263 else
00264 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
00265 }
00266 buf_ptr += 32 - st->codec->channels*4;
00267 }
00268 pkt->size = data_ptr - pkt->data;
00269 return 0;
00270 }
00271
00272 static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
00273 {
00274 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
00275 MXFContext *mxf = s->priv_data;
00276 ByteIOContext *pb = s->pb;
00277 offset_t end = url_ftell(pb) + klv->length;
00278 uint64_t size;
00279 uint64_t orig_size;
00280 uint64_t plaintext_size;
00281 uint8_t ivec[16];
00282 uint8_t tmpbuf[16];
00283 int index;
00284
00285 if (!mxf->aesc && s->key && s->keylen == 16) {
00286 mxf->aesc = av_malloc(av_aes_size);
00287 if (!mxf->aesc)
00288 return -1;
00289 av_aes_init(mxf->aesc, s->key, 128, 1);
00290 }
00291
00292 url_fskip(pb, klv_decode_ber_length(pb));
00293
00294 klv_decode_ber_length(pb);
00295 plaintext_size = get_be64(pb);
00296
00297 klv_decode_ber_length(pb);
00298 get_buffer(pb, klv->key, 16);
00299 if (!IS_KLV_KEY(klv, mxf_essence_element_key))
00300 return -1;
00301 index = mxf_get_stream_index(s, klv);
00302 if (index < 0)
00303 return -1;
00304
00305 klv_decode_ber_length(pb);
00306 orig_size = get_be64(pb);
00307 if (orig_size < plaintext_size)
00308 return -1;
00309
00310 size = klv_decode_ber_length(pb);
00311 if (size < 32 || size - 32 < orig_size)
00312 return -1;
00313 get_buffer(pb, ivec, 16);
00314 get_buffer(pb, tmpbuf, 16);
00315 if (mxf->aesc)
00316 av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1);
00317 if (memcmp(tmpbuf, checkv, 16))
00318 av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
00319 size -= 32;
00320 av_get_packet(pb, pkt, size);
00321 size -= plaintext_size;
00322 if (mxf->aesc)
00323 av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
00324 &pkt->data[plaintext_size], size >> 4, ivec, 1);
00325 pkt->size = orig_size;
00326 pkt->stream_index = index;
00327 url_fskip(pb, end - url_ftell(pb));
00328 return 0;
00329 }
00330
00331 static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
00332 {
00333 KLVPacket klv;
00334
00335 while (!url_feof(s->pb)) {
00336 if (klv_read_packet(&klv, s->pb) < 0)
00337 return -1;
00338 #ifdef DEBUG
00339 PRINT_KEY(s, "read packet", klv.key);
00340 #endif
00341 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
00342 int res = mxf_decrypt_triplet(s, pkt, &klv);
00343 if (res < 0) {
00344 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
00345 return -1;
00346 }
00347 return 0;
00348 }
00349 if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
00350 int index = mxf_get_stream_index(s, &klv);
00351 if (index < 0) {
00352 av_log(s, AV_LOG_ERROR, "error getting stream index\n");
00353 url_fskip(s->pb, klv.length);
00354 return -1;
00355 }
00356
00357 if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
00358 if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
00359 av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
00360 return -1;
00361 }
00362 } else
00363 av_get_packet(s->pb, pkt, klv.length);
00364 pkt->stream_index = index;
00365 pkt->pos = klv.offset;
00366 return 0;
00367 } else
00368 url_fskip(s->pb, klv.length);
00369 }
00370 return AVERROR(EIO);
00371 }
00372
00373 static int mxf_read_primer_pack(MXFContext *mxf)
00374 {
00375 ByteIOContext *pb = mxf->fc->pb;
00376 int item_num = get_be32(pb);
00377 int item_len = get_be32(pb);
00378
00379 if (item_len != 18) {
00380 av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n");
00381 return -1;
00382 }
00383 if (item_num > UINT_MAX / item_len)
00384 return -1;
00385 mxf->local_tags_count = item_num;
00386 mxf->local_tags = av_malloc(item_num*item_len);
00387 if (!mxf->local_tags)
00388 return -1;
00389 get_buffer(pb, mxf->local_tags, item_num*item_len);
00390 return 0;
00391 }
00392
00393 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
00394 {
00395 mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
00396 if (!mxf->metadata_sets)
00397 return -1;
00398 mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
00399 mxf->metadata_sets_count++;
00400 return 0;
00401 }
00402
00403 static int mxf_read_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid)
00404 {
00405 if (size != 16)
00406 return -1;
00407 if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
00408 get_buffer(pb, cryptocontext->source_container_ul, 16);
00409 return 0;
00410 }
00411
00412 static int mxf_read_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
00413 {
00414 switch (tag) {
00415 case 0x1901:
00416 mxf->packages_count = get_be32(pb);
00417 if (mxf->packages_count >= UINT_MAX / sizeof(UID))
00418 return -1;
00419 mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
00420 if (!mxf->packages_refs)
00421 return -1;
00422 url_fskip(pb, 4);
00423 get_buffer(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID));
00424 break;
00425 }
00426 return 0;
00427 }
00428
00429 static int mxf_read_source_clip(MXFStructuralComponent *source_clip, ByteIOContext *pb, int tag)
00430 {
00431 switch(tag) {
00432 case 0x0202:
00433 source_clip->duration = get_be64(pb);
00434 break;
00435 case 0x1201:
00436 source_clip->start_position = get_be64(pb);
00437 break;
00438 case 0x1101:
00439
00440 url_fskip(pb, 16);
00441 get_buffer(pb, source_clip->source_package_uid, 16);
00442 break;
00443 case 0x1102:
00444 source_clip->source_track_id = get_be32(pb);
00445 break;
00446 }
00447 return 0;
00448 }
00449
00450 static int mxf_read_material_package(MXFPackage *package, ByteIOContext *pb, int tag)
00451 {
00452 switch(tag) {
00453 case 0x4403:
00454 package->tracks_count = get_be32(pb);
00455 if (package->tracks_count >= UINT_MAX / sizeof(UID))
00456 return -1;
00457 package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
00458 if (!package->tracks_refs)
00459 return -1;
00460 url_fskip(pb, 4);
00461 get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
00462 break;
00463 }
00464 return 0;
00465 }
00466
00467 static int mxf_read_track(MXFTrack *track, ByteIOContext *pb, int tag)
00468 {
00469 switch(tag) {
00470 case 0x4801:
00471 track->track_id = get_be32(pb);
00472 break;
00473 case 0x4804:
00474 get_buffer(pb, track->track_number, 4);
00475 break;
00476 case 0x4B01:
00477 track->edit_rate.den = get_be32(pb);
00478 track->edit_rate.num = get_be32(pb);
00479 break;
00480 case 0x4803:
00481 get_buffer(pb, track->sequence_ref, 16);
00482 break;
00483 }
00484 return 0;
00485 }
00486
00487 static int mxf_read_sequence(MXFSequence *sequence, ByteIOContext *pb, int tag)
00488 {
00489 switch(tag) {
00490 case 0x0202:
00491 sequence->duration = get_be64(pb);
00492 break;
00493 case 0x0201:
00494 get_buffer(pb, sequence->data_definition_ul, 16);
00495 break;
00496 case 0x1001:
00497 sequence->structural_components_count = get_be32(pb);
00498 if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
00499 return -1;
00500 sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
00501 if (!sequence->structural_components_refs)
00502 return -1;
00503 url_fskip(pb, 4);
00504 get_buffer(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID));
00505 break;
00506 }
00507 return 0;
00508 }
00509
00510 static int mxf_read_source_package(MXFPackage *package, ByteIOContext *pb, int tag)
00511 {
00512 switch(tag) {
00513 case 0x4403:
00514 package->tracks_count = get_be32(pb);
00515 if (package->tracks_count >= UINT_MAX / sizeof(UID))
00516 return -1;
00517 package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
00518 if (!package->tracks_refs)
00519 return -1;
00520 url_fskip(pb, 4);
00521 get_buffer(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID));
00522 break;
00523 case 0x4401:
00524
00525 url_fskip(pb, 16);
00526 get_buffer(pb, package->package_uid, 16);
00527 break;
00528 case 0x4701:
00529 get_buffer(pb, package->descriptor_ref, 16);
00530 break;
00531 }
00532 return 0;
00533 }
00534
00535 static void mxf_read_pixel_layout(ByteIOContext *pb, MXFDescriptor *descriptor)
00536 {
00537 int code;
00538
00539 do {
00540 code = get_byte(pb);
00541 dprintf(NULL, "pixel layout: code 0x%x\n", code);
00542 switch (code) {
00543 case 0x52:
00544 descriptor->bits_per_sample += get_byte(pb);
00545 break;
00546 case 0x47:
00547 descriptor->bits_per_sample += get_byte(pb);
00548 break;
00549 case 0x42:
00550 descriptor->bits_per_sample += get_byte(pb);
00551 break;
00552 default:
00553 get_byte(pb);
00554 }
00555 } while (code != 0);
00556 }
00557
00558 static int mxf_read_generic_descriptor(MXFDescriptor *descriptor, ByteIOContext *pb, int tag, int size, UID uid)
00559 {
00560 switch(tag) {
00561 case 0x3F01:
00562 descriptor->sub_descriptors_count = get_be32(pb);
00563 if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
00564 return -1;
00565 descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
00566 if (!descriptor->sub_descriptors_refs)
00567 return -1;
00568 url_fskip(pb, 4);
00569 get_buffer(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID));
00570 break;
00571 case 0x3004:
00572 get_buffer(pb, descriptor->essence_container_ul, 16);
00573 break;
00574 case 0x3006:
00575 descriptor->linked_track_id = get_be32(pb);
00576 break;
00577 case 0x3201:
00578 get_buffer(pb, descriptor->essence_codec_ul, 16);
00579 break;
00580 case 0x3203:
00581 descriptor->width = get_be32(pb);
00582 break;
00583 case 0x3202:
00584 descriptor->height = get_be32(pb);
00585 break;
00586 case 0x320E:
00587 descriptor->aspect_ratio.num = get_be32(pb);
00588 descriptor->aspect_ratio.den = get_be32(pb);
00589 break;
00590 case 0x3D03:
00591 descriptor->sample_rate.num = get_be32(pb);
00592 descriptor->sample_rate.den = get_be32(pb);
00593 break;
00594 case 0x3D06:
00595 get_buffer(pb, descriptor->essence_codec_ul, 16);
00596 break;
00597 case 0x3D07:
00598 descriptor->channels = get_be32(pb);
00599 break;
00600 case 0x3D01:
00601 descriptor->bits_per_sample = get_be32(pb);
00602 break;
00603 case 0x3401:
00604 mxf_read_pixel_layout(pb, descriptor);
00605 break;
00606 default:
00607
00608 if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) {
00609 descriptor->extradata = av_malloc(size);
00610 if (!descriptor->extradata)
00611 return -1;
00612 descriptor->extradata_size = size;
00613 get_buffer(pb, descriptor->extradata, size);
00614 }
00615 break;
00616 }
00617 return 0;
00618 }
00619
00620
00621 static const MXFDataDefinitionUL mxf_data_definition_uls[] = {
00622 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, CODEC_TYPE_VIDEO },
00623 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, CODEC_TYPE_AUDIO },
00624 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x05,0x01,0x03,0x02,0x02,0x02,0x02,0x00,0x00 }, CODEC_TYPE_AUDIO },
00625 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, CODEC_TYPE_DATA },
00626 };
00627
00628 static const MXFCodecUL mxf_codec_uls[] = {
00629
00630 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, CODEC_ID_MPEG2VIDEO },
00631 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, CODEC_ID_MPEG2VIDEO },
00632 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, CODEC_ID_MPEG2VIDEO },
00633 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, CODEC_ID_MPEG2VIDEO },
00634 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14, CODEC_ID_MPEG4 },
00635 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, CODEC_ID_DVVIDEO },
00636 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, CODEC_ID_JPEG2000 },
00637 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_RAWVIDEO },
00638
00639 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE },
00640 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16LE },
00641 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13, CODEC_ID_PCM_S16BE },
00642 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15, CODEC_ID_PCM_ALAW },
00643 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15, CODEC_ID_AC3 },
00644 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15, CODEC_ID_MP2 },
00645
00646 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
00647 };
00648
00649 static const MXFCodecUL mxf_picture_essence_container_uls[] = {
00650 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, CODEC_ID_MPEG2VIDEO },
00651 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, CODEC_ID_DVVIDEO },
00652 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
00653 };
00654
00655 static const MXFCodecUL mxf_sound_essence_container_uls[] = {
00656 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, CODEC_ID_PCM_S16LE },
00657 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, CODEC_ID_MP2 },
00658 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, CODEC_ID_PCM_S16LE },
00659 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, CODEC_ID_NONE },
00660 };
00661
00662
00663
00664
00665
00666 static int mxf_match_uid(const UID key, const UID uid, int len)
00667 {
00668 int i;
00669 for (i = 0; i < len; i++) {
00670 if (i != 7 && key[i] != uid[i])
00671 return 0;
00672 }
00673 return 1;
00674 }
00675
00676 static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
00677 {
00678 while (uls->id != CODEC_ID_NONE) {
00679 if(mxf_match_uid(uls->uid, *uid, uls->matching_len))
00680 break;
00681 uls++;
00682 }
00683 return uls;
00684 }
00685
00686 static enum CodecType mxf_get_codec_type(const MXFDataDefinitionUL *uls, UID *uid)
00687 {
00688 while (uls->type != CODEC_TYPE_DATA) {
00689 if(mxf_match_uid(uls->uid, *uid, 16))
00690 break;
00691 uls++;
00692 }
00693 return uls->type;
00694 }
00695
00696 static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
00697 {
00698 int i;
00699
00700 if (!strong_ref)
00701 return NULL;
00702 for (i = 0; i < mxf->metadata_sets_count; i++) {
00703 if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) &&
00704 (type == AnyType || mxf->metadata_sets[i]->type == type)) {
00705 return mxf->metadata_sets[i];
00706 }
00707 }
00708 return NULL;
00709 }
00710
00711 static int mxf_parse_structural_metadata(MXFContext *mxf)
00712 {
00713 MXFPackage *material_package = NULL;
00714 MXFPackage *temp_package = NULL;
00715 int i, j, k;
00716
00717 dprintf(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);
00718
00719 for (i = 0; i < mxf->packages_count; i++) {
00720 material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);
00721 if (material_package) break;
00722 }
00723 if (!material_package) {
00724 av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");
00725 return -1;
00726 }
00727
00728 for (i = 0; i < material_package->tracks_count; i++) {
00729 MXFPackage *source_package = NULL;
00730 MXFTrack *material_track = NULL;
00731 MXFTrack *source_track = NULL;
00732 MXFTrack *temp_track = NULL;
00733 MXFDescriptor *descriptor = NULL;
00734 MXFStructuralComponent *component = NULL;
00735 UID *essence_container_ul = NULL;
00736 const MXFCodecUL *codec_ul = NULL;
00737 const MXFCodecUL *container_ul = NULL;
00738 AVStream *st;
00739
00740 if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
00741 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
00742 continue;
00743 }
00744
00745 if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
00746 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
00747 return -1;
00748 }
00749
00750
00751 for (j = 0; j < material_track->sequence->structural_components_count; j++) {
00752
00753 component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
00754 if (!component)
00755 continue;
00756
00757 for (k = 0; k < mxf->packages_count; k++) {
00758 temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);
00759 if (!temp_package)
00760 continue;
00761 if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {
00762 source_package = temp_package;
00763 break;
00764 }
00765 }
00766 if (!source_package) {
00767 av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);
00768 break;
00769 }
00770 for (k = 0; k < source_package->tracks_count; k++) {
00771 if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
00772 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
00773 return -1;
00774 }
00775 if (temp_track->track_id == component->source_track_id) {
00776 source_track = temp_track;
00777 break;
00778 }
00779 }
00780 if (!source_track) {
00781 av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);
00782 break;
00783 }
00784 }
00785 if (!source_track)
00786 continue;
00787
00788 st = av_new_stream(mxf->fc, source_track->track_id);
00789 if (!st) {
00790 av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");
00791 return -1;
00792 }
00793 st->priv_data = source_track;
00794 st->duration = component->duration;
00795 if (st->duration == -1)
00796 st->duration = AV_NOPTS_VALUE;
00797 st->start_time = component->start_position;
00798 av_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);
00799
00800 if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
00801 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");
00802 return -1;
00803 }
00804
00805 #ifdef DEBUG
00806 PRINT_KEY(mxf->fc, "data definition ul", source_track->sequence->data_definition_ul);
00807 #endif
00808 st->codec->codec_type = mxf_get_codec_type(mxf_data_definition_uls, &source_track->sequence->data_definition_ul);
00809
00810 source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);
00811 if (source_package->descriptor) {
00812 if (source_package->descriptor->type == MultipleDescriptor) {
00813 for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {
00814 MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);
00815
00816 if (!sub_descriptor) {
00817 av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");
00818 continue;
00819 }
00820 if (sub_descriptor->linked_track_id == source_track->track_id) {
00821 descriptor = sub_descriptor;
00822 break;
00823 }
00824 }
00825 } else if (source_package->descriptor->type == Descriptor)
00826 descriptor = source_package->descriptor;
00827 }
00828 if (!descriptor) {
00829 av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);
00830 continue;
00831 }
00832 #ifdef DEBUG
00833 PRINT_KEY(mxf->fc, "essence codec ul", descriptor->essence_codec_ul);
00834 PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);
00835 #endif
00836 essence_container_ul = &descriptor->essence_container_ul;
00837
00838
00839 if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {
00840 av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");
00841 for (k = 0; k < mxf->metadata_sets_count; k++) {
00842 MXFMetadataSet *metadata = mxf->metadata_sets[k];
00843 if (metadata->type == CryptoContext) {
00844 essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;
00845 break;
00846 }
00847 }
00848 }
00849
00850 codec_ul = mxf_get_codec_ul(mxf_codec_uls, &descriptor->essence_codec_ul);
00851 st->codec->codec_id = codec_ul->id;
00852 if (descriptor->extradata) {
00853 st->codec->extradata = descriptor->extradata;
00854 st->codec->extradata_size = descriptor->extradata_size;
00855 }
00856 if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
00857 container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
00858 if (st->codec->codec_id == CODEC_ID_NONE)
00859 st->codec->codec_id = container_ul->id;
00860 st->codec->width = descriptor->width;
00861 st->codec->height = descriptor->height;
00862 st->codec->bits_per_sample = descriptor->bits_per_sample;
00863 st->need_parsing = AVSTREAM_PARSE_HEADERS;
00864 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
00865 container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
00866 if (st->codec->codec_id == CODEC_ID_NONE)
00867 st->codec->codec_id = container_ul->id;
00868 st->codec->channels = descriptor->channels;
00869 st->codec->bits_per_sample = descriptor->bits_per_sample;
00870 st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
00871
00872 if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
00873 if (descriptor->bits_per_sample == 24)
00874 st->codec->codec_id = CODEC_ID_PCM_S24LE;
00875 else if (descriptor->bits_per_sample == 32)
00876 st->codec->codec_id = CODEC_ID_PCM_S32LE;
00877 } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
00878 if (descriptor->bits_per_sample == 24)
00879 st->codec->codec_id = CODEC_ID_PCM_S24BE;
00880 else if (descriptor->bits_per_sample == 32)
00881 st->codec->codec_id = CODEC_ID_PCM_S32BE;
00882 } else if (st->codec->codec_id == CODEC_ID_MP2) {
00883 st->need_parsing = AVSTREAM_PARSE_FULL;
00884 }
00885 }
00886 if (st->codec->codec_type != CODEC_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {
00887 av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");
00888 st->need_parsing = AVSTREAM_PARSE_FULL;
00889 }
00890 }
00891 return 0;
00892 }
00893
00894 static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
00895 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
00896 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType },
00897 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage },
00898 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage },
00899 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence },
00900 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip },
00901 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor },
00902 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00903 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00904 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00905 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00906 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00907 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor },
00908 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track },
00909 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track },
00910 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
00911 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
00912 };
00913
00914 static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)
00915 {
00916 ByteIOContext *pb = mxf->fc->pb;
00917 MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;
00918 uint64_t klv_end = url_ftell(pb) + klv->length;
00919
00920 if (!ctx)
00921 return -1;
00922 while (url_ftell(pb) + 4 < klv_end) {
00923 int tag = get_be16(pb);
00924 int size = get_be16(pb);
00925 uint64_t next = url_ftell(pb) + size;
00926 UID uid = {0};
00927
00928 if (!size) {
00929 av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
00930 continue;
00931 }
00932 if (tag > 0x7FFF) {
00933 int i;
00934 for (i = 0; i < mxf->local_tags_count; i++) {
00935 int local_tag = AV_RB16(mxf->local_tags+i*18);
00936 if (local_tag == tag) {
00937 memcpy(uid, mxf->local_tags+i*18+2, 16);
00938 dprintf(mxf->fc, "local tag 0x%04X\n", local_tag);
00939 #ifdef DEBUG
00940 PRINT_KEY(mxf->fc, "uid", uid);
00941 #endif
00942 }
00943 }
00944 }
00945 if (ctx_size && tag == 0x3C0A)
00946 get_buffer(pb, ctx->uid, 16);
00947 else if (read_child(ctx, pb, tag, size, uid) < 0)
00948 return -1;
00949
00950 url_fseek(pb, next, SEEK_SET);
00951 }
00952 if (ctx_size) ctx->type = type;
00953 return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
00954 }
00955
00956 static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
00957 {
00958 MXFContext *mxf = s->priv_data;
00959 KLVPacket klv;
00960
00961 if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) {
00962 av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n");
00963 return -1;
00964 }
00965 url_fseek(s->pb, -14, SEEK_CUR);
00966 mxf->fc = s;
00967 while (!url_feof(s->pb)) {
00968 const MXFMetadataReadTableEntry *metadata;
00969
00970 if (klv_read_packet(&klv, s->pb) < 0)
00971 return -1;
00972 #ifdef DEBUG
00973 PRINT_KEY(s, "read header", klv.key);
00974 #endif
00975 if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) ||
00976 IS_KLV_KEY(klv.key, mxf_essence_element_key)) {
00977
00978 url_fseek(s->pb, klv.offset, SEEK_SET);
00979 break;
00980 }
00981
00982 for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
00983 if (IS_KLV_KEY(klv.key, metadata->key)) {
00984 int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read;
00985 if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
00986 av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
00987 return -1;
00988 }
00989 break;
00990 }
00991 }
00992 if (!metadata->read)
00993 url_fskip(s->pb, klv.length);
00994 }
00995 return mxf_parse_structural_metadata(mxf);
00996 }
00997
00998 static int mxf_read_close(AVFormatContext *s)
00999 {
01000 MXFContext *mxf = s->priv_data;
01001 int i;
01002
01003 av_freep(&mxf->packages_refs);
01004 for (i = 0; i < mxf->metadata_sets_count; i++) {
01005 switch (mxf->metadata_sets[i]->type) {
01006 case MultipleDescriptor:
01007 av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs);
01008 break;
01009 case Sequence:
01010 av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs);
01011 break;
01012 case SourcePackage:
01013 case MaterialPackage:
01014 av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs);
01015 break;
01016 default:
01017 break;
01018 }
01019 av_freep(&mxf->metadata_sets[i]);
01020 }
01021 av_freep(&mxf->metadata_sets);
01022 av_freep(&mxf->aesc);
01023 av_freep(&mxf->local_tags);
01024 return 0;
01025 }
01026
01027 static int mxf_probe(AVProbeData *p) {
01028 uint8_t *bufp = p->buf;
01029 uint8_t *end = p->buf + p->buf_size;
01030
01031 if (p->buf_size < sizeof(mxf_header_partition_pack_key))
01032 return 0;
01033
01034
01035 end -= sizeof(mxf_header_partition_pack_key);
01036 for (; bufp < end; bufp++) {
01037 if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key))
01038 return AVPROBE_SCORE_MAX;
01039 }
01040 return 0;
01041 }
01042
01043
01044
01045 static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
01046 {
01047 AVStream *st = s->streams[stream_index];
01048 int64_t seconds;
01049
01050 if (!s->bit_rate)
01051 return -1;
01052 if (sample_time < 0)
01053 sample_time = 0;
01054 seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
01055 url_fseek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
01056 av_update_cur_dts(s, st, sample_time);
01057 return 0;
01058 }
01059
01060 AVInputFormat mxf_demuxer = {
01061 "mxf",
01062 "MXF format",
01063 sizeof(MXFContext),
01064 mxf_probe,
01065 mxf_read_header,
01066 mxf_read_packet,
01067 mxf_read_close,
01068 mxf_read_seek,
01069 };