diff options
author | elupus <elupus@xbmc.org> | 2011-11-09 22:38:41 +0100 |
---|---|---|
committer | elupus <elupus@xbmc.org> | 2011-11-09 22:38:41 +0100 |
commit | 6922560658abeaddfb86e897f1152dd268272376 (patch) | |
tree | 6c383ce30e5755e495c20105512ce52ae36da92e | |
parent | 35b27ddf0f7310b0321ea9d710a554000e08d5c2 (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.cpp | 25 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDAudio.h | 1 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDPlayerAudio.cpp | 18 |
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; } |