From 9bec4f777973c066ac12ae5ad2df107be23bdc7b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 3 Feb 2014 17:24:25 +0600 Subject: Fix T38455: Blenderplayer is not working Was a regression since avg_frame_rate changes. Didn't find reliable way to get stream duration which will work with both FFmpeg and Libav so added some freaking black magic to distinguish one from another. --- intern/ffmpeg/ffmpeg_compat.h | 11 +++++++++++ source/blender/imbuf/intern/anim_movie.c | 11 +++++++---- source/blender/imbuf/intern/indexer.c | 2 +- source/gameengine/VideoTexture/VideoFFmpeg.cpp | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 6cae957471d..801ab6e659d 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -419,4 +419,15 @@ void av_frame_free(AVFrame **frame) } #endif +FFMPEG_INLINE +AVRational av_get_r_frame_rate_compat(const AVStream *stream) +{ + /* Stupid way to distinguish FFmpeg from Libav. */ +#if LIBAVCODEC_VERSION_MICRO >= 100 + return stream->r_frame_rate; +#else + return stream->avg_frame_rate; +#endif +} + #endif diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index b7bea0d96b5..9a3042d149e 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -466,6 +466,7 @@ static int startffmpeg(struct anim *anim) AVCodec *pCodec; AVFormatContext *pFormatCtx = NULL; AVCodecContext *pCodecCtx; + AVRational frame_rate; int frs_num; double frs_den; int streamcount; @@ -527,12 +528,14 @@ static int startffmpeg(struct anim *anim) return -1; } + frame_rate = av_get_r_frame_rate_compat(pFormatCtx->streams[videoStream]); anim->duration = ceil(pFormatCtx->duration * - av_q2d(pFormatCtx->streams[videoStream]->avg_frame_rate) / + av_q2d(frame_rate) / AV_TIME_BASE); + printf("%d\n", anim->duration); - frs_num = pFormatCtx->streams[videoStream]->avg_frame_rate.num; - frs_den = pFormatCtx->streams[videoStream]->avg_frame_rate.den; + frs_num = frame_rate.num; + frs_den = frame_rate.den; frs_den *= AV_TIME_BASE; @@ -970,7 +973,7 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, v_st = anim->pFormatCtx->streams[anim->videoStream]; - frame_rate = av_q2d(v_st->avg_frame_rate); + frame_rate = av_q2d(av_get_r_frame_rate_compat(v_st)); 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 a3cb4048779..e45222706d7 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -910,7 +910,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, stream_size = avio_size(context->iFormatCtx->pb); - context->frame_rate = av_q2d(context->iStream->avg_frame_rate); + context->frame_rate = av_q2d(av_get_r_frame_rate_compat(context->iStream)); context->pts_time_base = av_q2d(context->iStream->time_base); while (av_read_frame(context->iFormatCtx, &next_packet) >= 0) { diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp index 139988f64ea..3bad7c92efe 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp +++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp @@ -220,7 +220,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV codecCtx->frame_rate_base=1000; m_baseFrameRate = (double)codecCtx->frame_rate / (double)codecCtx->frame_rate_base; #else - m_baseFrameRate = av_q2d(formatCtx->streams[videoStream]->r_frame_rate); + m_baseFrameRate = av_q2d(av_get_r_frame_rate_compat(formatCtx->streams[videoStream])); #endif if (m_baseFrameRate <= 0.0) m_baseFrameRate = defFrameRate; -- cgit v1.2.3