Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VideoPlayer: consider offset to vsync #9629

Merged
merged 4 commits into from Apr 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions xbmc/Application.cpp
Expand Up @@ -1883,8 +1883,6 @@ void CApplication::Render()
g_infoManager.UpdateFPS();
}

m_pPlayer->AfterRender();

// TODO: find better solution
// if video is rendered to a separate layer, we should not block this thread
if (!m_pPlayer->IsRenderingVideoLayer() || hasRendered)
Expand Down
7 changes: 0 additions & 7 deletions xbmc/ApplicationPlayer.cpp
Expand Up @@ -790,13 +790,6 @@ void CApplicationPlayer::Render(bool clear, uint32_t alpha, bool gui)
player->Render(clear, alpha, gui);
}

void CApplicationPlayer::AfterRender()
{
std::shared_ptr<IPlayer> player = GetInternal();
if (player)
player->AfterRender();
}

void CApplicationPlayer::FlushRenderer()
{
std::shared_ptr<IPlayer> player = GetInternal();
Expand Down
1 change: 0 additions & 1 deletion xbmc/ApplicationPlayer.h
Expand Up @@ -82,7 +82,6 @@ class CApplicationPlayer
void FrameMove();
bool HasFrame();
void Render(bool clear, uint32_t alpha = 255, bool gui = true);
void AfterRender();
void FlushRenderer();
void SetRenderViewMode(int mode);
float GetRenderAspectRatio();
Expand Down
2 changes: 0 additions & 2 deletions xbmc/cores/IPlayer.h
Expand Up @@ -394,8 +394,6 @@ class IPlayer

virtual void Render(bool clear, uint32_t alpha = 255, bool gui = true) {};

virtual void AfterRender() {};

virtual void FlushRenderer() {};

virtual void SetRenderViewMode(int mode) {};
Expand Down
3 changes: 1 addition & 2 deletions xbmc/cores/VideoPlayer/DVDAudio.cpp
Expand Up @@ -332,9 +332,8 @@ void CDVDAudio::SetResampleMode(int mode)

double CDVDAudio::GetClock()
{
double absolute;
if (m_pClock)
return m_pClock->GetClock(absolute) / DVD_TIME_BASE * 1000;
return (m_pClock->GetClock() + m_pClock->GetVsyncAdjust()) / DVD_TIME_BASE * 1000;
else
return 0.0;
}
Expand Down
64 changes: 42 additions & 22 deletions xbmc/cores/VideoPlayer/DVDClock.cpp
Expand Up @@ -39,6 +39,8 @@ CDVDClock::CDVDClock()
m_systemAdjust = 0;
m_speedAdjust = 0;
m_startClock = 0;
m_vSyncAdjust = 0;
m_frameTime = DVD_TIME_BASE / 60;

m_videoRefClock.reset(new CVideoReferenceClock());
m_lastSystemTime = m_videoRefClock->GetTime();
Expand Down Expand Up @@ -86,6 +88,18 @@ double CDVDClock::GetClock(double& absolute, bool interpolated /*= true*/)
return SystemToPlaying(current);
}

void CDVDClock::SetVsyncAdjust(double adjustment)
{
CSingleLock lock(m_critSection);
m_vSyncAdjust = adjustment;
}

double CDVDClock::GetVsyncAdjust()
{
CSingleLock lock(m_critSection);
return m_vSyncAdjust;
}

void CDVDClock::SetSpeed(int iSpeed)
{
// this will sometimes be a little bit of due to rounding errors, ie clock might jump abit when changing speed
Expand Down Expand Up @@ -124,38 +138,40 @@ double CDVDClock::GetSpeedAdjust()
return m_speedAdjust;
}

bool CDVDClock::Update(double clock, double absolute, double limit, const char* log)
double CDVDClock::ErrorAdjust(double error, const char* log)
{
double was_absolute;
double was_clock;

{
CSingleLock lock(m_critSection);
was_absolute = SystemToAbsolute(m_startClock);
was_clock = m_iDisc + absolute - was_absolute;
}
CSingleLock lock(m_critSection);

double error = std::abs(clock - was_clock);
double clock, absolute, adjustment;
clock = GetClock(absolute);

// skip minor updates while speed adjust is active
// -> adjusting buffer levels
if (m_speedAdjust != 0 && error < DVD_MSEC_TO_TIME(100))
{
return false;
return 0;
}
else if (error > limit)

adjustment = error;

if (m_vSyncAdjust != 0)
{
Discontinuity(clock, absolute);

CLog::Log(LOGDEBUG, "CDVDClock::Discontinuity - %s - was:%f, should be:%f, error:%f"
, log
, was_clock
, clock
, clock - was_clock);
return true;
if (error > 0.5 * m_frameTime)
adjustment = m_frameTime;
else if (error < -0.5 * m_frameTime)
adjustment = -m_frameTime;
else
adjustment = 0;
}
else
return false;

if (adjustment == 0)
return 0;

Discontinuity(clock+adjustment, absolute);

CLog::Log(LOGDEBUG, "CDVDClock::ErrorAdjust - %s - error:%f, adjusted:%f",
log, error, adjustment);
return adjustment;
}

