int complete;
MXFPartitionType type;
uint64_t previous_partition;
- uint64_t footer_partition;
int index_sid;
int body_sid;
} MXFPartition;
struct AVAES *aesc;
uint8_t *local_tags;
int local_tags_count;
+ uint64_t footer_partition;
} MXFContext;
enum MXFWrappingScheme {
if (length > 61444) /* worst case PAL 1920 samples 8 channels */
return -1;
- av_new_packet(pkt, length);
- avio_read(pb, pkt->data, length);
+ length = av_get_packet(pb, pkt, length);
+ if (length < 0)
+ return length;
data_ptr = pkt->data;
end_ptr = pkt->data + length;
buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
- for (; buf_ptr < end_ptr; ) {
+ for (; buf_ptr + st->codec->channels*4 < end_ptr; ) {
for (i = 0; i < st->codec->channels; i++) {
uint32_t sample = bytestream_get_le32(&buf_ptr);
if (st->codec->bits_per_coded_sample == 24)
}
buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M
}
- pkt->size = data_ptr - pkt->data;
+ av_shrink_packet(pkt, data_ptr - pkt->data);
return 0;
}
if (memcmp(tmpbuf, checkv, 16))
av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n");
size -= 32;
- av_get_packet(pb, pkt, size);
+ size = av_get_packet(pb, pkt, size);
+ if (size < 0)
+ return size;
+ else if (size < plaintext_size)
+ return AVERROR_INVALIDDATA;
size -= plaintext_size;
if (mxf->aesc)
av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size],
&pkt->data[plaintext_size], size >> 4, ivec, 1);
- pkt->size = orig_size;
+ av_shrink_packet(pkt, orig_size);
pkt->stream_index = index;
avio_skip(pb, end - avio_tell(pb));
return 0;
av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
return -1;
}
- } else
- av_get_packet(s->pb, pkt, klv.length);
+ } else {
+ int ret = av_get_packet(s->pb, pkt, klv.length);
+ if (ret < 0)
+ return ret;
+ }
pkt->stream_index = index;
pkt->pos = klv.offset;
return 0;
MXFContext *mxf = arg;
MXFPartition *partition;
UID op;
+ uint64_t footer_partition;
if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions))
return AVERROR(ENOMEM);
partition->complete = uid[14] > 2;
avio_skip(pb, 16);
partition->previous_partition = avio_rb64(pb);
- partition->footer_partition = avio_rb64(pb);
+ footer_partition = avio_rb64(pb);
avio_skip(pb, 16);
partition->index_sid = avio_rb32(pb);
avio_skip(pb, 8);
partition->body_sid = avio_rb32(pb);
avio_read(pb, op, sizeof(UID));
+ /* some files don'thave FooterPartition set in every partition */
+ if (footer_partition) {
+ if (mxf->footer_partition && mxf->footer_partition != footer_partition) {
+ av_log(mxf->fc, AV_LOG_ERROR, "inconsistent FooterPartition value: %li != %li\n",
+ mxf->footer_partition, footer_partition);
+ } else {
+ mxf->footer_partition = footer_partition;
+ }
+ }
+
av_dlog(mxf->fc, "PartitionPack: PreviousPartition = 0x%lx, "
"FooterPartition = 0x%lx, IndexSID = %i, BodySID = %i\n",
- partition->previous_partition, partition->footer_partition,
+ partition->previous_partition, footer_partition,
partition->index_sid, partition->body_sid);
if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;
/* TODO: implement CODEC_ID_RAWAUDIO */
if (st->codec->codec_id == CODEC_ID_PCM_S16LE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24LE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32LE;
} else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {
- if (descriptor->bits_per_sample == 24)
+ if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)
st->codec->codec_id = CODEC_ID_PCM_S24BE;
else if (descriptor->bits_per_sample == 32)
st->codec->codec_id = CODEC_ID_PCM_S32BE;
int res;
if (klv.key[5] == 0x53) {
res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type);
- } else
+ } else {
+ uint64_t next = avio_tell(s->pb) + klv.length;
res = metadata->read(mxf, s->pb, 0, 0, klv.key);
+ avio_seek(s->pb, next, SEEK_SET);
+ }
if (res < 0) {
av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
return -1;
if (sample_time < 0)
sample_time = 0;
seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
- avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET);
+ if (avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET) < 0)
+ return -1;
av_update_cur_dts(s, st, sample_time);
return 0;
}