From f0659b4f3c61fd4652e12bf1b3b0ad7fa1112d9d Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 18 Jan 2022 18:19:28 -0600 Subject: [PATCH] Fix random crash on stream start with renderers that require test frames --- app/streaming/session.cpp | 7 +++++++ app/streaming/video/ffmpeg.cpp | 14 ++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index f1a33119..9d202cbb 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -819,6 +819,11 @@ private: emit m_Session->sessionFinished(m_Session->m_PortTestResults); } + // The video decoder must already be destroyed, since it could + // try to interact with APIs that can only be called between + // LiStartConnection() and LiStopConnection(). + SDL_assert(m_Session->m_VideoDecoder == nullptr); + // Finish cleanup of the connection state LiStopConnection(); @@ -1717,6 +1722,8 @@ DispatchDeferredCleanup: SDL_AtomicUnlock(&m_InputHandlerLock); // Destroy the decoder, since this must be done on the main thread + // NB: This must happen before LiStopConnection() for pull-based + // decoders. SDL_AtomicLock(&m_DecoderLock); delete m_VideoDecoder; m_VideoDecoder = nullptr; diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index 465bbe86..27d8529b 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -424,13 +424,15 @@ bool FFmpegVideoDecoder::completeInitialization(const AVCodec* decoder, PDECODER // Tell overlay manager to use this frontend renderer Session::get()->getOverlayManager().setOverlayRenderer(m_FrontendRenderer); - } - m_DecoderThread = SDL_CreateThread(FFmpegVideoDecoder::decoderThreadProcThunk, "FFDecoder", (void*)this); - if (m_DecoderThread == nullptr) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Failed to create decoder thread: %s", SDL_GetError()); - return false; + // Only create the decoder thread when instantiating the decoder for real. It will use APIs from + // moonlight-common-c that can only be legally called with an established connection. + m_DecoderThread = SDL_CreateThread(FFmpegVideoDecoder::decoderThreadProcThunk, "FFDecoder", (void*)this); + if (m_DecoderThread == nullptr) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Failed to create decoder thread: %s", SDL_GetError()); + return false; + } } return true;