From d6b4c8e7dae6fad7c6fbd05722e4b7855970740c Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 20 Jan 2019 14:08:53 -0800 Subject: [PATCH] Avoid blocking decoding operations during Present calls --- app/streaming/video/ffmpeg-renderers/dxva2.cpp | 16 ++++++++++++++-- app/streaming/video/ffmpeg-renderers/dxva2.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 4584084a..5c2b8a4f 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -27,7 +27,8 @@ DXVA2Renderer::DXVA2Renderer() : m_ProcService(nullptr), m_Processor(nullptr), m_FrameIndex(0), - m_OverlayFont(nullptr) + m_OverlayFont(nullptr), + m_BlockingPresent(false) { RtlZeroMemory(m_DecSurfaces, sizeof(m_DecSurfaces)); RtlZeroMemory(&m_DXVAContext, sizeof(m_DXVAContext)); @@ -541,6 +542,8 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) d3dpp.BackBufferCount = 1; } + m_BlockingPresent = false; + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Windowed mode with DWM running"); } @@ -550,6 +553,7 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferCount = 1; + m_BlockingPresent = true; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "V-Sync enabled"); @@ -560,6 +564,7 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferCount = 1; + m_BlockingPresent = false; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "V-Sync disabled in tearing mode"); @@ -872,7 +877,14 @@ void DXVA2Renderer::renderFrameAtVsync(AVFrame *frame) return; } - hr = m_Device->PresentEx(nullptr, nullptr, nullptr, nullptr, 0); + do { + // Use D3DPRESENT_DONOTWAIT if present may block in order to avoid holding the giant + // lock around this D3D device for excessive lengths of time (blocking concurrent decoding tasks). + hr = m_Device->PresentEx(nullptr, nullptr, nullptr, nullptr, m_BlockingPresent ? D3DPRESENT_DONOTWAIT : 0); + if (hr == D3DERR_WASSTILLDRAWING) { + SDL_Delay(1); + } + } while (hr == D3DERR_WASSTILLDRAWING); if (FAILED(hr)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "PresentEx() failed: %x", diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.h b/app/streaming/video/ffmpeg-renderers/dxva2.h index a68ea9d1..a8070117 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.h +++ b/app/streaming/video/ffmpeg-renderers/dxva2.h @@ -70,4 +70,5 @@ private: DXVA2_VideoDesc m_Desc; REFERENCE_TIME m_FrameIndex; LPD3DXFONT m_OverlayFont; + bool m_BlockingPresent; };