perf(android): low-latency decode overhaul — vendor keys, async loop, system tuning
Close the latency gap on the Android client with per-SoC decoder tuning, an event-driven decode loop, and full system integration. - Decoder selection: rank MediaCodecList decoders in Kotlin (hardware/vendor preferred, software avoided, FEATURE_LowLatency probed) and create the chosen one by name. Per-SoC low-latency keys gated on the codec-name prefix: Qualcomm picture-order + low-latency, Exynos (also Google Tensor), Amlogic, HiSilicon; MediaTek vdec-lowlatency set unconditionally. operating-rate = MAX (Qualcomm) vs priority = 0 (else) are mutually exclusive. NVIDIA/Rockchip/Realtek have no vendor key — covered by ranking + the standard low-latency key. - Async decode loop: AMediaCodec async-notify replaces the poll loop, presenting a decoded frame the instant it is ready instead of waiting out a poll interval. Behind USE_ASYNC_DECODE with the synchronous loop kept for A/B during bring-up. - System integration: Wi-Fi FULL_LOW_LATENCY lock and HDMI ALLM (setPreferMinimalPostProcessing) for the stream's lifetime; game_mode_config.xml opting out of OEM downscaling / FPS overrides. - Pipeline: boost the data-plane pump + audio thread priorities, AAudio usage=Game, DSCP marking on by default on Android, ADPF setPreferPowerEfficiency(false), and setFrameRateWithChangeStrategy(ALWAYS) to force the HDMI mode switch on TV. - lowLatencyMode master toggle (default on) as the escape hatch; the stats HUD now shows the resolved decoder name. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
//! grown on XRuns (Google's anti-glitch technique).
|
||||
|
||||
use ndk::audio::{
|
||||
AudioCallbackResult, AudioDirection, AudioFormat, AudioPerformanceMode, AudioSharingMode,
|
||||
AudioStream, AudioStreamBuilder,
|
||||
AudioCallbackResult, AudioContentType, AudioDirection, AudioFormat, AudioPerformanceMode,
|
||||
AudioSharingMode, AudioStream, AudioStreamBuilder, AudioUsage,
|
||||
};
|
||||
use punktfunk_core::client::NativeClient;
|
||||
use punktfunk_core::error::PunktfunkError;
|
||||
@@ -235,6 +235,11 @@ impl AudioPlayback {
|
||||
// captures + Opus-encodes in exactly this order.
|
||||
.channel_count(channels as i32)
|
||||
.format(AudioFormat::PCM_Float)
|
||||
// Tag the stream as game audio (usage=Game / content=Movie): the audio HAL applies
|
||||
// its low-latency game-audio routing/policy and it's grouped correctly with the
|
||||
// game-mode profile. Advisory — ignored where the device has no such policy.
|
||||
.usage(AudioUsage::Game)
|
||||
.content_type(AudioContentType::Movie)
|
||||
.performance_mode(AudioPerformanceMode::LowLatency)
|
||||
.sharing_mode(sharing)
|
||||
.data_callback(Box::new(callback))
|
||||
|
||||
Reference in New Issue
Block a user