mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-14 05:12:27 +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,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Detected quit key combo");
|
"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
|
SDL_Event event;
|
||||||
// that might be processed before our quit message.
|
|
||||||
while (SDL_PollEvent(&event));
|
|
||||||
|
|
||||||
// Push a quit event to the main loop
|
// Push a quit event to the main loop
|
||||||
event.type = SDL_QUIT;
|
event.type = SDL_QUIT;
|
||||||
|
|
|
@ -98,6 +98,7 @@ FFmpegVideoDecoder::FFmpegVideoDecoder()
|
||||||
m_Renderer(nullptr)
|
m_Renderer(nullptr)
|
||||||
{
|
{
|
||||||
av_init_packet(&m_Pkt);
|
av_init_packet(&m_Pkt);
|
||||||
|
SDL_AtomicSet(&m_QueuedFrames, 0);
|
||||||
|
|
||||||
// Use linear filtering when renderer scaling is required
|
// Use linear filtering when renderer scaling is required
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||||
|
@ -105,6 +106,28 @@ FFmpegVideoDecoder::FFmpegVideoDecoder()
|
||||||
|
|
||||||
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);
|
avcodec_close(m_VideoDecoderCtx);
|
||||||
av_free(m_VideoDecoderCtx);
|
av_free(m_VideoDecoderCtx);
|
||||||
m_VideoDecoderCtx = nullptr;
|
m_VideoDecoderCtx = nullptr;
|
||||||
|
@ -218,6 +241,7 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
||||||
err = avcodec_receive_frame(m_VideoDecoderCtx, frame);
|
err = avcodec_receive_frame(m_VideoDecoderCtx, frame);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
// Queue the frame for rendering from the main thread
|
// Queue the frame for rendering from the main thread
|
||||||
|
SDL_AtomicIncRef(&m_QueuedFrames);
|
||||||
queueFrame(frame);
|
queueFrame(frame);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -232,6 +256,7 @@ void FFmpegVideoDecoder::renderFrame(SDL_UserEvent* event)
|
||||||
{
|
{
|
||||||
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
||||||
m_Renderer->renderFrame(frame);
|
m_Renderer->renderFrame(frame);
|
||||||
|
SDL_AtomicDecRef(&m_QueuedFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on main thread
|
// Called on main thread
|
||||||
|
@ -239,4 +264,5 @@ void FFmpegVideoDecoder::dropFrame(SDL_UserEvent* event)
|
||||||
{
|
{
|
||||||
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
AVFrame* frame = reinterpret_cast<AVFrame*>(event->data1);
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
|
SDL_AtomicDecRef(&m_QueuedFrames);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,5 @@ private:
|
||||||
QByteArray m_DecodeBuffer;
|
QByteArray m_DecodeBuffer;
|
||||||
const AVCodecHWConfig* m_HwDecodeCfg;
|
const AVCodecHWConfig* m_HwDecodeCfg;
|
||||||
IFFmpegRenderer* m_Renderer;
|
IFFmpegRenderer* m_Renderer;
|
||||||
|
SDL_atomic_t m_QueuedFrames;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue