Minimal fix for playback freezes when enabling tracks #8203

Background:

1. When the player has multiple audio renderers, by default they share a
   single AudioSink.
2. When any new renderer is enabled, all disabled renderers are reset
   prior to the new renderer being enabled. This is to give them a chance
   to free up resources in case the renderer being enabled needs them. These
   reset calls are expected to be no-ops for renderers that have never been
   enabled.

The issue:

The problematic case arises when there are two audio renderers and a third
renderer (e.g., text) is being enabled. In this case, the disabled audio
renderer's reset call ends up resetting the AudioSink that's shared with the
enabled audio renderer. The enabled audio renderer is then unable to make
progress, causing playback to freeze.

This is a minimal fix that directly prevents the mentioned issue. There are
multiple follow-ups that would probably make sense:

1. Having ExoPlayerImplInternal track which renderers need to be reset, and
   only resetting those renderers rather than all that are disabled. This
   seems like a good thing to do regardless, rather than relying on those
   calls being no-ops.
2. If we want to continue sharing AudioSink, we need to formalize this much
   better and make sure we have good test coverage. Messages like
   MSG_SET_VOLUME are also delivered to the AudioSink multiple times via
   each of the renderers, which works currently because DefaultAudioSink
   no-ops all but the first call in each case. This is pretty fragile though!

Issue: #8203
#minor-release
PiperOrigin-RevId: 343296081
This commit is contained in:
olly 2020-11-19 16:32:15 +00:00 committed by Oliver Woodman
parent 39f8c77568
commit 8c8176647c
2 changed files with 9 additions and 1 deletions

View file

@ -23,6 +23,9 @@
([#8106](https://github.com/google/ExoPlayer/issues/8106)).
* Suppress ProGuard warnings caused by Guava's compile-only dependencies
([#8103](https://github.com/google/ExoPlayer/issues/8103)).
* Fix issue that could cause playback to freeze when selecting tracks, if
extension audio renderers are being used
([#8203](https://github.com/google/ExoPlayer/issues/8203)).
* Track selection:
* Add option to specify multiple preferred audio or text languages.
* Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`.

View file

@ -102,6 +102,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private long currentPositionUs;
private boolean allowFirstBufferPositionDiscontinuity;
private boolean allowPositionDiscontinuity;
private boolean audioSinkNeedsReset;
private boolean experimentalKeepAudioTrackOnSeek;
@ -500,6 +501,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onDisabled() {
audioSinkNeedsReset = true;
try {
audioSink.flush();
} finally {
@ -516,7 +518,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
try {
super.onReset();
} finally {
audioSink.reset();
if (audioSinkNeedsReset) {
audioSinkNeedsReset = false;
audioSink.reset();
}
}
}