From 53f2ef2c4afb1d49a679dea9163cb0e4671f3117 Mon Sep 17 00:00:00 2001 From: Marton Balint Date: Sat, 11 Jul 2015 18:10:12 +0200 Subject: mxfdec: calculate the index in display order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should fix seeking for open GOP files as well. Reviewed-by: Tomas Härdin Signed-off-by: Marton Balint --- libavformat/mxfdec.c | 23 ++++++++++++++++++++--- tests/ref/seek/lavf-mxf | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index b3c25b765e..27dd5bcd41 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -233,6 +233,7 @@ typedef struct MXFIndexTable { int nb_segments; MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */ AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */ + int8_t *offsets; /* temporal offsets for display order to stored order conversion */ } MXFIndexTable; typedef struct MXFContext { @@ -1334,6 +1335,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta { int i, j, x; int8_t max_temporal_offset = -128; + uint8_t *flags; /* first compute how many entries we have */ for (i = 0; i < index_table->nb_segments; i++) { @@ -1352,8 +1354,12 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta return 0; if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) || - !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) { + !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry))) || + !(index_table->offsets = av_calloc(index_table->nb_ptses, sizeof(int8_t))) || + !(flags = av_calloc(index_table->nb_ptses, sizeof(uint8_t)))) { av_freep(&index_table->ptses); + av_freep(&index_table->fake_index); + av_freep(&index_table->offsets); return AVERROR(ENOMEM); } @@ -1411,8 +1417,7 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta break; } - index_table->fake_index[x].timestamp = x; - index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0; + flags[x] = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0; if (index < 0 || index >= index_table->nb_ptses) { av_log(mxf->fc, AV_LOG_ERROR, @@ -1421,11 +1426,20 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta continue; } + index_table->offsets[x] = offset; index_table->ptses[index] = x; max_temporal_offset = FFMAX(max_temporal_offset, offset); } } + /* calculate the fake index table in display order */ + for (x = 0; x < index_table->nb_ptses; x++) { + index_table->fake_index[x].timestamp = x; + if (index_table->ptses[x] != AV_NOPTS_VALUE) + index_table->fake_index[index_table->ptses[x]].flags = flags[x]; + } + av_freep(&flags); + index_table->first_dts = -max_temporal_offset; return 0; @@ -3085,6 +3099,7 @@ static int mxf_read_close(AVFormatContext *s) av_freep(&mxf->index_tables[i].segments); av_freep(&mxf->index_tables[i].ptses); av_freep(&mxf->index_tables[i].fake_index); + av_freep(&mxf->index_tables[i].offsets); } } av_freep(&mxf->index_tables); @@ -3158,6 +3173,8 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti /* behave as if we have a proper index */ if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0) return sample_time; + /* get the stored order index from the display order index */ + sample_time += t->offsets[sample_time]; } else { /* no IndexEntryArray (one or more CBR segments) * make sure we don't seek past the end */ diff --git a/tests/ref/seek/lavf-mxf b/tests/ref/seek/lavf-mxf index f1aaa197d6..ea0e0b6995 100644 --- a/tests/ref/seek/lavf-mxf +++ b/tests/ref/seek/lavf-mxf @@ -43,6 +43,6 @@ ret:-1 st: 1 flags:0 ts: 2.671667 ret: 0 st: 1 flags:1 ts: 1.565833 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24711 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24711 +ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24786 ret: 0 st:-1 flags:1 ts:-0.645825 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6656 size: 24801 -- cgit v1.2.3