Fix CRT shader: map OpenCL→QSV directly, skip broken VAAPI intermediate

hwmap=derive_device=vaapi:mode=write:reverse=1 after scale_opencl fails
because scale_opencl creates a new OpenCL surface that has no association
with the original VAAPI surface. reverse=1 requires an existing mapping.

On Intel, VAAPI and QSV share the same libva surfaces, so mapping the
post-CRT OpenCL frame directly to QSV (mode=write:reverse=1) works the
same way it does in the doOclTonemap path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mani
2026-02-25 23:18:48 +01:00
parent dd73b1d309
commit b9b7b6f7ef

View File

@@ -4924,14 +4924,21 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (IsCrtShaderEnabled(state))
{
// VAAPI → OpenCL → CRT → VAAPI round-trip, then map to QSV
// VAAPI → OpenCL → CRT → QSV (direct, no VAAPI intermediate).
// After scale_opencl the surface has no VAAPI association left,
// so reverse=1 to vaapi would fail. Map straight to QSV instead
// (on Intel, VAAPI and QSV share the same libva surfaces, so the
// QSV interop works for frames that originated in VAAPI).
mainFilters.Add("hwmap=derive_device=opencl:mode=read");
mainFilters.AddRange(GetCrtShaderOclFilters(state));
mainFilters.Add("hwmap=derive_device=vaapi:mode=write:reverse=1");
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=qsv");
mainFilters.Add("format=qsv");
}
else if (isQsvDecoder)
{