AVPlumber · Mixer cookbook

Mixer optimization cookbook

Changes with demonstrated CPU, GPU or VRAM impact, plus clearly identified mechanisms that reduce work.

Reviewed 15 October 2026 against e72ff8b4. Setup defaults and capacity notes updated at 74e3392f. These describe code and named workload settings, not the live state of every deployment.

The fixed-pool export Electron and the mixer's copy on import were removed at 159d0182: browsers run stock Electron with Chromium's ordinary capture, sampled in place. Measurements below that name a fixed pool or a copy on import describe the removed path.

Ranked for the current browser-heavy L4 workload and the size of the supported benefit. CPU percentages below mean percent of one core; 100% is one full core. Historical before/after steps share baselines and are not additive. Each entry labels whether its evidence is a measurement or an implementation mechanism.

Performance changes worth preserving

  1. 1. CUDA work queues: 32 compute / 8 copyGPU scheduling · short matched transition checkAt 36 browsers/50 fps on the since-removed fenced browser build, acquire-fence waits averaged ~14 → 1.7 ms and repeats went from thousands to zero. Reduced queue serialization is the likely mechanism; this adds no GPU engines.
  2. 2. Pinned direct and resident raw inputsCPU · historical 192-source measurementsDirect uploads removed CPU copies and 141 threads; mixer CPU fell 679 → 510% of one core. Later resident files reduced the input-reading group 139.7 → 27.3%, at ~8.8 GB pinned host RAM.
  3. 3. Direct input routing and optional metadataCPU · historical combined-change measurementThe routing/metadata/signalling build reduced mixer CPU 322 → 265% of one core and removed 105 demux threads. It preserves independent decoding and realtime pacing; individual changes were not measured separately.
  4. 4. CUarray decode and hardware-only HEVC workVRAM and CPU · two historical comparisonsCUarray storage saved 4.88 GiB at 192 inputs/20 outputs. Skipping software-only HEVC table clears reduced decoder CPU ~86 → 62% of one core. Arrays are a storage/copy optimization, not universally faster textures.
  5. 5. Ready-input waits and bounded pollingCPU · historical compositor measurementsEpoll reduced the busiest compositor 51.8 → 34.7% of one core. In later builds, 8 ms input polling reduced each Program compositor 12.1 → 7.3%. These are separate comparisons; keep deadline and delivery checks.
  6. 6. Browser frames go back one per new frameGPU allocation stability · 192-input L4 showChromium's ordinary capture, sampled in place, with a return queue of three in a frame queue of nine. A copy on import on top of it stalled the whole GPU within a minute under 40 moving windows.
  7. 7. Shared fan-out loops and coalesced signalsCPU scheduling and thread count · historical evidenceEvent-loop fan-out removed 192 threads (1,081 → 889). Its CPU mostly moved onto shared loops; persistent waits and coalesced signals reduce wake overhead. Thread reduction is measured; an isolated large CPU saving is not claimed.
  8. 8. Cropped DSKs and transparent-pixel fast pathsGPU pixel work · implementation mechanismCropped keys reduce capture and composition pixels; alpha-zero samples skip RGB/HDR conversion. Full-size scene pages keep true 1080p capture. This avoids known work, but there is no isolated percentage-speedup measurement.

Supporting guides: source colour tags and conversion · on-air repeats, skips and lean diagnostics.

Start with the right defaults

Layer What the reviewed configuration selects
L4 deployment 32 CUDA compute queues, eight copy queues; browser frame staggering enabled; up to ten windows per worker
L4 CUarray Setup defaults 40 browser windows at 25/30/50 fps; 30 at 60 fps, including four DSKs. AUX encoders default to p1.
L4 source profile Resident raw files; event-loop fan-out; Program/AUX input polling 8 ms; decoded lookahead one; raw pool ten
L4 CUarray decode HEVC, CUarray storage, twelve extra decode surfaces
Browser installation Stock Electron with the GBM shim, always preloaded on NVIDIA, in Docker and direct npm installs
Moving-browser experiment Removed path: fixed prewarmed pool nine, AVP copy on import, 4 × 10 windows at 50 fps; 3 × 10 at 60 fps with AUX p1

Generic library defaults differ. Each recipe names which settings belong to a profile, deployment override or optional build. Neither a browser ring nor CUDA queue count sets the compositor deadline.

Setup Apply and Defaults use those rate-dependent browser limits when allocating sources. Explicit saved encoder choices remain editable and preserved; Defaults restores AUX p1. The mixer samples Chromium's capture buffers in place. Fresh seed and saved-configuration behavior.

What was actually demonstrated

Read the current workload and limits before choosing a count: 40 moving windows at 25/30/50 fps and 30 at 60 fps were short checks with 32-layer transitions, with isolated repeats in some runs. They are not a claim of flawless sustained output or 40 windows at 60 fps.

The recorded mixer UI is a separate demonstration. Older CPU, memory and capacity experiments remain in historical evidence; obsolete browser, stream and branch-state advice has been removed from this recommendation list.

Maintained references