mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
parent
f0b34b8f4c
commit
d194ba93ac
2 changed files with 66 additions and 66 deletions
|
|
@ -141,7 +141,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
|
|
||||||
private @ReinitializationState int decoderReinitializationState;
|
private @ReinitializationState int decoderReinitializationState;
|
||||||
private boolean decoderReceivedBuffers;
|
private boolean decoderReceivedBuffers;
|
||||||
private boolean audioSinkNeedsConfigure;
|
private boolean audioTrackNeedsConfigure;
|
||||||
|
|
||||||
private long currentPositionUs;
|
private long currentPositionUs;
|
||||||
private boolean allowFirstBufferPositionDiscontinuity;
|
private boolean allowFirstBufferPositionDiscontinuity;
|
||||||
|
|
@ -206,7 +206,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
audioSink.setListener(new AudioSinkListener());
|
audioSink.setListener(new AudioSinkListener());
|
||||||
flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
|
flagsOnlyBuffer = DecoderInputBuffer.newNoDataInstance();
|
||||||
decoderReinitializationState = REINITIALIZATION_STATE_NONE;
|
decoderReinitializationState = REINITIALIZATION_STATE_NONE;
|
||||||
audioSinkNeedsConfigure = true;
|
audioTrackNeedsConfigure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -401,7 +401,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
releaseDecoder();
|
releaseDecoder();
|
||||||
maybeInitDecoder();
|
maybeInitDecoder();
|
||||||
// The audio track may need to be recreated once the new output format is known.
|
// The audio track may need to be recreated once the new output format is known.
|
||||||
audioSinkNeedsConfigure = true;
|
audioTrackNeedsConfigure = true;
|
||||||
} else {
|
} else {
|
||||||
outputBuffer.release();
|
outputBuffer.release();
|
||||||
outputBuffer = null;
|
outputBuffer = null;
|
||||||
|
|
@ -415,7 +415,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioSinkNeedsConfigure) {
|
if (audioTrackNeedsConfigure) {
|
||||||
Format outputFormat =
|
Format outputFormat =
|
||||||
getOutputFormat(decoder)
|
getOutputFormat(decoder)
|
||||||
.buildUpon()
|
.buildUpon()
|
||||||
|
|
@ -423,7 +423,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
.setEncoderPadding(encoderPadding)
|
.setEncoderPadding(encoderPadding)
|
||||||
.build();
|
.build();
|
||||||
audioSink.configure(outputFormat, /* specifiedBufferSize= */ 0, /* outputChannels= */ null);
|
audioSink.configure(outputFormat, /* specifiedBufferSize= */ 0, /* outputChannels= */ null);
|
||||||
audioSinkNeedsConfigure = false;
|
audioTrackNeedsConfigure = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioSink.handleBuffer(
|
if (audioSink.handleBuffer(
|
||||||
|
|
@ -585,7 +585,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
@Override
|
@Override
|
||||||
protected void onDisabled() {
|
protected void onDisabled() {
|
||||||
inputFormat = null;
|
inputFormat = null;
|
||||||
audioSinkNeedsConfigure = true;
|
audioTrackNeedsConfigure = true;
|
||||||
try {
|
try {
|
||||||
setSourceDrmSession(null);
|
setSourceDrmSession(null);
|
||||||
releaseDecoder();
|
releaseDecoder();
|
||||||
|
|
@ -738,7 +738,7 @@ public abstract class DecoderAudioRenderer<
|
||||||
// There aren't any final output buffers, so release the decoder immediately.
|
// There aren't any final output buffers, so release the decoder immediately.
|
||||||
releaseDecoder();
|
releaseDecoder();
|
||||||
maybeInitDecoder();
|
maybeInitDecoder();
|
||||||
audioSinkNeedsConfigure = true;
|
audioTrackNeedsConfigure = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eventDispatcher.inputFormatChanged(inputFormat, evaluation);
|
eventDispatcher.inputFormatChanged(inputFormat, evaluation);
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
private long currentPositionUs;
|
private long currentPositionUs;
|
||||||
private boolean allowFirstBufferPositionDiscontinuity;
|
private boolean allowFirstBufferPositionDiscontinuity;
|
||||||
private boolean allowPositionDiscontinuity;
|
private boolean allowPositionDiscontinuity;
|
||||||
private boolean audioSinkNeedsConfigure;
|
private boolean audioSinkNeedsReset;
|
||||||
|
|
||||||
private boolean experimentalKeepAudioTrackOnSeek;
|
private boolean experimentalKeepAudioTrackOnSeek;
|
||||||
|
|
||||||
|
|
@ -258,7 +258,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
this.audioSink = audioSink;
|
this.audioSink = audioSink;
|
||||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||||
audioSink.setListener(new AudioSinkListener());
|
audioSink.setListener(new AudioSinkListener());
|
||||||
audioSinkNeedsConfigure = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -505,7 +504,50 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
@Override
|
@Override
|
||||||
protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat)
|
protected void onOutputFormatChanged(Format format, @Nullable MediaFormat mediaFormat)
|
||||||
throws ExoPlaybackException {
|
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()}. */
|
/** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */
|
||||||
|
|
@ -557,9 +599,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDisabled() {
|
protected void onDisabled() {
|
||||||
audioSinkNeedsConfigure = true;
|
audioSinkNeedsReset = true;
|
||||||
try {
|
try {
|
||||||
audioSink.reset();
|
audioSink.flush();
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
super.onDisabled();
|
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
|
@Override
|
||||||
public boolean isEnded() {
|
public boolean isEnded() {
|
||||||
return super.isEnded() && audioSink.isEnded();
|
return super.isEnded() && audioSink.isEnded();
|
||||||
|
|
@ -639,8 +693,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeConfigureAudioSink(format, getCodecOutputMediaFormat());
|
|
||||||
|
|
||||||
if (isDecodeOnlyBuffer) {
|
if (isDecodeOnlyBuffer) {
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
codec.releaseOutputBuffer(bufferIndex, false);
|
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
|
* Returns whether the device's decoders are known to not support setting the codec operating
|
||||||
* rate.
|
* rate.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue