diff options
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayer.cpp | 107 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayer.h | 4 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 36 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.h | 5 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerVideo.cpp | 6 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerVideo.h | 3 |
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(); |