fix(android): gate the latency overhaul behind an experimental toggle, default off
apple / swift (push) Successful in 2m36s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 50s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 59s
apple / screenshots (push) Successful in 5m55s
windows-host / package (push) Successful in 7m32s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 1m19s
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Successful in 1m13s
release / apple (push) Successful in 12m3s
ci / web (push) Successful in 1m3s
ci / docs-site (push) Successful in 1m18s
ci / rust (push) Successful in 4m52s
ci / bench (push) Successful in 6m44s
android / android (push) Successful in 5m9s
arch / build-publish (push) Successful in 5m40s
decky / build-publish (push) Successful in 15s
deb / build-publish (push) Successful in 3m20s
linux-client-screenshots / screenshots (push) Successful in 2m0s
flatpak / build-publish (push) Successful in 4m52s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m21s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m13s
docker / deploy-docs (push) Successful in 6s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 5s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6s
web-screenshots / screenshots (push) Successful in 2m59s
android-screenshots / screenshots (push) Failing after 3m25s
apple / swift (push) Successful in 2m36s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 50s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 59s
apple / screenshots (push) Successful in 5m55s
windows-host / package (push) Successful in 7m32s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 1m19s
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Successful in 1m13s
release / apple (push) Successful in 12m3s
ci / web (push) Successful in 1m3s
ci / docs-site (push) Successful in 1m18s
ci / rust (push) Successful in 4m52s
ci / bench (push) Successful in 6m44s
android / android (push) Successful in 5m9s
arch / build-publish (push) Successful in 5m40s
decky / build-publish (push) Successful in 15s
deb / build-publish (push) Successful in 3m20s
linux-client-screenshots / screenshots (push) Successful in 2m0s
flatpak / build-publish (push) Successful in 4m52s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 10m21s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 10m13s
docker / deploy-docs (push) Successful in 6s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 5s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6s
web-screenshots / screenshots (push) Successful in 2m59s
android-screenshots / screenshots (push) Failing after 3m25s
The 27c53a4 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:
@@ -6,7 +6,7 @@ mod qos;
|
||||
mod udp;
|
||||
|
||||
pub use loopback::{loopback_pair, LoopbackTransport};
|
||||
pub use qos::{grow_socket_buffers, set_media_qos, MediaClass};
|
||||
pub use qos::{grow_socket_buffers, set_dscp_default, set_media_qos, MediaClass};
|
||||
/// Windows-only: reusable USO (UDP Send Offload) batch send for callers that own their own connected
|
||||
/// socket (the GameStream video sender) rather than going through [`UdpTransport`].
|
||||
#[cfg(target_os = "windows")]
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
//! [`set_media_qos`] DSCP-tags the latency-sensitive video/audio traffic (+ Linux `SO_PRIORITY`) so a
|
||||
//! QoS-aware path (Wi-Fi WMM access categories, a managed switch, a shaped uplink) can prioritize it
|
||||
//! over bulk flows. Mirrors what Apollo/Sunshine tag — DSCP **CS5** for video, **CS6** for audio. It
|
||||
//! is **opt-in** (`PUNKTFUNK_DSCP=1`): DSCP can interact badly with some consumer ISPs/routers, and on
|
||||
//! is **opt-in** (`PUNKTFUNK_DSCP=1`, or [`set_dscp_default`] from an embedder — the Android client
|
||||
//! ties it to its experimental low-latency mode): DSCP can interact badly with some consumer ISPs/routers, and on
|
||||
//! Windows a plain `IP_TOS` is silently stripped unless a qWAVE policy is active (Apollo uses the
|
||||
//! qWAVE API there — that port is a follow-up; today this is a no-op on the wire on Windows).
|
||||
|
||||
use std::net::UdpSocket;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
/// Target kernel socket-buffer size (`SO_SNDBUF`/`SO_RCVBUF`). A high-resolution frame is a burst (a
|
||||
/// 5120×1440 keyframe is ~130 packets the send thread hands to `sendmmsg` at once); the default UDP
|
||||
@@ -66,17 +68,27 @@ impl MediaClass {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether DSCP/QoS marking is enabled. Default **on for Android**, **off elsewhere**: on Wi-Fi
|
||||
/// (where most Android clients live) access points commonly map DSCP to WMM access categories, so
|
||||
/// tagging the video/audio sockets can win real airtime priority against other traffic on the link;
|
||||
/// on the wired paths the other clients use it's rarely honoured and some paths bleach or reject
|
||||
/// marked packets, so it stays opt-in there. `PUNKTFUNK_DSCP` overrides either way — `1`/`true`/`on`
|
||||
/// forces it on, `0`/`false`/`off` forces it off (e.g. to rule QoS out while debugging a flaky AP).
|
||||
/// Runtime default for DSCP marking when `PUNKTFUNK_DSCP` is unset (see [`set_dscp_default`]).
|
||||
/// Off unless an embedder opts in — on Wi-Fi, access points commonly map DSCP to WMM access
|
||||
/// categories (a real airtime-priority win), but wired paths rarely honour it and some bleach or
|
||||
/// reject marked packets, so it never turns on by itself.
|
||||
static DSCP_DEFAULT: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
/// Opt in to (or back out of) DSCP marking for sockets created from now on. Must be called BEFORE
|
||||
/// connecting — the tag is applied at socket creation. The Android client ties this to its
|
||||
/// experimental low-latency mode; `PUNKTFUNK_DSCP` still overrides in either direction.
|
||||
pub fn set_dscp_default(enabled: bool) {
|
||||
DSCP_DEFAULT.store(enabled, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Whether DSCP/QoS marking is enabled: `PUNKTFUNK_DSCP` when set (`1`/`true`/`on` forces it on,
|
||||
/// `0`/`false`/`off` forces it off — e.g. to rule QoS out while debugging a flaky AP), else the
|
||||
/// [`set_dscp_default`] runtime default.
|
||||
pub(crate) fn dscp_enabled() -> bool {
|
||||
match std::env::var("PUNKTFUNK_DSCP").as_deref() {
|
||||
Ok("1") | Ok("true") | Ok("on") => true,
|
||||
Ok("0") | Ok("false") | Ok("off") => false,
|
||||
_ => cfg!(target_os = "android"),
|
||||
_ => DSCP_DEFAULT.load(Ordering::Relaxed),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user