Skip to content

Commit

Permalink
Align MediaCodec and Decoder AudioRenderer onDisabled logic.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 443156130
  • Loading branch information
Samrobbo authored and icbaker committed Apr 26, 2022
1 parent 6939464 commit a29206d
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 66 deletions.
Expand Up @@ -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;
Expand Down Expand Up @@ -206,7 +206,7 @@ public DecoderAudioRenderer(
audioSink.setListener(new AudioSinkListener());
flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
decoderReinitializationState = REINITIALIZATION_STATE_NONE;
audioTrackNeedsConfigure = true;
audioSinkNeedsConfigure = true;
}

/**
Expand Down Expand Up @@ -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;
Expand All @@ -415,15 +415,15 @@ private boolean drainOutputBuffer()
return false;
}

if (audioTrackNeedsConfigure) {
if (audioSinkNeedsConfigure) {
Format outputFormat =
getOutputFormat(decoder)
.buildUpon()
.setEncoderDelay(encoderDelay)
.setEncoderPadding(encoderPadding)
.build();
audioSink.configure(outputFormat, /* specifiedBufferSize= */ 0, /* outputChannels= */ null);
audioTrackNeedsConfigure = false;
audioSinkNeedsConfigure = false;
}

if (audioSink.handleBuffer(
Expand Down Expand Up @@ -585,7 +585,7 @@ protected void onStopped() {
@Override
protected void onDisabled() {
inputFormat = null;
audioTrackNeedsConfigure = true;
audioSinkNeedsConfigure = true;
try {
setSourceDrmSession(null);
releaseDecoder();
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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;

Expand Down Expand Up @@ -258,6 +258,7 @@ public MediaCodecAudioRenderer(
this.audioSink = audioSink;
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
audioSink.setListener(new AudioSinkListener());
audioSinkNeedsConfigure = true;
}

@Override
Expand Down Expand Up @@ -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()}. */
Expand Down Expand Up @@ -599,9 +557,9 @@ protected void onStopped() {

@Override
protected void onDisabled() {
audioSinkNeedsReset = true;
audioSinkNeedsConfigure = true;
try {
audioSink.flush();
audioSink.reset();
} finally {
try {
super.onDisabled();
Expand All @@ -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();
Expand Down Expand Up @@ -693,6 +639,8 @@ protected boolean processOutputBuffer(
return true;
}

maybeConfigureAudioSink(format, getCodecOutputMediaFormat());

if (isDecodeOnlyBuffer) {
if (codec != null) {
codec.releaseOutputBuffer(bufferIndex, false);
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit a29206d

Please sign in to comment.