fix(android): gate the latency overhaul behind an experimental toggle, default off
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Has been cancelled
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Has been cancelled
windows-host / package (push) Has been cancelled
web-screenshots / screenshots (push) Has been cancelled
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
release / apple (push) Has been cancelled
linux-client-screenshots / screenshots (push) Has been cancelled
flatpak / build-publish (push) Has been cancelled
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Has been cancelled
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Has been cancelled
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Has been cancelled
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Has been cancelled
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Has been cancelled
docker / deploy-docs (push) Has been cancelled
decky / build-publish (push) Has been cancelled
deb / build-publish (push) Has been cancelled
arch / build-publish (push) Has been cancelled
android / android (push) Has been cancelled
android-screenshots / screenshots (push) Has been cancelled

The 5dc24a0 low-latency overhaul regressed badly on some phones. Every piece
of it — decoder ranking, per-SoC vendor keys, the async decode loop, pipeline
thread boosts, the ADPF max-performance bias, game-tagged AAudio, DSCP marking,
the Wi-Fi low-latency lock, HDMI ALLM and the forced TV mode switch — now rides
the "Low-latency mode (experimental)" toggle, default OFF. Off restores the
pre-overhaul pipeline byte-for-byte: the sync poll loop, the platform-default
decoder, and the original format keys (standard low-latency + blind Qualcomm
twin + priority=0 + operating-rate=MAX together).

- New pref key (low_latency_mode_experimental): the old key shipped default-ON,
  so any install that ever saved settings persisted true — flipping the default
  under the old key would leave exactly the regressed devices stuck on.
- DSCP is applied at socket creation, so the toggle reaches the transport via
  NativeBridge.nativeSetLowLatencyMode → transport::set_dscp_default, called in
  the connect choke point before nativeConnect; the core DSCP default reverts
  to off everywhere.
- nativeStartAudio(handle, lowLatencyMode) gates AAudio usage=Game.
- VideoDecoders.pickDecoder now skips `.secure` decoder twins and decoders that
  require FEATURE_SecurePlayback: they need a secure surface, and a secure twin
  could out-score its plain sibling (only it advertising FEATURE_LowLatency),
  which black-screens a clear stream.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 20:18:59 +02:00
parent 35e16303e6
commit da376b3122
13 changed files with 188 additions and 75 deletions
+9 -5
View File
@@ -103,8 +103,10 @@ pub struct HintSession {
impl HintSession {
/// Open a session hinting `tids` with an initial per-frame target of `target_ns` nanoseconds.
/// `None` when ADPF is unavailable (device API < 33) or the platform declines — the caller then
/// runs unhinted (a no-op, not an error).
pub fn create(target_ns: i64, tids: &[i32]) -> Option<Self> {
/// runs unhinted (a no-op, not an error). `prefer_performance` (the experimental low-latency
/// mode) additionally biases the governor away from power efficiency (API 35+); off, the
/// session runs with the platform default, as it did before the overhaul.
pub fn create(target_ns: i64, tids: &[i32], prefer_performance: bool) -> Option<Self> {
if target_ns <= 0 || tids.is_empty() {
return None;
}
@@ -119,9 +121,11 @@ impl HintSession {
// Tell the governor NOT to bias this session toward power efficiency (API 35+): our loop is
// latency-critical, so we want it kept on fast cores at high clocks over battery savings.
// Best-effort; absent below API 35.
if let Some(f) = api.set_prefer_power_efficiency {
// SAFETY: `session` is the live session just created; the fn takes it + a bool.
unsafe { f(session, false) };
if prefer_performance {
if let Some(f) = api.set_prefer_power_efficiency {
// SAFETY: `session` is the live session just created; the fn takes it + a bool.
unsafe { f(session, false) };
}
}
Some(Self { api, session })
}