From 40870b87809e1e75f3018fdf1432b8db35b39d13 Mon Sep 17 00:00:00 2001 From: olly Date: Wed, 4 Sep 2019 20:34:49 +0100 Subject: [PATCH] Prevent audio pops on audio format change. We'd like to switch opus audio bitrates in the middle of playback based on network conditions. Changing between different bitrates on the same codec should not require decoder initialization. PiperOrigin-RevId: 267208043 --- .../audio/SimpleDecoderAudioRenderer.java | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java index 22d34fc904..52d55b2c31 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/SimpleDecoderAudioRenderer.java @@ -361,6 +361,17 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements null, null, 0, null); } + /** + * Returns whether the existing decoder can be kept for a new format. + * + * @param oldFormat The previous format. + * @param newFormat The new format. + * @return True if the existing decoder can be kept. + */ + protected boolean canKeepCodec(Format oldFormat, Format newFormat) { + return false; + } + private boolean drainOutputBuffer() throws ExoPlaybackException, AudioDecoderException, AudioSink.ConfigurationException, AudioSink.InitializationException, AudioSink.WriteException { @@ -689,14 +700,16 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements } } - if (decoderReceivedBuffers) { - // Signal end of stream and wait for any final output buffers before re-initialization. - decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM; - } else { - // There aren't any final output buffers, so release the decoder immediately. - releaseDecoder(); - maybeInitDecoder(); - audioTrackNeedsConfigure = true; + if (!canKeepCodec(oldFormat, inputFormat)) { + if (decoderReceivedBuffers) { + // Signal end of stream and wait for any final output buffers before re-initialization. + decoderReinitializationState = REINITIALIZATION_STATE_SIGNAL_END_OF_STREAM; + } else { + // There aren't any final output buffers, so release the decoder immediately. + releaseDecoder(); + maybeInitDecoder(); + audioTrackNeedsConfigure = true; + } } encoderDelay = inputFormat.encoderDelay;