feat(player): optional local decoding so volume keys work on passthrough audio - #416
Open
Pierroons wants to merge 5 commits into
Open
feat(player): optional local decoding so volume keys work on passthrough audio#416Pierroons wants to merge 5 commits into
Pierroons wants to merge 5 commits into
Conversation
On Amlogic TV boxes, AC3/EAC3 streams are handed to the HDMI sink untouched. Playback works, but the stream never reaches the mixer, so volume keys have no effect on it: a stereo channel responds normally while a 5.1 movie ignores the remote entirely. Users read this as a broken remote, and there is no in-app way to change it. Adds a DISABLE_AUDIO_PASSTHROUGH preference, off by default — passthrough is the right behaviour when an A/V receiver does the decoding, and forcing it off would cost those users their surround track. NOT WORKING YET. The override targets DefaultRenderersFactory.buildAudioSink, which NextRenderersFactory appears to bypass when building its FFmpeg audio renderers: measured after install, the DIRECT/AC3 output thread is still created. The preference, its propagation and the UI entry are correct and verified; only the interception point is wrong. Next step: inspect how NextRenderersFactory assembles audio renderers and hook buildAudioRenderers instead. Verified so far: builds clean, installs alongside the release build via a debug applicationId suffix, preference persists, and the setting appears in Optional settings.
…apply Follow-up to the previous commit, which added the preference but had no effect. DefaultAudioSink.Builder only honours setAudioCapabilities when built WITHOUT a Context. Given one, it probes the real output instead and discards whatever was declared — silently, with no warning at build or run time. The override was therefore running exactly as written, and being ignored. Confirmed in the 1.9.1 bytecode: build() reads the context field and branches on it being null before applying the capabilities. Measured on an Amlogic X96 Max+ (Android 9), same 5.1 AC3 movie: before AudioOut_1FD type DIRECT AUDIO_FORMAT_AC3 6ch volume keys dead after AudioOut_D type MIXER PCM_16_BIT 2ch 12 through 15, back to 13 Playback is uninterrupted; the FFmpeg renderers already bundled handle the decoding. Trade-off unchanged and stated in the setting description: audio is downmixed to stereo while enabled, so anyone relying on an A/V receiver for surround should leave it off — which is the default.
Second half of the fix. Routing audio through the mixer was not enough: the stream played, the mixer ran, and nothing came out of the speakers. EXTENSION_RENDERER_MODE_ON keeps platform decoders first and only falls back to the bundled ones. ExoPlayer therefore picked OMX.amlogic.audio.decoder.ac3 — a hardware decoder built to feed a passthrough path. Asked for PCM instead, it produced no output at all, and reported no error: the failure is silent in both senses. Switching to EXTENSION_RENDERER_MODE_PREFER when the preference is on hands decoding to the FFmpeg renderers already shipped with the app. Only affects users who enabled the setting; default behaviour is untouched. Verified on an Amlogic X96 Max+ (Android 9) with a 5.1 AC3 movie: audio present and volume keys working across the full range, 13 down to 11 and back to 13.
…oding The previous commit raised the extension renderer mode on the factory itself. That mode applies to every renderer, not just audio: video went to the software decoders too, and playback on a modest TV box became a slideshow. Sound was fixed, picture was ruined. The mode is now overridden inside buildAudioRenderers, which receives it as a parameter, leaving the factory-wide setting untouched. Audio decoding goes to the bundled FFmpeg renderers; video keeps whatever the platform provides. Verified on an Amlogic X96 Max+ (Android 9) with a 5.1 AC3 movie: video OMX.amlogic.avc.decoder.awesome hardware, smooth playback audio MIXER / PCM_16_BIT decoded, volume keys working Confirmed by ear and eye, not only by dumpsys: the three earlier attempts each looked correct in the audio routing while producing silence or stutter.
oxyroid
requested changes
Aug 9, 2026
| private val renderersFactory: RenderersFactory by lazy { | ||
| Codecs.createRenderersFactory(context) | ||
| } | ||
| // La fabrique n'est plus mise en cache : le réglage de décodage audio peut |
Contributor
Author
There was a problem hiding this comment.
Fixed in 0ac32ec — it was left in French, which nobody else here reads. Sorry about that. I checked the other branches: it was the only one.
It had been left in French, which no one else on this project reads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On a TV box that feeds the speakers itself, the volume keys do nothing on
5.1 content while working normally on stereo channels.
Why
ExoPlayer asks the audio output what it can handle, and when the sink claims
AC3/EAC3 support it forwards the stream untouched. That is right with an A/V
receiver, but where the box decodes for itself the stream never reaches the
mixer — so Android volume has no hold on it. A stereo channel goes through
type 0 (MIXER)as PCM and responds; a 5.1 film goes out astype 1 (DIRECT)and ignores the remote entirely.An opt-in setting, off by default, declares stereo-only capabilities so
ExoPlayer decodes instead and audio flows back through the mixer.
Three traps on the way, one commit each
DefaultAudioSink.Builder(context)silently discardssetAudioCapabilities. With a Context it probes the real output and dropswhat was declared. The builder has to be constructed without one.
The hardware AC3 decoder produces nothing when asked for PCM.
EXTENSION_RENDERER_MODE_ONmakes ExoPlayer preferOMX.amlogic.audio.decoder.ac3, built to feed a passthrough path. Asked forPCM it emits no output and reports no error — the stream plays, the mixer
runs, and nothing is audible.
Raising the extension mode on the factory applies it to video too.
setExtensionRendererModecovers every renderer, so preferring FFmpegglobally also hands video to the software decoders, turning smooth playback
into a slideshow on a modest box. The mode is overridden inside
buildAudioRenderersinstead.Verification
Measured on device (Amlogic box, Android 9) on an AC3 5.1 film:
Confirmed by ear and by eye, not only from
dumpsys: each of the threeearlier attempts looked correct in the audio routing while producing silence
or stutter.