From c8dc11bb9ef92b8e90142a41e91b192346f4d7a0 Mon Sep 17 00:00:00 2001 From: Sasi Inguva Date: Wed, 9 Nov 2016 10:51:13 -0800 Subject: lavf/mov.c: Fallback to finding non-keyframe in fix_index, if keyframe search fails. Signed-off-by: Sasi Inguva Reviewed-by: Derek Buitenhuis Signed-off-by: Michael Niedermayer --- libavformat/mov.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'libavformat') diff --git a/libavformat/mov.c b/libavformat/mov.c index ca978c282e..9ec7d030d3 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2822,16 +2822,17 @@ static int get_edit_list_entry(MOVContext *mov, } /** - * Find the closest previous keyframe to the timestamp, in e_old index - * entries. + * Find the closest previous frame to the timestamp, in e_old index + * entries. Searching for just any frame / just key frames can be controlled by + * last argument 'flag'. * Returns the index of the entry in st->index_entries if successful, * else returns -1. */ -static int64_t find_prev_closest_keyframe_index(AVStream *st, - AVIndexEntry *e_old, - int nb_old, - int64_t timestamp, - int flag) +static int64_t find_prev_closest_index(AVStream *st, + AVIndexEntry *e_old, + int nb_old, + int64_t timestamp, + int flag) { AVIndexEntry *e_keep = st->index_entries; int nb_keep = st->nb_index_entries; @@ -3048,10 +3049,21 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) search_timestamp = FFMAX(search_timestamp - msc->time_scale, e_old[0].timestamp); } - index = find_prev_closest_keyframe_index(st, e_old, nb_old, search_timestamp, 0); + index = find_prev_closest_index(st, e_old, nb_old, search_timestamp, 0); if (index == -1) { - av_log(mov->fc, AV_LOG_ERROR, "Missing key frame while reordering index according to edit list\n"); - continue; + av_log(mov->fc, AV_LOG_WARNING, + "st: %d edit list: %"PRId64" Missing key frame while searching for timestamp: %"PRId64"\n", + st->index, edit_list_index, search_timestamp); + index = find_prev_closest_index(st, e_old, nb_old, search_timestamp, AVSEEK_FLAG_ANY); + + if (index == -1) { + av_log(mov->fc, AV_LOG_WARNING, + "st: %d edit list %"PRId64" Cannot find an index entry before timestamp: %"PRId64".\n" + "Rounding edit list media time to zero.\n", + st->index, edit_list_index, search_timestamp); + index = 0; + edit_list_media_time = 0; + } } current = e_old + index; @@ -4443,7 +4455,14 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) } e->rate = avio_rb32(pb) / 65536.0; av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n", - e->duration, e->time, e->rate); + e->duration, e->time, e->rate); + + if (e->time < 0 && e->time != -1 && + c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) { + av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n", + c->fc->nb_streams-1, i, e->time); + return AVERROR_INVALIDDATA; + } } sc->elst_count = i; -- cgit v1.2.3