aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelupus <elupus@xbmc.org>2011-11-09 22:38:41 +0100
committerelupus <elupus@xbmc.org>2011-11-09 22:38:41 +0100
commit6922560658abeaddfb86e897f1152dd268272376 (patch)
tree6c383ce30e5755e495c20105512ce52ae36da92e
parent35b27ddf0f7310b0321ea9d710a554000e08d5c2 (diff)
changed: add silence instead of flushing audio device on timout
This reduces the choppyness of live streams where our buffer run dry.
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.cpp25
-rw-r--r--xbmc/cores/dvdplayer/DVDAudio.h1
-rw-r--r--xbmc/cores/dvdplayer/DVDPlayerAudio.cpp18
3 files changed, 38 insertions, 6 deletions
diff --git a/xbmc/cores/dvdplayer/DVDAudio.cpp b/xbmc/cores/dvdplayer/DVDAudio.cpp
index 5c0fbaa45d..cc87b4fb54 100644
--- a/xbmc/cores/dvdplayer/DVDAudio.cpp
+++ b/xbmc/cores/dvdplayer/DVDAudio.cpp
@@ -230,6 +230,31 @@ DWORD CDVDAudio::AddPackets(const DVDAudioFrame &audioframe)
return total;
}
+double CDVDAudio::AddSilence(double delay)
+{
+ CLog::Log(LOGDEBUG, "CDVDAudio::AddSilence - %f seconds", delay);
+ DVDAudioFrame audioframe;
+ audioframe.passthrough = m_bPassthrough;
+ audioframe.channels = m_iChannels;
+ audioframe.sample_rate = m_iBitrate;
+ audioframe.bits_per_sample = m_iBitsPerSample;
+ audioframe.size = m_iChannels * (m_iBitsPerSample>>3);
+ audioframe.data = (BYTE*)calloc(1, audioframe.size);
+ if(audioframe.data == NULL)
+ return 0.0;
+ unsigned samples = m_iBitrate * delay;
+ unsigned added = 0;
+ for(; added < samples; added++)
+ {
+ if(AddPackets(audioframe) != audioframe.size)
+ break;
+ }
+ if(added < samples)
+ CLog::Log(LOGDEBUG, "CDVDAudio::AddSilence - failed to %d silence samples of %u", samples - added, samples);
+ free(audioframe.data);
+ return (double)added / m_iBitrate;
+}
+
void CDVDAudio::Finish()
{
CSingleLock lock (m_critSection);
diff --git a/xbmc/cores/dvdplayer/DVDAudio.h b/xbmc/cores/dvdplayer/DVDAudio.h
index e483936202..1f1393d72b 100644
--- a/xbmc/cores/dvdplayer/DVDAudio.h
+++ b/xbmc/cores/dvdplayer/DVDAudio.h
@@ -66,6 +66,7 @@ public:
bool IsValidFormat(const DVDAudioFrame &audioframe);
void Destroy();
DWORD AddPackets(const DVDAudioFrame &audioframe);
+ double AddSilence(double delay);
double GetDelay(); // returns the time it takes to play a packet if we add one at this time
double GetCacheTime(); // returns total amount of data cached in audio output at this time
double GetCacheTotal(); // returns total amount the audio device can buffer
diff --git a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
index 00916ff673..266884ae93 100644
--- a/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
+++ b/xbmc/cores/dvdplayer/DVDPlayerAudio.cpp
@@ -386,12 +386,18 @@ int CDVDPlayerAudio::DecodeFrame(DVDAudioFrame &audioframe, bool bDropPacket)
CDVDMsg* pMsg;
int priority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0;
-
int timeout;
- if(m_duration > 0)
- timeout = (int)(1000 * (m_duration / DVD_TIME_BASE + m_dvdAudio.GetCacheTime()));
+
+ double cached = m_dvdAudio.GetCacheTime();
+ if(cached > 0.0)
+ {
+ if(cached > 0.2)
+ timeout = (int)(1000 * (cached - 0.2));
+ else
+ timeout = 0; /* in a hurry, try to fill with something as soon as possible */
+ }
else
- timeout = 1000;
+ timeout = 1000; /* if nothing cached, we can just as well wait for a while */
// read next packet and return -1 on error
MsgQueueReturnCode ret = m_messageQueue.Get(&pMsg, timeout, priority);
@@ -550,9 +556,9 @@ void CDVDPlayerAudio::Process()
{
m_stalled = true;
- // Flush as the audio output may keep looping if we don't
+ // Add some silence to keep renderer from draining
if(m_speed == DVD_PLAYSPEED_NORMAL)
- m_dvdAudio.Flush();
+ m_dvdAudio.AddSilence(0.5);
continue;
}