Index: libs/libmythtv/mythplayer.cpp =================================================================== --- libs/libmythtv/mythplayer.cpp (revision 26696) +++ libs/libmythtv/mythplayer.cpp (working copy) @@ -232,7 +232,7 @@ next_play_speed(1.0f), next_normal_speed(true), play_speed(1.0f), normal_speed(true), frame_interval((int)(1000000.0f / 30)), m_frame_interval(0), - ffrew_skip(1), + ffrew_skip(1), ffrew_delta(0), ffrew_adjust(0), // Audio and video synchronization stuff videosync(NULL), avsync_delay(0), avsync_adjustment(0), avsync_avg(0), @@ -1906,7 +1906,7 @@ return false; } buffering = false; - if (was_buffering) + if (was_buffering && normal_speed) audio.Pause(false); return true; } @@ -2793,13 +2793,22 @@ { if (ffrew_skip > 0) { - long long delta = decoder->GetFramesRead() - framesPlayed; - long long real_skip = CalcMaxFFTime(ffrew_skip + delta) - delta; + long long cur_frame = decoder->GetFramesPlayed(); + long long real_skip = CalcMaxFFTime(ffrew_delta); + long long target_frame = cur_frame + real_skip - ffrew_adjust; if (real_skip >= 0) { - long long frame = decoder->GetFramesRead() + real_skip; - decoder->DoFastForward(frame, false); + decoder->DoFastForward(target_frame, false); } + long long seek_frame = decoder->GetFramesPlayed(); + if (seek_frame > target_frame) + ffrew_adjust = seek_frame - target_frame; + else + ffrew_adjust = 0; + VERBOSE(VB_PLAYBACK, LOC + QString("FFW : " + "cur_frame %1 target_frame %2 seek_frame %3 real_skip %4 ffrew_adjust %5") + .arg(cur_frame).arg(target_frame).arg(seek_frame).arg(real_skip) + .arg(ffrew_adjust)); } else if (CalcRWTime(-ffrew_skip) >= 0) { @@ -2810,10 +2819,23 @@ bool MythPlayer::DecoderGetFrameREW(void) { - long long curFrame = decoder->GetFramesRead(); - bool toBegin = -curFrame > ffrew_skip; - long long real_skip = (toBegin) ? -curFrame : ffrew_skip; - return decoder->DoRewind(curFrame + real_skip, false); + long long cur_frame = decoder->GetFramesPlayed(); + bool toBegin = -cur_frame > ffrew_delta; + long long real_skip = (toBegin) ? -cur_frame : ffrew_delta; + long long target_frame = cur_frame + real_skip + ffrew_adjust; + + bool ret = decoder->DoRewind(target_frame, false); + + long long seek_frame = decoder->GetFramesPlayed(); + if (seek_frame < target_frame) + ffrew_adjust = target_frame - seek_frame; + else + ffrew_adjust = 0; + VERBOSE(VB_PLAYBACK, LOC + QString("REW : " + "cur_frame %1 target_frame %2 seek_frame %3 real_skip %4 ffrew_adjust %5") + .arg(cur_frame).arg(target_frame).arg(seek_frame).arg(real_skip).arg(ffrew_adjust)); + return ret; + } bool MythPlayer::DecoderGetFrame(DecodeType decodetype, bool unsafe) @@ -3088,10 +3110,26 @@ } float temp_speed = (play_speed == 0.0) ? audio.GetStretchFactor() : play_speed; - frame_interval = (int) (1000000.0f * ffrew_skip / video_frame_rate / - temp_speed); + if (ffrew_skip == 1) + { + frame_interval = (int) (1000000.0f * ffrew_skip / video_frame_rate / + temp_speed); + } + else + { + frame_interval = 200000; // 5 fps + } videosync->setFrameInterval(frame_interval); + float ffw_fps = play_speed * video_frame_rate; // how many fps for ffw/rew + float dis_fps = 1000000.0f / (float)frame_interval; // display fps for ffw/rew + ffrew_delta = ffw_fps / dis_fps; // how many frames to skip for each frame_interval + if (ffrew_skip != 1) + ffrew_skip = ffrew_delta; + VERBOSE(VB_PLAYBACK, LOC + "FFW/REW : " + + QString("ffw_fps: %1 dis_fps: %2 ffrew_delta: %3 ffrew_skip %4") + .arg(ffw_fps).arg(dis_fps).arg(ffrew_delta).arg(ffrew_skip)); + VERBOSE(VB_PLAYBACK, LOC + "Play speed: " + QString("rate: %1 speed: %2 skip: %3 => new interval %4") .arg(video_frame_rate).arg(play_speed) Index: libs/libmythtv/mythplayer.h =================================================================== --- libs/libmythtv/mythplayer.h (revision 26693) +++ libs/libmythtv/mythplayer.h (working copy) @@ -666,6 +666,8 @@ int m_frame_interval;///< used to detect changes to frame_interval int ffrew_skip; + int ffrew_delta; + int ffrew_adjust; // Audio and video synchronization stuff VideoSync *videosync;