mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-02 15:55:39 +00:00
Rework audio renderer selection to fall back and treat ML_AUDIO as a hard selection
This commit is contained in:
parent
897f6fdd3e
commit
7acf91883a
@ -13,36 +13,87 @@
|
|||||||
|
|
||||||
#include <Limelight.h>
|
#include <Limelight.h>
|
||||||
|
|
||||||
IAudioRenderer* Session::createAudioRenderer()
|
#define TRY_INIT_RENDERER(renderer, opusConfig) \
|
||||||
{
|
{ \
|
||||||
#if defined(HAVE_SOUNDIO)
|
IAudioRenderer* __renderer = new renderer(); \
|
||||||
#ifdef Q_OS_LINUX
|
if (__renderer->prepareForPlayback(opusConfig)) \
|
||||||
// Default is SDL with libsoundio as an alternate
|
return __renderer; \
|
||||||
if (qgetenv("ML_AUDIO") == "libsoundio") {
|
delete __renderer; \
|
||||||
return new SoundIoAudioRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SdlAudioRenderer();
|
|
||||||
#else
|
|
||||||
// Default is libsoundio with SDL as an alternate
|
|
||||||
if (qgetenv("ML_AUDIO") == "SDL") {
|
|
||||||
return new SdlAudioRenderer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SoundIoAudioRenderer();
|
|
||||||
#endif
|
|
||||||
#elif defined(HAVE_SLAUDIO)
|
|
||||||
return new SLAudioRenderer();
|
|
||||||
#else
|
|
||||||
return new SdlAudioRenderer();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Session::getAudioRendererCapabilities()
|
IAudioRenderer* Session::createAudioRenderer(const POPUS_MULTISTREAM_CONFIGURATION opusConfig)
|
||||||
{
|
{
|
||||||
IAudioRenderer* audioRenderer;
|
// Handle explicit ML_AUDIO setting and fail if the requested backend fails
|
||||||
|
QString mlAudio = qgetenv("ML_AUDIO").toLower();
|
||||||
|
if (mlAudio == "sdl") {
|
||||||
|
TRY_INIT_RENDERER(SdlAudioRenderer, opusConfig)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_SOUNDIO
|
||||||
|
else if (mlAudio == "libsoundio") {
|
||||||
|
TRY_INIT_RENDERER(SoundIoAudioRenderer, opusConfig)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SLAUDIO)
|
||||||
|
else if (mlAudio == "slaudio") {
|
||||||
|
TRY_INIT_RENDERER(SLAudioRenderer, opusConfig)
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (!mlAudio.isEmpty()) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Unknown audio backend: %s",
|
||||||
|
SDL_getenv("ML_AUDIO"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
audioRenderer = createAudioRenderer();
|
// -------------- Automatic backend selection below this line ---------------
|
||||||
|
|
||||||
|
#if defined(HAVE_SLAUDIO)
|
||||||
|
// Steam Link should always have SLAudio
|
||||||
|
TRY_INIT_RENDERER(SLAudioRenderer, opusConfig)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_LINUX
|
||||||
|
// Linux defaults to SDL and fall backs to libsoundio
|
||||||
|
TRY_INIT_RENDERER(SdlAudioRenderer, opusConfig)
|
||||||
|
#ifdef HAVE_SOUNDIO
|
||||||
|
TRY_INIT_RENDERER(SoundIoAudioRenderer, opusConfig)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
// Windows and macOS default to libsoundio and fall back to SDL
|
||||||
|
#ifdef HAVE_SOUNDIO
|
||||||
|
TRY_INIT_RENDERER(SoundIoAudioRenderer, opusConfig)
|
||||||
|
#endif
|
||||||
|
TRY_INIT_RENDERER(SdlAudioRenderer, opusConfig)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Session::getAudioRendererCapabilities(int audioConfiguration)
|
||||||
|
{
|
||||||
|
// Build a fake OPUS_MULTISTREAM_CONFIGURATION to give
|
||||||
|
// the renderer the channel count and sample rate.
|
||||||
|
OPUS_MULTISTREAM_CONFIGURATION opusConfig = {};
|
||||||
|
opusConfig.sampleRate = 48000;
|
||||||
|
opusConfig.samplesPerFrame = 240;
|
||||||
|
|
||||||
|
switch (audioConfiguration)
|
||||||
|
{
|
||||||
|
case AUDIO_CONFIGURATION_STEREO:
|
||||||
|
opusConfig.channelCount = 2;
|
||||||
|
break;
|
||||||
|
case AUDIO_CONFIGURATION_51_SURROUND:
|
||||||
|
opusConfig.channelCount = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SDL_assert(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IAudioRenderer* audioRenderer = createAudioRenderer(&opusConfig);
|
||||||
if (audioRenderer == nullptr) {
|
if (audioRenderer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -56,13 +107,6 @@ int Session::getAudioRendererCapabilities()
|
|||||||
|
|
||||||
bool Session::testAudio(int audioConfiguration)
|
bool Session::testAudio(int audioConfiguration)
|
||||||
{
|
{
|
||||||
IAudioRenderer* audioRenderer;
|
|
||||||
|
|
||||||
audioRenderer = createAudioRenderer();
|
|
||||||
if (audioRenderer == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a fake OPUS_MULTISTREAM_CONFIGURATION to give
|
// Build a fake OPUS_MULTISTREAM_CONFIGURATION to give
|
||||||
// the renderer the channel count and sample rate.
|
// the renderer the channel count and sample rate.
|
||||||
OPUS_MULTISTREAM_CONFIGURATION opusConfig = {};
|
OPUS_MULTISTREAM_CONFIGURATION opusConfig = {};
|
||||||
@ -82,11 +126,14 @@ bool Session::testAudio(int audioConfiguration)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = audioRenderer->prepareForPlayback(&opusConfig);
|
IAudioRenderer* audioRenderer = createAudioRenderer(&opusConfig);
|
||||||
|
if (audioRenderer == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
delete audioRenderer;
|
delete audioRenderer;
|
||||||
|
|
||||||
return ret;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Session::arInit(int /* audioConfiguration */,
|
int Session::arInit(int /* audioConfiguration */,
|
||||||
@ -111,9 +158,8 @@ int Session::arInit(int /* audioConfiguration */,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer();
|
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer(opusConfig);
|
||||||
if (!s_ActiveSession->m_AudioRenderer->prepareForPlayback(opusConfig)) {
|
if (s_ActiveSession->m_AudioRenderer == nullptr) {
|
||||||
delete s_ActiveSession->m_AudioRenderer;
|
|
||||||
opus_multistream_decoder_destroy(s_ActiveSession->m_OpusDecoder);
|
opus_multistream_decoder_destroy(s_ActiveSession->m_OpusDecoder);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
@ -211,11 +257,7 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength)
|
|||||||
// so we return to real-time playback and don't accumulate latency.
|
// so we return to real-time playback and don't accumulate latency.
|
||||||
Uint32 audioReinitStartTime = SDL_GetTicks();
|
Uint32 audioReinitStartTime = SDL_GetTicks();
|
||||||
|
|
||||||
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer();
|
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer(&s_ActiveSession->m_AudioConfig);
|
||||||
if (!s_ActiveSession->m_AudioRenderer->prepareForPlayback(&s_ActiveSession->m_AudioConfig)) {
|
|
||||||
delete s_ActiveSession->m_AudioRenderer;
|
|
||||||
s_ActiveSession->m_AudioRenderer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint32 audioReinitStopTime = SDL_GetTicks();
|
Uint32 audioReinitStopTime = SDL_GetTicks();
|
||||||
|
|
||||||
|
@ -350,12 +350,6 @@ bool Session::initialize()
|
|||||||
"Encoder configured for %d slices per frame",
|
"Encoder configured for %d slices per frame",
|
||||||
slices);
|
slices);
|
||||||
|
|
||||||
LiInitializeAudioCallbacks(&m_AudioCallbacks);
|
|
||||||
m_AudioCallbacks.init = arInit;
|
|
||||||
m_AudioCallbacks.cleanup = arCleanup;
|
|
||||||
m_AudioCallbacks.decodeAndPlaySample = arDecodeAndPlaySample;
|
|
||||||
m_AudioCallbacks.capabilities = getAudioRendererCapabilities();
|
|
||||||
|
|
||||||
LiInitializeStreamConfiguration(&m_StreamConfig);
|
LiInitializeStreamConfiguration(&m_StreamConfig);
|
||||||
m_StreamConfig.width = m_Preferences->width;
|
m_StreamConfig.width = m_Preferences->width;
|
||||||
m_StreamConfig.height = m_Preferences->height;
|
m_StreamConfig.height = m_Preferences->height;
|
||||||
@ -385,6 +379,12 @@ bool Session::initialize()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LiInitializeAudioCallbacks(&m_AudioCallbacks);
|
||||||
|
m_AudioCallbacks.init = arInit;
|
||||||
|
m_AudioCallbacks.cleanup = arCleanup;
|
||||||
|
m_AudioCallbacks.decodeAndPlaySample = arDecodeAndPlaySample;
|
||||||
|
m_AudioCallbacks.capabilities = getAudioRendererCapabilities(m_StreamConfig.audioConfiguration);
|
||||||
|
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Audio configuration: %d",
|
"Audio configuration: %d",
|
||||||
m_StreamConfig.audioConfiguration);
|
m_StreamConfig.audioConfiguration);
|
||||||
|
@ -66,13 +66,11 @@ private:
|
|||||||
StreamingPreferences::VideoDecoderSelection vds,
|
StreamingPreferences::VideoDecoderSelection vds,
|
||||||
int videoFormat, int width, int height, int frameRate);
|
int videoFormat, int width, int height, int frameRate);
|
||||||
|
|
||||||
IAudioRenderer* createAudioRenderer();
|
IAudioRenderer* createAudioRenderer(const POPUS_MULTISTREAM_CONFIGURATION opusConfig);
|
||||||
|
|
||||||
int detectAudioConfiguration();
|
|
||||||
|
|
||||||
bool testAudio(int audioConfiguration);
|
bool testAudio(int audioConfiguration);
|
||||||
|
|
||||||
int getAudioRendererCapabilities();
|
int getAudioRendererCapabilities(int audioConfiguration);
|
||||||
|
|
||||||
void getWindowDimensions(int& x, int& y,
|
void getWindowDimensions(int& x, int& y,
|
||||||
int& width, int& height);
|
int& width, int& height);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user