From f8e693a060705faddbbebca77a059b33a5d923d6 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 14 Feb 2019 22:32:54 -0800 Subject: [PATCH] Drop samples to account for lost time reinitializing audio. Fixes #176 --- app/streaming/audio/audio.cpp | 27 +++++++++++++++++++++++++++ app/streaming/session.cpp | 3 ++- app/streaming/session.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/streaming/audio/audio.cpp b/app/streaming/audio/audio.cpp index c61312e2..e77d2d2b 100644 --- a/app/streaming/audio/audio.cpp +++ b/app/streaming/audio/audio.cpp @@ -115,6 +115,21 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength) } } + // See if we need to drop this sample + if (s_ActiveSession->m_DropAudioEndTime != 0) { + if (SDL_TICKS_PASSED(SDL_GetTicks(), s_ActiveSession->m_DropAudioEndTime)) { + // Avoid calling SDL_GetTicks() now + s_ActiveSession->m_DropAudioEndTime = 0; + + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Audio drop window has ended"); + } + else { + // We're still in the drop window + return; + } + } + s_ActiveSession->m_AudioSampleCount++; if (s_ActiveSession->m_AudioRenderer != nullptr) { @@ -145,10 +160,22 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength) // safe to reinitialize here because we can't be torn down while // the audio decoder/playback thread is still alive. if (s_ActiveSession->m_AudioRenderer == nullptr && (s_ActiveSession->m_AudioSampleCount % 200) == 0) { + // Since we're doing this inline and audio initialization takes time, we need + // to drop samples to account for the time we've spent blocking audio rendering + // so we return to real-time playback and don't accumulate latency. + Uint32 audioReinitStartTime = SDL_GetTicks(); + s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer(); if (!s_ActiveSession->m_AudioRenderer->prepareForPlayback(&s_ActiveSession->m_AudioConfig)) { delete s_ActiveSession->m_AudioRenderer; s_ActiveSession->m_AudioRenderer = nullptr; } + + Uint32 audioReinitStopTime = SDL_GetTicks(); + + s_ActiveSession->m_DropAudioEndTime = audioReinitStopTime + (audioReinitStopTime - audioReinitStartTime); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Audio reinitialization took %d ms - starting drop window", + audioReinitStopTime - audioReinitStartTime); } } diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 1cf661db..bdc91eb7 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -312,7 +312,8 @@ Session::Session(NvComputer* computer, NvApp& app, StreamingPreferences *prefere m_InputHandlerLock(0), m_OpusDecoder(nullptr), m_AudioRenderer(nullptr), - m_AudioSampleCount(0) + m_AudioSampleCount(0), + m_DropAudioEndTime(0) { } diff --git a/app/streaming/session.h b/app/streaming/session.h index 4b063ae2..d710f696 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -149,6 +149,7 @@ private: IAudioRenderer* m_AudioRenderer; OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig; int m_AudioSampleCount; + Uint32 m_DropAudioEndTime; Overlay::OverlayManager m_OverlayManager;