From fba35aa8c5cdedb3132b286874c5185c59af35a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 19 Sep 2019 13:46:12 +0200 Subject: Use FFmpeg's own `av_guess_frame_rate()` function instead of guessing ourselves This was introduced in FFmpeg lavf 55.1.100 in 2013. For systems that are still on LibAV or older FFmpeg there is a fallback implementation that performs the same guess as we did before in `av_get_r_frame_rate_compat()`. --- intern/ffmpeg/ffmpeg_compat.h | 36 ++++++++++---------------------- source/blender/imbuf/intern/anim_movie.c | 4 ++-- source/blender/imbuf/intern/indexer.c | 2 +- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index d254fa76ba9..123e18430a9 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -528,35 +528,21 @@ bool av_check_encoded_with_ffmpeg(AVFormatContext *ctx) return false; } -FFMPEG_INLINE -AVRational av_get_r_frame_rate_compat(AVFormatContext *ctx, const AVStream *stream) +/* Libav doesn't have av_guess_frame_rate(). + * It was introduced in FFmpeg's lavf 55.1.100. */ +#ifdef AV_USING_LIBAV +AVRational av_guess_frame_rate(AVFormatContext *ctx, AVStream *stream, AVFrame *frame) { - /* If the video is encoded with FFmpeg and we are decoding with FFmpeg - * as well it seems to be more reliable to use r_frame_rate (tbr). - * - * For other cases we fall back to avg_frame_rate (fps) when possible. - */ -#ifdef AV_USING_FFMPEG - if (av_check_encoded_with_ffmpeg(ctx)) { - return stream->r_frame_rate; - } -#endif - -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1) - /* For until r_frame_rate was deprecated use it. */ + (void)ctx; + (void)frame; +# if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 23, 1) + /* For until r_frame_rate was deprecated (in Libav) use it. */ return stream->r_frame_rate; -#else -# ifdef AV_USING_FFMPEG - /* Some of the videos might have average frame rate set to, while the - * r_frame_rate will show a correct value. This happens, for example, for - * OGG video files saved with Blender. */ - if (stream->avg_frame_rate.den == 0) { - return stream->r_frame_rate; - } -# endif +# else return stream->avg_frame_rate; -#endif +# endif } +#endif #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 32, 0) # define AV_OPT_SEARCH_FAKE_OBJ 0 diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index da7dcc54343..5bfcca22fae 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -569,7 +569,7 @@ static int startffmpeg(struct anim *anim) return -1; } - frame_rate = av_get_r_frame_rate_compat(pFormatCtx, video_stream); + frame_rate = av_guess_frame_rate(pFormatCtx, video_stream, NULL); if (video_stream->nb_frames != 0) { anim->duration = video_stream->nb_frames; } @@ -1040,7 +1040,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ v_st = anim->pFormatCtx->streams[anim->videoStream]; - frame_rate = av_q2d(av_get_r_frame_rate_compat(anim->pFormatCtx, v_st)); + frame_rate = av_q2d(av_guess_frame_rate(anim->pFormatCtx, v_st, NULL)); st_time = anim->pFormatCtx->start_time; pts_time_base = av_q2d(v_st->time_base); diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 66e0a681f8f..97a0cc85301 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -900,7 +900,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, stream_size = avio_size(context->iFormatCtx->pb); - context->frame_rate = av_q2d(av_get_r_frame_rate_compat(context->iFormatCtx, context->iStream)); + context->frame_rate = av_q2d(av_guess_frame_rate(context->iFormatCtx, context->iStream, NULL)); context->pts_time_base = av_q2d(context->iStream->time_base); while (av_read_frame(context->iFormatCtx, &next_packet) >= 0) { -- cgit v1.2.3