|
|
@@ -213,6 +213,7 @@ typedef struct { |
|
|
|
struct AVAES *aesc; |
|
|
|
uint8_t *local_tags; |
|
|
|
int local_tags_count; |
|
|
|
uint64_t last_partition; |
|
|
|
uint64_t footer_partition; |
|
|
|
KLVPacket current_klv_data; |
|
|
|
int current_klv_index; |
|
|
@@ -254,6 +255,7 @@ static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x |
|
|
|
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 }; |
|
|
|
static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; |
|
|
|
static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; |
|
|
|
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 }; |
|
|
|
static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; |
|
|
|
|
|
|
|
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) |
|
|
@@ -1852,31 +1854,33 @@ static int mxf_parse_handle_essence(MXFContext *mxf) |
|
|
|
|
|
|
|
if (mxf->parsing_backward) { |
|
|
|
return mxf_seek_to_previous_partition(mxf); |
|
|
|
} else { |
|
|
|
if (!mxf->footer_partition) { |
|
|
|
av_dlog(mxf->fc, "no footer\n"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} else if (mxf->footer_partition || mxf->last_partition){ |
|
|
|
uint64_t offset; |
|
|
|
|
|
|
|
offset = mxf->footer_partition ? mxf->footer_partition : mxf->last_partition; |
|
|
|
|
|
|
|
av_dlog(mxf->fc, "seeking to footer\n"); |
|
|
|
av_dlog(mxf->fc, "seeking to last partition\n"); |
|
|
|
|
|
|
|
/* remember where we were so we don't end up seeking further back than this */ |
|
|
|
mxf->last_forward_tell = avio_tell(pb); |
|
|
|
|
|
|
|
if (!pb->seekable) { |
|
|
|
av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing footer\n"); |
|
|
|
av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing last partition\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/* seek to footer partition and parse backward */ |
|
|
|
if ((ret = avio_seek(pb, mxf->run_in + mxf->footer_partition, SEEK_SET)) < 0) { |
|
|
|
av_log(mxf->fc, AV_LOG_ERROR, "failed to seek to footer @ 0x%"PRIx64" (%"PRId64") - partial file?\n", |
|
|
|
mxf->run_in + mxf->footer_partition, ret); |
|
|
|
/* seek to last partition and parse backward */ |
|
|
|
if ((ret = avio_seek(pb, mxf->run_in + offset, SEEK_SET)) < 0) { |
|
|
|
av_log(mxf->fc, AV_LOG_ERROR, "failed to seek to last partition @ 0x%"PRIx64" (%"PRId64") - partial file?\n", |
|
|
|
mxf->run_in + offset, ret); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
mxf->current_partition = NULL; |
|
|
|
mxf->parsing_backward = 1; |
|
|
|
} else { |
|
|
|
av_dlog(mxf->fc, "can't find last partition\n"); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
return 1; |
|
|
@@ -1968,6 +1972,34 @@ static void mxf_handle_small_eubc(AVFormatContext *s) |
|
|
|
mxf->edit_units_per_packet = 1920; |
|
|
|
} |
|
|
|
|
|
|
|
static void mxf_read_random_index_pack(AVFormatContext *s) |
|
|
|
{ |
|
|
|
MXFContext *mxf = s->priv_data; |
|
|
|
uint32_t length; |
|
|
|
int64_t file_size; |
|
|
|
KLVPacket klv; |
|
|
|
|
|
|
|
if (!s->pb->seekable) |
|
|
|
return; |
|
|
|
|
|
|
|
file_size = avio_size(s->pb); |
|
|
|
avio_seek(s->pb, file_size - 4, SEEK_SET); |
|
|
|
length = avio_rb32(s->pb); |
|
|
|
if (length <= 32 || length >= FFMIN(file_size, INT_MAX)) |
|
|
|
goto end; |
|
|
|
avio_seek(s->pb, file_size - length, SEEK_SET); |
|
|
|
if (klv_read_packet(&klv, s->pb) < 0 || |
|
|
|
!IS_KLV_KEY(klv.key, mxf_random_index_pack_key) || |
|
|
|
klv.length != length - 20) |
|
|
|
goto end; |
|
|
|
|
|
|
|
avio_skip(s->pb, klv.length - 12); |
|
|
|
mxf->last_partition = avio_rb64(s->pb); |
|
|
|
|
|
|
|
end: |
|
|
|
avio_seek(s->pb, mxf->run_in, SEEK_SET); |
|
|
|
} |
|
|
|
|
|
|
|
static int mxf_read_header(AVFormatContext *s) |
|
|
|
{ |
|
|
|
MXFContext *mxf = s->priv_data; |
|
|
@@ -1986,6 +2018,8 @@ static int mxf_read_header(AVFormatContext *s) |
|
|
|
mxf->fc = s; |
|
|
|
mxf->run_in = avio_tell(s->pb); |
|
|
|
|
|
|
|
mxf_read_random_index_pack(s); |
|
|
|
|
|
|
|
while (!url_feof(s->pb)) { |
|
|
|
const MXFMetadataReadTableEntry *metadata; |
|
|
|
|
|
|
|