aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2015-04-03 14:03:44 +0200
committerRainer Hochecker <fernetmenta@online.de>2015-04-10 18:31:12 +0200
commit6b3d4dbfc39058c9c30133c93fd2e6254a951ac3 (patch)
tree14eb32b25178f098c33c68e66fc03cd55c973e77
parent58c028f8ac206523991c0df1c155767a48a6a192 (diff)
dvdplayer/omxplayer: protect live streams (pvr) from stalling
-rw-r--r--xbmc/cores/VideoRenderers/RenderManager.cpp9
-rw-r--r--xbmc/cores/dvdplayer/DVDClock.cpp53
-rw-r--r--xbmc/cores/dvdplayer/DVDClock.h10
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.cpp30
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.h1
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.cpp5
-rw-r--r--xbmc/linux/OMXClock.cpp20
-rw-r--r--xbmc/linux/OMXClock.h2
-rw-r--r--xbmc/video/VideoReferenceClock.cpp8
-rw-r--r--xbmc/video/VideoReferenceClock.h1
10 files changed, 106 insertions, 33 deletions
diff --git a/xbmc/cores/VideoRenderers/RenderManager.cpp b/xbmc/cores/VideoRenderers/RenderManager.cpp
index 25323ef43c..25d380981c 100644
--- a/xbmc/cores/VideoRenderers/RenderManager.cpp
+++ b/xbmc/cores/VideoRenderers/RenderManager.cpp
@@ -175,6 +175,15 @@ void CXBMCRenderManager::WaitPresentTime(double presenttime)
return;
}
+ CDVDClock *dvdclock = CDVDClock::GetMasterClock();
+ if(dvdclock != NULL && dvdclock->GetSpeedAdjust() != 0.0)
+ {
+ CDVDClock::WaitAbsoluteClock(presenttime * DVD_TIME_BASE);
+ m_presenterr = 0;
+ m_presentcorr = 0;
+ return;
+ }
+
double clock = CDVDClock::WaitAbsoluteClock(presenttime * DVD_TIME_BASE) / DVD_TIME_BASE;
double target = 0.5;
double error = ( clock - presenttime ) / frametime - target;
diff --git a/xbmc/cores/dvdplayer/DVDClock.cpp b/xbmc/cores/dvdplayer/DVDClock.cpp
index a496ec0172..2629530d8d 100644
--- a/xbmc/cores/dvdplayer/DVDClock.cpp
+++ b/xbmc/cores/dvdplayer/DVDClock.cpp
@@ -29,7 +29,7 @@
int64_t CDVDClock::m_systemOffset;
int64_t CDVDClock::m_systemFrequency;
CCriticalSection CDVDClock::m_systemsection;
-CDVDClock *CDVDClock::m_playerclock = NULL;;
+CDVDClock *CDVDClock::m_playerclock = NULL;
CDVDClock::CDVDClock()
: m_master(MASTER_CLOCK_NONE)
@@ -42,6 +42,9 @@ CDVDClock::CDVDClock()
m_bReset = true;
m_iDisc = 0;
m_maxspeedadjust = 0.0;
+ m_lastSystemTime = g_VideoReferenceClock.GetTime();
+ m_systemAdjust = 0;
+ m_speedAdjust = 0;
m_startClock = 0;
@@ -103,7 +106,12 @@ CDVDClock* CDVDClock::GetMasterClock()
double CDVDClock::GetClock(bool interpolated /*= true*/)
{
CSharedLock lock(m_critSection);
- return SystemToPlaying(g_VideoReferenceClock.GetTime(interpolated));
+
+ int64_t current = g_VideoReferenceClock.GetTime(interpolated);
+ m_systemAdjust += m_speedAdjust * (current - m_lastSystemTime);
+ m_lastSystemTime = current;
+
+ return SystemToPlaying(current);
}
double CDVDClock::GetClock(double& absolute, bool interpolated /*= true*/)
@@ -115,8 +123,7 @@ double CDVDClock::GetClock(double& absolute, bool interpolated /*= true*/)
absolute = SystemToAbsolute(current);
}
- CSharedLock lock(m_critSection);
- return SystemToPlaying(current);
+ return GetClock(interpolated);
}
void CDVDClock::SetSpeed(int iSpeed)
@@ -145,6 +152,18 @@ void CDVDClock::SetSpeed(int iSpeed)
m_systemUsed = newfreq;
}
+void CDVDClock::SetSpeedAdjust(double adjust)
+{
+ CExclusiveLock lock(m_critSection);
+ m_speedAdjust = adjust;
+}
+
+double CDVDClock::GetSpeedAdjust()
+{
+ CExclusiveLock lock(m_critSection);
+ return m_speedAdjust;
+}
+
bool CDVDClock::Update(double clock, double absolute, double limit, const char* log)
{
CExclusiveLock lock(m_critSection);
@@ -174,26 +193,8 @@ void CDVDClock::Discontinuity(double clock, double absolute)
m_pauseClock = m_startClock;
m_iDisc = clock;
m_bReset = false;
-}
-
-void CDVDClock::Pause()
-{
- CExclusiveLock lock(m_critSection);
- if(!m_pauseClock)
- m_pauseClock = g_VideoReferenceClock.GetTime();
-}
-
-void CDVDClock::Resume()
-{
- CExclusiveLock lock(m_critSection);
- if( m_pauseClock )
- {
- int64_t current;
- current = g_VideoReferenceClock.GetTime();
-
- m_startClock += current - m_pauseClock;
- m_pauseClock = 0;
- }
+ m_systemAdjust = 0;
+ m_speedAdjust = 0;
}
void CDVDClock::SetMaxSpeedAdjust(double speed)
@@ -265,6 +266,8 @@ double CDVDClock::SystemToPlaying(int64_t system)
if(m_pauseClock)
m_pauseClock = m_startClock;
m_iDisc = 0;
+ m_systemAdjust = 0;
+ m_speedAdjust = 0;
m_bReset = false;
}
@@ -273,7 +276,7 @@ double CDVDClock::SystemToPlaying(int64_t system)
else
current = system;
- return DVD_TIME_BASE * (double)(current - m_startClock) / m_systemUsed + m_iDisc;
+ return DVD_TIME_BASE * (double)(current - m_startClock + m_systemAdjust) / m_systemUsed + m_iDisc;
}
EMasterClock CDVDClock::GetMaster()
diff --git a/xbmc/cores/dvdplayer/DVDClock.h b/xbmc/cores/dvdplayer/DVDClock.h
index d6b2d0a71a..cf03af5101 100644
--- a/xbmc/cores/dvdplayer/DVDClock.h
+++ b/xbmc/cores/dvdplayer/DVDClock.h
@@ -66,9 +66,9 @@ public:
}
void Reset() { m_bReset = true; }
- void Pause();
- void Resume();
void SetSpeed(int iSpeed);
+ void SetSpeedAdjust(double adjust);
+ double GetSpeedAdjust();
double GetClockSpeed(); /**< get the current speed of the clock relative normal system time */
@@ -101,7 +101,11 @@ protected:
static int64_t m_systemOffset;
static CCriticalSection m_systemsection;
- double m_maxspeedadjust;
+ int64_t m_systemAdjust;
+ int64_t m_lastSystemTime;
+ double m_speedAdjust;
+
+ double m_maxspeedadjust;
CCriticalSection m_speedsection;
static CDVDClock *m_playerclock;
};
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
index c146331e2a..38252ed830 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -1778,6 +1778,7 @@ void CDVDPlayer::HandlePlaySpeed()
if(m_caching != caching)
SetCaching(caching);
+ // check buffering levels and adjust clock
if (m_playSpeed == DVD_PLAYSPEED_NORMAL && m_caching == CACHESTATE_DONE)
{
// due to i.e. discontinuities of pts the stream may have drifted away
@@ -1788,6 +1789,31 @@ void CDVDPlayer::HandlePlaySpeed()
CLog::Log(LOGDEBUG,"CDVDPlayer::HandlePlaySpeed - audio stream stalled, tiggering re-sync");
TriggerResync();
}
+
+ if (CachePVRStream())
+ {
+ if (m_CurrentAudio.id >= 0)
+ {
+ double adjust = -1.0; // a unique value
+ if (m_clock.GetSpeedAdjust() == 0.0 && m_dvdPlayerAudio->GetLevel() < 5)
+ adjust = -0.01;
+ else if (m_clock.GetSpeedAdjust() == 0.0 && m_dvdPlayerAudio->GetLevel() > 95)
+ adjust = 0.01;
+
+ if (m_clock.GetSpeedAdjust() < 0 && m_dvdPlayerAudio->GetLevel() > 20)
+ adjust = 0.0;
+ else if (m_clock.GetSpeedAdjust() > 0 && m_dvdPlayerAudio->GetLevel() < 80)
+ adjust = 0.0;
+
+ if (adjust != -1.0)
+ {
+ m_clock.SetSpeedAdjust(adjust);
+ if (m_omxplayer_mode)
+ m_OmxPlayerState.av_clock.OMXSetSpeedAdjust(adjust);
+ CLog::Log(LOGDEBUG, "CDVDPlayer::HandlePlaySpeed set clock adjust: %f", adjust);
+ }
+ }
+ }
}
if(GetPlaySpeed() != DVD_PLAYSPEED_NORMAL && GetPlaySpeed() != DVD_PLAYSPEED_PAUSE)
@@ -2699,6 +2725,10 @@ void CDVDPlayer::SetCaching(ECacheState state)
m_pInputStream->ResetScanTimeout(0);
}
m_caching = state;
+
+ m_clock.SetSpeedAdjust(0);
+ if (m_omxplayer_mode)
+ m_OmxPlayerState.av_clock.OMXSetSpeedAdjust(0);
}
void CDVDPlayer::SetPlaySpeed(int speed)
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h
index 468239c3c6..e12a800ba1 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.h
+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
@@ -68,6 +68,7 @@ public:
bool OMXStateExecute(bool lock = true) { return false; }
void OMXStateIdle(bool lock = true) {}
bool HDMIClockSync(bool lock = true) { return false; }
+ void OMXSetSpeedAdjust(double adjust, bool lock = true) {}
};
#endif
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
index 69dc501c18..8d739ea904 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -201,10 +201,7 @@ bool CDVDPlayerVideo::OpenStream( CDVDStreamInfo &hint )
return false;
}
- if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && !g_VideoReferenceClock.IsRunning())
- {
- g_VideoReferenceClock.Create();
- }
+ g_VideoReferenceClock.Start();
if(m_messageQueue.IsInited())
m_messageQueue.Put(new CDVDMsgVideoCodecChange(hint, codec), 0);
diff --git a/xbmc/linux/OMXClock.cpp b/xbmc/linux/OMXClock.cpp
index 46df52e879..4f094df927 100644
--- a/xbmc/linux/OMXClock.cpp
+++ b/xbmc/linux/OMXClock.cpp
@@ -45,6 +45,7 @@ OMXClock::OMXClock()
m_clock = NULL;
m_last_media_time = 0.0f;
m_last_media_time_read = 0.0f;
+ m_speedAdjust = 0;
pthread_mutex_init(&m_lock, NULL);
}
@@ -477,7 +478,7 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
if(lock)
Lock();
- CLog::Log(LOGDEBUG, "OMXClock::OMXSetSpeed(%.2f) pause_resume:%d", (float)speed / (float)DVD_PLAYSPEED_NORMAL, pause_resume);
+ CLog::Log(LOGDEBUG, "OMXClock::OMXSetSpeed(%.3f) pause_resume:%d", (float)speed / (float)DVD_PLAYSPEED_NORMAL * (1.0 + m_speedAdjust), pause_resume);
if (pause_resume)
{
@@ -485,6 +486,8 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
OMX_INIT_STRUCTURE(scaleType);
scaleType.xScale = (speed << 16) / DVD_PLAYSPEED_NORMAL;
+ scaleType.xScale += scaleType.xScale * m_speedAdjust;
+
OMX_ERRORTYPE omx_err = m_omx_clock.SetConfig(OMX_IndexConfigTimeScale, &scaleType);
if(omx_err != OMX_ErrorNone)
{
@@ -504,6 +507,21 @@ bool OMXClock::OMXSetSpeed(int speed, bool lock /* = true */, bool pause_resume
return true;
}
+void OMXClock::OMXSetSpeedAdjust(double adjust, bool lock /* = true */)
+{
+ if(lock)
+ Lock();
+ // we only support resampling (and hence clock adjustment) in this mode
+ if (CSettings::Get().GetBool("videoplayer.usedisplayasclock"))
+ {
+ m_speedAdjust = adjust;
+ OMXSetSpeed(m_omx_speed, false, true);
+ m_last_media_time = 0.0f;
+ }
+ if(lock)
+ UnLock();
+}
+
bool OMXClock::OMXFlush(bool lock)
{
if(m_omx_clock.GetComponent() == NULL)
diff --git a/xbmc/linux/OMXClock.h b/xbmc/linux/OMXClock.h
index 8f0613487d..df0d4cfb9c 100644
--- a/xbmc/linux/OMXClock.h
+++ b/xbmc/linux/OMXClock.h
@@ -59,6 +59,7 @@ private:
COMXCoreComponent m_omx_clock;
double m_last_media_time;
double m_last_media_time_read;
+ double m_speedAdjust;
public:
OMXClock();
~OMXClock();
@@ -82,6 +83,7 @@ public:
bool OMXPause(bool lock = true);
bool OMXResume(bool lock = true);
bool OMXSetSpeed(int speed, bool lock = true, bool pause_resume = false);
+ void OMXSetSpeedAdjust(double adjust, bool lock = true);
int OMXPlaySpeed() { return m_omx_speed; };
bool OMXFlush(bool lock = true);
COMXCoreComponent *GetOMXClock();
diff --git a/xbmc/video/VideoReferenceClock.cpp b/xbmc/video/VideoReferenceClock.cpp
index f97e0bf401..a363c3612d 100644
--- a/xbmc/video/VideoReferenceClock.cpp
+++ b/xbmc/video/VideoReferenceClock.cpp
@@ -28,6 +28,7 @@
#include "guilib/GraphicContext.h"
#include "video/videosync/VideoSync.h"
#include "windowing/WindowingFactory.h"
+#include "settings/Settings.h"
#if defined(HAS_GLX)
#include "video/videosync/VideoSyncGLX.h"
@@ -72,6 +73,13 @@ CVideoReferenceClock::~CVideoReferenceClock()
{
}
+void CVideoReferenceClock::Start()
+{
+ CSingleExit lock(g_graphicsContext);
+ if(CSettings::Get().GetBool("videoplayer.usedisplayasclock") && !IsRunning())
+ Create();
+}
+
void CVideoReferenceClock::Stop()
{
CSingleExit lock(g_graphicsContext);
diff --git a/xbmc/video/VideoReferenceClock.h b/xbmc/video/VideoReferenceClock.h
index 937b53e323..d0a9c3f9f1 100644
--- a/xbmc/video/VideoReferenceClock.h
+++ b/xbmc/video/VideoReferenceClock.h
@@ -39,6 +39,7 @@ class CVideoReferenceClock : public CThread
bool GetClockInfo(int& MissedVblanks, double& ClockSpeed, double& RefreshRate);
void SetFineAdjust(double fineadjust);
void RefreshChanged();
+ void Start();
void Stop();
private: