From 316d455540db0fa84b6fba3712bea6561d460d2f Mon Sep 17 00:00:00 2001 From: Sylvain Gadrat Date: Thu, 23 Oct 2014 00:51:58 +0200 Subject: [PATCH] Fix inacurate frame timing All time references are now kept in clock tick to avoid imprecision due to unit changes. s_last_frame is now updated only when we effectively encode a frame. s_last_frame and b_start_dumping are now used in a way similar to the Windows implementation. --- Source/Core/VideoCommon/AVIDump.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Source/Core/VideoCommon/AVIDump.cpp b/Source/Core/VideoCommon/AVIDump.cpp index b7de6badbcdc..2e1bbf9b97b7 100644 --- a/Source/Core/VideoCommon/AVIDump.cpp +++ b/Source/Core/VideoCommon/AVIDump.cpp @@ -335,7 +335,7 @@ static int s_height; static int s_size; static u64 s_last_frame; bool b_start_dumping = false; -static s64 s_last_pts; +static u64 s_last_pts; static void InitAVCodec() { @@ -353,7 +353,7 @@ bool AVIDump::Start(int w, int h) s_height = h; s_last_frame = CoreTiming::GetTicks(); - s_last_pts = AV_NOPTS_VALUE; + s_last_pts = 0; InitAVCodec(); bool success = CreateFile(); @@ -445,15 +445,14 @@ void AVIDump::AddFrame(const u8* data, int width, int height) int got_packet = 0; int error = 0; u64 delta = CoreTiming::GetTicks() - s_last_frame; - if (s_last_pts != AV_NOPTS_VALUE) - s_scaled_frame->pts = s_last_pts; - else - s_scaled_frame->pts = 0; - s_scaled_frame->pts += (delta * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond(); - s_last_frame += delta; - if (s_scaled_frame->pts != s_last_pts || s_last_pts == AV_NOPTS_VALUE) + u64 pts_in_ticks = s_last_pts + delta; + s64 last_pts = (s_last_pts * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond(); + s_scaled_frame->pts = (pts_in_ticks * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond(); + if (s_scaled_frame->pts != last_pts || !b_start_dumping) { - s_last_pts = s_scaled_frame->pts; + s_last_frame = CoreTiming::GetTicks(); + s_last_pts = pts_in_ticks; + b_start_dumping = true; error = avcodec_encode_video2(s_stream->codec, &pkt, s_scaled_frame, &got_packet); } while (!error && got_packet)