diff options
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp | 41 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h | 2 |
2 files changed, 27 insertions, 16 deletions
diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp index 0d80d1e243..ca295496bf 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.cpp @@ -22,6 +22,7 @@ #include "AESinkPULSE.h" #include "utils/log.h" #include "Util.h" +#include "utils/TimeUtils.h" #include "guilib/LocalizeStrings.h" #include "Application.h" @@ -439,6 +440,8 @@ CAESinkPULSE::CAESinkPULSE() m_MainLoop = NULL; m_BytesPerSecond = 0; m_BufferSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; m_Channels = 0; m_Stream = NULL; m_Context = NULL; @@ -462,6 +465,8 @@ bool CAESinkPULSE::Initialize(AEAudioFormat &format, std::string &device) m_passthrough = false; m_BytesPerSecond = 0; m_BufferSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; m_Channels = 0; m_Stream = NULL; m_Context = NULL; @@ -694,6 +699,8 @@ void CAESinkPULSE::Deinitialize() m_IsAllocated = false; m_passthrough = false; m_periodSize = 0; + m_filled_bytes = 0; + m_lastPackageStamp = 0; if (m_Stream) Drain(); @@ -730,25 +737,24 @@ void CAESinkPULSE::GetDelay(AEDelayStatus& status) status.SetDelay(0); return; } - int error = 0; - pa_usec_t latency = (pa_usec_t) -1; + pa_threaded_mainloop_lock(m_MainLoop); - if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0) - { - if (error == -PA_ERR_NODATA) - { - WaitForOperation(pa_stream_update_timing_info(m_Stream, NULL,NULL), m_MainLoop, "Update Timing Information"); - if ((error = pa_stream_get_latency(m_Stream, &latency, NULL)) < 0) - { - CLog::Log(LOGDEBUG, "GetDelay - Failed to get Latency %d", error); - } - } - } - if (error < 0 ) - latency = (pa_usec_t) 0; + const pa_timing_info* pti = pa_stream_get_timing_info(m_Stream); + // only incorporate local sink delay + internal PA transport delay + double sink_delay = (pti->configured_sink_usec / 1000000.0); + double transport_delay = pti->transport_usec / 1000000.0; + + uint64_t diff = CurrentHostCounter() - m_lastPackageStamp; + unsigned int bytes_played = (unsigned int) ((double) diff * (double) m_BytesPerSecond / (double) CurrentHostFrequency() + 0.5); + + int buffer_delay = m_filled_bytes - bytes_played; + if (buffer_delay < 0) + buffer_delay = 0; pa_threaded_mainloop_unlock(m_MainLoop); - status.SetDelay(latency / 1000000.0); + + double delay = buffer_delay / (double) m_BytesPerSecond + sink_delay + transport_delay; + status.SetDelay(delay); } double CAESinkPULSE::GetCacheTotal() @@ -775,6 +781,7 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig while ((length = pa_stream_writable_size(m_Stream)) < m_periodSize) pa_threaded_mainloop_wait(m_MainLoop); + unsigned int free = length; length = std::min((unsigned int)length, available); int error = pa_stream_write(m_Stream, buffer, length, NULL, 0, PA_SEEK_RELATIVE); @@ -785,6 +792,8 @@ unsigned int CAESinkPULSE::AddPackets(uint8_t **data, unsigned int frames, unsig CLog::Log(LOGERROR, "CPulseAudioDirectSound::AddPackets - pa_stream_write failed\n"); return 0; } + m_lastPackageStamp = CurrentHostCounter(); + m_filled_bytes = m_BufferSize - (free - length); unsigned int res = (unsigned int)(length / m_format.m_frameSize); return res; diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h index 46e9db50cb..c04bc18291 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPULSE.h @@ -71,6 +71,8 @@ private: pa_cvolume m_Volume; bool m_volume_needs_update; uint32_t m_periodSize; + uint64_t m_lastPackageStamp; + uint64_t m_filled_bytes; pa_context *m_Context; pa_threaded_mainloop *m_MainLoop; |