Skip to content

feat: QSV hardware padding with capability gate + keep frames in hardware through setpts - #1

Closed
M-Pepper wants to merge 2 commits into
mainfrom
qsv-hardware-pad
Closed

feat: QSV hardware padding with capability gate + keep frames in hardware through setpts#1
M-Pepper wants to merge 2 commits into
mainfrom
qsv-hardware-pad

Conversation

@M-Pepper

@M-Pepper M-Pepper commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Two commits:

feat: add QSV hardware padding via vpp_qsv pad options with
capability gate
— new PadQsvFilter (mirroring PadVaapiFilter)
emits vpp_qsv=pad_w=..:pad_h=..:pad_x=-1:pad_y=-1:pad_color=black.
Selection mirrors VaapiPipelineBuilder.SetPad (respects the existing
PadMode profile setting and the HDR-tonemap override) plus a new
option-level capability gate: HardwareCapabilitiesFactory probes
ffmpeg -h filter=vpp_qsv (cached, cleared with the other capability
caches) and the hardware pad is only selected when pad_w exists —
stock ffmpeg builds keep today's software pad byte-identically. The
probing infrastructure is generic (IFFmpegCapabilities.HasFilterOption)
and could later gate other option-dependent features.

perf: keep QSV frames in hardware through setpts when no software
filters are needed
— two measured problems and their fix:

  1. The QSV pipeline unconditionally downloads to system memory after
    filtering ("always for setpts"). setpts/fps are timestamp-only
    and accept hardware frames, so when the encoder is QSV and nothing
    downstream needs software frames (no watermark, no subtitle
    overlay/burn-in, no graphics engine, no colorspace conversion), the
    download is skipped and frames flow GPU-to-GPU into the encoder.
  2. Chaining two vpp_qsv instances (separate scale then pad) drops the
    final frame at EOF (1439/1440; reproducible with two plain scales on
    stock ffmpeg), so hardware scale+pad fold into a single
    ScaleAndPadQsvFilter instance.

Measured on Intel Arc Pro B50 (60s 640x480 → 1440x1080 padded to
1920x1080, h264, exact emitted chain incl. setsar/setpts/fps):

chain fps CPU
today: hwdownload + CPU pad 242 5.6s
this PR, full-GPU 518 1.5s

with all 1440/1440 frames delivered.

Honest scoping notes:

  • With NormalizeColors enabled (the default), the software colorspace
    filter still requires the download, so the full-GPU path currently
    applies when color normalization is off or no conversion is needed.
    vpp_qsv has out_color_matrix/primaries/transfer options that could
    move that conversion on-GPU too; we're validating color parity and
    intend to propose it as a follow-up.
  • Anamorphic sources keep their pre-existing separate SAR pre-scale
    instance (and the pre-existing EOF behavior that implies).
  • All software-requiring configs (watermark, subtitles, graphics
    engine, software encoder, colorspace, software pad mode, stock
    ffmpeg) were verified byte-identical to current behavior at the
    command-string level.

Tests: 29 passing in ErsatzTV.FFmpeg.Tests, including option-parser
tests, filter emission tests, and builder-level tests asserting the
full-GPU chain, the capability-absent fallback, and the retained
download when colorspace conversion follows.

Companion PRs: M-Pepper/ErsatzTV-ffmpeg#1 (carries the ffmpeg patches — also
submitted upstream to ffmpeg-devel 2026-07-30), M-Pepper/next#1 (same
feature for the Rust engine).

Refs: ErsatzTV#1070, ErsatzTV#1615.

McKenzie Pepper and others added 2 commits July 30, 2026 11:37
…y gate

The QSV pipeline previously always padded in software, forcing a
hwdownload/pad/hwupload round-trip. ffmpeg's vpp_qsv filter is gaining
pad_w/pad_h/pad_x/pad_y/pad_color options, so when the ffmpeg binary
exposes them we can pad on the GPU instead, mirroring the existing
pad_vaapi hardware path.

A new capability probe runs `ffmpeg -h filter=vpp_qsv` and parses the
available AVOption names, surfaced as IFFmpegCapabilities.HasFilterOption.
QsvPipelineBuilder.SetPad now emits PadQsvFilter (vpp_qsv=pad_w=..:pad_h=..
:pad_x=-1:pad_y=-1:pad_color=black) when vpp_qsv advertises pad_w, and
keeps the software PadFilter fallback for HDR tonemap, forced software
pad mode, and stock ffmpeg builds without the pad options. The gate is
what makes this safe to upstream, since stock ffmpeg has no vpp_qsv pad
options yet.

Co-Authored-By: Claude Fable 5 <[email protected]>
…ters are needed

The QSV pipeline downloaded every hardware frame to system memory before
setpts "always for setpts", then re-fed software frames to the qsv encoder.
Combined with commit 30280ae's GPU pad this was a net loss on Intel B50
(224 fps / 6.5s CPU vs. 242 fps / 5.6s CPU for the old download+CPU-pad path)
because the padded frame was downloaded only to be uploaded again by h264_qsv.

setpts and fps operate on timestamps only and accept hardware frames, and the
qsv encoder ingests hardware frames directly, so the download is now skipped
whenever nothing downstream needs system memory: hardware qsv encoder, no
watermark, no subtitle overlay or burn-in, no graphics engine, and no
follow-on colorspace conversion (which prepends its own hwdownload). Every
config that still needs software frames keeps the download in exactly the same
place as before. On B50 the full-GPU chain measures 503 fps / 1.8s CPU, 2.1x
the old download+CPU-pad baseline.

Because two chained vpp_qsv instances drop the final frame at EOF (1439/1440,
a pre-existing ffmpeg quirk reproducible with two plain scales on stock
ffmpeg), a hardware scale followed by a hardware pad is now emitted as one
vpp_qsv instance carrying both the scale and the pad_w/pad_h options.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0139ePZuiHJGo2g4PY2tQJ9Q
@M-Pepper

Copy link
Copy Markdown
Owner Author

Superseded by the upstream PR: ErsatzTV#2965

@M-Pepper M-Pepper closed this Jul 30, 2026
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