241 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
242 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
243 static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 };
244 static const uint8_t mxf_system_item_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 };
247 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 };
248 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
249 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
250 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 };
251 static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 };
253 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
259 int bytes_num = size & 0x7f;
265 size = size << 8 |
avio_r8(pb);
277 else if (b != key[i])
291 return klv->
length == -1 ? -1 : 0;
311 const uint8_t *buf_ptr, *end_ptr;
320 data_ptr = pkt->
data;
321 end_ptr = pkt->
data + length;
322 buf_ptr = pkt->
data + 4;
325 uint32_t
sample = bytestream_get_le32(&buf_ptr);
327 bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff);
329 bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff);
339 static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b};
345 uint64_t plaintext_size;
372 if (orig_size < plaintext_size)
376 if (size < 32 || size - 32 < orig_size)
382 if (memcmp(tmpbuf, checkv, 16))
388 else if (size < plaintext_size)
390 size -= plaintext_size;
393 &pkt->
data[plaintext_size], size >> 4, ivec, 1);
406 if (item_len != 18) {
410 if (item_num > 65536 || item_num < 0)
426 uint64_t footer_partition;
427 uint32_t nb_essence_containers;
448 memset(partition, 0,
sizeof(*partition));
486 "PreviousPartition equal to ThisPartition %"PRIx64
"\n",
499 "Overriding PreviousPartition with %"PRIx64
"\n",
504 if (footer_partition) {
507 "inconsistent FooterPartition value: %"PRIu64
" != %"PRIu64
"\n",
515 "PartitionPack: ThisPartition = 0x%"PRIX64
516 ", PreviousPartition = 0x%"PRIX64
", "
517 "FooterPartition = 0x%"PRIX64
", IndexSID = %i, BodySID = %i\n",
526 "PreviousPartition points to this partition or forward\n");
530 if (op[12] == 1 && op[13] == 1) mxf->
op =
OP1a;
531 else if (op[12] == 1 && op[13] == 2) mxf->
op =
OP1b;
532 else if (op[12] == 1 && op[13] == 3) mxf->
op =
OP1c;
533 else if (op[12] == 2 && op[13] == 1) mxf->
op =
OP2a;
534 else if (op[12] == 2 && op[13] == 2) mxf->
op =
OP2b;
535 else if (op[12] == 2 && op[13] == 3) mxf->
op =
OP2c;
536 else if (op[12] == 3 && op[13] == 1) mxf->
op =
OP3a;
537 else if (op[12] == 3 && op[13] == 2) mxf->
op =
OP3b;
538 else if (op[12] == 3 && op[13] == 3) mxf->
op =
OP3c;
539 else if (op[12] == 64&& op[13] == 1) mxf->
op =
OPSonyOpt;
540 else if (op[12] == 0x10) {
545 if (nb_essence_containers != 1) {
551 "\"OPAtom\" with %"PRIu32
" ECs - assuming %s\n",
552 nb_essence_containers,
553 op ==
OP1a ?
"OP1a" :
"OPAtom");
559 av_log(mxf->
fc,
AV_LOG_ERROR,
"unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]);
648 if (package->tracks_count >= UINT_MAX /
sizeof(
UID))
650 package->tracks_refs =
av_malloc(package->tracks_count *
sizeof(
UID));
651 if (!package->tracks_refs)
714 if (package->tracks_count >= UINT_MAX /
sizeof(
UID))
716 package->tracks_refs =
av_malloc(package->tracks_count *
sizeof(
UID));
717 if (!package->tracks_refs)
728 avio_read(pb, package->descriptor_ref, 16);
816 int code, value, ofs = 0;
825 layout[ofs++] = code;
826 layout[ofs++] = value;
921 for (i = 0; i <
len; i++) {
922 if (i != 7 && key[i] != uid[i])
930 while (uls->
uid[0]) {
955 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14,
AV_CODEC_ID_MPEG2VIDEO },
956 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14,
AV_CODEC_ID_DVVIDEO },
957 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14,
AV_CODEC_ID_RAWVIDEO },
958 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
963 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x00,0x00 }, 14,
AV_CODEC_ID_MPEG2VIDEO },
964 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
969 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,
AV_CODEC_ID_H264 },
970 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,
AV_CODEC_ID_JPEG2000 },
971 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
976 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14,
AV_CODEC_ID_PCM_S16LE },
977 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14,
AV_CODEC_ID_MP2 },
978 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14,
AV_CODEC_ID_PCM_S16LE },
979 { { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0xff,0x4b,0x46,0x41,0x41,0x00,0x0d,0x4d,0x4F }, 14,
AV_CODEC_ID_PCM_S16LE },
980 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14,
AV_CODEC_ID_AAC },
981 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0,
AV_CODEC_ID_NONE },
985 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16, 0 },
986 { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x09,0x0d,0x01,0x03,0x01,0x02,0x0e,0x00,0x00 }, 16,
AV_CODEC_ID_NONE },
990 "vbi_vanc_smpte_436M",
995 int i, j, nb_segments = 0;
997 int last_body_sid = -1, last_index_sid = -1, last_index_start = -1;
1007 *sorted_segments =
av_mallocz(nb_segments *
sizeof(**sorted_segments));
1008 unsorted_segments =
av_mallocz(nb_segments *
sizeof(*unsorted_segments));
1009 if (!*sorted_segments || !unsorted_segments) {
1019 *nb_sorted_segments = 0;
1022 for (i = 0; i < nb_segments; i++) {
1023 int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
1024 uint64_t best_index_duration = 0;
1026 for (j = 0; j < nb_segments; j++) {
1048 (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best];
1049 last_body_sid = best_body_sid;
1050 last_index_sid = best_index_sid;
1051 last_index_start = best_index_start;
1065 int64_t offset_in = offset;
1082 "failed to find absolute offset of %"PRIX64
" in BodySID %i - partial file?\n",
1083 offset_in, body_sid);
1115 int64_t offset_temp = 0;
1139 av_log(mxf->
fc,
AV_LOG_ERROR,
"IndexSID %i segment at %"PRId64
" missing EditUnitByteCount and IndexEntryArray\n",
1145 *edit_unit_out = edit_unit;
1163 int8_t max_temporal_offset = -128;
1195 for (x = 0; x < index_table->
nb_ptses; x++)
1227 int index_delta = 1;
1236 for (j = 0; j < n; j += index_delta, x++) {
1238 int index = x + offset;
1242 "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64
"?\n",
1250 if (index < 0 || index >= index_table->
nb_ptses) {
1252 "index entry %i + TemporalOffset %i = %i, which is out of bounds\n",
1258 max_temporal_offset =
FFMAX(max_temporal_offset, offset);
1262 index_table->
first_dts = -max_temporal_offset;
1273 int i, j, k, ret, nb_sorted_segments;
1277 nb_sorted_segments <= 0) {
1283 for (i = 0; i < nb_sorted_segments; i++) {
1284 if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid)
1286 else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) {
1289 goto finish_decoding_index;
1298 goto finish_decoding_index;
1302 for (i = j = 0; i < nb_sorted_segments; i++) {
1303 if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) {
1319 " pointer array\n");
1321 goto finish_decoding_index;
1324 if (sorted_segments[i]->index_start_position)
1325 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i starts at EditUnit %"PRId64
" - seeking may not work as expected\n",
1333 goto finish_decoding_index;
1341 av_log(mxf->
fc,
AV_LOG_WARNING,
"IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n",
1358 finish_decoding_index:
1381 if (material_package)
break;
1383 if (!material_package) {
1395 UID *essence_container_ul =
NULL;
1423 source_package = temp_package;
1427 if (!source_package) {
1428 av_dlog(mxf->
fc,
"material track %d: no corresponding source package found\n", material_track->
track_id);
1438 source_track = temp_track;
1442 if (!source_track) {
1447 if (!source_track || !component)
1478 "Invalid edit rate (%d/%d) found on stream #%d, "
1479 "defaulting to 25/1\n",
1500 if (!sub_descriptor) {
1505 descriptor = sub_descriptor;
1526 essence_container_ul = &((
MXFCryptoContext *)metadata)->source_container_ul;
1538 container_ul =
mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul);
1548 "SegmentedFrame layout isn't currently supported\n");
1556 "OneField frame layout isn't currently supported\n");
1573 "Field dominance %d support",
1582 "Unknown frame layout type: %d\n",
1604 char material_origin[3];
1605 snprintf(material_origin,
sizeof(material_origin),
"%d", material_track->
sequence->
origin);
1609 char source_origin[3];
1610 snprintf(source_origin,
sizeof(source_origin),
"%d", source_track->
sequence->
origin);
1614 container_ul =
mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
1625 "found for stream #%d, time base forced to 1/48000\n",
1653 essence_container_ul)->
id;
1654 if (codec_id >= 0 &&
1657 mxf_data_essence_descriptor[codec_id], 0);
1690 buf_size = size + size / 2 + 1;
1710 for (i = 0; i <
sizeof(
UID); i++) {
1711 snprintf(p, 2 + 1,
"%.2x", uid[i]);
1713 if (i == 3 || i == 5 || i == 7 || i == 9) {
1714 snprintf(p, 1 + 1,
"-");
1723 struct tm time = { 0 };
1724 time.tm_year = (timestamp >> 48) - 1900;
1725 time.tm_mon = (timestamp >> 40 & 0xFF) - 1;
1726 time.tm_mday = (timestamp >> 32 & 0xFF);
1727 time.tm_hour = (timestamp >> 24 & 0xFF);
1728 time.tm_min = (timestamp >> 16 & 0xFF);
1729 time.tm_sec = (timestamp >> 8 & 0xFF);
1734 time.tm_mon = av_clip(time.tm_mon, 0, 11);
1735 time.tm_mday = av_clip(time.tm_mday, 1, 31);
1736 time.tm_hour = av_clip(time.tm_hour, 0, 23);
1737 time.tm_min = av_clip(time.tm_min, 0, 59);
1738 time.tm_sec = av_clip(time.tm_sec, 0, 59);
1743 strftime(*str, 32,
"%Y-%m-%d %H:%M:%S", &time);
1748 #define SET_STR_METADATA(pb, name, str) do { \
1749 if ((ret = mxf_read_utf16_string(pb, size, &str)) < 0) \
1751 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
1754 #define SET_UID_METADATA(pb, name, var, str) do { \
1755 avio_read(pb, var, 16); \
1756 if ((ret = mxf_uid_to_str(var, &str)) < 0) \
1758 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
1761 #define SET_TS_METADATA(pb, name, var, str) do { \
1762 var = avio_rb64(pb); \
1763 if ((ret = mxf_timestamp_to_str(var, &str)) < 0) \
1765 av_dict_set(&s->metadata, name, str, AV_DICT_DONT_STRDUP_VAL); \
1806 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 },
mxf_read_primer_pack },
1808 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 },
mxf_read_partition_pack },
1809 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 },
mxf_read_partition_pack },
1810 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 },
mxf_read_partition_pack },
1811 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 },
mxf_read_partition_pack },
1812 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 },
mxf_read_partition_pack },
1813 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 },
mxf_read_partition_pack },
1814 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 },
mxf_read_partition_pack },
1815 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 },
mxf_read_partition_pack },
1816 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 },
mxf_read_partition_pack },
1817 { { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 },
mxf_read_partition_pack },
1818 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x30,0x00 },
mxf_read_identification_metadata },
1819 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 },
mxf_read_content_storage, 0,
AnyType },
1820 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 },
mxf_read_source_package,
sizeof(
MXFPackage),
SourcePackage },
1821 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 },
mxf_read_material_package,
sizeof(
MXFPackage),
MaterialPackage },
1822 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 },
mxf_read_sequence,
sizeof(
MXFSequence),
Sequence },
1823 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 },
mxf_read_source_clip,
sizeof(
MXFStructuralComponent),
SourceClip },
1824 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
MultipleDescriptor },
1825 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1826 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1827 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1828 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1829 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1830 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1831 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1832 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5c,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1833 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x5e,0x00 },
mxf_read_generic_descriptor,
sizeof(
MXFDescriptor),
Descriptor },
1834 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
1835 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 },
mxf_read_track,
sizeof(
MXFTrack),
Track },
1836 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 },
mxf_read_cryptographic_context,
sizeof(
MXFCryptoContext),
CryptoContext },
1837 { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 },
mxf_read_index_table_segment,
sizeof(
MXFIndexTableSegment),
IndexTableSegment },
1838 { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
NULL, 0,
AnyType },
1856 av_dlog(mxf->
fc,
"local tag %#04x size %d\n", tag, size);
1865 if (local_tag == tag) {
1867 av_dlog(mxf->
fc,
"local tag %#04x\n", local_tag);
1872 if (ctx_size && tag == 0x3C0A)
1874 else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0)
1884 "local tag %#04x extends past end of local set @ %#"PRIx64
"\n",
1890 if (ctx_size) ctx->
type = type;
1910 av_dlog(mxf->
fc,
"seeking to previous partition\n");
1931 av_dlog(mxf->
fc,
"no last partition\n");
1935 av_dlog(mxf->
fc,
"seeking to last partition\n");
1948 "failed to seek to last partition @ 0x%" PRIx64
1949 " (%"PRId64
") - partial file?\n",
1950 mxf->
run_in + offset, ret);
1998 "partition %i: bad ThisPartition = %"PRIX64
"\n",
2008 int64_t ret = (position / kag_size) * kag_size;
2009 return ret == position ? ret : ret + kag_size;
2025 int64_t op1a_essence_offset =
2093 if (length <= 32 || length >=
FFMIN(file_size, INT_MAX))
2098 klv.
length != length - 20)
2112 int64_t essence_offset = 0;
2149 "found essence prior to first PartitionPack\n");
2157 if (!essence_offset)
2158 essence_offset = klv.
offset;
2174 for (metadata = mxf_metadata_read_table; metadata->
read; metadata++) {
2177 if (klv.
key[5] == 0x53) {
2202 if (!metadata->
read)
2206 if (!essence_offset) {
2224 av_log(mxf->
fc,
AV_LOG_INFO,
"got %i index tables - only the first one (IndexSID %i) will be used\n",
2242 int64_t last_ofs = -1, next_ofs = -1;
2254 NULL, &next_ofs, 0) < 0)
2257 if (next_ofs <= last_ofs) {
2261 "next_ofs didn't change. not deriving packet timestamps\n");
2265 if (next_ofs > current_offset)
2268 last_ofs = next_ofs;
2281 uint64_t *sample_count)
2283 int i, total = 0, size = 0;
2290 if ((sample_rate.
num / sample_rate.
den) == 48000)
2293 int remainder = (sample_rate.
num * time_base.
num) %
2294 (time_base.
den * sample_rate.
den);
2296 av_mul_q(sample_rate, time_base)));
2299 "seeking detected on stream #%d with time base (%d/%d) and "
2300 "sample rate (%d/%d), audio pts won't be accurate.\n",
2301 stream_index, time_base.
num, time_base.
den,
2302 sample_rate.
num, sample_rate.
den);
2328 if (!bits_per_sample)
2362 int64_t next_ofs, next_klv;
2369 "error getting stream index %"PRIu32
"\n",
2383 if (next_ofs >= 0 && next_klv > next_ofs) {
2388 "OPAtom misinterpreted as OP1a?"
2389 "KLV for edit unit %i extending into "
2396 if (klv.
key[12] == 0x06 && klv.
key[13] == 0x01 && klv.
key[14] == 0x10) {
2449 int64_t ret64, pos, next_pos;
2478 if ((size = next_pos - pos) <= 0) {
2483 if ((ret64 =
avio_seek(s->
pb, pos, SEEK_SET)) < 0)
2568 for (; bufp < end; bufp++) {
2595 if (sample_time < 0)
2610 sample_time =
FFMAX(sample_time, 0);
2634 uint64_t current_sample_count = 0;
static const uint8_t mxf_crypto_source_container_ul[]
static void mxf_compute_essence_containers(MXFContext *mxf)
Figure out the proper offset and length of the essence container in each partition.
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static int mxf_parse_structural_metadata(MXFContext *mxf)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
int64_t avio_size(AVIOContext *s)
Get the filesize.
unsigned int component_depth
KLVPacket current_klv_data
static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static const MXFMetadataReadTableEntry mxf_metadata_read_table[]
#define PRINT_KEY(pc, s, x)
static int klv_read_packet(KLVPacket *klv, AVIOContext *pb)
UID * structural_components_refs
#define AV_LOG_WARNING
Something somehow does not look correct.
static int mxf_seek_to_previous_partition(MXFContext *mxf)
Seeks to the previous partition, if possible.
int64_t pos
byte position in stream, -1 if unknown
static int mxf_probe(AVProbeData *p)
void av_shrink_packet(AVPacket *pkt, int size)
Reduce packet size, correctly zeroing padding.
static void mxf_read_random_index_pack(AVFormatContext *s)
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
int index
stream index in AVFormatContext
#define SET_TS_METADATA(pb, name, var, str)
uint64_t footer_partition
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
enum MXFMetadataSetType type
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
static int mxf_uid_to_str(UID uid, char **str)
static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length)
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define FF_ARRAY_ELEMS(a)
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
unsigned int avio_rb16(AVIOContext *s)
static int mxf_read_header(AVFormatContext *s)
enum MXFMetadataSetType type
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
static int mxf_parse_handle_partition_or_eof(MXFContext *mxf)
Called when the next partition or EOF is encountered.
static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type)
static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
static int is_pcm(enum AVCodecID codec_id)
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
const MXFSamplesPerFrame * ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base)
Opaque data information usually continuous.
static const uint8_t mxf_avid_essence_element_key[]
unsigned int avio_rb32(AVIOContext *s)
AVRational index_edit_rate
enum AVStreamParseType need_parsing
int id
Format-specific stream ID.
static int mxf_read_close(AVFormatContext *s)
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
AVStream ** streams
A list of all streams in the file.
static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out)
Computes the absolute file offset of the given essence container offset.
static void compute_partition_essence_offset(AVFormatContext *s, MXFContext *mxf, KLVPacket *klv)
static const uint8_t mxf_klv_key[]
int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static double av_q2d(AVRational a)
Convert rational to double.
static int mxf_compute_index_tables(MXFContext *mxf)
Sorts and collects index table segments into index tables.
MXFIndexTableSegment ** segments
const MXFCodecUL ff_mxf_codec_uls[]
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
static const uint8_t mxf_sony_mpeg4_extradata[]
#define AVERROR_EOF
End of file.
static av_cold int read_close(AVFormatContext *ctx)
#define AV_LOG_VERBOSE
Detailed information.
uint64_t avio_rb64(AVIOContext *s)
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
static const MXFCodecUL mxf_intra_only_essence_container_uls[]
unsigned int vert_subsampling
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
static const uint8_t mxf_random_index_pack_key[]
static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments)
static int mxf_timestamp_to_str(uint64_t timestamp, char **str)
int64_t original_duration
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define SET_UID_METADATA(pb, name, var, str)
static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
AVCodecID
Identify the syntax and semantics of the bitstream.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int last_forward_partition
int av_get_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor)
int8_t * temporal_offset_entries
static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, int64_t *edit_unit_out, int64_t *offset_out, int nag)
MXFDescriptor * descriptor
uint64_t index_start_position
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)
static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[]
static const MXFCodecUL mxf_sound_essence_container_uls[]
void av_log(void *avcl, int level, const char *fmt,...)
static int mxf_parse_handle_essence(MXFContext *mxf)
Called when essence is encountered.
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
static int64_t round_to_kag(int64_t position, int kag_size)
static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static int mxf_match_uid(const UID key, const UID uid, int len)
int avio_r8(AVIOContext *s)
AVCodecContext * codec
Codec context associated with this stream.
int buf_size
Size of buf except extra allocated bytes.
int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt)
const MXFCodecUL ff_mxf_pixel_format_uls[]
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
static const MXFCodecUL * mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid)
MXFPartition * partitions
static const uint8_t mxf_essence_element_key[]
static void * mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type)
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
static int mxf_read_utf16_string(AVIOContext *pb, int size, char **str)
unsigned int horiz_subsampling
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
static const uint8_t mxf_encrypted_triplet_key[]
enum AVPixelFormat pix_fmt
int64_t essence_offset
absolute offset of essence
int width
picture width / height.
static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
int edit_units_per_packet
how many edit units to read at a time (PCM, OPAtom)
int64_t last_forward_tell
static av_always_inline int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
static const uint8_t mxf_header_partition_pack_key[]
static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv)
static int mxf_read_identification_metadata(void *arg, AVIOContext *pb, int tag, int size, UID _uid, int64_t klv_offset)
static const char * mxf_data_essence_descriptor[]
static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv)
enum AVPixelFormat pix_fmt
static void mxf_handle_small_eubc(AVFormatContext *s)
Deal with the case where for some audio atoms EditUnitByteCount is very small (2, 4...
const MXFCodecUL ff_mxf_data_definition_uls[]
SMPTE RP224 http://www.smpte-ra.org/mdd/index.html.
UID * sub_descriptors_refs
static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
preferred ID for MPEG-1/2 video decoding
static int read_header(FFV1Context *f)
#define AVERROR_PATCHWELCOME
Not yet implemented in Libav, patches welcome.
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
#define AV_LOG_INFO
Standard information.
enum AVMediaType codec_type
int sub_descriptors_count
int sample_rate
samples per second
AVIOContext * pb
I/O context.
static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static const uint8_t mxf_encrypted_essence_container[]
main external API structure.
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
static const MXFCodecUL mxf_data_essence_container_uls[]
rational number numerator/denominator
static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static const uint8_t mxf_system_item_key[]
unsigned partitions_count
static int mxf_is_intra_only(MXFDescriptor *d)
This structure contains the data a format has to probe a file.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
static int64_t klv_decode_ber_length(AVIOContext *pb)
int64_t duration
Decoding: duration of the stream, in stream time base.
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static const MXFCodecUL mxf_picture_essence_container_uls[]
int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen)
static int mxf_set_audio_pts(MXFContext *mxf, AVCodecContext *codec, AVPacket *pkt)
int64_t start_time
Decoding: pts of the first frame of the stream, in stream time base.
MXFMetadataReadFunc * read
AVInputFormat ff_mxf_demuxer
AVIndexEntry * fake_index
int structural_components_count
static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_table)
int eof_reached
true if eof reached
uint64_t * stream_offset_entries
int channels
number of audio channels
static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
void * priv_data
Format private data.
static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid)
Returns the end position of the essence container with given BodySID, or zero if unknown.
static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
#define SET_STR_METADATA(pb, name, str)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
static void * av_mallocz_array(size_t nmemb, size_t size)
static int64_t mxf_set_current_edit_unit(MXFContext *mxf, int64_t current_offset)
Sets mxf->current_edit_unit based on what offset we're currently at.
int bit_rate
Total stream bitrate in bit/s, 0 if not available.
MXFMetadataSet ** metadata_sets
static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
static int mxf_compute_sample_count(MXFContext *mxf, int stream_index, uint64_t *sample_count)
enum AVFieldOrder field_order
Field order.
int avio_feof(AVIOContext *s)
MXFIndexTable * index_tables
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
AVPixelFormat
Pixel format.
This structure stores compressed data.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
MXFPartition * current_partition
#define AV_NOPTS_VALUE
Undefined timestamp value.
uint64_t previous_partition
int64_t header_byte_count