Commit Graph

2 Commits

Author SHA1 Message Date
Skyler Lehmkuhl 6348e57de0 nv12: convert with the source colorspace matrix (not hardcoded BT.709)
The NV12→RGB pass hardcoded BT.709, so SD (BT.601) clips had slightly wrong hues.
Read each frame's AVColorSpace in the importer and derive the Y'CbCr→R'G'B'
matrix (BT.709/601/240M/2020; Unspecified guessed by height like swscale/players),
carry the four coefficients on GpuVideoFrame, and apply them in the shader.

- core: GpuVideoFrame.coeffs + ycbcr_coeffs(kr, kb) helper.
- hw_video.rs: map AVColorSpace → (kr, kb) → coeffs.
- nv12_blit{.rs,.wgsl}: uniform grows to 80 bytes (adds a coeffs vec4); the matrix
  multiply uses params.coeffs instead of literals.

BT.2020's transfer is still approximated as sRGB. The DRM-modifier-without-SAMPLED case stays a graceful software fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 02:32:57 -04:00
Skyler Lehmkuhl 1848c920d9 editor: wire hardware video decode + NV12 preview compositing (Stage 3c-preview)
Make the dormant core HW-decode engine live for the preview path:

- hw_video.rs: editor's HwVideoImporter — maps a decoded VAAPI surface to a
  DRM-PRIME DMA-BUF and imports it as wgpu NV12 plane textures on the *shared*
  device (the only one with the import extensions). install() creates the VAAPI
  device and injects it + the importer into the VideoManager.
- main.rs: track whether the shared device is actually in use; only then (Linux,
  not LB_NO_SHARED_DEVICE) install hardware decode, using the CreationContext's
  shared device + adapter.
- nv12_blit.rs + nv12_blit.wgsl: NV12 plane textures → BT.709 → sRGB-encoded →
  linear, written straight into the Rgba16Float HDR layer (no CPU upload). Colour
  math mirrors the software path so HW/SW video match; honours full_range.
- stage.rs: the preview Video arm branches on inst.gpu (NV12 blit) vs rgba_data
  (existing upload+blit_straight); sets render_hardware_ok = !cpu_renderer so the
  CPU fallback still gets software frames.
- video_exporter.rs: sets render_hardware_ok(false) before both compositing
  passes — export composites on the encoder's separate device, so a hardware
  decoder downloads to CPU instead (export stays software, correct).
- dmabuf.rs: imported plane textures now also carry SAMPLED/TEXTURE_BINDING so
  they can be sampled by the NV12 blit (they were render-target-only); into_planes
  hands the textures to the longer-lived GpuVideoFrame.
- video.rs: cache-key the GPU/CPU representation on want_gpu (HW-configured AND
  render_hardware_ok) so software-only decode keeps a single cache entry.

Preview only this pass; export GPU-residency is the 3c-export follow-up. Untested
at runtime here (no GPU/display in container) — both crates compile.
2026-06-26 02:21:22 -04:00