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 | 69 | OP3b, |
| 70 | 70 | OP3c, |
| 71 | 71 | OPAtom, |
| 72 | + OPSONYOpt, /* FATE sample, violates the spec in places */ | |
| 72 | 73 | } MXFOP; |
| 73 | 74 | |
| 74 | 75 | typedef struct { |
| @@ -81,6 +82,10 @@ typedef struct { · 6 unmodified lines | ||
| 81 | 82 | int64_t this_partition; |
| 82 | 83 | int64_t essence_offset; /* absolute offset of essence */ |
| 83 | 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 | 89 | } MXFPartition; |
| 85 | 90 | |
| 86 | 91 | typedef struct { |
| @@ -203,7 +208,8 @@ enum MXFWrappingScheme { · 116 unmodified lines | ||
| 203 | 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 | 214 | typedef struct { |
| 209 | 215 | const UID key; |
| @@ -416,7 +422,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) · 206 unmodified lines | ||
| 416 | 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 | 427 | MXFContext *mxf = arg; |
| 422 | 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 | 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 | 447 | MXFContext *mxf = arg; |
| 442 | 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 | 471 | memset(partition, 0, sizeof(*partition)); |
| 466 | 472 | mxf->partitions_count++; |
| 473 | + partition->pack_length = avio_tell(pb) - klv_offset + size; | |
| 467 | 474 | |
| 468 | 475 | switch(uid[13]) { |
| 469 | 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 | 490 | /* consider both footers to be closed (there is only Footer and CompleteFooter) */ |
| 484 | 491 | partition->closed = partition->type == Footer || !(uid[14] & 1); |
| 485 | 492 | partition->complete = uid[14] > 2; |
| 486 | − avio_skip(pb, 8); | |
| 493 | + avio_skip(pb, 4); | |
| 494 | + partition->kag_size = avio_rb32(pb); | |
| 487 | 495 | partition->this_partition = avio_rb64(pb); |
| 488 | 496 | partition->previous_partition = avio_rb64(pb); |
| 489 | 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 | 500 | partition->index_sid = avio_rb32(pb); |
| 492 | 501 | avio_skip(pb, 8); |
| 493 | 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 | 528 | else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b; |
| 520 | 529 | else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c; |
| 521 | 530 | else if (op[12] == 0x10) mxf->op = OPAtom; |
| 522 | − else | |
| 523 | − av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh\n", op[12], op[13]); | |
| 531 | + else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt; | |
| 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 | 548 | return 0; |
| 526 | 549 | } |
| @@ -537,7 +560,7 @@ static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) · 10 unmodified lines | ||
| 537 | 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 | 565 | MXFCryptoContext *cryptocontext = arg; |
| 543 | 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 | 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 | 575 | MXFContext *mxf = arg; |
| 553 | 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 | 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 | 593 | MXFStructuralComponent *source_clip = arg; |
| 571 | 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 | 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 | 615 | MXFPackage *package = arg; |
| 593 | 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 | 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 | 633 | MXFTrack *track = arg; |
| 611 | 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 | 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 | 654 | MXFSequence *sequence = arg; |
| 632 | 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 | 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 | 678 | MXFPackage *package = arg; |
| 656 | 679 | switch(tag) { |
| @@ -729,7 +752,7 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg · 72 unmodified lines | ||
| 729 | 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 | 757 | MXFIndexTableSegment *segment = arg; |
| 735 | 758 | switch(tag) { |
| @@ -792,7 +815,7 @@ static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor) · 56 unmodified lines | ||
| 792 | 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 | 820 | MXFDescriptor *descriptor = arg; |
| 798 | 821 | switch(tag) { |
| @@ -1321,7 +1344,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF · 522 unmodified lines | ||
| 1321 | 1344 | } |
| 1322 | 1345 | if (ctx_size && tag == 0x3C0A) |
| 1323 | 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 | 1348 | return -1; |
| 1326 | 1349 | |
| 1327 | 1350 | avio_seek(pb, next, SEEK_SET); |
| @@ -1531,7 +1554,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) · 203 unmodified lines | ||
| 1531 | 1554 | res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type); |
| 1532 | 1555 | } else { |
| 1533 | 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 | 1558 | avio_seek(s->pb, next, SEEK_SET); |
| 1536 | 1559 | } |
| 1537 | 1560 | if (res < 0) { |