237 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
238 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
239 static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
240 static const uint8_t mxf_system_item_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04 };
243 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 };
244 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
245 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
246 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
248 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
254 int bytes_num = size & 0x7f;
260 size = size << 8 |
avio_r8(pb);
272 else if (b != key[i])
286 return klv->
length == -1 ? -1 : 0;
306 const uint8_t *buf_ptr, *end_ptr;
315 data_ptr = pkt->
data;
316 end_ptr = pkt->
data + length;
317 buf_ptr = pkt->
data + 4;
320 uint32_t
sample = bytestream_get_le32(&buf_ptr);
322 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
324 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
334 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
340 uint64_t plaintext_size;
367 if (orig_size < plaintext_size)
371 if (size < 32 || size - 32 < orig_size)
377 if (memcmp(tmpbuf, checkv, 16))
383 else if (size < plaintext_size)
385 size -= plaintext_size;
388 &pkt->
data[plaintext_size], size >> 4, ivec, 1);
401 if (item_len != 18) {
405 if (item_num > UINT_MAX / item_len)
420 uint64_t footer_partition;
421 uint32_t nb_essence_containers;
442 memset(partition, 0,
sizeof(*partition));
478 if (footer_partition) {
481 "inconsistent FooterPartition value: %"PRIu64
" != %"PRIu64
"\n",
489 "PartitionPack: ThisPartition = 0x%"PRIX64
490 ", PreviousPartition = 0x%"PRIX64
", "
491 "FooterPartition = 0x%"PRIX64
", IndexSID = %i, BodySID = %i\n",
500 "PreviousPartition points to this partition or forward\n");
504 if (op[12] == 1 && op[13] == 1) mxf->
op =
OP1a;
505 else if (op[12] == 1 && op[13] == 2) mxf->
op =
OP1b;
506 else if (op[12] == 1 && op[13] == 3) mxf->
op =
OP1c;
507 else if (op[12] == 2 && op[13] == 1) mxf->
op =
OP2a;
508 else if (op[12] == 2 && op[13] == 2) mxf->
op =
OP2b;
509 else if (op[12] == 2 && op[13] == 3) mxf->
op =
OP2c;
510 else if (op[12] == 3 && op[13] == 1) mxf->
op =
OP3a;
511 else if (op[12] == 3 && op[13] == 2) mxf->
op =
OP3b;
512 else if (op[12] == 3 && op[13] == 3) mxf->
op =
OP3c;
513 else if (op[12] == 64&& op[13] == 1) mxf->
op =
OPSonyOpt;
514 else if (op[12] == 0x10) {
519 if (nb_essence_containers != 1) {
525 "\"OPAtom\" with %u ECs - assuming %s\n",
526 nb_essence_containers,
527 op ==
OP1a ?
"OP1a" :
"OPAtom");
533 av_log(mxf->
fc,
AV_LOG_ERROR,
"unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);
621 if (package->tracks_count >= UINT_MAX /
sizeof(
UID))
623 package->tracks_refs =
av_malloc(package->tracks_count *
sizeof(
UID));
624 if (!package->tracks_refs)
684 if (package->tracks_count >= UINT_MAX /
sizeof(
UID))
686 package->tracks_refs =
av_malloc(package->tracks_count *
sizeof(
UID));
687 if (!package->tracks_refs)
698 avio_read(pb, package->descriptor_ref, 16);
782 int code, value, ofs = 0;
791 layout[ofs++] = code;
792 layout[ofs++] = value;
887 for (i = 0; i <
len; i++) {
888 if (i != 7 && key[i] != uid[i])
896 while (uls->
uid[0]) {
921 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14,
AV_CODEC_ID_MPEG2VIDEO },
922 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,
AV_CODEC_ID_DVVIDEO },
923 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14,
AV_CODEC_ID_RAWVIDEO },
924 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
929 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x00,0x00 }, 14,
AV_CODEC_ID_MPEG2VIDEO },
930 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
935 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,
AV_CODEC_ID_H264 },
936 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,
AV_CODEC_ID_JPEG2000 },
937 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
942 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14,
AV_CODEC_ID_PCM_S16LE },
943 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,
AV_CODEC_ID_MP2 },
944 { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14,
AV_CODEC_ID_PCM_S16LE },
945 { { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0xFF,0x4B,0x46,0x41,0x41,0x00,0x0D,0x4D,0x4F }, 14,
AV_CODEC_ID_PCM_S16LE },
946 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
951 int i, j, nb_segments = 0;
953 int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
963 *sorted_segments =
av_mallocz(nb_segments *
sizeof(**sorted_segments));
964 unsorted_segments =
av_mallocz(nb_segments *
sizeof(*unsorted_segments));
965 if (!*sorted_segments || !unsorted_segments) {
975 *nb_sorted_segments = 0;
978 for (i = 0; i < nb_segments; i++) {
979 int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
980 uint64_t best_index_duration = 0;
982 for (j = 0; j < nb_segments; j++) {
1004 (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
1005 last_body_sid = best_body_sid;
1006 last_index_sid = best_index_sid;
1007 last_index_start = best_index_start;
1021 int64_t offset_in = offset;
1038 "failed to find absolute offset of %"PRIX64
" in BodySID %i - partial file?\n",
1039 offset_in, body_sid);
1071 int64_t offset_temp = 0;
1095 av_log(mxf->
fc,
AV_LOG_ERROR,
"IndexSID %i segment at %"PRId64
" missing EditUnitByteCount and IndexEntryArray\n",
1101 *edit_unit_out = edit_unit;
1119 int8_t max_temporal_offset = -128;
1151 for (x = 0; x < index_table->
nb_ptses; x++)
1183 int index_delta = 1;
1192 for (j = 0; j < n; j += index_delta, x++) {
1194 int index = x + offset;
1198 "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64
"?\n",
1206 if (index < 0 || index >= index_table->
nb_ptses) {
1208 "index entry %i + TemporalOffset %i = %i, which is out of bounds\n",
1214 max_temporal_offset =
FFMAX(max_temporal_offset, offset);
1218 index_table->
first_dts = -max_temporal_offset;
1229 int i, j, k, ret, nb_sorted_segments;
1233 nb_sorted_segments <= 0) {
1239 for (i = 0; i < nb_sorted_segments; i++) {
1240 if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid)
1242 else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) {
1245 goto finish_decoding_index;
1254 goto finish_decoding_index;
1258 for (i = j = 0; i < nb_sorted_segments; i++) {
1259 if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) {
1275 " pointer array\n");
1277 goto finish_decoding_index;
1280 if (sorted_segments[i]->index_start_position)
1281 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i starts at EditUnit %"PRId64
" - seeking may not work as expected\n",
1289 goto finish_decoding_index;
1297 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n",
1314 finish_decoding_index:
1337 if (material_package)
break;
1339 if (!material_package) {
1351 UID *essence_container_ul =
NULL;
1379 source_package = temp_package;
1383 if (!source_package) {
1384 av_dlog(mxf->
fc,
"material track %d: no corresponding source package found\n", material_track->
track_id);
1394 source_track = temp_track;
1398 if (!source_track) {
1403 if (!source_track || !component)
1434 "Invalid edit rate (%d/%d) found on stream #%d, "
1435 "defaulting to 25/1\n",
1452 if (!sub_descriptor) {
1457 descriptor = sub_descriptor;
1478 essence_container_ul = &((
MXFCryptoContext *)metadata)->source_container_ul;
1490 container_ul =
mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
1500 "SegmentedFrame layout isn't currently supported\n");
1508 "OneField frame layout isn't currently supported\n");
1525 "Field dominance %d support",
1533 "Unknown frame layout type: %d\n",
1555 container_ul =
mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
1566 "found for stream #%d, time base forced to 1/48000\n",
1610 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 },
mxf_read_primer_pack },
1611 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 },
mxf_read_partition_pack },
1612 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 },
mxf_read_partition_pack },
1613 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 },
mxf_read_partition_pack },
1614 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 },
mxf_read_partition_pack },
1615 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 },
mxf_read_partition_pack },
1616 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 },
mxf_read_partition_pack },
1617 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 },
mxf_read_partition_pack },
1618 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 },
mxf_read_partition_pack },
1619 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 },
mxf_read_partition_pack },
1620 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 },
mxf_read_partition_pack },
1621 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 },
mxf_read_content_storage, 0,
AnyType },
1622 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 },
mxf_read_source_package,
sizeof(
MXFPackage),
SourcePackage },
1623 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 },
mxf_read_material_package,
sizeof(
MXFPackage),
MaterialPackage },
1624 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 },
mxf_read_sequence,
sizeof(
MXFSequence),
Sequence },
1625 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 },
mxf_read_source_clip,
sizeof(
MXFStructuralComponent),
SourceClip },
1626 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
MultipleDescriptor },
1627 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1628 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1629 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1630 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1631 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1632 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1633 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
1634 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
1635 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 },
mxf_read_cryptographic_context,
sizeof(
MXFCryptoContext),
CryptoContext },
1636 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 },
mxf_read_index_table_segment,
sizeof(
MXFIndexTableSegment),
IndexTableSegment },
1637 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
NULL, 0,
AnyType },
1655 av_dlog(mxf->
fc,
"local tag %#04x size %d\n", tag, size);
1664 if (local_tag == tag) {
1666 av_dlog(mxf->
fc,
"local tag %#04x\n", local_tag);
1671 if (ctx_size && tag == 0x3C0A)
1673 else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0)
1683 "local tag %#04x extends past end of local set @ %#"PRIx64
"\n",
1689 if (ctx_size) ctx->
type = type;
1709 av_dlog(mxf->
fc,
"seeking to previous partition\n");
1731 av_dlog(mxf->
fc,
"seeking to footer\n");
1743 av_log(mxf->
fc,
AV_LOG_ERROR,
"failed to seek to footer @ 0x%"PRIx64
" (%"PRId64
") - partial file?\n",
1792 "partition %i: bad ThisPartition = %"PRIX64
"\n",
1802 int64_t ret = (position / kag_size) * kag_size;
1803 return ret == position ? ret : ret + kag_size;
1819 int64_t op1a_essence_offset =
1878 int64_t essence_offset = 0;
1912 "found essence prior to first PartitionPack\n");
1920 if (!essence_offset)
1921 essence_offset = klv.
offset;
1937 for (metadata = mxf_metadata_read_table; metadata->
read; metadata++) {
1940 if (klv.
key[5] == 0x53) {
1962 if (!metadata->
read)
1966 if (!essence_offset) {
1984 av_log(mxf->
fc,
AV_LOG_INFO,
"got %i index tables - only the first one (IndexSID %i) will be used\n",
2002 int64_t last_ofs = -1, next_ofs = -1;
2014 NULL, &next_ofs, 0) < 0)
2017 if (next_ofs <= last_ofs) {
2021 "next_ofs didn't change. not deriving packet timestamps\n");
2025 if (next_ofs > current_offset)
2028 last_ofs = next_ofs;
2061 int64_t next_ofs, next_klv;
2079 if (next_ofs >= 0 && next_klv > next_ofs) {
2084 "OPAtom misinterpreted as OP1a?"
2085 "KLV for edit unit %i extending into "
2092 if (klv.
key[12] == 0x06 && klv.
key[13] == 0x01 && klv.
key[14] == 0x10) {
2137 int64_t ret64, pos, next_pos;
2166 if ((size = next_pos - pos) <= 0) {
2171 if ((ret64 =
avio_seek(s->
pb, pos, SEEK_SET)) < 0)
2251 for (; bufp < end; bufp++) {
2272 if (sample_time < 0)
2287 sample_time =
FFMAX(sample_time, 0);