Skip to content

Export VA decode surfaces before the first decode (fixes libva-v4l2request on Apple Silicon) - #111

Open
ludagoo wants to merge 1 commit into
omacom:mainfrom
ludagoo:fix/v4l2request-export-before-decode
Open

ludagoo wants to merge 1 commit into
omacom:mainfrom
ludagoo:fix/v4l2request-export-before-decode

Conversation

@ludagoo

@ludagoo ludagoo commented Nov 1, 2026

Copy link
Copy Markdown

Bug

On Apple Silicon (Asahi, libva-v4l2request / AVD), GPU decode produced blocky, corrupted frames and logged:

libva-v4l2request: cannot decode into the already-exported surface

The client exported each decode surface (vaExportSurfaceHandle) lazily in DecodeStream, after the first decode. v4l2-request drivers fix the capture memory mode on the first decode and reject surfaces exported after that.

Fix

H264Decoder now exports every surface once, when the stream (and decode context) is created and before any decode. It keeps the PrimeDescriptors and exposes them via exports(). DecodeStream imports those descriptors instead of exporting on generation change. A resolution change or reconnect builds a new stream, so it gets fresh surfaces and fresh exports.

Tests

  • scripts/check.sh (fmt, clippy -D warnings, unit tests): PASS on aarch64. One clippy fix is unrelated: an image.rs SAFETY comment moved above its closure for undocumented_unsafe_blocks on rust 1.93.
  • scripts/e2e.sh adds 4c. It holds a GPU-decode session under steady damage for 300 frames (~15 s, well past startup), then connects again with a fresh decoder/exports. It fails on any decode error. It also runs on decode-only machines like Apple AVD, where the server uses the CPU tier.
    • M1 Air (Honeykrisp + libva-v4l2request): 4c PASS, both runs 300 frames, 0 decode errors. Sections 1, 2, 5b–10 also pass.
    • These failures also happen on unmodified main on this machine and are unrelated to this change: 4b cpu server -> cpu client ("server applied the requested output scale") and 11 (fcitx keymap switch).
    • Not run: Intel iHD and AMD radeonsi. The Air has no VA-API encoder, so sections 3/4 and the GPU tier matrix were skipped. Please run e2e on an Intel and an AMD box (CLAUDE.md), or let CI cover them.

libva-v4l2request (Apple Silicon AVD on Asahi) fixes the capture memory
mode on the first decode and then rejects surfaces exported afterwards
("cannot decode into the already-exported surface"), so the GPU client
decoded garbage/blocky frames. Export every decode surface when the stream
is created and import those descriptors in the Vulkan pipeline.

e2e: add 4c, a GPU-decode session held under steady damage (300 frames)
and run twice with a fresh decoder, failing on any decode error. It also
runs on decode-only machines (server on the CPU tier).

Also move an image.rs SAFETY comment above its closure so clippy
(undocumented_unsafe_blocks, rust 1.93) passes.
@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

The PR exports each VA-API decode surface before the first decode and keeps its descriptor with the stream.

  • VA decode surfaces are exported before their first picture is decoded.
  • The Vulkan image cleanup note sits above its closure.

Acknowledgments supplied by ludagoo:

  • The CPU-to-CPU output-scale assertion and fcitx keymap-switch failures also occur on unchanged main and were identified as unrelated.
  • Intel iHD and AMD radeonsi testing was not run because the available machine was an M1 Air.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[New SPS] --> B[Create decode surfaces]
  B --> C[Export every surface and keep descriptors]
  C --> D[Create VA-API context]
  D --> E[Submit decode]
  E --> F[Import saved descriptors when generation changes]
  F --> G[Wait for the decoded surface]
  G --> H[Run Vulkan recombine]
Loading

Reviews (1) · Last reviewed commit: "Export decode surfaces before the first ..." · Reviewed by Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant