Commit Graph

3 Commits

Author SHA1 Message Date
Skyler Lehmkuhl b301c63387 Address code-review findings across export, decode, and data model
Export correctness:
- Honor the user's color-range (Limited/Full) on the software encode path:
  thread full_range through gpu_yuv (new shader range uniform), the CPU
  swscale fallback (sws_setColorspaceDetails → BT.709 + range, fixing the
  BT.601 hue/level shift on odd-width exports), and the encoder color tags.
- Reject HDR + WebM up front with a clear message and log the forced HEVC
  override instead of producing an unplayable file.
- Delete dead render_frame_to_rgba_hdr (hardcoded Stretch; live HDR path
  already honors the fit mode).

Decode/playback (video.rs):
- Drain the decoder at EOF (send_eof + flush) so the final B-frame-delayed
  frames render instead of erroring; per-frame logic extracted to a helper.
- Missing-PTS frames continue monotonically rather than snapping to ts=0.
- Force exact thumbnail width so sub-128px sources aren't shown stretched.

Resource leaks (gpu-video-encoder):
- dmabuf import_raw: RAII guard frees the duped fd + partial VkImages/memory
  on every error path.
- vaapi alloc: free device/frames-ctx/AVFrames on the unexpected-DRM path.

Data model / robustness:
- collapse_boundary_spikes requires a full curve reversal (all control
  points) so it no longer deletes a real lens/sliver and drops the fill.
- Export audio spin-wait ignores a stale `finished` flag when a forward
  seek is pending (was rendering silence over real audio).
- RasterDiff apply_before/after take current dims and skip on a post-resize
  mismatch.
- beam_archive read_media_full caps the preallocation from untrusted total_len.

UI/visual:
- SVG export skips hidden layers/empty groups; import folds fill-opacity into
  gradients and surfaces failures as a notification.
- Active raster-layer border uses playback_time + overlay_transform.
- gpu_brush remove_layer_texture also evicts the stale low-res proxy.
- ensure_raster_resident_for_undo registers faulted frames in the LRU so
  resident RAM stays bounded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:47:32 -04:00
Skyler Lehmkuhl 2bce5e93a6 gpu-video-encoder: VAAPI driver retry, Vello-capable device, Send
Three fixes found while running the zero-copy export on real Intel hardware:

- vaapi::create_device() retries LIBVA_DRIVER_NAME in order iHD -> auto ->
  i965 -> radeonsi. libva was auto-selecting the legacy i965 driver, which
  fails on newer Intel GPUs; the modern iHD (intel-media-driver) is needed.
  encoder.rs now builds its hwdevice through this helper.
- vk_device: request the adapter's full limits instead of downlevel_defaults.
  Vello's compute pipelines need max_storage_buffers_per_shader_stage >= 5
  (downlevel caps at 4), which panicked Vello's shader init on the export
  device. This device only ever runs on a real VAAPI GPU.
- ZeroCopyEncoder: unsafe impl Send. It owns its FFmpeg/Vulkan handles
  exclusively and is only moved (onto the export thread), never shared.
2026-06-25 18:15:05 -04:00
Skyler Lehmkuhl 5917ce7921 Add gpu-video-encoder crate: zero-copy VAAPI encode (validated)
New workspace crate isolating the unsafe GPU<->encoder interop for
zero-copy hardware video encoding. Every link is validated by a test on
real Intel/Mesa/iHD hardware:

- nv12: GPU RGBA->NV12 compute (BT.709 full-range), byte-exact vs a CPU
  reference.
- vaapi: VAAPI hwcontext + h264_vaapi encode (CPU-fed NV12 -> valid H.264),
  and DRM-PRIME surface layout probing.
- vk_device: a custom wgpu Vulkan device that adds
  VK_EXT_image_drm_format_modifier (+ external-memory fd/dma-buf) via the
  wgpu-hal device-from-raw path, so a tiled VAAPI surface can be imported.
- dmabuf: import a VAAPI NV12 surface's tiled DMA-BUF as two aliasing wgpu
  textures (Y=R8, UV=RG8) at the plane offsets.
- zerocopy test: render values via Vulkan straight into the VAAPI surface
  and read them back 100% correct -- proving the GPU writes into the
  encoder surface with no CPU copy.

Not yet wired into the editor; real-frame render + encode-from-surface +
fallback wiring follow. Linux-only (libva); other platforms fall back.
2026-06-23 19:07:37 -04:00