void CDVDClock::Discontinuity(double clock, double absolute)
Expand All @@ -168,6 +184,7 @@ void CDVDClock::Discontinuity(double clock, double absolute)
m_bReset = false;
m_systemAdjust = 0;
m_speedAdjust = 0;
m_vSyncAdjust = 0;
}

void CDVDClock::SetMaxSpeedAdjust(double speed)
Expand All @@ -184,6 +201,8 @@ int CDVDClock::UpdateFramerate(double fps, double* interval /*= NULL*/)
if(fps == 0.0)
return -1;

m_frameTime = 1/fps * DVD_TIME_BASE;

//check if the videoreferenceclock is running, will return -1 if not
double rate = m_videoRefClock->GetRefreshRate(interval);

Expand Down Expand Up @@ -242,6 +261,7 @@ double CDVDClock::SystemToPlaying(int64_t system)
m_iDisc = 0;
m_systemAdjust = 0;
m_speedAdjust = 0;
m_vSyncAdjust = 0;
m_bReset = false;
}

Expand Down
6 changes: 5 additions & 1 deletion xbmc/cores/VideoPlayer/DVDClock.h
Expand Up @@ -47,7 +47,7 @@ class CDVDClock
double GetClock(bool interpolated = true);
double GetClock(double& absolute, bool interpolated = true);

bool Update(double clock, double absolute, double limit, const char* log);
double ErrorAdjust(double error, const char* log);
void Discontinuity(double clock, double absolute);
void Discontinuity(double clock = 0LL)
{
Expand All @@ -72,6 +72,8 @@ class CDVDClock

double GetRefreshRate();
bool GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate) const;
void SetVsyncAdjust(double adjustment);
double GetVsyncAdjust();

protected:
double SystemToAbsolute(int64_t system);
Expand All @@ -93,6 +95,8 @@ class CDVDClock
int64_t m_systemAdjust;
int64_t m_lastSystemTime;
double m_speedAdjust;
double m_vSyncAdjust;
double m_frameTime;

double m_maxspeedadjust;
CCriticalSection m_speedsection;
Expand Down
5 changes: 0 additions & 5 deletions xbmc/cores/VideoPlayer/VideoPlayer.cpp
Expand Up @@ -4933,11 +4933,6 @@ void CVideoPlayer::Render(bool clear, uint32_t alpha, bool gui)
m_renderManager.Render(clear, 0, alpha, gui);
}

void CVideoPlayer::AfterRender()
{
m_renderManager.FrameFinish();
}

void CVideoPlayer::FlushRenderer()
{
m_renderManager.Flush();
Expand Down
1 change: 0 additions & 1 deletion xbmc/cores/VideoPlayer/VideoPlayer.h
Expand Up @@ -317,7 +317,6 @@ class CVideoPlayer : public IPlayer, public CThread, public IVideoPlayer, public
virtual void FrameMove();
virtual bool HasFrame();
virtual void Render(bool clear, uint32_t alpha = 255, bool gui = true);
virtual void AfterRender();
virtual void FlushRenderer();
virtual void SetRenderViewMode(int mode);
float GetRenderAspectRatio();
Expand Down
8 changes: 3 additions & 5 deletions xbmc/cores/VideoPlayer/VideoPlayerAudio.cpp
Expand Up @@ -530,14 +530,12 @@ bool CVideoPlayerAudio::OutputPacket(DVDAudioFrame &audioframe)
if (m_synctype == SYNC_DISCON)
{
double limit, error;
limit = DVD_MSEC_TO_TIME(10);
error = syncerror;

double absolute;
double clock = m_pClock->GetClock(absolute);
if (m_pClock->Update(clock + error, absolute, limit - 0.001, "CVideoPlayerAudio::OutputPacket"))
double correction = m_pClock->ErrorAdjust(error, "CVideoPlayerAudio::OutputPacket");
if (correction != 0)
{
m_dvdAudio.SetSyncErrorCorrection(-error);
m_dvdAudio.SetSyncErrorCorrection(-correction);
}
}
m_dvdAudio.AddPackets(audioframe);
Expand Down