Skip to content

feat(vpp)!: resize into recycled surfaces, one pool per output size - #9

Merged
kixelated merged 1 commit into
mainfrom
vpp/resize-pool
Nov 6, 2026
Merged

kixelated merged 1 commit into
mainfrom
vpp/resize-pool

Conversation

@kixelated

@kixelated kixelated commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Part of the moq-video VAAPI quest, moq-dev/moq#8013, which switches moq-video's GPU resize over to this.

Problem

moq-video resizes a decoded VAAPI frame with Processor::process and exports the result with ExportedFrame::from_surface. Each call allocates a new VA surface and the driver destroys it when the frame drops, so a stream of resizes allocates once per frame.

Approach

  • Processor::resize(input, size, input_color, output_color) scales into NV12 and returns an ExportedFrame. Its output comes from a surface pool kept per output size, the same pool the decoder already uses for its targets, now in src/pool.rs.
  • Once the caller drops a frame, its surface is the next one written at that size. A frame still held is never written over: the next resize allocates another surface beside it. Each size keeps at most one free surface, and any returned past that is destroyed.
  • ExportedFrame::export takes a pooled surface, so a resized frame returns to its pool the same way a decoded one does.

Impact

  • New: Processor::resize.
  • Breaking: Processor::process is private. resize is what it was public for, and moq-video is its only user.

Validation

On Intel Arrow Lake (iHD 26.1.2) and AMD Radeon RX 9070 (radeonsi, Mesa 26.0.8), cargo test --lib, cargo clippy --all-targets -- -D warnings, and cargo fmt --all --check. The AMD run pointed the VPP tests at its render node for the run only.

  • a_released_output_is_written_into_again resizes twice into the same size, releases the first frame, and checks by DMA-BUF inode that the next resize reuses its surface. It also holds one frame while resizing a different picture and checks that the held frame keeps its pixels and that the pool allocated twice and keeps one free.
  • a_scaled_surface_reads_back_at_its_new_size now goes through resize.

Alternatives

  • A bounded pool that blocks or fails when every surface is held: that turns a slow consumer into errors, as the decoder pool's PR argued, so this bounds only what is kept free.
  • Keeping process public beside resize: two ways to do one thing, one of which allocates every call.

Review

Codex (quest review), one round: no findings.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

`Processor::resize` scales a surface into NV12 and returns it exported,
writing into a surface pool kept per output size. Once the caller drops a
frame, its surface is the next one written at that size; a frame still
held is never written over, and the next resize allocates beside it. At
most one free surface is kept per size.

The pool moves out of the decoder into its own module so both share it.
`Processor::process` becomes private: `resize` covers what it was public
for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated
kixelated marked this pull request as ready for review November 6, 2026 09:25
@coderabbitai

coderabbitai Bot commented Nov 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9c45dbdb-440c-4ed5-b514-b4ef7cb65369
Commits

Reviewing files that changed from the base of the PR and between af121c7 and dba9a75.

Files selected for processing: 5

  • README.md
  • src/decode.rs
  • src/lib.rs
  • src/pool.rs
  • src/vpp.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated
kixelated merged commit fd21fff into main Nov 6, 2026
2 checks passed
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