From 085249a37951046ef3e0556e4ccac2390afd9764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Mon, 19 Dec 2011 11:00:14 +0100 Subject: [PATCH 1/5] mxfdec: Ignore the last entry in Avid's index table segments The last entry is the total size of the essence container. Previously a TemporalOffset error would be logged, even though segments like these are expected. --- libavformat/mxfdec.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 3a0962429c..8a5c3c96ef 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1072,11 +1072,16 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta for (i = x = 0; i < index_table->nb_segments; i++) { MXFIndexTableSegment *s = index_table->segments[i]; int index_delta = 1; + int n = s->nb_index_entries; - if (s->nb_index_entries == 2 * s->index_duration + 1) + if (s->nb_index_entries == 2 * s->index_duration + 1) { index_delta = 2; /* Avid index */ - for (j = 0; j < s->nb_index_entries; j += index_delta, x++) { + /* ignore the last entry - it's the size of the essence container */ + n--; + } + + for (j = 0; j < n; j += index_delta, x++) { int offset = s->temporal_offset_entries[j] / index_delta; int index = x + offset; From 6e9081f4d87b4ebcd3355ebd560307c59d2104c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Tue, 20 Dec 2011 09:57:07 +0100 Subject: [PATCH 2/5] mxfdec: Make sure x < index_table->nb_ptses Without this the demuxer will SIGSEGV on files with IndexEntryCount < IndexDuration --- libavformat/mxfdec.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 8a5c3c96ef..ea1129388e 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1085,6 +1085,12 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta int offset = s->temporal_offset_entries[j] / index_delta; int index = x + offset; + if (x >= index_table->nb_ptses) { + av_log(mxf->fc, AV_LOG_ERROR, "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64"?\n", + s->nb_index_entries, s->index_duration); + break; + } + index_table->fake_index[x].timestamp = x; index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0; From 54cbbdd25abbdea251afbaa9b7c42cdc63d9ebc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Tue, 20 Dec 2011 09:59:29 +0100 Subject: [PATCH 3/5] mxfdec: Remove unused variables --- libavformat/mxfdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index ea1129388e..254061c03c 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -662,7 +662,7 @@ static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment) { - int i, j, length; + int i, length; segment->nb_index_entries = avio_rb32(pb); length = avio_rb32(pb); @@ -1839,7 +1839,7 @@ static int mxf_read_close(AVFormatContext *s) { MXFContext *mxf = s->priv_data; MXFIndexTableSegment *seg; - int i, j; + int i; av_freep(&mxf->packages_refs); From 1888bd1b6d2bedc7bbded91d3a8d236236b5aa3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Tue, 20 Dec 2011 11:22:23 +0100 Subject: [PATCH 4/5] mxfdec: Make sure mxf->nb_index_tables > 0 in mxf_packet_timestamps() Only the OPAtom demuxing logic is guaranteed to have index tables, meaning OP1a files that lack an index would cause SIGSEGV. --- libavformat/mxfdec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 254061c03c..75d4b51a3f 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1714,6 +1714,10 @@ static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt) int64_t next_ofs; MXFIndexTable *t = &mxf->index_tables[0]; + /* this is called from the OP1a demuxing logic, which means there may be no index tables */ + if (mxf->nb_index_tables <= 0) + return; + /* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */ for (;;) { if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0) @@ -1795,6 +1799,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) return mxf_read_packet_old(s, pkt); /* OPAtom - clip wrapped demuxing */ + /* NOTE: mxf_read_header() makes sure nb_index_tables > 0 for OPAtom */ st = s->streams[0]; t = &mxf->index_tables[0]; From 5b718009b2c54a6ade9241fe5ae175e6f069791b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Tue, 20 Dec 2011 11:32:23 +0100 Subject: [PATCH 5/5] mxfdec: Sanity-check SampleRate This avoids a SIGFPE if SampleRate is missing or set to naughty values. --- libavformat/mxfdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 75d4b51a3f..b6a63c90a2 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1370,6 +1370,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codec->codec_id = container_ul->id; st->codec->channels = descriptor->channels; st->codec->bits_per_coded_sample = descriptor->bits_per_sample; + if (descriptor->sample_rate.den > 0) 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) {