diff --git a/app/streaming/audio/audio.cpp b/app/streaming/audio/audio.cpp index b41c60ec..6ccc2f43 100644 --- a/app/streaming/audio/audio.cpp +++ b/app/streaming/audio/audio.cpp @@ -28,6 +28,22 @@ IAudioRenderer* Session::createAudioRenderer() #endif } +int Session::getAudioRendererCapabilities() +{ + IAudioRenderer* audioRenderer; + + audioRenderer = createAudioRenderer(); + if (audioRenderer == nullptr) { + return 0; + } + + int caps = audioRenderer->getCapabilities(); + + delete audioRenderer; + + return caps; +} + bool Session::testAudio(int audioConfiguration) { IAudioRenderer* audioRenderer; diff --git a/app/streaming/audio/renderers/renderer.h b/app/streaming/audio/renderers/renderer.h index 52880c73..1d9901c6 100644 --- a/app/streaming/audio/renderers/renderer.h +++ b/app/streaming/audio/renderers/renderer.h @@ -13,4 +13,6 @@ public: // Return false if an unrecoverable error has occurred and the renderer must be reinitialized virtual bool submitAudio(int bytesWritten) = 0; + + virtual int getCapabilities() = 0; }; diff --git a/app/streaming/audio/renderers/sdl.h b/app/streaming/audio/renderers/sdl.h index 0a186096..53716fa7 100644 --- a/app/streaming/audio/renderers/sdl.h +++ b/app/streaming/audio/renderers/sdl.h @@ -16,6 +16,8 @@ public: virtual bool submitAudio(int bytesWritten); + virtual int getCapabilities(); + private: SDL_AudioDeviceID m_AudioDevice; void* m_AudioBuffer; diff --git a/app/streaming/audio/renderers/sdlaud.cpp b/app/streaming/audio/renderers/sdlaud.cpp index e8ceb828..84d3e096 100644 --- a/app/streaming/audio/renderers/sdlaud.cpp +++ b/app/streaming/audio/renderers/sdlaud.cpp @@ -100,3 +100,8 @@ bool SdlAudioRenderer::submitAudio(int bytesWritten) return true; } + +int SdlAudioRenderer::getCapabilities() +{ + return CAPABILITY_DIRECT_SUBMIT; +} diff --git a/app/streaming/audio/renderers/slaud.cpp b/app/streaming/audio/renderers/slaud.cpp index 27e72866..5e7e1ff4 100644 --- a/app/streaming/audio/renderers/slaud.cpp +++ b/app/streaming/audio/renderers/slaud.cpp @@ -90,6 +90,11 @@ bool SLAudioRenderer::submitAudio(int bytesWritten) return true; } +int SLAudioRenderer::getCapabilities() +{ + return CAPABILITY_SLOW_OPUS_DECODER; +} + void SLAudioRenderer::slLogCallback(void*, ESLAudioLog logLevel, const char *message) { SDL_LogPriority priority; diff --git a/app/streaming/audio/renderers/slaud.h b/app/streaming/audio/renderers/slaud.h index 52bf8d88..4c2829fc 100644 --- a/app/streaming/audio/renderers/slaud.h +++ b/app/streaming/audio/renderers/slaud.h @@ -16,6 +16,8 @@ public: virtual bool submitAudio(int bytesWritten); + virtual int getCapabilities(); + private: static void slLogCallback(void* context, ESLAudioLog logLevel, const char* message); diff --git a/app/streaming/audio/renderers/soundioaudiorenderer.cpp b/app/streaming/audio/renderers/soundioaudiorenderer.cpp index 2e18ec74..ff479b58 100644 --- a/app/streaming/audio/renderers/soundioaudiorenderer.cpp +++ b/app/streaming/audio/renderers/soundioaudiorenderer.cpp @@ -317,6 +317,11 @@ bool SoundIoAudioRenderer::submitAudio(int bytesWritten) return true; } +int SoundIoAudioRenderer::getCapabilities() +{ + return CAPABILITY_DIRECT_SUBMIT; +} + void SoundIoAudioRenderer::sioErrorCallback(SoundIoOutStream* stream, int err) { auto me = reinterpret_cast(stream->userdata); diff --git a/app/streaming/audio/renderers/soundioaudiorenderer.h b/app/streaming/audio/renderers/soundioaudiorenderer.h index ad29bb04..cc8c7b5e 100644 --- a/app/streaming/audio/renderers/soundioaudiorenderer.h +++ b/app/streaming/audio/renderers/soundioaudiorenderer.h @@ -17,6 +17,8 @@ public: virtual bool submitAudio(int bytesWritten); + virtual int getCapabilities(); + private: int scoreChannelLayout(const struct SoundIoChannelLayout* layout, const OPUS_MULTISTREAM_CONFIGURATION* opusConfig); diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 0915cb94..20ca983b 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -43,22 +43,6 @@ CONNECTION_LISTENER_CALLBACKS Session::k_ConnCallbacks = { Session::clConnectionStatusUpdate }; -AUDIO_RENDERER_CALLBACKS Session::k_AudioCallbacks = { - Session::arInit, - nullptr, - nullptr, - Session::arCleanup, - Session::arDecodeAndPlaySample, -#ifndef STEAM_LINK - CAPABILITY_DIRECT_SUBMIT -#else - // We cannot use direct submit for Steam Link because the - // SLAudio renderer needs to look at the audio backlog to - // cap latency since playback is a blocking operation. - CAPABILITY_SLOW_OPUS_DECODER -#endif -}; - Session* Session::s_ActiveSession; QSemaphore Session::s_ActiveSessionSemaphore(1); @@ -365,6 +349,12 @@ bool Session::initialize() "Encoder configured for %d slices per frame", slices); + LiInitializeAudioCallbacks(&m_AudioCallbacks); + m_AudioCallbacks.init = arInit; + m_AudioCallbacks.cleanup = arCleanup; + m_AudioCallbacks.decodeAndPlaySample = arDecodeAndPlaySample; + m_AudioCallbacks.capabilities = getAudioRendererCapabilities(); + LiInitializeStreamConfiguration(&m_StreamConfig); m_StreamConfig.width = m_Preferences->width; m_StreamConfig.height = m_Preferences->height; @@ -948,7 +938,7 @@ void Session::exec(int displayOriginX, int displayOriginY) int err = LiStartConnection(&hostInfo, &m_StreamConfig, &k_ConnCallbacks, &m_VideoCallbacks, - m_AudioDisabled ? nullptr : &k_AudioCallbacks, + m_AudioDisabled ? nullptr : &m_AudioCallbacks, NULL, 0, NULL, 0); if (err != 0) { // We already displayed an error dialog in the stage failure diff --git a/app/streaming/session.h b/app/streaming/session.h index 16805c56..4392d47c 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -72,6 +72,8 @@ private: bool testAudio(int audioConfiguration); + int getAudioRendererCapabilities(); + void getWindowDimensions(int& x, int& y, int& width, int& height); @@ -129,6 +131,7 @@ private: StreamingPreferences* m_Preferences; STREAM_CONFIGURATION m_StreamConfig; DECODER_RENDERER_CALLBACKS m_VideoCallbacks; + AUDIO_RENDERER_CALLBACKS m_AudioCallbacks; NvComputer* m_Computer; NvApp m_App; SDL_Window* m_Window; @@ -158,7 +161,6 @@ private: Overlay::OverlayManager m_OverlayManager; - static AUDIO_RENDERER_CALLBACKS k_AudioCallbacks; static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks; static Session* s_ActiveSession; static QSemaphore s_ActiveSessionSemaphore;