diff options
author | Peter Frühberger <Peter.Fruehberger@gmail.com> | 2024-10-19 10:10:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-19 10:10:59 +0200 |
commit | 93dc72679b7364201beebf320de433ebf9ddd570 (patch) | |
tree | c459f850be79f8ed4672834f29c1b0a336d06b0d | |
parent | ad51569897c335f0183e7567457e8824047bb22e (diff) | |
parent | eb62ba12e1d61e037aae40f320fdd1de5807b372 (diff) |
Merge pull request #25829 from fritsch/cache3
AudioTrack: Revisit pause bursts and delay
-rw-r--r-- | xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAESink.cpp | 7 | ||||
-rw-r--r-- | xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp | 77 |
2 files changed, 24 insertions, 60 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<decltype(m_extSilenceTimeout)>::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 { diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkAUDIOTRACK.cpp index 149bc7a268..875901b158 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 <numeric> + #include <androidjni/AudioFormat.h> #include <androidjni/AudioManager.h> #include <androidjni/AudioTrack.h> @@ -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,49 +922,28 @@ unsigned int CAESinkAUDIOTRACK::AddPackets(uint8_t **data, unsigned int frames, } unsigned int written_frames = static_cast<unsigned int>(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 - { - // waiting should only be done if sink is not run dry - double period_time = m_format.m_frames / static_cast<double>(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; } @@ -1248,7 +1222,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 +1234,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; } |