Permalink
Browse files

player: fix rewind

  • Loading branch information...
1 parent 780f98d commit 39c342f1a80ed179e973cf7cb83e08f225af1ea0 @FernetMenta committed Nov 2, 2012
View
5 xbmc/cores/dvdplayer/DVDMessage.h
@@ -218,28 +218,31 @@ class CDVDMsgPlayerSetState : public CDVDMsg
class CDVDMsgPlayerSeek : public CDVDMsg
{
public:
- CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false)
+ CDVDMsgPlayerSeek(int time, bool backward, bool flush = true, bool accurate = true, bool restore = true, bool trickplay = false, bool sync = true)
: CDVDMsg(PLAYER_SEEK)
, m_time(time)
, m_backward(backward)
, m_flush(flush)
, m_accurate(accurate)
, m_restore(restore)
, m_trickplay(trickplay)
+ , m_sync(sync)
{}
int GetTime() { return m_time; }
bool GetBackward() { return m_backward; }
bool GetFlush() { return m_flush; }
bool GetAccurate() { return m_accurate; }
bool GetRestore() { return m_restore; }
bool GetTrickPlay() { return m_trickplay; }
+ bool GetSync() { return m_sync; }
private:
int m_time;
bool m_backward;
bool m_flush;
bool m_accurate;
bool m_restore; // whether to restore any EDL cut time
bool m_trickplay;
+ bool m_sync;
};
class CDVDMsgPlayerSeekChapter : public CDVDMsg
View
33 xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -1543,11 +1543,13 @@ void CDVDPlayer::HandlePlaySpeed()
}
else if (m_CurrentVideo.id >= 0
&& (m_CurrentVideo.inited == true || GetPlaySpeed() < 0) // allow rewind at end of file
- && m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts()
+ && (m_SpeedState.lastpts != m_dvdPlayerVideo.GetCurrentPts() || fabs(m_SpeedState.lastabstime - CDVDClock::GetAbsoluteClock()) > DVD_MSEC_TO_TIME(200))
+ && (m_dvdPlayerVideo.GetCurrentPts() != DVD_NOPTS_VALUE)
&& m_SpeedState.lasttime != GetTime())
{
m_SpeedState.lastpts = m_dvdPlayerVideo.GetCurrentPts();
m_SpeedState.lasttime = GetTime();
+ m_SpeedState.lastabstime = CDVDClock::GetAbsoluteClock();
// check how much off clock video is when ff/rw:ing
// a problem here is that seeking isn't very accurate
// and since the clock will be resynced after seek
@@ -1566,7 +1568,7 @@ void CDVDPlayer::HandlePlaySpeed()
{
CLog::Log(LOGDEBUG, "CDVDPlayer::Process - Seeking to catch up");
int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset + 500000.0 * m_playSpeed / DVD_PLAYSPEED_NORMAL);
- m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true));
+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, (GetPlaySpeed() < 0), true, false, false, true, false));
}
}
}
@@ -2025,7 +2027,7 @@ void CDVDPlayer::HandleMessages()
if(!m_pSubtitleDemuxer->SeekTime(time, msg.GetBackward()))
CLog::Log(LOGDEBUG, "failed to seek subtitle demuxer: %d, success", time);
}
- FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate());
+ FlushBuffers(!msg.GetFlush(), start, msg.GetAccurate(), msg.GetSync());
}
else
CLog::Log(LOGWARNING, "error while seeking");
@@ -2163,9 +2165,10 @@ void CDVDPlayer::HandleMessages()
double offset;
offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp;
offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
+ offset = DVD_TIME_TO_MSEC(offset);
if(offset > 1000) offset = 1000;
if(offset < -1000) offset = -1000;
- m_State.time += DVD_TIME_TO_MSEC(offset);
+ m_State.time += offset;
m_State.timestamp = CDVDClock::GetAbsoluteClock();
}
@@ -2181,7 +2184,8 @@ void CDVDPlayer::HandleMessages()
// do a seek after rewind, clock is not in sync with current pts
if (m_playSpeed < 0 && speed >= 0)
{
- m_messenger.Put(new CDVDMsgPlayerSeek(GetTime(), true, true, true));
+ int64_t iTime = (int64_t)DVD_TIME_TO_MSEC(m_clock.GetClock() + m_State.time_offset);
+ m_messenger.Put(new CDVDMsgPlayerSeek(iTime, true, true, false, false, true));
}
// if playspeed is different then DVD_PLAYSPEED_NORMAL or DVD_PLAYSPEED_PAUSE
@@ -2762,10 +2766,11 @@ int64_t CDVDPlayer::GetTime()
{
offset = CDVDClock::GetAbsoluteClock() - m_State.timestamp;
offset *= m_playSpeed / DVD_PLAYSPEED_NORMAL;
+ offset = DVD_TIME_TO_MSEC(offset);
if(offset > 1000) offset = 1000;
if(offset < -1000) offset = -1000;
}
- return llrint(m_State.time + DVD_TIME_TO_MSEC(offset));
+ return llrint(m_State.time + offset);
}
// return length in msec
@@ -3135,7 +3140,7 @@ bool CDVDPlayer::CloseTeletextStream(bool bWaitForBuffers)
return true;
}
-void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
+void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate, bool sync)
{
double startpts;
if(accurate)
@@ -3147,19 +3152,23 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
if(startpts != DVD_NOPTS_VALUE)
startpts -= m_offset_pts;
- m_CurrentAudio.inited = false;
+ if (sync)
+ {
+ m_CurrentAudio.inited = false;
+ m_CurrentVideo.inited = false;
+ m_CurrentSubtitle.inited = false;
+ m_CurrentTeletext.inited = false;
+ }
+
m_CurrentAudio.dts = DVD_NOPTS_VALUE;
m_CurrentAudio.startpts = startpts;
- m_CurrentVideo.inited = false;
m_CurrentVideo.dts = DVD_NOPTS_VALUE;
m_CurrentVideo.startpts = startpts;
- m_CurrentSubtitle.inited = false;
m_CurrentSubtitle.dts = DVD_NOPTS_VALUE;
m_CurrentSubtitle.startpts = startpts;
- m_CurrentTeletext.inited = false;
m_CurrentTeletext.dts = DVD_NOPTS_VALUE;
m_CurrentTeletext.startpts = startpts;
@@ -3203,7 +3212,7 @@ void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate)
m_CurrentTeletext.started = false;
}
- if(pts != DVD_NOPTS_VALUE)
+ if(pts != DVD_NOPTS_VALUE && sync)
m_clock.Discontinuity(pts);
UpdatePlayState(0);
}
View
7 xbmc/cores/dvdplayer/DVDPlayer.h
@@ -310,7 +310,7 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
bool GetCachingTimes(double& play_left, double& cache_left, double& file_offset);
- void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true);
+ void FlushBuffers(bool queued, double pts = DVD_NOPTS_VALUE, bool accurate = true, bool sync = true);
void HandleMessages();
void HandlePlaySpeed();
@@ -359,8 +359,9 @@ class CDVDPlayer : public IPlayer, public CThread, public IDVDPlayer
int m_playSpeed;
struct SSpeedState
{
- double lastpts; // holds last display pts during ff/rw operations
- double lasttime;
+ double lastpts; // holds last display pts during ff/rw operations
+ int64_t lasttime;
+ double lastabstime;
} m_SpeedState;
int m_errorCount;
View
10 xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -1268,13 +1268,13 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts)
if( m_speed < 0 )
{
- double decoderPts = m_droppingStats.m_lastDecoderPts;
+ double inputPts = m_droppingStats.m_lastPts;
double renderPts = m_droppingStats.m_lastRenderPts;
if (pts > renderPts)
{
- if (decoderPts >= renderPts)
+ if (inputPts >= renderPts)
{
- Sleep(200);
+ Sleep(50);
}
return result | EOS_DROPPED;
}
@@ -1571,7 +1571,7 @@ double CDVDPlayerVideo::GetCurrentPts()
if( m_stalled )
iRenderPts = DVD_NOPTS_VALUE;
- else
+ else if ( m_speed == DVD_PLAYSPEED_NORMAL)
iRenderPts = iRenderPts - max(0.0, iSleepTime);
return iRenderPts;
@@ -1671,6 +1671,8 @@ int CDVDPlayerVideo::CalcDropRequirement(double pts)
int iSkippedDeint = 0;
int iBufferLevel;
+ m_droppingStats.m_lastPts = pts;
+
// get decoder stats
if (!m_pVideoCodec->GetPts(iDecoderPts, iSkippedDeint, interlaced))
iDecoderPts = pts;
View
1 xbmc/cores/dvdplayer/DVDPlayerVideo.h
@@ -51,6 +51,7 @@ class CDroppingStats
double m_totalGain;
double m_lastDecoderPts;
double m_lastRenderPts;
+ double m_lastPts;
unsigned int m_lateFrames;
unsigned int m_dropRequests;
bool m_requestOutputDrop;

0 comments on commit 39c342f

Please sign in to comment.