diff options
-rw-r--r-- | xbmc/cores/dvdplayer/DVDAudio.cpp | 92 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDAudio.h | 18 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 49 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.h | 1 |
4 files changed, 51 insertions, 109 deletions
diff --git a/xbmc/cores/dvdplayer/DVDAudio.cpp b/xbmc/cores/dvdplayer/DVDAudio.cpp index 6514030357..9d7900e6b3 100644 --- a/xbmc/cores/dvdplayer/DVDAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDAudio.cpp @@ -31,66 +31,6 @@ using namespace std; -CPTSOutputQueue::CPTSOutputQueue() -{ - Flush(); -} - -void CPTSOutputQueue::Add(double pts, double delay, double duration, double timestamp) -{ - CSingleLock lock(m_sync); - - // don't accept a re-add, since that would cause time moving back - double last = m_queue.empty() ? m_current.pts : m_queue.back().pts; - if(last == pts) - return; - - TPTSItem item; - item.pts = pts; - item.timestamp = timestamp + delay; - item.duration = duration; - - // first one is applied directly - if(m_queue.empty() && m_current.pts == DVD_NOPTS_VALUE) - m_current = item; - else - m_queue.push(item); - - // call function to make sure the queue - // doesn't grow should nobody call it - Current(timestamp); -} -void CPTSOutputQueue::Flush() -{ - CSingleLock lock(m_sync); - - while( !m_queue.empty() ) m_queue.pop(); - m_current.pts = DVD_NOPTS_VALUE; - m_current.timestamp = 0.0; - m_current.duration = 0.0; -} - -double CPTSOutputQueue::Current(double timestamp) -{ - CSingleLock lock(m_sync); - - if(!m_queue.empty() && m_current.pts == DVD_NOPTS_VALUE) - { - m_current = m_queue.front(); - m_queue.pop(); - } - - while( !m_queue.empty() && timestamp >= m_queue.front().timestamp ) - { - m_current = m_queue.front(); - m_queue.pop(); - } - - if( m_current.timestamp == 0 ) return m_current.pts; - - return m_current.pts + min(m_current.duration, (timestamp - m_current.timestamp)); -} - CDVDAudio::CDVDAudio(volatile bool &bStop) : m_bStop(bStop) { @@ -160,13 +100,16 @@ void CDVDAudio::Destroy() m_iBitsPerSample = 0; m_bPassthrough = false; m_bPaused = true; - m_time.Flush(); + m_playingPts = DVD_NOPTS_VALUE; } unsigned int CDVDAudio::AddPackets(const DVDAudioFrame &audioframe) { CSingleLock lock (m_critSection); + m_playingPts = audioframe.pts - GetDelay(); + m_timeOfPts = CDVDClock::GetAbsoluteClock(); + if(!m_pAudioStream) return 0; @@ -198,11 +141,6 @@ unsigned int CDVDAudio::AddPackets(const DVDAudioFrame &audioframe) lock.Enter(); } while (!m_bStop); - double time_added = DVD_SEC_TO_TIME(m_SecondsPerByte * audioframe.nb_frames * audioframe.framesize); - double delay = GetDelay(); - double timestamp = CDVDClock::GetAbsoluteClock(); - m_time.Add(audioframe.pts, delay - time_added, audioframe.duration, timestamp); - return total - frames; } @@ -246,8 +184,9 @@ float CDVDAudio::GetCurrentAttenuation() void CDVDAudio::Pause() { CSingleLock lock (m_critSection); - if (m_pAudioStream) m_pAudioStream->Pause(); - m_time.Flush(); + if (m_pAudioStream) + m_pAudioStream->Pause(); + m_playingPts = DVD_NOPTS_VALUE; } void CDVDAudio::Resume() @@ -260,7 +199,7 @@ double CDVDAudio::GetDelay() { CSingleLock lock (m_critSection); - double delay = 0.0; + double delay = 0.3; if(m_pAudioStream) delay = m_pAudioStream->GetDelay(); @@ -275,7 +214,7 @@ void CDVDAudio::Flush() { m_pAudioStream->Flush(); } - m_time.Flush(); + m_playingPts = DVD_NOPTS_VALUE; } bool CDVDAudio::IsValidFormat(const DVDAudioFrame &audioframe) @@ -325,14 +264,15 @@ double CDVDAudio::GetCacheTotal() void CDVDAudio::SetPlayingPts(double pts) { - CSingleLock lock (m_critSection); - m_time.Flush(); - double delay = GetDelay(); - double timestamp = CDVDClock::GetAbsoluteClock(); - m_time.Add(pts, delay, 0, timestamp); + CSingleLock lock(m_critSection); + m_playingPts = pts - GetDelay(); + m_timeOfPts = CDVDClock::GetAbsoluteClock(); } double CDVDAudio::GetPlayingPts() { - return m_time.Current(CDVDClock::GetAbsoluteClock()); + if (m_playingPts == DVD_NOPTS_VALUE) + return 0.0; + + return m_playingPts + CDVDClock::GetAbsoluteClock() - m_timeOfPts; } diff --git a/xbmc/cores/dvdplayer/DVDAudio.h b/xbmc/cores/dvdplayer/DVDAudio.h index 629fb3237e..057a40a1f4 100644 --- a/xbmc/cores/dvdplayer/DVDAudio.h +++ b/xbmc/cores/dvdplayer/DVDAudio.h @@ -36,21 +36,6 @@ extern "C" { typedef struct stDVDAudioFrame DVDAudioFrame; -class CPTSOutputQueue -{ -private: - typedef struct {double pts; double timestamp; double duration;} TPTSItem; - TPTSItem m_current; - std::queue<TPTSItem> m_queue; - CCriticalSection m_sync; - -public: - CPTSOutputQueue(); - void Add(double pts, double delay, double duration, double timestamp); - void Flush(); - double Current(double timestamp); -}; - class CSingleLock; class CDVDAudio @@ -82,7 +67,8 @@ public: IAEStream *m_pAudioStream; protected: - CPTSOutputQueue m_time; + double m_playingPts; + double m_timeOfPts; CCriticalSection m_critSection; int m_iBitrate; diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp index fdd6696fac..baadbccbad 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp @@ -428,12 +428,11 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe) if (speed == DVD_PLAYSPEED_NORMAL) { m_dvdAudio.Resume(); + m_syncclock = true; } else { - m_syncclock = true; - if (speed != DVD_PLAYSPEED_PAUSE) - m_dvdAudio.Flush(); + m_dvdAudio.Flush(); m_dvdAudio.Pause(); } m_speed = speed; @@ -562,7 +561,7 @@ void CDVDPlayerAudio::Process() } // Zero out the frame data if we are supposed to silence the audio - if (m_silence) + if (m_silence || m_syncclock) { int size = audioframe.nb_frames * audioframe.framesize / audioframe.planes; for (unsigned int i=0; i<audioframe.planes; i++) @@ -639,21 +638,19 @@ void CDVDPlayerAudio::HandleSyncError(double duration) double absolute; double clock = m_pClock->GetClock(absolute); double error = m_dvdAudio.GetPlayingPts() - clock; - EMasterClock master = m_pClock->GetMaster(); - if( (fabs(error) > DVD_MSEC_TO_TIME(100) || m_syncclock) - && (master == MASTER_CLOCK_AUDIO - || master == MASTER_CLOCK_AUDIO_VIDEOREF) ) - { - m_pClock->Update(clock+error, absolute, 0.0, "CDVDPlayerAudio::HandleSyncError1"); - m_errors.Flush(); - m_error = 0; - m_syncclock = false; + m_errors.Add(error); + if (fabs(error) > DVD_MSEC_TO_TIME(100)) + { + m_syncclock = true; return; } - - m_errors.Add(error); + else if (m_syncclock && fabs(error) < DVD_MSEC_TO_TIME(50)) + { + m_syncclock = false; + m_errors.Flush(); + } //check if measured error for 2 seconds if (m_errors.Get(m_error)) @@ -707,7 +704,27 @@ void CDVDPlayerAudio::HandleSyncError(double duration) bool CDVDPlayerAudio::OutputPacket(DVDAudioFrame &audioframe) { - if (m_synctype == SYNC_DISCON) + if (m_syncclock) + { + double absolute; + double clock = m_pClock->GetClock(absolute); + double error = m_dvdAudio.GetPlayingPts() - clock; + m_dvdAudio.SetResampleRatio(1.0); + if (error > 0) + { + int dups = std::min(DVD_MSEC_TO_TIME(100), error) / audioframe.duration; + for (int i = 0; i < dups; i++) + { + m_dvdAudio.AddPackets(audioframe); + } + m_dvdAudio.AddPackets(audioframe); + } + else + { + m_dvdAudio.SetPlayingPts(m_audioClock); + } + } + else if (m_synctype == SYNC_DISCON) { m_dvdAudio.AddPackets(audioframe); } diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.h b/xbmc/cores/dvdplayer/DVDPlayerAudio.h index e8b2ab6086..5db89f6683 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerAudio.h +++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.h @@ -134,7 +134,6 @@ public: // holds stream information for current playing stream CDVDStreamInfo m_streaminfo; - CPTSOutputQueue m_ptsOutput; CPTSInputQueue m_ptsInput; double GetCurrentPts() { CSingleLock lock(m_info_section); return m_info.pts; } |