aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Hochecker <fernetmenta@online.de>2014-12-30 21:40:06 +0100
committerRainer Hochecker <fernetmenta@online.de>2014-12-30 21:40:06 +0100
commita3a4154b45df3a08b731577b2e7cba15c8fbcaa0 (patch)
tree6f4d22eb775da1e6be5635d352ba4c5c9f6512c9
parente8b707af7f4a1f2564c4d9f4cb857c7da0fa9066 (diff)
parent46373a0afbd72da0902e9cf970d8e53491a1e9d1 (diff)
Merge pull request #6044 from FernetMenta/audio
dvdplayer: make audioplayer sync to dvdclock without changing it
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.cpp92
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.h18
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.cpp49
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.h1
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; }