4. Keep decode on the GPU and bound its lookahead
CUarray storage removes an NVDEC staging copy; explicit surface and queue budgets prevent CPU savings from starving the decoder.
Reviewed 15 October 2026 against e72ff8b4. These pages describe that code and named workload settings; they do not assert what every deployment runs.
Separate storage, lookahead and decode surfaces
| Setting | Generic default | L4 CUarray profile |
|---|---|---|
decode_storage |
cuda |
cuarray, HEVC |
extra_hw_frames |
3 | 12 |
decoded_frames_ahead |
Unset | 1 |
Direct CUarray sampling avoids copying every decoded surface to linear CUDA storage. Those arrays remain owned by the decoder until consumers release them. One frame of decoded lookahead does not mean one decoder surface: codec references, in-flight decode and all downstream holders still need surfaces.
Keep the profile's twelve extra surfaces unless the actual codec, B-frame pattern and transition workload pass with less. A too-small pool can report “No decoder surfaces left” and lose frames even though GPU memory is lower. Do not transplant a short H.264 test's defaults into the HEVC show.
Skip software-only work in hardware HEVC decode
FFmpeg patch 0020-avcodec-hevc-hwaccel-frame-start.patch skips five software-decoder table clears when hardware acceleration is active, roughly 650 KB of per-picture writes at 1080p. Software decoding retains those clears. The historical decoder threads fell from about 86 to 62% of one core; this requires the patched FFmpeg build, not just a mixer option.
The CUarray path also depends on the bundled FFmpeg NVDEC and CUDA-filter patches. GPU consumers must understand array-backed frames and their producer-stream dependencies; a format name alone does not provide that interoperability.
CUarray storage is not a universal texture-speed recommendation. Sampling cost depends on the kernel and access pattern. Keep the array path for the measured decode/memory benefit; do not assume replacing AVP-owned linear browser-copy storage with arrays would improve throughput.
Evidence and correctness
The earlier matched 192-input/20-output CUarray test saved 4.88 GiB (20.65 → 15.77 GiB). This is a historical memory comparison, not a new capacity guarantee. Original storage experiment · HEVC CPU measurements.
Validate decoded pixels and timestamps with the actual software pixel format and filters. Then run the transition workload with all outputs. Primitive correctness, successful startup and a complete capacity run are separate checks. Do not add CPU downloads/uploads to conceal a broken GPU path.
Implementation at the reviewed revision
- demos/mixer/instance_profiles.py
- pyplumber/mixer/config.py
- src/nodes/decoders.cpp
- src/nodes/hwaccel/cuda_rect_draw.cpp
- deps/ffmpeg/9/0020-avcodec-hevc-hwaccel-frame-start.patch
- deps/ffmpeg/9/0012-avcodec-nvdec-cuarray-budget.patch
- deps/ffmpeg/9/0014-avcodec-nvdec-private-stream.patch
- deps/ffmpeg/9/0015-avfilter-cuda-array-inputs.patch