Fix CRT shader: simplify VAAPI path to mirror Jellyfin's own OCL pattern

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 <noreply@anthropic.com>
This commit is contained in:
mani
2026-02-26 00:16:56 +01:00
parent 945cb3a116
commit 26668426d4

View File

@@ -4924,30 +4924,25 @@ namespace MediaBrowser.Controller.MediaEncoding
{ {
if (IsCrtShaderEnabled(state)) if (IsCrtShaderEnabled(state))
{ {
// VAAPI → QSV → OpenCL → CRT → QSV. // VAAPI → OpenCL → CRT → VAAPI (reverse=1) → QSV.
// hwmap reverse=1 only works back to the device the OpenCL context // Mirrors the doOclTonemap+isVaInVaOut pattern: derive OpenCL
// was derived from. By going VAAPI→QSV first (zero-copy on Intel, // from VAAPI, process, then reverse-map back to VAAPI, and
// they share the same libva surface), the OpenCL is then derived // finally derive QSV (zero-copy, same libva surface).
// 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");
mainFilters.Add("hwmap=derive_device=opencl:mode=read"); mainFilters.Add("hwmap=derive_device=opencl:mode=read");
mainFilters.AddRange(GetCrtShaderOclFilters(state)); mainFilters.AddRange(GetCrtShaderOclFilters(state));
mainFilters.Add("hwmap=derive_device=qsv:mode=write:reverse=1:extra_hw_frames=16"); mainFilters.Add("hwmap=derive_device=vaapi:mode=write:reverse=1");
mainFilters.Add("format=qsv"); mainFilters.Add("format=vaapi");
}
else
{
mainFilters.Add("hwmap=derive_device=qsv");
mainFilters.Add("format=qsv");
} }
// VAAPI → QSV (zero-copy, shared libva surface)
mainFilters.Add("hwmap=derive_device=qsv");
mainFilters.Add("format=qsv");
} }
else if (isQsvDecoder) else if (isQsvDecoder)
{ {
if (IsCrtShaderEnabled(state)) 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.Add("hwmap=derive_device=opencl:mode=read");
mainFilters.AddRange(GetCrtShaderOclFilters(state)); mainFilters.AddRange(GetCrtShaderOclFilters(state));
mainFilters.Add("hwmap=derive_device=qsv:mode=write:reverse=1:extra_hw_frames=16"); mainFilters.Add("hwmap=derive_device=qsv:mode=write:reverse=1:extra_hw_frames=16");