aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.cpp107
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayer.h4
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.cpp36
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.h5
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.cpp6
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerVideo.h3
6 files changed, 92 insertions, 69 deletions
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp
index 50bc779e37..3d0a8a6117 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp
@@ -283,7 +283,6 @@ CDVDPlayer::CDVDPlayer(IPlayerCallback& callback)
m_errorCount = 0;
m_playSpeed = DVD_PLAYSPEED_NORMAL;
m_caching = CACHESTATE_DONE;
- m_seeking = false;
m_pDlgCache = NULL;
@@ -321,7 +320,6 @@ bool CDVDPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
m_pDlgCache = new CDlgCache(3000, "" , m_item.GetLabel());
m_bAbortRequest = false;
- m_seeking = false;
SetPlaySpeed(DVD_PLAYSPEED_NORMAL);
m_State.Clear();
@@ -843,12 +841,8 @@ void CDVDPlayer::Process()
if (m_pDlgCache)
m_pDlgCache->SetMessage(g_localizeStrings.Get(10213));
-#if 0 // disable this untill our queues are time based
- if(!m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
- && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_TV)
- && !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_HTSP))
- SetCaching(CACHESTATE_FULL);
-#endif
+ // make sure all selected stream have data on startup
+ SetCaching(CACHESTATE_INIT);
while (!m_bAbortRequest)
{
@@ -914,8 +908,7 @@ void CDVDPlayer::Process()
|| (!m_dvdPlayerVideo.AcceptsData() && m_CurrentVideo.id >= 0))
{
Sleep(10);
- if (m_caching)
- SetCaching(CACHESTATE_DONE);
+ SetCaching(CACHESTATE_DONE);
continue;
}
@@ -995,8 +988,7 @@ void CDVDPlayer::Process()
m_CurrentTeletext.inited = false;
// if we are caching, start playing it again
- if (m_caching && !m_bAbortRequest)
- SetCaching(CACHESTATE_DONE);
+ SetCaching(CACHESTATE_DONE);
// while players are still playing, keep going to allow seekbacks
if(m_dvdPlayerAudio.m_messageQueue.GetDataSize() > 0
@@ -1107,8 +1099,7 @@ void CDVDPlayer::ProcessAudioData(CDemuxStream* pStream, DemuxPacket* pPacket)
}
// check if we are too slow and need to recache
- if(CheckStartCaching(m_CurrentAudio) && m_dvdPlayerAudio.IsStalled())
- SetCaching(CACHESTATE_FULL);
+ CheckStartCaching(m_CurrentAudio);
CheckContinuity(m_CurrentAudio, pPacket);
if(pPacket->dts != DVD_NOPTS_VALUE)
@@ -1143,8 +1134,7 @@ void CDVDPlayer::ProcessVideoData(CDemuxStream* pStream, DemuxPacket* pPacket)
}
// check if we are too slow and need to recache
- if(CheckStartCaching(m_CurrentVideo) && m_dvdPlayerVideo.IsStalled())
- SetCaching(CACHESTATE_FULL);
+ CheckStartCaching(m_CurrentVideo);
if( pPacket->iSize != 4) //don't check the EOF_SEQUENCE of stillframes
{
@@ -1233,6 +1223,21 @@ void CDVDPlayer::ProcessTeletextData(CDemuxStream* pStream, DemuxPacket* pPacket
void CDVDPlayer::HandlePlaySpeed()
{
+ if(m_caching == CACHESTATE_INIT)
+ {
+ // if all enabled streams have been inited we are done
+ if((m_CurrentVideo.id < 0 || m_CurrentVideo.inited)
+ && (m_CurrentAudio.id < 0 || m_CurrentAudio.inited))
+ SetCaching(CACHESTATE_PLAY);
+ }
+ if(m_caching == CACHESTATE_PLAY)
+ {
+ // if all enabled streams have started playing we are done
+ if((m_CurrentVideo.id < 0 || !m_dvdPlayerVideo.AcceptsData() || !m_dvdPlayerVideo.IsStalled())
+ && (m_CurrentAudio.id < 0 || !m_dvdPlayerAudio.AcceptsData() || !m_dvdPlayerAudio.IsStalled()))
+ SetCaching(CACHESTATE_DONE);
+ }
+
if(GetPlaySpeed() != DVD_PLAYSPEED_NORMAL && GetPlaySpeed() != DVD_PLAYSPEED_PAUSE)
{
if (IsInMenu())
@@ -1274,9 +1279,25 @@ void CDVDPlayer::HandlePlaySpeed()
bool CDVDPlayer::CheckStartCaching(CCurrentStream& current)
{
- return !m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)
- && m_caching == CACHESTATE_DONE && m_playSpeed == DVD_PLAYSPEED_NORMAL
- && current.inited;
+ if(m_caching != CACHESTATE_DONE
+ || m_playSpeed != DVD_PLAYSPEED_NORMAL)
+ return false;
+
+ if(current.type == STREAM_AUDIO && m_dvdPlayerAudio.IsStalled()
+ || current.type == STREAM_VIDEO && m_dvdPlayerVideo.IsStalled())
+ {
+ if(m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD))
+ SetCaching(CACHESTATE_INIT);
+ else
+ {
+ if(current.inited)
+ SetCaching(CACHESTATE_FULL);
+ else
+ SetCaching(CACHESTATE_INIT);
+ }
+ return true;
+ }
+ return false;
}
bool CDVDPlayer::CheckPlayerInit(CCurrentStream& current, unsigned int source)
@@ -1958,22 +1979,23 @@ void CDVDPlayer::SetCaching(ECacheState state)
if(m_caching == state)
return;
- if(state != CACHESTATE_DONE)
+ CLog::Log(LOGDEBUG, "CDVDPlayer::SetCaching - caching state %d", state);
+ if(state == CACHESTATE_FULL
+ || state == CACHESTATE_INIT)
{
- CLog::Log(LOGDEBUG, "CDVDPlayer::SetCaching - started caching");
m_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);
m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_caching = state;
}
- else
+
+ if(state == CACHESTATE_PLAY
+ || state == CACHESTATE_DONE)
{
- CLog::Log(LOGDEBUG, "CDVDPlayer::SetCaching - stopped caching");
m_clock.SetSpeed(m_playSpeed);
m_dvdPlayerAudio.SetSpeed(m_playSpeed);
m_dvdPlayerVideo.SetSpeed(m_playSpeed);
- m_caching = state;
}
+ m_caching = state;
}
void CDVDPlayer::SetPlaySpeed(int speed)
@@ -2699,6 +2721,18 @@ void CDVDPlayer::FlushBuffers(bool queued)
// clear subtitle and menu overlays
m_overlayContainer.Clear();
+
+ // make sure players are properly flushed, should put them in stalled state
+ CDVDMsgGeneralSynchronize* msg = new CDVDMsgGeneralSynchronize(1000, 0);
+ msg->Acquire();
+ m_dvdPlayerAudio.m_messageQueue.Put(msg, 1);
+ msg->Acquire();
+ m_dvdPlayerVideo.m_messageQueue.Put(msg, 1);
+ msg->Wait(&m_bStop, 0);
+ msg->Release();
+
+ // we should now wait for init cache
+ SetCaching(CACHESTATE_INIT);
}
m_CurrentAudio.inited = false;
m_CurrentVideo.inited = false;
@@ -3440,32 +3474,11 @@ CStdString CDVDPlayer::GetPlayingTitle()
CDVDPlayer::CPlayerSeek::CPlayerSeek(CDVDPlayer* player)
: m_player(*player)
{
- if(m_player.m_playSpeed != DVD_PLAYSPEED_NORMAL)
- return;
-
- if(m_player.m_caching)
- return;
-
g_infoManager.SetDisplayAfterSeek(100000);
- m_player.m_seeking = true;
- m_player.m_playSpeed = DVD_PLAYSPEED_PAUSE;
- m_player.m_clock.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_player.m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_PAUSE);
- m_player.m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_PAUSE);
+ m_player.SetCaching(CACHESTATE_INIT);
}
CDVDPlayer::CPlayerSeek::~CPlayerSeek()
{
- if(m_player.m_playSpeed != DVD_PLAYSPEED_PAUSE)
- return;
-
- if(m_player.m_caching)
- return;
-
g_infoManager.SetDisplayAfterSeek();
- m_player.m_playSpeed = DVD_PLAYSPEED_NORMAL;
- m_player.m_dvdPlayerAudio.SetSpeed(DVD_PLAYSPEED_NORMAL);
- m_player.m_dvdPlayerVideo.SetSpeed(DVD_PLAYSPEED_NORMAL);
- m_player.m_clock.SetSpeed(DVD_PLAYSPEED_NORMAL);
- m_player.m_seeking = false;
}
diff --git a/xbmc/cores/dvdplayer/DVDPlayer.h b/xbmc/cores/dvdplayer/DVDPlayer.h
index 32fd2269ca..bc603df393 100644
--- a/xbmc/cores/dvdplayer/DVDPlayer.h
+++ b/xbmc/cores/dvdplayer/DVDPlayer.h
@@ -213,7 +213,8 @@ public:
enum ECacheState
{ CACHESTATE_DONE = 0
, CACHESTATE_FULL // player is filling up the demux queue
- , CACHESTATE_NEXT // player is waiting for first packet of each stream
+ , CACHESTATE_INIT // player is waiting for first packet of each stream
+ , CACHESTATE_PLAY // player is waiting for players to not be stalled
};
virtual bool IsCaching() const { return m_caching == CACHESTATE_FULL; }
@@ -285,7 +286,6 @@ protected:
std::string m_filename; // holds the actual filename
std::string m_content; // hold a hint to what content file contains (mime type)
ECacheState m_caching;
- bool m_seeking; // player is currently trying to fullfill a seek request
CFileItem m_item;
CCurrentStream m_CurrentAudio;
diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
index 27e67e941f..3c14f584a2 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
@@ -135,8 +135,8 @@ CDVDPlayerAudio::CDVDPlayerAudio(CDVDClock* pClock)
m_audioClock = 0;
m_droptime = 0;
m_speed = DVD_PLAYSPEED_NORMAL;
- m_stalled = false;
- m_started = false;
+ m_stalled = true;
+ m_duration = 0.0;
m_freq = CurrentHostFrequency();
@@ -171,8 +171,7 @@ bool CDVDPlayerAudio::OpenStream( CDVDStreamInfo &hints )
m_droptime = 0;
m_audioClock = 0;
- m_stalled = false;
- m_started = false;
+ m_stalled = true;
m_synctype = SYNC_DISCON;
m_setsynctype = g_guiSettings.GetInt("videoplayer.synctype");
@@ -274,7 +273,6 @@ bool CDVDPlayerAudio::OpenDecoder(CDVDStreamInfo &hints, BYTE* buffer /* = NULL*
int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
{
int result = 0;
- int datatimeout = 1000;
// make sure the sent frame is clean
memset(&audioframe, 0, sizeof(DVDAudioFrame));
@@ -336,9 +334,11 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
// increase audioclock to after the packet
m_audioClock += audioframe.duration;
- datatimeout = (unsigned int)(DVD_TIME_TO_MSEC(audioframe.duration * 2.0));
}
+ if(audioframe.duration > 0)
+ m_duration = audioframe.duration;
+
// if demux source want's us to not display this, continue
if(m_decode.msg->GetPacketDrop())
continue;
@@ -357,10 +357,17 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
if (m_messageQueue.ReceivedAbortRequest()) return DECODE_FLAG_ABORT;
CDVDMsg* pMsg;
- int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE) ? 1 : 0;
+ int priority = (m_speed == DVD_PLAYSPEED_PAUSE) ? 1 : 0;
+
+ int timeout;
+ if(m_duration > 0)
+ timeout = (int)(1000 * (m_duration / DVD_TIME_BASE + m_dvdAudio.GetCacheTime()));
+ else
+ timeout = 1000;
+
// read next packet and return -1 on error
LeaveCriticalSection(&m_critCodecSection); //Leave here as this might stall a while
- MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, datatimeout, iPriority);
+ MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority);
EnterCriticalSection(&m_critCodecSection);
if (ret == MSGQ_TIMEOUT)
@@ -413,6 +420,7 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
m_ptsInput.Flush();
m_resampler.Flush();
m_syncclock = true;
+ m_stalled = true;
if (m_pAudioCodec)
m_pAudioCodec->Reset();
@@ -493,8 +501,7 @@ void CDVDPlayerAudio::Process()
if( result & DECODE_FLAG_TIMEOUT )
{
- if(m_started)
- m_stalled = true;
+ m_stalled = true;
continue;
}
@@ -512,9 +519,6 @@ void CDVDPlayerAudio::Process()
if( audioframe.size == 0 )
continue;
- m_stalled = false;
- m_started = true;
-
packetadded = true;
// we have succesfully decoded an audio frame, setup renderer to match
@@ -536,6 +540,8 @@ void CDVDPlayerAudio::Process()
if(m_speed > 0)
m_droptime += audioframe.duration * DVD_PLAYSPEED_NORMAL / m_speed;
while( !m_bStop && m_droptime > m_pClock->GetAbsoluteClock() ) Sleep(1);
+
+ m_stalled = false;
}
else
{
@@ -545,6 +551,10 @@ void CDVDPlayerAudio::Process()
// add any packets play
packetadded = OutputPacket(audioframe);
+
+ // we are not running until something is cached in output device
+ if(m_stalled && m_dvdAudio.GetCacheTime() > 0.0)
+ m_stalled = false;
}
// store the delay for this pts value so we can calculate the current playing
diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h
index c42e8f7362..1fc45fdffe 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h
+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h
@@ -121,8 +121,7 @@ public:
double GetCurrentPts() { return m_ptsOutput.Current(); }
- bool IsStalled() { return m_stalled
- && m_messageQueue.GetDataSize() == 0; }
+ bool IsStalled() { return m_stalled; }
bool IsPassthrough() const;
protected:
@@ -173,7 +172,7 @@ protected:
int m_speed;
double m_droptime;
bool m_stalled;
- bool m_started;
+ double m_duration; // last packets duration
CDVDPlayerResampler m_resampler;
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
index 826f2131c0..c63aac63fd 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp
@@ -350,9 +350,10 @@ void CDVDPlayerVideo::Process()
continue;
//Okey, start rendering at stream fps now instead, we are likely in a stillframe
- if( !m_stalled && m_started )
+ if( !m_stalled )
{
- CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate);
+ if(m_started)
+ CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe detected, switching to forced %f fps", m_fFrameRate);
m_stalled = true;
pts+= frametime*4;
}
@@ -437,6 +438,7 @@ void CDVDPlayerVideo::Process()
m_iFrameRateLength = 1;
m_bAllowDrop = !m_bCalcFrameRate;
m_iFrameRateErr = 0;
+ m_stalled = true;
}
else if (pMsg->IsType(CDVDMsg::VIDEO_NOSKIP))
{
diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.h b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
index c6ac84600c..5ff23cca66 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerVideo.h
+++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.h
@@ -81,8 +81,7 @@ public:
double GetSubtitleDelay() { return m_iSubtitleDelay; }
void SetSubtitleDelay(double delay) { m_iSubtitleDelay = delay; }
- bool IsStalled() { return m_stalled
- && m_messageQueue.GetDataSize() == 0; }
+ bool IsStalled() { return m_stalled; }
int GetNrOfDroppedFrames() { return m_iDroppedFrames; }
bool InitializedOutputDevice();