diff --git a/docs/decisions.md b/docs/decisions.md index 120311eaa..eafa749d4 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -2401,3 +2401,30 @@ shared row already delivers the user-visible behavior with no schema change. **Accepted trade-off:** every channel on the shared preset shares one geometry; per-channel tweaks mean creating a second preset on the Watermarks screen. +## 2026-07-20 (#498) — QSV decode is split from QSV encode via a single `QsvPreferNativeDecoder` bool + +`FFmpegProfile.HardwareAcceleration` picked one pipeline builder for **both** decode and encode, so an +Intel QSV profile decoded with the QSV decoder — which is materially less tolerant of imperfect H.264 than +FFmpeg's native VA-API decoder and cannot carry Dolby Vision metadata. Jellyfin, on identical hardware, +avoids this by decoding with VA-API and encoding with QSV; that combination was not expressible in +ErsatzTV. Full design: `docs/superpowers/specs/2026-07-20-qsv-native-decode-design.md`. + +- **Chosen: a single, QSV-scoped `FFmpegProfile.QsvPreferNativeDecoder` boolean**, mirroring Jellyfin's + "Prefer OS native DXVA or VA-API hardware decoders" checkbox exactly — Jellyfin itself deliberately + collapses this to one default-on toggle rather than a decode-family picker, and copying the reference + tool's granularity avoids over-building past a problem it has already solved. +- **Default ON.** Native VA-API decode is strictly more tolerant of imperfect streams than the QSV decoder + wrapper, and Dolby Vision passthrough requires it — so the working configuration *is* the default for a + reliability fix. Existing QSV profiles adopt the hybrid on upgrade via the migration's + `HasDefaultValue(true)` (SQLite `INTEGER`/MySQL `tinyint` `NOT NULL DEFAULT 1`), no opt-in required. +- **Rejected: a general `DecodeHardwareAcceleration` enum column** decoupling decode and encode hardware + families entirely. More configurable than Jellyfin's own control, but nothing in the codebase or the + reported failure needs that generality yet — `FFmpegState` already separates + `DecoderHardwareAccelerationMode` / `EncoderHardwareAccelerationMode` internally (used today for the + software-decode-plus-hardware-encode error-loop fallback), so the seam to grow into a real enum exists + if a second asymmetric-decode case ever shows up on another hardware family. Deferred rather than + built now, on YAGNI grounds. +- **Contained to the QSV builder.** The flag does not touch `PipelineBuilderFactory`'s single-builder + dispatch per profile, and does not repurpose the existing decode/encode-mode fields into a general + cross-family selector — that repurposing is exactly the rejected enum option, just introduced through + the back door.