60 #define MXF_MAX_CHUNK_SIZE (32 << 20)
141 } MXFTimecodeComponent;
194 #define MXF_FIELD_DOMINANCE_DEFAULT 0
195 #define MXF_FIELD_DOMINANCE_FF 1
196 #define MXF_FIELD_DOMINANCE_FL 2
308 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
309 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
310 static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
311 static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x0a,0x0e,0x0f,0x03,0x01 };
312 static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 };
313 static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 };
316 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 };
317 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
318 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
319 static const uint8_t mxf_random_index_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x11,0x01,0x00 };
320 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
321 static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf };
322 static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 };
323 static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 };
324 static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 };
326 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
331 switch ((*ctx)->type) {
372 int bytes_num =
size & 0x7f;
380 if (
size > INT64_MAX)
392 else if (
b !=
key[
i])
411 if (pos > INT64_MAX -
length)
421 for (
i = 0;
i <
s->nb_streams;
i++) {
428 return s->nb_streams == 1 &&
s->streams[0]->priv_data ? 0 : -1;
457 int cdp_identifier, cdp_length, cdp_footer_id, ccdata_id, cc_count;
458 int line_num, sample_coding, sample_count;
459 int did, sdid, data_length;
474 length -= 6 + 8 + sample_count;
475 if (line_num != 9 && line_num != 11)
477 if (sample_coding == 7 || sample_coding == 8 || sample_coding == 9) {
489 if (did != 0x61 || sdid != 1) {
494 if (cdp_identifier != 0x9669) {
503 if (ccdata_id != 0x72) {
511 if (cdp_length - 9 - 4 < cc_count * 3) {
515 avio_skip(
s->pb, data_length - 9 - 4 - cc_count * 3);
517 if (cdp_footer_id != 0x74) {
532 const uint8_t *buf_ptr, *end_ptr;
550 uint32_t
sample = bytestream_get_le32(&buf_ptr);
552 bytestream_put_le24(&data_ptr, (
sample >> 4) & 0xffffff);
554 bytestream_put_le16(&data_ptr, (
sample >> 12) & 0xffff);
564 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
570 uint64_t plaintext_size;
576 if (!mxf->
aesc &&
s->key &&
s->keylen == 16) {
603 if (orig_size < plaintext_size)
607 if (
size < 32 ||
size - 32 < orig_size || (
int)orig_size != orig_size)
613 if (memcmp(tmpbuf, checkv, 16))
619 else if (
size < plaintext_size)
621 size -= plaintext_size;
637 if (item_len != 18) {
641 if (item_num > 65536 || item_num < 0) {
663 uint64_t footer_partition;
664 uint32_t nb_essence_containers;
686 memset(partition, 0,
sizeof(*partition));
728 av_dict_set(&
s->metadata,
"operational_pattern_ul", str, 0);
734 "PreviousPartition equal to ThisPartition %"PRIx64
"\n",
747 "Overriding PreviousPartition with %"PRIx64
"\n",
752 if (footer_partition) {
755 "inconsistent FooterPartition value: %"PRIu64
" != %"PRIu64
"\n",
763 "PartitionPack: ThisPartition = 0x%"PRIX64
764 ", PreviousPartition = 0x%"PRIX64
", "
765 "FooterPartition = 0x%"PRIX64
", IndexSID = %i, BodySID = %i\n",
775 "PreviousPartition points to this partition or forward\n");
779 if (
op[12] == 1 &&
op[13] == 1) mxf->
op =
OP1a;
780 else if (
op[12] == 1 &&
op[13] == 2) mxf->
op =
OP1b;
781 else if (
op[12] == 1 &&
op[13] == 3) mxf->
op =
OP1c;
782 else if (
op[12] == 2 &&
op[13] == 1) mxf->
op =
OP2a;
783 else if (
op[12] == 2 &&
op[13] == 2) mxf->
op =
OP2b;
784 else if (
op[12] == 2 &&
op[13] == 3) mxf->
op =
OP2c;
785 else if (
op[12] == 3 &&
op[13] == 1) mxf->
op =
OP3a;
786 else if (
op[12] == 3 &&
op[13] == 2) mxf->
op =
OP3b;
787 else if (
op[12] == 3 &&
op[13] == 3) mxf->
op =
OP3c;
789 else if (
op[12] == 0x10) {
794 if (nb_essence_containers != 1) {
800 "\"OPAtom\" with %"PRIu32
" ECs - assuming %s\n",
801 nb_essence_containers,
802 op ==
OP1a ?
"OP1a" :
"OPAtom");
868 if (size < 0 || size > INT_MAX/2)
890 #define READ_STR16(type, big_endian) \
891 static int mxf_read_utf16 ## type ##_string(AVIOContext *pb, int size, char** str) \
893 return mxf_read_utf16_string(pb, size, str, big_endian); \
939 MXFTimecodeComponent *mxf_timecode =
arg;
942 mxf_timecode->start_frame =
avio_rb64(pb);
948 mxf_timecode->drop_frame =
avio_r8(pb);
976 mxf_read_utf16be_string(pb,
size, &track->
name);
1029 &package->tracks_count);
1033 avio_read(pb, package->package_uid, 16);
1036 avio_read(pb, package->descriptor_ref, 16);
1039 return mxf_read_utf16be_string(pb,
size, &package->name);
1042 &package->comment_count);
1070 if (
segment->temporal_offset_entries)
1087 for (
i = 0;
i <
segment->nb_index_entries;
i++) {
1122 segment->index_edit_rate.den);
1151 }
while (
code != 0);
1159 int entry_count, entry_size;
1192 if (entry_size == 4) {
1193 if (entry_count > 0)
1197 if (entry_count > 1)
1271 return mxf_read_utf16le_string(pb,
size - 17, &tagged_value->
value);
1273 return mxf_read_utf16be_string(pb,
size - 17, &tagged_value->
value);
1283 return mxf_read_utf16be_string(pb,
size, &tagged_value->
name);
1297 for (
i = 0;
i <
len;
i++) {
1306 while (uls->
uid[0]) {
1331 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0c,0x01,0x00 }, 14,
AV_CODEC_ID_JPEG2000,
NULL, 14 },
1332 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x10,0x60,0x01 }, 14,
AV_CODEC_ID_H264,
NULL, 15 },
1333 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, 14,
AV_CODEC_ID_DNXHD,
NULL, 14 },
1334 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x12,0x01,0x00 }, 14,
AV_CODEC_ID_VC1,
NULL, 14 },
1335 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x14,0x01,0x00 }, 14,
AV_CODEC_ID_TIFF,
NULL, 14 },
1336 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x15,0x01,0x00 }, 14,
AV_CODEC_ID_DIRAC,
NULL, 14 },
1337 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1b,0x01,0x00 }, 14,
AV_CODEC_ID_CFHD,
NULL, 14 },
1338 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1c,0x01,0x00 }, 14,
AV_CODEC_ID_PRORES,
NULL, 14 },
1339 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14,
AV_CODEC_ID_MPEG2VIDEO,
NULL, 15 },
1340 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14,
AV_CODEC_ID_MPEG2VIDEO,
NULL, 15,
D10D11Wrap },
1341 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,
AV_CODEC_ID_DVVIDEO,
NULL, 15 },
1342 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14,
AV_CODEC_ID_RAWVIDEO,
NULL, 15,
RawVWrap },
1343 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15,
AV_CODEC_ID_HQ_HQA },
1344 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x02,0x01 }, 15,
AV_CODEC_ID_HQX },
1345 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x15,0x00,0x04,0x02,0x10,0x00,0x01 }, 16,
AV_CODEC_ID_HEVC,
NULL, 15 },
1346 { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4f }, 14,
AV_CODEC_ID_RAWVIDEO },
1347 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
1352 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x00,0x00 }, 14,
AV_CODEC_ID_MPEG2VIDEO },
1353 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
1358 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,
AV_CODEC_ID_H264 },
1359 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,
AV_CODEC_ID_JPEG2000 },
1360 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
1365 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 16, 1440 },
1366 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 16, 1440 },
1367 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 16, 1440 },
1368 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 16, 1440 },
1369 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 0 },
1374 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14,
AV_CODEC_ID_PCM_S16LE,
NULL, 14,
RawAWrap },
1375 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,
AV_CODEC_ID_MP2,
NULL, 15 },
1376 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14,
AV_CODEC_ID_PCM_S16LE,
NULL, 13 },
1377 { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4F }, 14,
AV_CODEC_ID_PCM_S16LE },
1378 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14,
AV_CODEC_ID_AAC },
1379 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
1383 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0d,0x00,0x00 }, 16,
AV_CODEC_ID_NONE,
"vbi_smpte_436M", 11 },
1384 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16,
AV_CODEC_ID_NONE,
"vbi_vanc_smpte_436M", 11 },
1385 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x13,0x01,0x01 }, 16,
AV_CODEC_ID_TTML },
1386 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
1402 val = (*essence_container_ul)[
codec_ul->wrapping_indicator_pos];
1403 switch (
codec_ul->wrapping_indicator_type) {
1408 if (
val == 0x03 ||
val == 0x04)
1425 int i, j, nb_segments = 0;
1427 int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
1437 if (!(unsorted_segments =
av_calloc(nb_segments,
sizeof(*unsorted_segments))) ||
1438 !(*sorted_segments =
av_calloc(nb_segments,
sizeof(**sorted_segments)))) {
1447 if (
s->edit_unit_byte_count ||
s->nb_index_entries)
1448 unsorted_segments[nb_segments++] =
s;
1450 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i segment at %"PRId64
" missing EditUnitByteCount and IndexEntryArray\n",
1451 s->index_sid,
s->index_start_position);
1461 *nb_sorted_segments = 0;
1464 for (
i = 0;
i < nb_segments;
i++) {
1465 int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
1466 uint64_t best_index_duration = 0;
1468 for (j = 0; j < nb_segments; j++) {
1476 s->body_sid > last_body_sid ||
1477 s->body_sid == last_body_sid &&
s->index_sid > last_index_sid ||
1478 s->body_sid == last_body_sid &&
s->index_sid == last_index_sid &&
s->index_start_position > last_index_start) &&
1480 s->body_sid < best_body_sid ||
1481 s->body_sid == best_body_sid &&
s->index_sid < best_index_sid ||
1482 s->body_sid == best_body_sid &&
s->index_sid == best_index_sid &&
s->index_start_position < best_index_start ||
1483 s->body_sid == best_body_sid &&
s->index_sid == best_index_sid &&
s->index_start_position == best_index_start &&
s->index_duration > best_index_duration)) {
1485 best_body_sid =
s->body_sid;
1486 best_index_sid =
s->index_sid;
1487 best_index_start =
s->index_start_position;
1488 best_index_duration =
s->index_duration;
1496 (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
1497 last_body_sid = best_body_sid;
1498 last_index_sid = best_index_sid;
1499 last_index_start = best_index_start;
1522 m0 = m = (
a +
b) >> 1;
1524 while (m < b && mxf->partitions[m].body_sid != body_sid)
1527 if (m < b && mxf->partitions[m].body_offset <=
offset)
1539 *partition_out = last_p;
1544 "failed to find absolute offset of %"PRIX64
" in BodySID %i - partial file?\n",
1574 int64_t offset_temp = 0;
1581 edit_unit =
FFMAX(edit_unit,
s->index_start_position);
1583 if (edit_unit < s->index_start_position +
s->index_duration) {
1584 int64_t
index = edit_unit -
s->index_start_position;
1586 if (
s->edit_unit_byte_count)
1587 offset_temp +=
s->edit_unit_byte_count *
index;
1589 if (
s->nb_index_entries == 2 *
s->index_duration + 1)
1592 if (index < 0 || index >=
s->nb_index_entries) {
1594 index_table->
index_sid,
s->index_start_position);
1598 offset_temp =
s->stream_offset_entries[
index];
1602 *edit_unit_out =
av_rescale_q(edit_unit, edit_rate,
s->index_edit_rate);
1607 offset_temp +=
s->edit_unit_byte_count *
s->index_duration;
1620 int8_t max_temporal_offset = -128;
1627 if (!
s->nb_index_entries) {
1632 if (
s->index_duration > INT_MAX - index_table->
nb_ptses) {
1638 index_table->
nb_ptses +=
s->index_duration;
1657 for (x = 0; x < index_table->
nb_ptses; x++)
1689 int index_delta = 1;
1690 int n =
s->nb_index_entries;
1692 if (
s->nb_index_entries == 2 *
s->index_duration + 1) {
1698 for (j = 0; j <
n; j += index_delta, x++) {
1699 int offset =
s->temporal_offset_entries[j] / index_delta;
1704 "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64
"?\n",
1705 s->nb_index_entries,
s->index_duration);
1711 if (index < 0 || index >= index_table->
nb_ptses) {
1713 "index entry %i + TemporalOffset %i = %i, which is out of bounds\n",
1720 max_temporal_offset =
FFMAX(max_temporal_offset,
offset);
1725 for (x = 0; x < index_table->
nb_ptses; x++) {
1732 index_table->
first_dts = -max_temporal_offset;
1743 int i, j, k,
ret, nb_sorted_segments;
1747 nb_sorted_segments <= 0) {
1753 for (
i = 0;
i < nb_sorted_segments;
i++) {
1754 if (
i == 0 || sorted_segments[
i-1]->index_sid != sorted_segments[
i]->index_sid)
1756 else if (sorted_segments[
i-1]->body_sid != sorted_segments[
i]->body_sid) {
1759 goto finish_decoding_index;
1768 goto finish_decoding_index;
1772 for (
i = j = 0;
i < nb_sorted_segments;
i++) {
1773 if (
i != 0 && sorted_segments[
i-1]->index_sid != sorted_segments[
i]->index_sid) {
1790 " pointer array\n");
1792 goto finish_decoding_index;
1795 if (sorted_segments[
i]->index_start_position)
1796 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i starts at EditUnit %"PRId64
" - seeking may not work as expected\n",
1804 goto finish_decoding_index;
1827 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n",
1844 finish_decoding_index:
1864 for (
i = 0;
i <
sizeof(
UID);
i++) {
1867 if (
i == 3 ||
i == 5 ||
i == 7 ||
i == 9) {
1884 for (
i = 0;
i <
sizeof(
UID);
i++) {
1889 for (
i = 0;
i <
sizeof(
UID);
i++) {
1925 switch (component->
type) {
1927 return (MXFTimecodeComponent*)component;
1943 package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], SourcePackage);
1947 if (!memcmp(package->package_ul, package_ul, 16) && !memcmp(package->package_uid, package_uid, 16))
1965 if (!sub_descriptor) {
1970 return sub_descriptor;
2013 switch (component->
type) {
2035 size = strlen(
tag->name) + 8 + 1;
2051 MXFTimecodeComponent *mxf_tc =
NULL;
2055 int64_t start_position;
2068 if (physical_package->
name && physical_package->
name[0])
2088 "Invalid edit rate (%d/%d) found on structural"
2089 " component #%d, defaulting to 25/1\n",
2163 if (material_package)
break;
2165 if (!material_package) {
2171 if (material_package->
name && material_package->
name[0])
2182 MXFTimecodeComponent *mxf_tc =
NULL;
2183 UID *essence_container_ul =
NULL;
2197 mxf_tc = (MXFTimecodeComponent*)component;
2214 mxf_tc = (MXFTimecodeComponent*)component;
2233 if (!source_package) {
2244 source_track = temp_track;
2248 if (!source_track) {
2267 if(source_track && component)
2270 if (!source_track || !component || !source_package) {
2314 "Invalid edit rate (%d/%d) found on stream #%d, "
2315 "defaulting to 25/1\n",
2347 essence_container_ul = &((
MXFCryptoContext *)metadata)->source_container_ul;
2363 for (k = 0; k < 16; k++) {
2366 if (!(k+1 & 19) || k == 5)
2372 if (source_package->
name && source_package->
name[0])
2374 if (material_track->
name && material_track->
name[0])
2422 "Field dominance %d support",
2436 "Field dominance %d support",
2501 "found for stream #%d, time base forced to 1/48000\n",
2536 if (container_ul->
desc)
2539 !strcmp(container_ul->
desc,
"vbi_vanc_smpte_436M")) {
2575 "with different wrapping\n",
i, j, track1->
body_sid);
2588 struct tm time = { 0 };
2590 time.tm_year = (timestamp >> 48) - 1900;
2591 time.tm_mon = (timestamp >> 40 & 0xFF) - 1;
2592 time.tm_mday = (timestamp >> 32 & 0xFF);
2593 time.tm_hour = (timestamp >> 24 & 0xFF);
2594 time.tm_min = (timestamp >> 16 & 0xFF);
2595 time.tm_sec = (timestamp >> 8 & 0xFF);
2596 msecs = (timestamp & 0xFF) * 4;
2599 time.tm_mon = av_clip(time.tm_mon, 0, 11);
2600 time.tm_mday = av_clip(time.tm_mday, 1, 31);
2601 time.tm_hour = av_clip(time.tm_hour, 0, 23);
2602 time.tm_min = av_clip(time.tm_min, 0, 59);
2603 time.tm_sec = av_clip(time.tm_sec, 0, 59);
2604 msecs = av_clip(msecs, 0, 999);
2606 return (int64_t)
av_timegm(&time) * 1000000 + msecs * 1000;
2609 #define SET_STR_METADATA(pb, name, str) do { \
2610 if ((ret = mxf_read_utf16be_string(pb, size, &str)) < 0) \
2612 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
2615 #define SET_UID_METADATA(pb, name, var, str) do { \
2616 avio_read(pb, var, 16); \
2617 if ((ret = mxf_uid_to_str(var, &str)) < 0) \
2619 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
2622 #define SET_TS_METADATA(pb, name, var, str) do { \
2623 var = avio_rb64(pb); \
2624 if (var && (ret = avpriv_dict_set_timestamp(&s->metadata, name, mxf_timestamp_to_int64(var))) < 0) \
2679 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 },
mxf_read_primer_pack },
2680 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 },
mxf_read_partition_pack },
2681 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 },
mxf_read_partition_pack },
2682 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 },
mxf_read_partition_pack },
2683 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 },
mxf_read_partition_pack },
2684 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 },
mxf_read_partition_pack },
2685 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 },
mxf_read_partition_pack },
2686 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 },
mxf_read_partition_pack },
2687 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 },
mxf_read_partition_pack },
2688 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 },
mxf_read_partition_pack },
2689 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 },
mxf_read_partition_pack },
2690 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x2f,0x00 },
mxf_read_preface_metadata },
2691 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x30,0x00 },
mxf_read_identification_metadata },
2692 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 },
mxf_read_content_storage, 0,
AnyType },
2693 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 },
mxf_read_package,
sizeof(
MXFPackage),
SourcePackage },
2694 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 },
mxf_read_package,
sizeof(
MXFPackage),
MaterialPackage },
2695 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0f,0x00 },
mxf_read_sequence,
sizeof(
MXFSequence),
Sequence },
2696 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x05,0x00 },
mxf_read_essence_group,
sizeof(
MXFEssenceGroup),
EssenceGroup},
2697 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 },
mxf_read_source_clip,
sizeof(
MXFStructuralComponent),
SourceClip },
2698 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3f,0x00 },
mxf_read_tagged_value,
sizeof(
MXFTaggedValue),
TaggedValue },
2699 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
MultipleDescriptor },
2700 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2701 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2702 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2703 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2704 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2705 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2706 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5b,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2707 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2708 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2709 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x64,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
2710 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
2711 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
2712 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 },
mxf_read_timecode_component,
sizeof(MXFTimecodeComponent),
TimecodeComponent },
2713 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0c,0x00 },
mxf_read_pulldown_component,
sizeof(
MXFPulldownComponent),
PulldownComponent },
2714 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 },
mxf_read_cryptographic_context,
sizeof(
MXFCryptoContext),
CryptoContext },
2715 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 },
mxf_read_index_table_segment,
sizeof(
MXFIndexTableSegment),
IndexTableSegment },
2716 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x23,0x00 },
mxf_read_essence_container_data,
sizeof(
MXFEssenceContainerData),
EssenceContainerData },
2717 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
NULL, 0,
AnyType },
2749 if (next < 0 || next > INT64_MAX -
size)
2762 if (local_tag ==
tag) {
2769 if (ctx_size &&
tag == 0x3C0A) {
2786 "local tag %#04x extends past end of local set @ %#"PRIx64
"\n",
2792 if (ctx_size)
ctx->type =
type;
2807 key[13] >= 2 &&
key[13] <= 4;
2819 if (klv.
key[5] == 0x53) {
2849 int64_t current_partition_ofs;
2880 if (klv.
offset >= current_partition_ofs) {
2882 PRIx64
" indirectly points to itself\n", current_partition_ofs);
2922 "failed to seek to FooterPartition @ 0x%" PRIx64
2923 " (%"PRId64
") - partial file?\n",
2946 for (
int i = 0;
i <
s->nb_streams;
i++) {
2982 if (x < mxf->partitions_count - 1)
2989 "partition %i: bad ThisPartition = %"PRIX64
"\n",
3052 int essence_partition_count = 0;
3053 int edit_unit_byte_count = 0;
3075 essence_partition_count++;
3079 if (essence_partition_count != 1)
3088 if (edit_unit_byte_count <= 0)
3108 segment->edit_unit_byte_count = edit_unit_byte_count;
3109 segment->index_start_position = 0;
3121 int64_t file_size, max_rip_length, min_rip_length;
3137 max_rip_length = ((file_size - mxf->
run_in) / 105) * 12 + 28;
3138 max_rip_length =
FFMIN(max_rip_length, INT_MAX);
3141 min_rip_length = 16+1+24+4;
3147 if (length < min_rip_length || length > max_rip_length)
3175 int64_t essence_offset = 0;
3218 if (!essence_offset)
3219 essence_offset = klv.
offset;
3241 if (!metadata->
read) {
3248 if (!essence_offset) {
3260 for (
int i = 0;
i <
s->nb_streams;
i++)
3268 av_log(mxf->
fc,
AV_LOG_INFO,
"got %i index tables - only the first one (IndexSID %i) will be used\n",
3278 for (
int i = 0;
i <
s->nb_streams;
i++)
3304 if (
offset < current_offset)
3318 int i, total = 0,
size = 0;
3323 int64_t sample_count;
3336 "seeking detected on stream #%d with time base (%d/%d) and "
3337 "sample rate (%d/%d), audio pts won't be accurate.\n",
3350 sample_count = (edit_unit /
size) * (uint64_t)total;
3351 for (
i = 0;
i < edit_unit %
size;
i++) {
3355 return sample_count;
3365 int64_t next_ofs = -1;
3368 int64_t new_edit_unit;
3381 if (next_ofs > current_offset)
3396 av_log(mxf->
fc,
AV_LOG_WARNING,
"edit unit sync lost on stream %d, jumping from %"PRId64
" to %"PRId64
"\n", st->
index, edit_unit, new_edit_unit);
3408 if (!bits_per_sample)
3414 || bits_per_sample <= 0
3415 || par->
channels * (int64_t)bits_per_sample < 8)
3460 int64_t max_data_size;
3468 max_data_size = klv.
length;
3482 max_data_size = klv.
next_klv - pos;
3495 "error getting stream index %"PRIu32
"\n",
3511 if (next_ofs <= 0) {
3519 if ((
size = next_ofs - pos) <= 0) {
3525 if (
size > max_data_size)
3526 size = max_data_size;
3536 if (klv.
key[12] == 0x06 && klv.
key[13] == 0x01 && klv.
key[14] == 0x10) {
3588 for (
i = 0;
i <
s->nb_streams;
i++)
3589 s->streams[
i]->priv_data =
NULL;
3623 for (; bufp <
end;) {
3624 if (!((bufp[13] - 1) & 0xF2)){
3642 AVStream *st =
s->streams[stream_index];
3661 if (sample_time < 0)
3665 seekpos =
avio_seek(
s->pb, (
s->bit_rate * seconds) >> 3, SEEK_SET);
3677 for (
i = 0;
i <
s->nb_streams;
i++) {
3678 MXFTrack *new_source_track =
s->streams[
i]->priv_data;
3681 source_track = new_source_track;
3686 if (
i ==
s->nb_streams)
3692 sample_time =
FFMAX(sample_time, 0);
3701 sample_time < t->ptses[0] &&
3703 sample_time = t->
ptses[0];
3709 sample_time += t->
offsets[sample_time];
3725 if (seekpos < klv.next_klv - klv.length || seekpos >= klv.
next_klv) {
3737 for (
i = 0;
i <
s->nb_streams;
i++) {
3741 int64_t track_edit_unit = sample_time;
3751 {
"eia608_extract",
"extract eia 608 captions from s436m track",