From 583e0902e43a41eaed5df0008f2d24ec68ec2716 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sat, 12 Oct 2024 11:06:06 +0200 Subject: AESinkAudioTrack: Revisit Pause bursts for RAW - Properly Check Pause Bursts again - Do not weight the average as it's meant to smooth audio hal abruptness - Stop sleeping in normal AddPacket Use-Case --- xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 65 ++++++++--------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index 149bc7a268..5c29565aba 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -20,6 +20,8 @@ #include "platform/android/activity/XBMCApp.h" +#include + #include #include #include @@ -768,25 +770,16 @@ void CAESinkAUDIOTRACK::GetDelay(AEDelayStatus& status) // the RAW hack for simulating pause bursts should not come // into the way of hw delay + if (m_pause_ms > m_audiotrackbuffer_sec * 1000.0) + m_pause_ms = m_audiotrackbuffer_sec * 1000.0; + if (m_pause_ms > 0.0) { - double difference = (m_audiotrackbuffer_sec - delay) * 1000; - if (usesAdvancedLogging) - { - CLog::Log(LOGINFO, "Faking Pause-Bursts in Delay - returning smoothed {} ms Original {} ms", - m_audiotrackbuffer_sec * 1000, delay * 1000); - CLog::Log(LOGINFO, "Difference: {} ms m_pause_ms {}", difference, m_pause_ms); - } - // buffer not yet reached - if (difference > 0.0) + if (delay < m_audiotrackbuffer_sec) delay = m_audiotrackbuffer_sec; else - { - CLog::Log(LOGINFO, "Resetting pause bursts as buffer level was reached! (2)"); - m_pause_ms = 0.0; - } + m_audiotrackbuffer_sec = delay; } - const double d = GetMovingAverageDelay(delay); // Audiotrack is caching more than we thought it would @@ -798,6 +791,8 @@ void CAESinkAUDIOTRACK::GetDelay(AEDelayStatus& status) if (usesAdvancedLogging) { CLog::Log(LOGINFO, "Delay Current: {:f} ms", d * 1000); + if (m_pause_ms > 0.0) + CLog::Log(LOGINFO, "Delay faked due to pause delay: {:f} ms", m_pause_ms); } status.SetDelay(d); } @@ -927,35 +922,27 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t **data, unsigned int frames, } unsigned int written_frames = static_cast(written / m_format.m_frameSize); double time_to_add_ms = 1000.0 * (CurrentHostCounter() - startTime) / CurrentHostFrequency(); + // Get Back in Sync with faked pause bursts if (m_passthrough && !m_info.m_wantsIECPassthrough) { - // AT does not consume in a blocking way - it runs ahead and blocks - // exactly once with the last package for some 100 ms - double extra_sleep = 0.0; - if (time_to_add_ms < m_format.m_streamInfo.GetDuration()) - extra_sleep = (m_format.m_streamInfo.GetDuration() - time_to_add_ms) / 2; - - // if there is still place, just add it without blocking - if (m_delay < (m_audiotrackbuffer_sec - (m_format.m_streamInfo.GetDuration() / 1000.0))) - extra_sleep = 0; - if (m_pause_ms > 0.0) { - extra_sleep = 0; - m_pause_ms -= m_format.m_streamInfo.GetDuration(); + // Idea here is: Slowly correct the wrong buffer so that AE should not realize + // but do not underrun while doing so + double extra_sleep_ms = m_format.m_streamInfo.GetDuration() / 2.0 - time_to_add_ms; + if (extra_sleep_ms > 0) + { + CLog::Log(LOGDEBUG, "Sleeping for {:f}", extra_sleep_ms); + m_pause_ms -= extra_sleep_ms; + usleep(extra_sleep_ms * 1000); + } if (m_pause_ms <= 0.0) { m_pause_ms = 0.0; - CLog::Log(LOGINFO, "Resetting pause bursts as buffer level was reached! (1)"); + extra_sleep_ms = 0.0; + CLog::Log(LOGDEBUG, "Resetting pause bursts as buffer level was reached! (1)"); } } - else - { - if (m_delay > 0.3) - extra_sleep *= 2; - } - - usleep(extra_sleep * 1000); } else { @@ -969,7 +956,6 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t **data, unsigned int frames, usleep(time_off * 500); // sleep half the error on average away } } - return written_frames; } @@ -1248,7 +1234,6 @@ double CAESinkAUDIOTRACK::GetMovingAverageDelay(double newestdelay) return d; #endif - m_linearmovingaverage.push_back(newestdelay); // new values are in the back, old values are in the front @@ -1261,12 +1246,8 @@ double CAESinkAUDIOTRACK::GetMovingAverageDelay(double newestdelay) m_linearmovingaverage.pop_front(); size--; } - // m_{LWMA}^{(n)}(t) = \frac{2}{n (n+1)} \sum_{i=1}^n i \; x(t-n+i) - const double denom = 2.0 / (size * (size + 1)); - double sum = 0.0; - for (size_t i = 0; i < m_linearmovingaverage.size(); i++) - sum += (i + 1) * m_linearmovingaverage.at(i); + double sum = std::accumulate(m_linearmovingaverage.begin(), m_linearmovingaverage.end(), 0.0); - return sum * denom; + return sum / size; } -- cgit v1.2.3 From 33c70144f7dbfca50b05082bc88a9d6371e3be58 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sat, 12 Oct 2024 11:07:29 +0200 Subject: AESinkAudioTrack: Stop pseudo blocking for IEC The audio hal does not care if we sleep for it, it blocks itself when the buffer is filled. --- xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index 5c29565aba..875901b158 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp @@ -944,18 +944,6 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t **data, unsigned int frames, } } } - else - { - // waiting should only be done if sink is not run dry - double period_time = m_format.m_frames / static_cast(m_sink_sampleRate); - if (m_delay >= (m_audiotrackbuffer_sec - period_time)) - { - double time_should_ms = 1000.0 * written_frames / m_format.m_sampleRate; - double time_off = time_should_ms - time_to_add_ms; - if (time_off > 0) - usleep(time_off * 500); // sleep half the error on average away - } - } return written_frames; } -- cgit v1.2.3 From eb62ba12e1d61e037aae40f320fdd1de5807b372 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sat, 12 Oct 2024 14:59:09 +0200 Subject: Use Silence again for all formats (AddPause) --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp index f0cce1885b..9eb39fdc2c 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp @@ -1207,12 +1207,7 @@ void CActiveAESink::SetSilenceTimer() m_extSilenceTimeout = XbmcThreads::EndTime::Max(); else if (m_extAppFocused) // handles no playback/GUI and playback in pause and seek { - // only true with AudioTrack RAW + passthrough + TrueHD - const bool noSilenceOnPause = - !m_needIecPack && m_requestedFormat.m_dataFormat == AE_FMT_RAW && - m_sinkFormat.m_streamInfo.m_type == CAEStreamInfo::STREAM_TYPE_TRUEHD; - - m_extSilenceTimeout = (noSilenceOnPause) ? 0ms : m_silenceTimeOut; + m_extSilenceTimeout = m_silenceTimeOut; } else { -- cgit v1.2.3