feat: QSV hardware padding with capability gate + keep frames in hardware through setpts - #1
Closed
M-Pepper wants to merge 2 commits into
Closed
feat: QSV hardware padding with capability gate + keep frames in hardware through setpts#1M-Pepper wants to merge 2 commits into
M-Pepper wants to merge 2 commits into
Conversation
…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
This was referenced Jul 30, 2026
Owner
Author
|
Superseded by the upstream PR: ErsatzTV#2965 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits:
feat: add QSV hardware padding via vpp_qsv pad options with
capability gate — new
PadQsvFilter(mirroringPadVaapiFilter)emits
vpp_qsv=pad_w=..:pad_h=..:pad_x=-1:pad_y=-1:pad_color=black.Selection mirrors
VaapiPipelineBuilder.SetPad(respects the existingPadModeprofile setting and the HDR-tonemap override) plus a newoption-level capability gate:
HardwareCapabilitiesFactoryprobesffmpeg -h filter=vpp_qsv(cached, cleared with the other capabilitycaches) and the hardware pad is only selected when
pad_wexists —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:
filtering ("always for setpts").
setpts/fpsare timestamp-onlyand 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.
vpp_qsvinstances (separate scale then pad) drops thefinal frame at EOF (1439/1440; reproducible with two plain scales on
stock ffmpeg), so hardware scale+pad fold into a single
ScaleAndPadQsvFilterinstance.Measured on Intel Arc Pro B50 (60s 640x480 → 1440x1080 padded to
1920x1080, h264, exact emitted chain incl. setsar/setpts/fps):
with all 1440/1440 frames delivered.
Honest scoping notes:
NormalizeColorsenabled (the default), the software colorspacefilter still requires the download, so the full-GPU path currently
applies when color normalization is off or no conversion is needed.
vpp_qsvhasout_color_matrix/primaries/transferoptions that couldmove that conversion on-GPU too; we're validating color parity and
intend to propose it as a follow-up.
instance (and the pre-existing EOF behavior that implies).
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.