Files
qbz/crates/qbz-app
vicrodh a69491a49e feat(player): re-wire the low-memory profile into qbz/qbzd (#660)
The system_capabilities profiler (Normal vs LowMemory, built for #331)
lost all its consumers in the Tauri removal; 2.0.2 shipped it as dead
code and qbzd got OOM-killed (exit 137) on 1 GB Pi hosts at track
transitions. Phase A wiring:

- Frontends read memory_profile() at startup and push it down via the
  new player memory_tuning (initial-buffer cap, L1 budget, low-memory
  gate) before the Player is created.
- L1 audio cache sized from the profile (400 MB Normal / 50 MB
  LowMemory; was hardcoded 400 MB).
- Oversized tracks (>L1/4 = 12.5 MB on LowMemory) skip the promotion
  clone and the parallel CMAF RAM accumulator entirely; the finished
  track is streamed to the L2 disk cache in 1 MB chunks straight from
  the playback buffer — no second in-RAM copy. Gapless degrades to a
  small gap for those tracks (a gap beats an OOM kill).
- Stream buffer preallocates total_size up front (try_reserve_exact,
  1 GiB cap, dynamic fallback) — no more ~8 doubling reallocs + memcpy
  per track (weak-CPU relief).
- New memory-pressure watchdog (15 s): critical pressure evicts the
  L1 (L2 disk kept) and halts prefetch; low pressure pauses HiRes
  prefetch (downgrades to Lossless). Spawned by both frontends; qbzd
  aborts+joins it for the #521 shutdown ordering.
- Prefetch honors the profile (depth cap, HiRes->Lossless downgrade).

Normal-profile behavior is byte-identical (every behavioral change is
gated on the LowMemory class; profile values equal the old hardcodes).

Phase B (follow-ups): tempfile spill of the live stream buffer for
giant tracks, POLLERR flood rate-limit, desktop kick_prefetch halt
check, L2-read on the play_track cache-hit path.

km
2026-07-26 23:56:39 -06:00
..