mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-13 21:02:28 +00:00
Fix crashes when restarting streaming with DXVA2 renderer due to leaked surface references
This commit is contained in:
parent
9c2befc386
commit
faaf9dfa07
3 changed files with 31 additions and 4 deletions
|
@ -65,11 +65,11 @@ void SdlInputHandler::handleKeyEvent(SDL_KeyboardEvent* event)
|
|||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Detected quit key combo");
|
||||
|
||||
SDL_Event event;
|
||||
// Uncapture the mouse to avoid processing any
|
||||
// further keyboard input
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
|
||||
// Drain the event queue of any additional input
|
||||
// that might be processed before our quit message.
|
||||
while (SDL_PollEvent(&event));
|
||||
SDL_Event event;
|
||||
|
||||
// Push a quit event to the main loop
|
||||
event.type = SDL_QUIT;
|
||||
|
|
|
@ -98,6 +98,7 @@ FFmpegVideoDecoder::FFmpegVideoDecoder()
|
|||
m_Renderer(nullptr)
|
||||
{
|
||||
av_init_packet(&m_Pkt);
|
||||
SDL_AtomicSet(&m_QueuedFrames, 0);
|
||||
|
||||
// Use linear filtering when renderer scaling is required
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||
|
@ -105,6 +106,28 @@ FFmpegVideoDecoder::FFmpegVideoDecoder()
|
|||
|
||||
FFmpegVideoDecoder::~FFmpegVideoDecoder()
|
||||
{
|
||||
// Drop any frames still queued to ensure
|
||||
// they are properly freed.
|
||||
SDL_Event event;
|
||||
|
||||
while (SDL_AtomicGet(&m_QueuedFrames) > 0) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Waiting for %d frames to return",
|
||||
SDL_AtomicGet(&m_QueuedFrames));
|
||||
|
||||
if (SDL_PeepEvents(&event,
|
||||
1,
|
||||
SDL_GETEVENT,
|
||||
SDL_USEREVENT,
|
||||
SDL_USEREVENT) == 1) {
|
||||
dropFrame(&event.user);
|
||||
}
|
||||
else {
|
||||
SDL_Delay(100);
|
||||
SDL_PumpEvents();
|
||||
}
|
||||
}
|
||||
|
||||
avcodec_close(m_VideoDecoderCtx);
|
||||
av_free(m_VideoDecoderCtx);
|
||||
m_VideoDecoderCtx = nullptr;
|
||||
|
@ -218,6 +241,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
|||
err = avcodec_receive_frame(m_VideoDecoderCtx, frame);
|
||||
if (err == 0) {
|
||||
// Queue the frame for rendering from the main thread
|
||||
SDL_AtomicIncRef(&m_QueuedFrames);
|
||||
queueFrame(frame);
|
||||
}
|
||||
else {
|
||||
|
@ -232,6 +256,7 @@ void FFmpegVideoDecoder::renderFrame(SDL_UserEvent* event)
|
|||
{
|
||||
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
||||
m_Renderer->renderFrame(frame);
|
||||
SDL_AtomicDecRef(&m_QueuedFrames);
|
||||
}
|
||||
|
||||
// Called on main thread
|
||||
|
@ -239,4 +264,5 @@ void FFmpegVideoDecoder::dropFrame(SDL_UserEvent* event)
|
|||
{
|
||||
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
||||
av_frame_free(&frame);
|
||||
SDL_AtomicDecRef(&m_QueuedFrames);
|
||||
}
|
||||
|
|
|
@ -38,4 +38,5 @@ private:
|
|||
QByteArray m_DecodeBuffer;
|
||||
const AVCodecHWConfig* m_HwDecodeCfg;
|
||||
IFFmpegRenderer* m_Renderer;
|
||||
SDL_atomic_t m_QueuedFrames;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue