From 26668426d454df4bd4f7c489c8f0873245a3176e Mon Sep 17 00:00:00 2001 From: mani Date: Thu, 26 Feb 2026 00:16:56 +0100 Subject: [PATCH] Fix CRT shader: simplify VAAPI path to mirror Jellyfin's own OCL pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All previous hwmap changes were based on diagnosing exit code 8 as a mapping failure, but the real cause was always build_opts. Now that build_opts is removed, use the same VAAPI→OpenCL→reverse(VAAPI)→QSV pattern that Jellyfin already uses for the doOclTonemap+isVaInVaOut path instead of the unnecessary QSV intermediate. Co-Authored-By: Claude Sonnet 4.6 --- .../MediaEncoding/EncodingHelper.cs | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index e1611081d8..f3fcf69511 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4924,30 +4924,25 @@ namespace MediaBrowser.Controller.MediaEncoding { if (IsCrtShaderEnabled(state)) { - // VAAPI → QSV → OpenCL → CRT → QSV. - // hwmap reverse=1 only works back to the device the OpenCL context - // was derived from. By going VAAPI→QSV first (zero-copy on Intel, - // they share the same libva surface), the OpenCL is then derived - // from QSV, and the reverse map back to QSV works exactly like the - // doOclTonemap path with a QSV decoder. - mainFilters.Add("hwmap=derive_device=qsv"); - mainFilters.Add("format=qsv"); + // VAAPI → OpenCL → CRT → VAAPI (reverse=1) → QSV. + // Mirrors the doOclTonemap+isVaInVaOut pattern: derive OpenCL + // from VAAPI, process, then reverse-map back to VAAPI, and + // finally derive QSV (zero-copy, same libva surface). mainFilters.Add("hwmap=derive_device=opencl:mode=read"); mainFilters.AddRange(GetCrtShaderOclFilters(state)); - mainFilters.Add("hwmap=derive_device=qsv:mode=write:reverse=1:extra_hw_frames=16"); - mainFilters.Add("format=qsv"); - } - else - { - mainFilters.Add("hwmap=derive_device=qsv"); - mainFilters.Add("format=qsv"); + mainFilters.Add("hwmap=derive_device=vaapi:mode=write:reverse=1"); + mainFilters.Add("format=vaapi"); } + + // VAAPI → QSV (zero-copy, shared libva surface) + mainFilters.Add("hwmap=derive_device=qsv"); + mainFilters.Add("format=qsv"); } else if (isQsvDecoder) { if (IsCrtShaderEnabled(state)) { - // QSV → OpenCL → CRT → QSV round-trip (SDR, no tonemap) + // QSV → OpenCL → CRT → QSV (reverse=1) mainFilters.Add("hwmap=derive_device=opencl:mode=read"); mainFilters.AddRange(GetCrtShaderOclFilters(state)); mainFilters.Add("hwmap=derive_device=qsv:mode=write:reverse=1:extra_hw_frames=16");