-
Notifications
You must be signed in to change notification settings - Fork 648
Description
Version
Media3 main branch
More version details
Issue
In the class OnRoutingChangedListenerApi24 of DefaultAudioSink.java
private static final class OnRoutingChangedListenerApi24 {
private final AudioTrack audioTrack;
private final AudioCapabilitiesReceiver capabilitiesReceiver;
@Nullable private OnRoutingChangedListener listener;
public OnRoutingChangedListenerApi24(
AudioTrack audioTrack, AudioCapabilitiesReceiver capabilitiesReceiver) {
this.audioTrack = audioTrack;
this.capabilitiesReceiver = capabilitiesReceiver;
this.listener = this::onRoutingChanged;
// the following line gets handler of ExoPlayer:Playback thread
Handler handler = new Handler(Looper.myLooper());
audioTrack.addOnRoutingChangedListener(listener, handler);
}
public void release() {
audioTrack.removeOnRoutingChangedListener(checkNotNull(listener));
listener = null;
}
private void onRoutingChanged(AudioRouting router) {
if (listener == null) {
// Stale event.
return;
}
@Nullable AudioDeviceInfo routedDevice = router.getRoutedDevice();
if (routedDevice != null) {
capabilitiesReceiver.setRoutedDevice(routedDevice);
}
}
}
It sets the handler of ExoPlayer:Playback thread (via Looper.myLooper()) to audioTrack.addOnRoutingChangedListener.
When playing content with ddp audiotrack in offload mode, the onRoutingChanged will be triggered at the first few secs of the playback.
perfetto trace of the issue: androidxmedia3.original.perfetto.trace.zip

When onRoutingChanged takes too long in ExoPlayer:Playback thread, the next doSomeWork has to drop frames since the rendering timestamp are too late.
Optimize propose:
We suggest create a new thread to handle the callback of routing changed
public OnRoutingChangedListenerApi24(
AudioTrack audioTrack, AudioCapabilitiesReceiver capabilitiesReceiver) {
this.audioTrack = audioTrack;
this.capabilitiesReceiver = capabilitiesReceiver;
this.listener = this::onRoutingChanged;
if (routingChangedHandlerThread == null) {
routingChangedHandlerThread =
new HandlerThread("ExoPlayer:RoutingChangedHandler", Process.THREAD_PRIORITY_AUDIO);
routingChangedHandlerThread.start();
}
Handler handler = new Handler(routingChangedHandlerThread.getLooper());
audioTrack.addOnRoutingChangedListener(listener, handler);
}
perfetto trace of the optimize modification: androidxmedia3.optimized.perfetto.trace.zip

And from our verification with the proposed modification, no more frames dropped are observed at the initial playback.
Devices that reproduce the issue
Amazon Fire TV devices.
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
- Paying the content with ddp audio track.
- When the onRoutingChangedListener of AudioTrack is triggered at the beginning of the playback,
onRoutingChangedtakes too long inExoPlayer:Playbackthread, the nextdoSomeWorkhas to drop frames since the rendering timestamp are too late.
Expected result
The playback should be smooth.
Actual result
Observes visual stutter at the initial playback.
Media
The contents with ddp audio track.
Bug Report
- You will email the zip file produced by
adb bugreportto android-media-github@google.com after filing this issue.