From e18a03abc328953835304b122e9330f87c34ac57 Mon Sep 17 00:00:00 2001 From: Laurens Voerman Date: Tue, 19 Jun 2018 09:21:02 +0200 Subject: [PATCH] resolve av sync failure with ffmpeg 3.2 and up --- src/osgPlugins/ffmpeg/FFmpegClocks.cpp | 3 +-- src/osgPlugins/ffmpeg/FFmpegDecoderVideo.cpp | 26 +++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/osgPlugins/ffmpeg/FFmpegClocks.cpp b/src/osgPlugins/ffmpeg/FFmpegClocks.cpp index 9b656fceb..d6f25f153 100644 --- a/src/osgPlugins/ffmpeg/FFmpegClocks.cpp +++ b/src/osgPlugins/ffmpeg/FFmpegClocks.cpp @@ -155,8 +155,7 @@ double FFmpegClocks::videoSynchClock(const AVFrame * const frame, const double t // Update the video clock to take into account the frame delay - double frame_delay = time_base; - frame_delay += frame->repeat_pict * (frame_delay * 0.5); + double frame_delay = time_base * (1 + frame->repeat_pict); m_video_clock += frame_delay; diff --git a/src/osgPlugins/ffmpeg/FFmpegDecoderVideo.cpp b/src/osgPlugins/ffmpeg/FFmpegDecoderVideo.cpp index 083d3dbf5..25df979a0 100644 --- a/src/osgPlugins/ffmpeg/FFmpegDecoderVideo.cpp +++ b/src/osgPlugins/ffmpeg/FFmpegDecoderVideo.cpp @@ -180,6 +180,8 @@ void FFmpegDecoderVideo::decodeLoop() // Publish the frame if we have decoded a complete frame if (frame_finished) { +#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(57,24,102) + //ffmpeg-3.0 and below AVRational timebase; // Find out the frame pts if (m_frame->pts != int64_t(AV_NOPTS_VALUE)) @@ -207,7 +209,29 @@ void FFmpegDecoderVideo::decodeLoop() pts *= av_q2d(timebase); - const double synched_pts = m_clocks.videoSynchClock(m_frame.get(), av_q2d(timebase), pts); +#else + //above ffmpeg-3.0 + // Find out the frame pts + if (m_frame->pts != int64_t(AV_NOPTS_VALUE)) + { + pts = av_q2d(m_stream->time_base) * m_frame->pts; + } + else if (packet.packet.dts == int64_t(AV_NOPTS_VALUE) && + m_frame->opaque != 0 && + *reinterpret_cast(m_frame->opaque) != int64_t(AV_NOPTS_VALUE)) + { + pts = av_q2d(m_stream->time_base) * *reinterpret_cast(m_frame->opaque); + } + else if (packet.packet.dts != int64_t(AV_NOPTS_VALUE)) + { + pts = av_q2d(m_stream->time_base) * packet.packet.dts; + } + else + { + pts = 0; + } +#endif + const double synched_pts = m_clocks.videoSynchClock(m_frame.get(), av_q2d(av_inv_q(m_context->framerate)), pts); const double frame_delay = m_clocks.videoRefreshSchedule(synched_pts); publishFrame(frame_delay, m_clocks.audioDisabled());