From: Carl Hetherington Date: Fri, 12 Jul 2013 22:52:35 +0000 (+0100) Subject: Try to improve refetching of last frame and seek backwards. X-Git-Tag: v2.0.48~1337^2~253 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=bc5253cec3293a3cde39f5b9fea491a6be720640;p=dcpomatic.git Try to improve refetching of last frame and seek backwards. --- diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 27009114c..c77cb71c0 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -264,8 +264,22 @@ void FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate) { double const time_base = av_q2d (_format_context->streams[_video_stream]->time_base); - int64_t const vt = frame / (_ffmpeg_content->video_frame_rate() * time_base); - av_seek_frame (_format_context, _video_stream, vt, AVSEEK_FLAG_BACKWARD); + + /* If we are doing an accurate seek, our initial shot will be 5 frames (5 being + a number plucked from the air) earlier than we want to end up. The loop below + will hopefully then step through to where we want to be. + */ + int initial = frame; + if (accurate) { + initial -= 5; + } + + /* Initial seek time in the stream's timebase */ + int64_t const initial_vt = initial / (_ffmpeg_content->video_frame_rate() * time_base); + /* Wanted final seek time in the stream's timebase */ + int64_t const final_vt = frame / (_ffmpeg_content->video_frame_rate() * time_base); + + av_seek_frame (_format_context, _video_stream, initial_vt, AVSEEK_FLAG_BACKWARD); avcodec_flush_buffers (video_codec_context()); if (_subtitle_codec_context) { @@ -293,7 +307,7 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate) int const r = avcodec_decode_video2 (video_codec_context(), _frame, &finished, &_packet); if (r >= 0 && finished) { int64_t const bet = av_frame_get_best_effort_timestamp (_frame); - if (bet >= vt) { + if (bet >= final_vt) { _video_position = rint ( (bet * time_base + _pts_offset) * _ffmpeg_content->video_frame_rate() ); diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 2cc63aea4..ab53a9d15 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -141,8 +141,12 @@ FilmViewer::fetch_current_frame_again () } Time const t = _film->video_frames_to_time (1); - - _player->seek (_player->video_position() - t * 1.5, true); + + /* This 2.5 is, in theory: 1 to get back to the same frame, 1 more + because we are about to call fetch_next_frame(), and 0.5 for luck. + */ + + _player->seek (_player->video_position() - t * 2.5, true); fetch_next_frame (); }