From a29206d891193fc7efa312edd551e8e4ee5729b0 Mon Sep 17 00:00:00 2001 From: samrobinson Date: Wed, 20 Apr 2022 20:00:19 +0100 Subject: [PATCH] Align MediaCodec and Decoder AudioRenderer onDisabled logic. PiperOrigin-RevId: 443156130 --- .../exoplayer/audio/DecoderAudioRenderer.java | 14 +-- .../audio/MediaCodecAudioRenderer.java | 118 +++++++++--------- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java index b1ccd35438c..11c6ca0ecba 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java @@ -141,7 +141,7 @@ public abstract class DecoderAudioRenderer< private @ReinitializationState int decoderReinitializationState; private boolean decoderReceivedBuffers; - private boolean audioTrackNeedsConfigure; + private boolean audioSinkNeedsConfigure; private long currentPositionUs; private boolean allowFirstBufferPositionDiscontinuity; @@ -206,7 +206,7 @@ public DecoderAudioRenderer( audioSink.setListener(new AudioSinkListener()); flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance(); decoderReinitializationState = REINITIALIZATION_STATE_NONE; - audioTrackNeedsConfigure = true; + audioSinkNeedsConfigure = true; } /** @@ -401,7 +401,7 @@ private boolean drainOutputBuffer() releaseDecoder(); maybeInitDecoder(); // The audio track may need to be recreated once the new output format is known. - audioTrackNeedsConfigure = true; + audioSinkNeedsConfigure = true; } else { outputBuffer.release(); outputBuffer = null; @@ -415,7 +415,7 @@ private boolean drainOutputBuffer() return false; } - if (audioTrackNeedsConfigure) { + if (audioSinkNeedsConfigure) { Format outputFormat = getOutputFormat(decoder) .buildUpon() @@ -423,7 +423,7 @@ private boolean drainOutputBuffer() .setEncoderPadding(encoderPadding) .build(); audioSink.configure(outputFormat, /* specifiedBufferSize= */ 0, /* outputChannels= */ null); - audioTrackNeedsConfigure = false; + audioSinkNeedsConfigure = false; } if (audioSink.handleBuffer( @@ -585,7 +585,7 @@ protected void onStopped() { @Override protected void onDisabled() { inputFormat = null; - audioTrackNeedsConfigure = true; + audioSinkNeedsConfigure = true; try { setSourceDrmSession(null); releaseDecoder(); @@ -738,7 +738,7 @@ private void onInputFormatChanged(FormatHolder formatHolder) throws ExoPlaybackE // There aren't any final output buffers, so release the decoder immediately. releaseDecoder(); maybeInitDecoder(); - audioTrackNeedsConfigure = true; + audioSinkNeedsConfigure = true; } } eventDispatcher.inputFormatChanged(inputFormat, evaluation); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java index a07750ce255..d17d92da918 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java @@ -107,7 +107,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media private long currentPositionUs; private boolean allowFirstBufferPositionDiscontinuity; private boolean allowPositionDiscontinuity; - private boolean audioSinkNeedsReset; + private boolean audioSinkNeedsConfigure; private boolean experimentalKeepAudioTrackOnSeek; @@ -258,6 +258,7 @@ public MediaCodecAudioRenderer( this.audioSink = audioSink; eventDispatcher = new EventDispatcher(eventHandler, eventListener); audioSink.setListener(new AudioSinkListener()); + audioSinkNeedsConfigure = true; } @Override @@ -504,50 +505,7 @@ protected DecoderReuseEvaluation onInputFormatChanged(FormatHolder formatHolder) @Override protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat) throws ExoPlaybackException { - Format audioSinkInputFormat; - @Nullable int[] channelMap = null; - if (decryptOnlyCodecFormat != null) { // Direct playback with a codec for decryption. - audioSinkInputFormat = decryptOnlyCodecFormat; - } else if (getCodec() == null) { // Direct playback with codec bypass. - audioSinkInputFormat = format; - } else { - @C.PcmEncoding int pcmEncoding; - if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)) { - // For PCM streams, the encoder passes through int samples despite set to float mode. - pcmEncoding = format.pcmEncoding; - } else if (Util.SDK_INT >= 24 && mediaFormat.containsKey(MediaFormat.KEY_PCM_ENCODING)) { - pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING); - } else if (mediaFormat.containsKey(VIVO_BITS_PER_SAMPLE_KEY)) { - pcmEncoding = Util.getPcmEncoding(mediaFormat.getInteger(VIVO_BITS_PER_SAMPLE_KEY)); - } else { - // If the format is anything other than PCM then we assume that the audio decoder will - // output 16-bit PCM. - pcmEncoding = C.ENCODING_PCM_16BIT; - } - audioSinkInputFormat = - new Format.Builder() - .setSampleMimeType(MimeTypes.AUDIO_RAW) - .setPcmEncoding(pcmEncoding) - .setEncoderDelay(format.encoderDelay) - .setEncoderPadding(format.encoderPadding) - .setChannelCount(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)) - .setSampleRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE)) - .build(); - if (codecNeedsDiscardChannelsWorkaround - && audioSinkInputFormat.channelCount == 6 - && format.channelCount < 6) { - channelMap = new int[format.channelCount]; - for (int i = 0; i < format.channelCount; i++) { - channelMap[i] = i; - } - } - } - try { - audioSink.configure(audioSinkInputFormat, /* specifiedBufferSize= */ 0, channelMap); - } catch (AudioSink.ConfigurationException e) { - throw createRendererException( - e, e.format, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED); - } + audioSinkNeedsConfigure = true; } /** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */ @@ -599,9 +557,9 @@ protected void onStopped() { @Override protected void onDisabled() { - audioSinkNeedsReset = true; + audioSinkNeedsConfigure = true; try { - audioSink.flush(); + audioSink.reset(); } finally { try { super.onDisabled(); @@ -611,18 +569,6 @@ protected void onDisabled() { } } - @Override - protected void onReset() { - try { - super.onReset(); - } finally { - if (audioSinkNeedsReset) { - audioSinkNeedsReset = false; - audioSink.reset(); - } - } - } - @Override public boolean isEnded() { return super.isEnded() && audioSink.isEnded(); @@ -693,6 +639,8 @@ protected boolean processOutputBuffer( return true; } + maybeConfigureAudioSink(format, getCodecOutputMediaFormat()); + if (isDecodeOnlyBuffer) { if (codec != null) { codec.releaseOutputBuffer(bufferIndex, false); @@ -875,6 +823,58 @@ private void updateCurrentPosition() { } } + private void maybeConfigureAudioSink(Format format, @Nullable MediaFormat mediaFormat) + throws ExoPlaybackException { + if (!audioSinkNeedsConfigure) { + return; + } + Format audioSinkInputFormat; + @Nullable int[] channelMap = null; + if (decryptOnlyCodecFormat != null) { // Direct playback with a codec for decryption. + audioSinkInputFormat = decryptOnlyCodecFormat; + } else if (getCodec() == null) { // Direct playback with codec bypass. + audioSinkInputFormat = format; + } else { + @C.PcmEncoding int pcmEncoding; + if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)) { + // For PCM streams, the encoder passes through int samples despite set to float mode. + pcmEncoding = format.pcmEncoding; + } else if (Util.SDK_INT >= 24 && mediaFormat.containsKey(MediaFormat.KEY_PCM_ENCODING)) { + pcmEncoding = mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING); + } else if (mediaFormat.containsKey(VIVO_BITS_PER_SAMPLE_KEY)) { + pcmEncoding = Util.getPcmEncoding(mediaFormat.getInteger(VIVO_BITS_PER_SAMPLE_KEY)); + } else { + // If the format is anything other than PCM then we assume that the audio decoder will + // output 16-bit PCM. + pcmEncoding = C.ENCODING_PCM_16BIT; + } + audioSinkInputFormat = + new Format.Builder() + .setSampleMimeType(MimeTypes.AUDIO_RAW) + .setPcmEncoding(pcmEncoding) + .setEncoderDelay(format.encoderDelay) + .setEncoderPadding(format.encoderPadding) + .setChannelCount(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT)) + .setSampleRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE)) + .build(); + if (codecNeedsDiscardChannelsWorkaround + && audioSinkInputFormat.channelCount == 6 + && format.channelCount < 6) { + channelMap = new int[format.channelCount]; + for (int i = 0; i < format.channelCount; i++) { + channelMap[i] = i; + } + } + } + try { + audioSink.configure(audioSinkInputFormat, /* specifiedBufferSize= */ 0, channelMap); + audioSinkNeedsConfigure = false; + } catch (AudioSink.ConfigurationException e) { + throw createRendererException( + e, e.format, PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED); + } + } + /** * Returns whether the device's decoders are known to not support setting the codec operating * rate.