PiperOrigin-RevId: 444347415
This commit is contained in:
samrobinson 2022-04-25 20:59:35 +01:00 committed by Ian Baker
parent f0b34b8f4c
commit d194ba93ac
2 changed files with 66 additions and 66 deletions

View file

@ -141,7 +141,7 @@ public abstract class DecoderAudioRenderer<
private @ReinitializationState int decoderReinitializationState;
private boolean decoderReceivedBuffers;
private boolean audioSinkNeedsConfigure;
private boolean audioTrackNeedsConfigure;
private long currentPositionUs;
private boolean allowFirstBufferPositionDiscontinuity;
@ -206,7 +206,7 @@ public abstract class DecoderAudioRenderer<
audioSink.setListener(new AudioSinkListener());
flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
decoderReinitializationState = REINITIALIZATION_STATE_NONE;
audioSinkNeedsConfigure = true;
audioTrackNeedsConfigure = true;
}
/**
@ -401,7 +401,7 @@ public abstract class DecoderAudioRenderer<
releaseDecoder();
maybeInitDecoder();
// The audio track may need to be recreated once the new output format is known.
audioSinkNeedsConfigure = true;
audioTrackNeedsConfigure = true;
} else {
outputBuffer.release();
outputBuffer = null;
@ -415,7 +415,7 @@ public abstract class DecoderAudioRenderer<
return false;
}
if (audioSinkNeedsConfigure) {
if (audioTrackNeedsConfigure) {
Format outputFormat =
getOutputFormat(decoder)
.buildUpon()
@ -423,7 +423,7 @@ public abstract class DecoderAudioRenderer<
.setEncoderPadding(encoderPadding)
.build();
audioSink.configure(outputFormat, /* specifiedBufferSize= */ 0, /* outputChannels= */ null);
audioSinkNeedsConfigure = false;
audioTrackNeedsConfigure = false;
}
if (audioSink.handleBuffer(
@ -585,7 +585,7 @@ public abstract class DecoderAudioRenderer<
@Override
protected void onDisabled() {
inputFormat = null;
audioSinkNeedsConfigure = true;
audioTrackNeedsConfigure = true;
try {
setSourceDrmSession(null);
releaseDecoder();
@ -738,7 +738,7 @@ public abstract class DecoderAudioRenderer<
// There aren't any final output buffers, so release the decoder immediately.
releaseDecoder();
maybeInitDecoder();
audioSinkNeedsConfigure = true;
audioTrackNeedsConfigure = true;
}
}
eventDispatcher.inputFormatChanged(inputFormat, evaluation);

View file

@ -107,7 +107,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
private long currentPositionUs;
private boolean allowFirstBufferPositionDiscontinuity;
private boolean allowPositionDiscontinuity;
private boolean audioSinkNeedsConfigure;
private boolean audioSinkNeedsReset;
private boolean experimentalKeepAudioTrackOnSeek;
@ -258,7 +258,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
this.audioSink = audioSink;
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
audioSink.setListener(new AudioSinkListener());
audioSinkNeedsConfigure = true;
}
@Override
@ -505,7 +504,50 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat)
throws ExoPlaybackException {
audioSinkNeedsConfigure = true;
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);
}
}
/** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */
@ -557,9 +599,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Override
protected void onDisabled() {
audioSinkNeedsConfigure = true;
audioSinkNeedsReset = true;
try {
audioSink.reset();
audioSink.flush();
} finally {
try {
super.onDisabled();
@ -569,6 +611,18 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
}
}
@Override
protected void onReset() {
try {
super.onReset();
} finally {
if (audioSinkNeedsReset) {
audioSinkNeedsReset = false;
audioSink.reset();
}
}
}
@Override
public boolean isEnded() {
return super.isEnded() && audioSink.isEnded();
@ -639,8 +693,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
return true;
}
maybeConfigureAudioSink(format, getCodecOutputMediaFormat());
if (isDecodeOnlyBuffer) {
if (codec != null) {
codec.releaseOutputBuffer(bufferIndex, false);
@ -823,58 +875,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
}
}
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.