From b197d83ca3f7316a4eb31bf60d9895835f7f2b4b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 31 Oct 2017 20:44:21 +0100 Subject: avformat/utils: Look at the first 3 frames if timestamps indicate frame reorder but decoder delay does not Fixes: Ticket6487 Signed-off-by: Michael Niedermayer --- libavformat/avformat.h | 1 + libavformat/utils.c | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'libavformat') diff --git a/libavformat/avformat.h b/libavformat/avformat.h index c068aa8009..3c6775d0f6 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1026,6 +1026,7 @@ typedef struct AVStream { double (*duration_error)[2][MAX_STD_TIMEBASES]; int64_t codec_info_duration; int64_t codec_info_duration_fields; + int frame_delay_evidence; /** * 0 -> decoder has not been searched for yet. diff --git a/libavformat/utils.c b/libavformat/utils.c index 3fd17dd771..87887063be 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3628,6 +3628,7 @@ FF_ENABLE_DEPRECATION_WARNINGS /* check if one codec still needs to be handled */ for (i = 0; i < ic->nb_streams; i++) { int fps_analyze_framecount = 20; + int count; st = ic->streams[i]; if (!has_codec_parameters(st, NULL)) @@ -3644,14 +3645,18 @@ FF_ENABLE_DEPRECATION_WARNINGS if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ + count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ? + st->info->codec_info_duration_fields/2 : + st->info->duration_count; if (!(st->r_frame_rate.num && st->avg_frame_rate.num) && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - int count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ? - st->info->codec_info_duration_fields/2 : - st->info->duration_count; if (count < fps_analyze_framecount) break; } + // Look at the first 3 frames if there is evidence of frame delay + // but the decoder delay is not set. + if (st->info->frame_delay_evidence && count < 2 && st->internal->avctx->has_b_frames == 0) + break; if (!st->internal->avctx->extradata && (!st->internal->extract_extradata.inited || st->internal->extract_extradata.bsf) && @@ -3801,10 +3806,13 @@ FF_ENABLE_DEPRECATION_WARNINGS st->info->codec_info_duration_fields += st->parser && st->need_parsing && avctx->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { #if FF_API_R_FRAME_RATE - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) ff_rfps_add_frame(ic, st, pkt->dts); #endif + if (pkt->dts != pkt->pts && pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE) + st->info->frame_delay_evidence = 1; + } if (!st->internal->avctx->extradata) { ret = extract_extradata(st, pkt); if (ret < 0) -- cgit v1.2.3