mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 14:11:33 +00:00
Don't block in audio/video renderer callbacks while the renderer is being destroyed
This commit is contained in:
@@ -120,13 +120,16 @@ void Session::arDecodeAndPlaySample(char* sampleData, int sampleLength)
|
|||||||
SAMPLES_PER_FRAME,
|
SAMPLES_PER_FRAME,
|
||||||
0);
|
0);
|
||||||
if (samplesDecoded > 0) {
|
if (samplesDecoded > 0) {
|
||||||
SDL_AtomicLock(&s_ActiveSession->m_AudioRendererLock);
|
// If we can't acquire the lock, that means we're being destroyed
|
||||||
if (s_ActiveSession->m_AudioRenderer != nullptr) {
|
// so don't even bother trying to wait.
|
||||||
s_ActiveSession->m_AudioRenderer->submitAudio(s_ActiveSession->m_OpusDecodeBuffer,
|
if (SDL_AtomicTryLock(&s_ActiveSession->m_AudioRendererLock)) {
|
||||||
static_cast<int>(sizeof(short) *
|
if (s_ActiveSession->m_AudioRenderer != nullptr) {
|
||||||
samplesDecoded *
|
s_ActiveSession->m_AudioRenderer->submitAudio(s_ActiveSession->m_OpusDecodeBuffer,
|
||||||
s_ActiveSession->m_AudioConfig.channelCount));
|
static_cast<int>(sizeof(short) *
|
||||||
|
samplesDecoded *
|
||||||
|
s_ActiveSession->m_AudioConfig.channelCount));
|
||||||
|
}
|
||||||
|
SDL_AtomicUnlock(&s_ActiveSession->m_AudioRendererLock);
|
||||||
}
|
}
|
||||||
SDL_AtomicUnlock(&s_ActiveSession->m_AudioRendererLock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-15
@@ -170,25 +170,33 @@ int Session::drSubmitDecodeUnit(PDECODE_UNIT du)
|
|||||||
// Use a lock since we'll be yanking this decoder out
|
// Use a lock since we'll be yanking this decoder out
|
||||||
// from underneath the session when we initiate destruction.
|
// from underneath the session when we initiate destruction.
|
||||||
// We need to destroy the decoder on the main thread to satisfy
|
// We need to destroy the decoder on the main thread to satisfy
|
||||||
// some API constraints (like DXVA2).
|
// some API constraints (like DXVA2). If we can't acquire it,
|
||||||
|
// that means the decoder is about to be destroyed, so we can
|
||||||
|
// safely return DR_OK and wait for m_NeedsIdr to be set by
|
||||||
|
// the decoder reinitialization code.
|
||||||
|
|
||||||
SDL_AtomicLock(&s_ActiveSession->m_DecoderLock);
|
if (SDL_AtomicTryLock(&s_ActiveSession->m_DecoderLock)) {
|
||||||
|
if (s_ActiveSession->m_NeedsIdr) {
|
||||||
|
// If we reset our decoder, we'll need to request an IDR frame
|
||||||
|
s_ActiveSession->m_NeedsIdr = false;
|
||||||
|
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
||||||
|
return DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
if (s_ActiveSession->m_NeedsIdr) {
|
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
|
||||||
// If we reset our decoder, we'll need to request an IDR frame
|
if (decoder != nullptr) {
|
||||||
s_ActiveSession->m_NeedsIdr = false;
|
int ret = decoder->submitDecodeUnit(du);
|
||||||
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
||||||
return DR_NEED_IDR;
|
return ret;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
|
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
||||||
if (decoder != nullptr) {
|
return DR_OK;
|
||||||
int ret = decoder->submitDecodeUnit(du);
|
}
|
||||||
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
// Decoder is going away. Ignore anything coming in until
|
||||||
|
// the lock is released.
|
||||||
return DR_OK;
|
return DR_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user