Don't block in audio/video renderer callbacks while the renderer is being destroyed

This commit is contained in:
Cameron Gutman
2018-09-22 20:03:41 -07:00
parent afb2b465a8
commit 605d52f160
2 changed files with 33 additions and 22 deletions
+10 -7
View File
@@ -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
View File
@@ -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;
} }
} }