From ca26fa2dd0ee8eaa71f8de79a66b2c88c25b14d2 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 4 Nov 2019 22:56:42 -0800 Subject: [PATCH] Add basic HEVC Main10 support in DXVA2 renderer --- .../video/ffmpeg-renderers/dxva2.cpp | 22 +++++++++++++++---- .../video/ffmpeg-renderers/renderer.h | 11 +++++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/dxva2.cpp b/app/streaming/video/ffmpeg-renderers/dxva2.cpp index 13a04085..a0256267 100644 --- a/app/streaming/video/ffmpeg-renderers/dxva2.cpp +++ b/app/streaming/video/ffmpeg-renderers/dxva2.cpp @@ -382,9 +382,6 @@ bool DXVA2Renderer::isDecoderBlacklisted() HRESULT hr; bool result = false; - // TODO: Update for HEVC Main10 - SDL_assert(m_VideoFormat != VIDEO_FORMAT_H265_MAIN10); - if (qgetenv("DXVA2_DISABLE_DECODER_BLACKLIST") == "1") { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "DXVA2 decoder blacklist is disabled"); @@ -432,6 +429,15 @@ bool DXVA2Renderer::isDecoderBlacklisted() "GPU blacklisted for HEVC due to hybrid decode"); result = (m_VideoFormat & VIDEO_FORMAT_MASK_H265) != 0; break; + case 0x1900: // Skylake + // Blacklist these for HEVC Main10 to avoid hybrid decode. + // Regular HEVC Main is fine though. + if (m_VideoFormat == VIDEO_FORMAT_H265_MAIN10) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "GPU blacklisted for HEVC Main10 due to hybrid decode"); + result = false; + break; + } default: // Intel drivers from before late-2017 had a bug that caused some strange artifacts // when decoding HEVC. Avoid HEVC on drivers prior to build 4836 which I confirmed @@ -545,6 +551,8 @@ bool DXVA2Renderer::initializeDevice(SDL_Window* window, bool enableVsync) d3dpp.BackBufferWidth = currentMode.Width; d3dpp.BackBufferHeight = currentMode.Height; d3dpp.FullScreen_RefreshRateInHz = currentMode.RefreshRate; + + // TODO: Need to select 10-bit color format for HDR d3dpp.BackBufferFormat = currentMode.Format; } else { @@ -680,7 +688,13 @@ bool DXVA2Renderer::initialize(PDECODER_PARAMETERS params) m_Desc.SampleFormat.VideoPrimaries = DXVA2_VideoPrimaries_Unknown; m_Desc.SampleFormat.VideoTransferFunction = DXVA2_VideoTransFunc_Unknown; m_Desc.SampleFormat.SampleFormat = DXVA2_SampleProgressiveFrame; - m_Desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2'); + + if (m_VideoFormat == VIDEO_FORMAT_H265_MAIN10) { + m_Desc.Format = (D3DFORMAT)MAKEFOURCC('P','0','1','0'); + } + else { + m_Desc.Format = (D3DFORMAT)MAKEFOURCC('N','V','1','2'); + } if (!initializeDevice(params->window, params->enableVsync)) { return false; diff --git a/app/streaming/video/ffmpeg-renderers/renderer.h b/app/streaming/video/ffmpeg-renderers/renderer.h index c8c1d880..0580c81f 100644 --- a/app/streaming/video/ffmpeg-renderers/renderer.h +++ b/app/streaming/video/ffmpeg-renderers/renderer.h @@ -47,9 +47,14 @@ public: } virtual enum AVPixelFormat getPreferredPixelFormat(int videoFormat) { - // Planar YUV 4:2:0 - SDL_assert(videoFormat != VIDEO_FORMAT_H265_MAIN10); - return AV_PIX_FMT_YUV420P; + if (videoFormat == VIDEO_FORMAT_H265_MAIN10) { + // 10-bit YUV 4:2:0 + return AV_PIX_FMT_P010; + } + else { + // Planar YUV 4:2:0 + return AV_PIX_FMT_YUV420P; + } } // IOverlayRenderer