These values include KAGSize, HeaderByteCount and IndexByteCount. The length of the pack itself is also stored, and KAGSize is sanity checked. The FATE sample has KAGSize == 0, which is adjusted to 512. Other bad KAGSizes are set to 1.
Unified · Split
| @@ -69,6 +69,7 @@ typedef enum { · 68 unmodified lines | |||
| 69 | OP3b, | 69 | OP3b, |
| 70 | OP3c, | 70 | OP3c, |
| 71 | OPAtom, | 71 | OPAtom, |
| 72 | OPSONYOpt, /* FATE sample, violates the spec in places */ | ||
| 72 | } MXFOP; | 73 | } MXFOP; |
| 73 | 74 | ||
| 74 | typedef struct { | 75 | typedef struct { |
| @@ -81,6 +82,10 @@ typedef struct { · 6 unmodified lines | |||
| 81 | int64_t this_partition; | 82 | int64_t this_partition; |
| 82 | int64_t essence_offset; /* absolute offset of essence */ | 83 | int64_t essence_offset; /* absolute offset of essence */ |
| 83 | int64_t essence_length; | 84 | int64_t essence_length; |
| 85 | int32_t kag_size; | ||
| 86 | int64_t header_byte_count; | ||
| 87 | int64_t index_byte_count; | ||
| 88 | int pack_length; | ||
| 84 | } MXFPartition; | 89 | } MXFPartition; |
| 85 | 90 | ||
| 86 | typedef struct { | 91 | typedef struct { |
| @@ -203,7 +208,8 @@ enum MXFWrappingScheme { · 116 unmodified lines | |||
| 203 | Clip, | 208 | Clip, |
| 204 | }; | 209 | }; |
| 205 | 210 | ||
| 206 | typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid); | 211 | /* NOTE: klv_offset is not set (-1) for local keys */ |
| 212 | typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset); | ||
| 207 | 213 | ||
| 208 | typedef struct { | 214 | typedef struct { |
| 209 | const UID key; | 215 | const UID key; |
| @@ -416,7 +422,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) · 206 unmodified lines | |||
| 416 | return AVERROR_EOF; | 422 | return AVERROR_EOF; |
| 417 | } | 423 | } |
| 418 | 424 | ||
| 419 | static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 425 | static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 420 | { | 426 | { |
| 421 | MXFContext *mxf = arg; | 427 | MXFContext *mxf = arg; |
| 422 | int item_num = avio_rb32(pb); | 428 | int item_num = avio_rb32(pb); |
| @@ -436,7 +442,7 @@ static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, U · 13 unmodified lines | |||
| 436 | return 0; | 442 | return 0; |
| 437 | } | 443 | } |
| 438 | 444 | ||
| 439 | static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 445 | static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 440 | { | 446 | { |
| 441 | MXFContext *mxf = arg; | 447 | MXFContext *mxf = arg; |
| 442 | MXFPartition *partition; | 448 | MXFPartition *partition; |
| @@ -464,6 +470,7 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size · 21 unmodified lines | |||
| 464 | 470 | ||
| 465 | memset(partition, 0, sizeof(*partition)); | 471 | memset(partition, 0, sizeof(*partition)); |
| 466 | mxf->partitions_count++; | 472 | mxf->partitions_count++; |
| 473 | partition->pack_length = avio_tell(pb) - klv_offset + size; | ||
| 467 | 474 | ||
| 468 | switch(uid[13]) { | 475 | switch(uid[13]) { |
| 469 | case 2: | 476 | case 2: |
| @@ -483,11 +490,13 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size · 13 unmodified lines | |||
| 483 | /* consider both footers to be closed (there is only Footer and CompleteFooter) */ | 490 | /* consider both footers to be closed (there is only Footer and CompleteFooter) */ |
| 484 | partition->closed = partition->type == Footer || !(uid[14] & 1); | 491 | partition->closed = partition->type == Footer || !(uid[14] & 1); |
| 485 | partition->complete = uid[14] > 2; | 492 | partition->complete = uid[14] > 2; |
| 486 | avio_skip(pb, 8); | 493 | avio_skip(pb, 4); |
| 494 | partition->kag_size = avio_rb32(pb); | ||
| 487 | partition->this_partition = avio_rb64(pb); | 495 | partition->this_partition = avio_rb64(pb); |
| 488 | partition->previous_partition = avio_rb64(pb); | 496 | partition->previous_partition = avio_rb64(pb); |
| 489 | footer_partition = avio_rb64(pb); | 497 | footer_partition = avio_rb64(pb); |
| 490 | avio_skip(pb, 16); | 498 | partition->header_byte_count = avio_rb64(pb); |
| 499 | partition->index_byte_count = avio_rb64(pb); | ||
| 491 | partition->index_sid = avio_rb32(pb); | 500 | partition->index_sid = avio_rb32(pb); |
| 492 | avio_skip(pb, 8); | 501 | avio_skip(pb, 8); |
| 493 | partition->body_sid = avio_rb32(pb); | 502 | partition->body_sid = avio_rb32(pb); |
| @@ -519,8 +528,22 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size · 25 unmodified lines | |||
| 519 | else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b; | 528 | else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b; |
| 520 | else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c; | 529 | else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c; |
| 521 | else if (op[12] == 0x10) mxf->op = OPAtom; | 530 | else if (op[12] == 0x10) mxf->op = OPAtom; |
| 522 | else | 531 | else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt; |
| 523 | av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh\n", op[12], op[13]); | 532 | else { |
| 533 | av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]); | ||
| 534 | mxf->op = OP1a; | ||
| 535 | } | ||
| 536 | |||
| 537 | if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) { | ||
| 538 | av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %i - guessing ", partition->kag_size); | ||
| 539 | |||
| 540 | if (mxf->op == OPSONYOpt) | ||
| 541 | partition->kag_size = 512; | ||
| 542 | else | ||
| 543 | partition->kag_size = 1; | ||
| 544 | |||
| 545 | av_log(mxf->fc, AV_LOG_WARNING, "%i\n", partition->kag_size); | ||
| 546 | } | ||
| 524 | 547 | ||
| 525 | return 0; | 548 | return 0; |
| 526 | } | 549 | } |
| @@ -537,7 +560,7 @@ static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) · 10 unmodified lines | |||
| 537 | return 0; | 560 | return 0; |
| 538 | } | 561 | } |
| 539 | 562 | ||
| 540 | static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 563 | static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 541 | { | 564 | { |
| 542 | MXFCryptoContext *cryptocontext = arg; | 565 | MXFCryptoContext *cryptocontext = arg; |
| 543 | if (size != 16) | 566 | if (size != 16) |
| @@ -547,7 +570,7 @@ static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, i · 3 unmodified lines | |||
| 547 | return 0; | 570 | return 0; |
| 548 | } | 571 | } |
| 549 | 572 | ||
| 550 | static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 573 | static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 551 | { | 574 | { |
| 552 | MXFContext *mxf = arg; | 575 | MXFContext *mxf = arg; |
| 553 | switch (tag) { | 576 | switch (tag) { |
| @@ -565,7 +588,7 @@ static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int siz · 11 unmodified lines | |||
| 565 | return 0; | 588 | return 0; |
| 566 | } | 589 | } |
| 567 | 590 | ||
| 568 | static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 591 | static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 569 | { | 592 | { |
| 570 | MXFStructuralComponent *source_clip = arg; | 593 | MXFStructuralComponent *source_clip = arg; |
| 571 | switch(tag) { | 594 | switch(tag) { |
| @@ -587,7 +610,7 @@ static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, U · 15 unmodified lines | |||
| 587 | return 0; | 610 | return 0; |
| 588 | } | 611 | } |
| 589 | 612 | ||
| 590 | static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 613 | static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 591 | { | 614 | { |
| 592 | MXFPackage *package = arg; | 615 | MXFPackage *package = arg; |
| 593 | switch(tag) { | 616 | switch(tag) { |
| @@ -605,7 +628,7 @@ static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int si · 11 unmodified lines | |||
| 605 | return 0; | 628 | return 0; |
| 606 | } | 629 | } |
| 607 | 630 | ||
| 608 | static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 631 | static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 609 | { | 632 | { |
| 610 | MXFTrack *track = arg; | 633 | MXFTrack *track = arg; |
| 611 | switch(tag) { | 634 | switch(tag) { |
| @@ -626,7 +649,7 @@ static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid · 14 unmodified lines | |||
| 626 | return 0; | 649 | return 0; |
| 627 | } | 650 | } |
| 628 | 651 | ||
| 629 | static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 652 | static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 630 | { | 653 | { |
| 631 | MXFSequence *sequence = arg; | 654 | MXFSequence *sequence = arg; |
| 632 | switch(tag) { | 655 | switch(tag) { |
| @@ -650,7 +673,7 @@ static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID · 17 unmodified lines | |||
| 650 | return 0; | 673 | return 0; |
| 651 | } | 674 | } |
| 652 | 675 | ||
| 653 | static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 676 | static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 654 | { | 677 | { |
| 655 | MXFPackage *package = arg; | 678 | MXFPackage *package = arg; |
| 656 | switch(tag) { | 679 | switch(tag) { |
| @@ -729,7 +752,7 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg · 72 unmodified lines | |||
| 729 | return 0; | 752 | return 0; |
| 730 | } | 753 | } |
| 731 | 754 | ||
| 732 | static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 755 | static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 733 | { | 756 | { |
| 734 | MXFIndexTableSegment *segment = arg; | 757 | MXFIndexTableSegment *segment = arg; |
| 735 | switch(tag) { | 758 | switch(tag) { |
| @@ -792,7 +815,7 @@ static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor) · 56 unmodified lines | |||
| 792 | ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt); | 815 | ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt); |
| 793 | } | 816 | } |
| 794 | 817 | ||
| 795 | static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid) | 818 | static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) |
| 796 | { | 819 | { |
| 797 | MXFDescriptor *descriptor = arg; | 820 | MXFDescriptor *descriptor = arg; |
| 798 | switch(tag) { | 821 | switch(tag) { |
| @@ -1321,7 +1344,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF · 522 unmodified lines | |||
| 1321 | } | 1344 | } |
| 1322 | if (ctx_size && tag == 0x3C0A) | 1345 | if (ctx_size && tag == 0x3C0A) |
| 1323 | avio_read(pb, ctx->uid, 16); | 1346 | avio_read(pb, ctx->uid, 16); |
| 1324 | else if (read_child(ctx, pb, tag, size, uid) < 0) | 1347 | else if (read_child(ctx, pb, tag, size, uid, -1) < 0) |
| 1325 | return -1; | 1348 | return -1; |
| 1326 | 1349 | ||
| 1327 | avio_seek(pb, next, SEEK_SET); | 1350 | avio_seek(pb, next, SEEK_SET); |
| @@ -1531,7 +1554,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) · 203 unmodified lines | |||
| 1531 | res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type); | 1554 | res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type); |
| 1532 | } else { | 1555 | } else { |
| 1533 | uint64_t next = avio_tell(s->pb) + klv.length; | 1556 | uint64_t next = avio_tell(s->pb) + klv.length; |
| 1534 | res = metadata->read(mxf, s->pb, 0, 0, klv.key); | 1557 | res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset); |
| 1535 | avio_seek(s->pb, next, SEEK_SET); | 1558 | avio_seek(s->pb, next, SEEK_SET); |
| 1536 | } | 1559 | } |
| 1537 | if (res < 0) { | 1560 | if (res < 0) { |