mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add nullness annotations to MediaCodecRenderer
#fixit
PiperOrigin-RevId: 570403923
(cherry picked from commit 7a91474af9)
This commit is contained in:
parent
0480b70f36
commit
7957554442
1 changed files with 66 additions and 41 deletions
|
|
@ -17,6 +17,7 @@ package androidx.media3.exoplayer.mediacodec;
|
||||||
|
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
|
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||||
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_DRM_SESSION_CHANGED;
|
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_DRM_SESSION_CHANGED;
|
||||||
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_OPERATING_RATE_CHANGED;
|
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_OPERATING_RATE_CHANGED;
|
||||||
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED;
|
import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED;
|
||||||
|
|
@ -124,7 +125,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
private static final int DECODER_QUERY_ERROR = CUSTOM_ERROR_CODE_BASE + 2;
|
private static final int DECODER_QUERY_ERROR = CUSTOM_ERROR_CODE_BASE + 2;
|
||||||
|
|
||||||
/** The MIME type for which a decoder was being initialized. */
|
/** The MIME type for which a decoder was being initialized. */
|
||||||
public final String mimeType;
|
@Nullable public final String mimeType;
|
||||||
|
|
||||||
/** Whether it was required that the decoder support a secure output path. */
|
/** Whether it was required that the decoder support a secure output path. */
|
||||||
public final boolean secureDecoderRequired;
|
public final boolean secureDecoderRequired;
|
||||||
|
|
@ -173,9 +174,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DecoderInitializationException(
|
private DecoderInitializationException(
|
||||||
String message,
|
@Nullable String message,
|
||||||
@Nullable Throwable cause,
|
@Nullable Throwable cause,
|
||||||
String mimeType,
|
@Nullable String mimeType,
|
||||||
boolean secureDecoderRequired,
|
boolean secureDecoderRequired,
|
||||||
@Nullable MediaCodecInfo mediaCodecInfo,
|
@Nullable MediaCodecInfo mediaCodecInfo,
|
||||||
@Nullable String diagnosticInfo,
|
@Nullable String diagnosticInfo,
|
||||||
|
|
@ -440,7 +441,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
targetPlaybackSpeed = 1f;
|
targetPlaybackSpeed = 1f;
|
||||||
renderTimeLimitMs = C.TIME_UNSET;
|
renderTimeLimitMs = C.TIME_UNSET;
|
||||||
pendingOutputStreamChanges = new ArrayDeque<>();
|
pendingOutputStreamChanges = new ArrayDeque<>();
|
||||||
setOutputStreamInfo(OutputStreamInfo.UNSET);
|
outputStreamInfo = OutputStreamInfo.UNSET;
|
||||||
// MediaCodec outputs audio buffers in native endian:
|
// MediaCodec outputs audio buffers in native endian:
|
||||||
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
|
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
|
||||||
// and code called from MediaCodecAudioRenderer.processOutputBuffer expects this endianness.
|
// and code called from MediaCodecAudioRenderer.processOutputBuffer expects this endianness.
|
||||||
|
|
@ -461,6 +462,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
|
lastProcessedOutputBufferTimeUs = C.TIME_UNSET;
|
||||||
codecDrainState = DRAIN_STATE_NONE;
|
codecDrainState = DRAIN_STATE_NONE;
|
||||||
codecDrainAction = DRAIN_ACTION_NONE;
|
codecDrainAction = DRAIN_ACTION_NONE;
|
||||||
|
decoderCounters = new DecoderCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -544,7 +546,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
|
|
||||||
setCodecDrmSession(sourceDrmSession);
|
setCodecDrmSession(sourceDrmSession);
|
||||||
|
|
||||||
String mimeType = inputFormat.sampleMimeType;
|
String mimeType = checkNotNull(inputFormat).sampleMimeType;
|
||||||
|
@Nullable DrmSession codecDrmSession = this.codecDrmSession;
|
||||||
if (codecDrmSession != null) {
|
if (codecDrmSession != null) {
|
||||||
@Nullable CryptoConfig cryptoConfig = codecDrmSession.getCryptoConfig();
|
@Nullable CryptoConfig cryptoConfig = codecDrmSession.getCryptoConfig();
|
||||||
if (mediaCrypto == null) {
|
if (mediaCrypto == null) {
|
||||||
|
|
@ -568,7 +571,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
mediaCryptoRequiresSecureDecoder =
|
mediaCryptoRequiresSecureDecoder =
|
||||||
!frameworkCryptoConfig.forceAllowInsecureDecoderComponents
|
!frameworkCryptoConfig.forceAllowInsecureDecoderComponents
|
||||||
&& mediaCrypto.requiresSecureDecoderComponent(mimeType);
|
&& mediaCrypto.requiresSecureDecoderComponent(checkStateNotNull(mimeType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (FrameworkCryptoConfig.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC
|
if (FrameworkCryptoConfig.WORKAROUND_DEVICE_NEEDS_KEYS_TO_CONFIGURE_CODEC
|
||||||
|
|
@ -681,7 +684,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
outputFormatChanged = true;
|
outputFormatChanged = true;
|
||||||
}
|
}
|
||||||
if (outputFormatChanged || (codecOutputMediaFormatChanged && outputFormat != null)) {
|
if (outputFormatChanged || (codecOutputMediaFormatChanged && outputFormat != null)) {
|
||||||
onOutputFormatChanged(outputFormat, codecOutputMediaFormat);
|
onOutputFormatChanged(checkNotNull(outputFormat), codecOutputMediaFormat);
|
||||||
codecOutputMediaFormatChanged = false;
|
codecOutputMediaFormatChanged = false;
|
||||||
needToNotifyOutputFormatChangeAfterStreamChange = false;
|
needToNotifyOutputFormatChangeAfterStreamChange = false;
|
||||||
}
|
}
|
||||||
|
|
@ -800,7 +803,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
codec.release();
|
codec.release();
|
||||||
decoderCounters.decoderReleaseCount++;
|
decoderCounters.decoderReleaseCount++;
|
||||||
onCodecReleased(codecInfo.name);
|
onCodecReleased(checkNotNull(codecInfo).name);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
codec = null;
|
codec = null;
|
||||||
|
|
@ -941,7 +944,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
/** Flushes the codec. */
|
/** Flushes the codec. */
|
||||||
private void flushCodec() {
|
private void flushCodec() {
|
||||||
try {
|
try {
|
||||||
codec.flush();
|
checkStateNotNull(codec).flush();
|
||||||
} finally {
|
} finally {
|
||||||
resetCodecStateForFlush();
|
resetCodecStateForFlush();
|
||||||
}
|
}
|
||||||
|
|
@ -1035,6 +1038,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
private void maybeInitCodecWithFallback(
|
private void maybeInitCodecWithFallback(
|
||||||
@Nullable MediaCrypto crypto, boolean mediaCryptoRequiresSecureDecoder)
|
@Nullable MediaCrypto crypto, boolean mediaCryptoRequiresSecureDecoder)
|
||||||
throws DecoderInitializationException {
|
throws DecoderInitializationException {
|
||||||
|
Format inputFormat = checkNotNull(this.inputFormat);
|
||||||
if (availableCodecInfos == null) {
|
if (availableCodecInfos == null) {
|
||||||
try {
|
try {
|
||||||
List<MediaCodecInfo> allAvailableCodecInfos =
|
List<MediaCodecInfo> allAvailableCodecInfos =
|
||||||
|
|
@ -1063,9 +1067,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
DecoderInitializationException.NO_SUITABLE_DECODER_ERROR);
|
DecoderInitializationException.NO_SUITABLE_DECODER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayDeque<MediaCodecInfo> availableCodecInfos = checkNotNull(this.availableCodecInfos);
|
||||||
MediaCodecInfo preferredCodecInfo = availableCodecInfos.peekFirst();
|
MediaCodecInfo preferredCodecInfo = availableCodecInfos.peekFirst();
|
||||||
while (codec == null) {
|
while (codec == null) {
|
||||||
MediaCodecInfo codecInfo = availableCodecInfos.peekFirst();
|
MediaCodecInfo codecInfo = checkNotNull(availableCodecInfos.peekFirst());
|
||||||
if (!shouldInitCodec(codecInfo)) {
|
if (!shouldInitCodec(codecInfo)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1106,11 +1111,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
availableCodecInfos = null;
|
this.availableCodecInfos = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MediaCodecInfo> getAvailableCodecInfos(boolean mediaCryptoRequiresSecureDecoder)
|
private List<MediaCodecInfo> getAvailableCodecInfos(boolean mediaCryptoRequiresSecureDecoder)
|
||||||
throws DecoderQueryException {
|
throws DecoderQueryException {
|
||||||
|
Format inputFormat = checkNotNull(this.inputFormat);
|
||||||
List<MediaCodecInfo> codecInfos =
|
List<MediaCodecInfo> codecInfos =
|
||||||
getDecoderInfos(mediaCodecSelector, inputFormat, mediaCryptoRequiresSecureDecoder);
|
getDecoderInfos(mediaCodecSelector, inputFormat, mediaCryptoRequiresSecureDecoder);
|
||||||
if (codecInfos.isEmpty() && mediaCryptoRequiresSecureDecoder) {
|
if (codecInfos.isEmpty() && mediaCryptoRequiresSecureDecoder) {
|
||||||
|
|
@ -1150,6 +1156,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initCodec(MediaCodecInfo codecInfo, @Nullable MediaCrypto crypto) throws Exception {
|
private void initCodec(MediaCodecInfo codecInfo, @Nullable MediaCrypto crypto) throws Exception {
|
||||||
|
Format inputFormat = checkNotNull(this.inputFormat);
|
||||||
long codecInitializingTimestamp;
|
long codecInitializingTimestamp;
|
||||||
long codecInitializedTimestamp;
|
long codecInitializedTimestamp;
|
||||||
String codecName = codecInfo.name;
|
String codecName = codecInfo.name;
|
||||||
|
|
@ -1188,17 +1195,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
codecInputFormat = inputFormat;
|
codecInputFormat = inputFormat;
|
||||||
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
|
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
|
||||||
codecNeedsDiscardToSpsWorkaround =
|
codecNeedsDiscardToSpsWorkaround =
|
||||||
codecNeedsDiscardToSpsWorkaround(codecName, codecInputFormat);
|
codecNeedsDiscardToSpsWorkaround(codecName, checkNotNull(codecInputFormat));
|
||||||
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
|
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
|
||||||
codecNeedsSosFlushWorkaround = codecNeedsSosFlushWorkaround(codecName);
|
codecNeedsSosFlushWorkaround = codecNeedsSosFlushWorkaround(codecName);
|
||||||
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
|
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
|
||||||
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
|
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
|
||||||
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecName);
|
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecName);
|
||||||
codecNeedsMonoChannelCountWorkaround =
|
codecNeedsMonoChannelCountWorkaround =
|
||||||
codecNeedsMonoChannelCountWorkaround(codecName, codecInputFormat);
|
codecNeedsMonoChannelCountWorkaround(codecName, checkNotNull(codecInputFormat));
|
||||||
codecNeedsEosPropagation =
|
codecNeedsEosPropagation =
|
||||||
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
|
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
|
||||||
if (codec.needsReconfiguration()) {
|
if (checkNotNull(codec).needsReconfiguration()) {
|
||||||
this.codecReconfigured = true;
|
this.codecReconfigured = true;
|
||||||
this.codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
this.codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||||
this.codecNeedsAdaptationWorkaroundBuffer =
|
this.codecNeedsAdaptationWorkaroundBuffer =
|
||||||
|
|
@ -1255,6 +1262,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
drainAndReinitializeCodec();
|
drainAndReinitializeCodec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaCodecAdapter codec = checkNotNull(this.codec);
|
||||||
if (inputIndex < 0) {
|
if (inputIndex < 0) {
|
||||||
inputIndex = codec.dequeueInputBufferIndex();
|
inputIndex = codec.dequeueInputBufferIndex();
|
||||||
if (inputIndex < 0) {
|
if (inputIndex < 0) {
|
||||||
|
|
@ -1280,7 +1288,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
|
|
||||||
if (codecNeedsAdaptationWorkaroundBuffer) {
|
if (codecNeedsAdaptationWorkaroundBuffer) {
|
||||||
codecNeedsAdaptationWorkaroundBuffer = false;
|
codecNeedsAdaptationWorkaroundBuffer = false;
|
||||||
buffer.data.put(ADAPTATION_WORKAROUND_BUFFER);
|
checkNotNull(buffer.data).put(ADAPTATION_WORKAROUND_BUFFER);
|
||||||
codec.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0);
|
codec.queueInputBuffer(inputIndex, 0, ADAPTATION_WORKAROUND_BUFFER.length, 0, 0);
|
||||||
resetInputBuffer();
|
resetInputBuffer();
|
||||||
codecReceivedBuffers = true;
|
codecReceivedBuffers = true;
|
||||||
|
|
@ -1290,13 +1298,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
// For adaptive reconfiguration, decoders expect all reconfiguration data to be supplied at
|
// For adaptive reconfiguration, decoders expect all reconfiguration data to be supplied at
|
||||||
// the start of the buffer that also contains the first frame in the new format.
|
// the start of the buffer that also contains the first frame in the new format.
|
||||||
if (codecReconfigurationState == RECONFIGURATION_STATE_WRITE_PENDING) {
|
if (codecReconfigurationState == RECONFIGURATION_STATE_WRITE_PENDING) {
|
||||||
for (int i = 0; i < codecInputFormat.initializationData.size(); i++) {
|
for (int i = 0; i < checkNotNull(codecInputFormat).initializationData.size(); i++) {
|
||||||
byte[] data = codecInputFormat.initializationData.get(i);
|
byte[] data = codecInputFormat.initializationData.get(i);
|
||||||
buffer.data.put(data);
|
checkNotNull(buffer.data).put(data);
|
||||||
}
|
}
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
|
codecReconfigurationState = RECONFIGURATION_STATE_QUEUE_PENDING;
|
||||||
}
|
}
|
||||||
int adaptiveReconfigurationBytes = buffer.data.position();
|
int adaptiveReconfigurationBytes = checkNotNull(buffer.data).position();
|
||||||
|
|
||||||
FormatHolder formatHolder = getFormatHolder();
|
FormatHolder formatHolder = getFormatHolder();
|
||||||
|
|
||||||
|
|
@ -1386,8 +1394,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
buffer.cryptoInfo.increaseClearDataFirstSubSampleBy(adaptiveReconfigurationBytes);
|
buffer.cryptoInfo.increaseClearDataFirstSubSampleBy(adaptiveReconfigurationBytes);
|
||||||
}
|
}
|
||||||
if (codecNeedsDiscardToSpsWorkaround && !bufferEncrypted) {
|
if (codecNeedsDiscardToSpsWorkaround && !bufferEncrypted) {
|
||||||
NalUnitUtil.discardToSps(buffer.data);
|
NalUnitUtil.discardToSps(checkNotNull(buffer.data));
|
||||||
if (buffer.data.position() == 0) {
|
if (checkNotNull(buffer.data).position() == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
codecNeedsDiscardToSpsWorkaround = false;
|
codecNeedsDiscardToSpsWorkaround = false;
|
||||||
|
|
@ -1397,9 +1405,12 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
|
|
||||||
if (waitingForFirstSampleInFormat) {
|
if (waitingForFirstSampleInFormat) {
|
||||||
if (!pendingOutputStreamChanges.isEmpty()) {
|
if (!pendingOutputStreamChanges.isEmpty()) {
|
||||||
pendingOutputStreamChanges.peekLast().formatQueue.add(presentationTimeUs, inputFormat);
|
pendingOutputStreamChanges
|
||||||
|
.peekLast()
|
||||||
|
.formatQueue
|
||||||
|
.add(presentationTimeUs, checkNotNull(inputFormat));
|
||||||
} else {
|
} else {
|
||||||
outputStreamInfo.formatQueue.add(presentationTimeUs, inputFormat);
|
outputStreamInfo.formatQueue.add(presentationTimeUs, checkNotNull(inputFormat));
|
||||||
}
|
}
|
||||||
waitingForFirstSampleInFormat = false;
|
waitingForFirstSampleInFormat = false;
|
||||||
}
|
}
|
||||||
|
|
@ -1416,11 +1427,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
onQueueInputBuffer(buffer);
|
onQueueInputBuffer(buffer);
|
||||||
try {
|
try {
|
||||||
if (bufferEncrypted) {
|
if (bufferEncrypted) {
|
||||||
codec.queueSecureInputBuffer(
|
checkNotNull(codec)
|
||||||
|
.queueSecureInputBuffer(
|
||||||
inputIndex, /* offset= */ 0, buffer.cryptoInfo, presentationTimeUs, /* flags= */ 0);
|
inputIndex, /* offset= */ 0, buffer.cryptoInfo, presentationTimeUs, /* flags= */ 0);
|
||||||
} else {
|
} else {
|
||||||
codec.queueInputBuffer(
|
checkNotNull(codec)
|
||||||
inputIndex, /* offset= */ 0, buffer.data.limit(), presentationTimeUs, /* flags= */ 0);
|
.queueInputBuffer(
|
||||||
|
inputIndex,
|
||||||
|
/* offset= */ 0,
|
||||||
|
checkNotNull(buffer.data).limit(),
|
||||||
|
presentationTimeUs,
|
||||||
|
/* flags= */ 0);
|
||||||
}
|
}
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
throw createRendererException(
|
throw createRendererException(
|
||||||
|
|
@ -1535,9 +1552,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
// Copy the current codec and codecInfo to local variables so they remain accessible if the
|
// Copy the current codec and codecInfo to local variables so they remain accessible if the
|
||||||
// member variables are updated during the logic below.
|
// member variables are updated during the logic below.
|
||||||
MediaCodecAdapter codec = this.codec;
|
MediaCodecAdapter codec = this.codec;
|
||||||
MediaCodecInfo codecInfo = this.codecInfo;
|
MediaCodecInfo codecInfo = checkNotNull(this.codecInfo);
|
||||||
|
|
||||||
Format oldFormat = codecInputFormat;
|
Format oldFormat = checkNotNull(codecInputFormat);
|
||||||
if (drmNeedsCodecReinitialization(codecInfo, newFormat, codecDrmSession, sourceDrmSession)) {
|
if (drmNeedsCodecReinitialization(codecInfo, newFormat, codecDrmSession, sourceDrmSession)) {
|
||||||
drainAndReinitializeCodec();
|
drainAndReinitializeCodec();
|
||||||
return new DecoderReuseEvaluation(
|
return new DecoderReuseEvaluation(
|
||||||
|
|
@ -1663,7 +1680,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
lastProcessedOutputBufferTimeUs = presentationTimeUs;
|
lastProcessedOutputBufferTimeUs = presentationTimeUs;
|
||||||
while (!pendingOutputStreamChanges.isEmpty()
|
while (!pendingOutputStreamChanges.isEmpty()
|
||||||
&& presentationTimeUs >= pendingOutputStreamChanges.peek().previousStreamLastBufferTimeUs) {
|
&& presentationTimeUs >= pendingOutputStreamChanges.peek().previousStreamLastBufferTimeUs) {
|
||||||
setOutputStreamInfo(pendingOutputStreamChanges.poll());
|
setOutputStreamInfo(checkNotNull(pendingOutputStreamChanges.poll()));
|
||||||
onProcessedStreamChange();
|
onProcessedStreamChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1767,7 +1784,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
* @throws ExoPlaybackException If an error occurs releasing or initializing a codec.
|
* @throws ExoPlaybackException If an error occurs releasing or initializing a codec.
|
||||||
* @return False if codec release and re-initialization was triggered. True in all other cases.
|
* @return False if codec release and re-initialization was triggered. True in all other cases.
|
||||||
*/
|
*/
|
||||||
private boolean updateCodecOperatingRate(Format format) throws ExoPlaybackException {
|
private boolean updateCodecOperatingRate(@Nullable Format format) throws ExoPlaybackException {
|
||||||
if (Util.SDK_INT < 23) {
|
if (Util.SDK_INT < 23) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1780,7 +1797,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
float newCodecOperatingRate =
|
float newCodecOperatingRate =
|
||||||
getCodecOperatingRateV23(targetPlaybackSpeed, format, getStreamFormats());
|
getCodecOperatingRateV23(targetPlaybackSpeed, checkNotNull(format), getStreamFormats());
|
||||||
if (codecOperatingRate == newCodecOperatingRate) {
|
if (codecOperatingRate == newCodecOperatingRate) {
|
||||||
// No change.
|
// No change.
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1795,7 +1812,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
// above the assumed minimum rate.
|
// above the assumed minimum rate.
|
||||||
Bundle codecParameters = new Bundle();
|
Bundle codecParameters = new Bundle();
|
||||||
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, newCodecOperatingRate);
|
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, newCodecOperatingRate);
|
||||||
codec.setParameters(codecParameters);
|
checkNotNull(codec).setParameters(codecParameters);
|
||||||
codecOperatingRate = newCodecOperatingRate;
|
codecOperatingRate = newCodecOperatingRate;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -1871,6 +1888,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
*/
|
*/
|
||||||
private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs)
|
private boolean drainOutputBuffer(long positionUs, long elapsedRealtimeUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
|
MediaCodecAdapter codec = checkNotNull(this.codec);
|
||||||
if (!hasOutputBuffer()) {
|
if (!hasOutputBuffer()) {
|
||||||
int outputIndex;
|
int outputIndex;
|
||||||
if (codecNeedsEosOutputExceptionWorkaround && codecReceivedEos) {
|
if (codecNeedsEosOutputExceptionWorkaround && codecReceivedEos) {
|
||||||
|
|
@ -1950,7 +1968,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
outputBufferInfo.presentationTimeUs,
|
outputBufferInfo.presentationTimeUs,
|
||||||
isDecodeOnlyOutputBuffer,
|
isDecodeOnlyOutputBuffer,
|
||||||
isLastOutputBuffer,
|
isLastOutputBuffer,
|
||||||
outputFormat);
|
checkNotNull(outputFormat));
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
processEndOfStream();
|
processEndOfStream();
|
||||||
if (outputStreamEnded) {
|
if (outputStreamEnded) {
|
||||||
|
|
@ -1972,7 +1990,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
outputBufferInfo.presentationTimeUs,
|
outputBufferInfo.presentationTimeUs,
|
||||||
isDecodeOnlyOutputBuffer,
|
isDecodeOnlyOutputBuffer,
|
||||||
isLastOutputBuffer,
|
isLastOutputBuffer,
|
||||||
outputFormat);
|
checkNotNull(outputFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (processedOutputBuffer) {
|
if (processedOutputBuffer) {
|
||||||
|
|
@ -1991,7 +2009,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
/** Processes a change in the decoder output {@link MediaFormat}. */
|
/** Processes a change in the decoder output {@link MediaFormat}. */
|
||||||
private void processOutputMediaFormatChanged() {
|
private void processOutputMediaFormatChanged() {
|
||||||
codecHasOutputMediaFormat = true;
|
codecHasOutputMediaFormat = true;
|
||||||
MediaFormat mediaFormat = codec.getOutputFormat();
|
MediaFormat mediaFormat = checkNotNull(codec).getOutputFormat();
|
||||||
if (codecAdaptationWorkaroundMode != ADAPTATION_WORKAROUND_MODE_NEVER
|
if (codecAdaptationWorkaroundMode != ADAPTATION_WORKAROUND_MODE_NEVER
|
||||||
&& mediaFormat.getInteger(MediaFormat.KEY_WIDTH) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT
|
&& mediaFormat.getInteger(MediaFormat.KEY_WIDTH) == ADAPTATION_WORKAROUND_SLICE_WIDTH_HEIGHT
|
||||||
&& mediaFormat.getInteger(MediaFormat.KEY_HEIGHT)
|
&& mediaFormat.getInteger(MediaFormat.KEY_HEIGHT)
|
||||||
|
|
@ -2209,7 +2227,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
if (newFrameworkCryptoConfig.forceAllowInsecureDecoderComponents) {
|
if (newFrameworkCryptoConfig.forceAllowInsecureDecoderComponents) {
|
||||||
requiresSecureDecoder = false;
|
requiresSecureDecoder = false;
|
||||||
} else {
|
} else {
|
||||||
requiresSecureDecoder = newSession.requiresSecureDecoder(newFormat.sampleMimeType);
|
requiresSecureDecoder =
|
||||||
|
newSession.requiresSecureDecoder(checkNotNull(newFormat.sampleMimeType));
|
||||||
}
|
}
|
||||||
if (!codecInfo.secure && requiresSecureDecoder) {
|
if (!codecInfo.secure && requiresSecureDecoder) {
|
||||||
// Re-initialization is required because newSession might require switching to the secure
|
// Re-initialization is required because newSession might require switching to the secure
|
||||||
|
|
@ -2227,10 +2246,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
|
|
||||||
@RequiresApi(23)
|
@RequiresApi(23)
|
||||||
private void updateDrmSessionV23() throws ExoPlaybackException {
|
private void updateDrmSessionV23() throws ExoPlaybackException {
|
||||||
CryptoConfig cryptoConfig = sourceDrmSession.getCryptoConfig();
|
CryptoConfig cryptoConfig = checkNotNull(sourceDrmSession).getCryptoConfig();
|
||||||
if (cryptoConfig instanceof FrameworkCryptoConfig) {
|
if (cryptoConfig instanceof FrameworkCryptoConfig) {
|
||||||
try {
|
try {
|
||||||
mediaCrypto.setMediaDrmSession(((FrameworkCryptoConfig) cryptoConfig).sessionId);
|
checkNotNull(mediaCrypto)
|
||||||
|
.setMediaDrmSession(((FrameworkCryptoConfig) cryptoConfig).sessionId);
|
||||||
} catch (MediaCryptoException e) {
|
} catch (MediaCryptoException e) {
|
||||||
throw createRendererException(
|
throw createRendererException(
|
||||||
e, inputFormat, PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR);
|
e, inputFormat, PlaybackException.ERROR_CODE_DRM_SYSTEM_ERROR);
|
||||||
|
|
@ -2271,7 +2291,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
bypassBatchBuffer.getFirstSampleTimeUs(),
|
bypassBatchBuffer.getFirstSampleTimeUs(),
|
||||||
isDecodeOnly,
|
isDecodeOnly,
|
||||||
bypassBatchBuffer.isEndOfStream(),
|
bypassBatchBuffer.isEndOfStream(),
|
||||||
outputFormat)) {
|
checkNotNull(outputFormat))) {
|
||||||
// The batch buffer has been fully processed.
|
// The batch buffer has been fully processed.
|
||||||
onProcessedOutputBuffer(bypassBatchBuffer.getLastSampleTimeUs());
|
onProcessedOutputBuffer(bypassBatchBuffer.getLastSampleTimeUs());
|
||||||
bypassBatchBuffer.clear();
|
bypassBatchBuffer.clear();
|
||||||
|
|
@ -2347,7 +2367,11 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
// TODO(b/298634018): Adjust encoderDelay value based on starting position.
|
// TODO(b/298634018): Adjust encoderDelay value based on starting position.
|
||||||
int numberPreSkipSamples =
|
int numberPreSkipSamples =
|
||||||
OpusUtil.getPreSkipSamples(outputFormat.initializationData.get(0));
|
OpusUtil.getPreSkipSamples(outputFormat.initializationData.get(0));
|
||||||
outputFormat = outputFormat.buildUpon().setEncoderDelay(numberPreSkipSamples).build();
|
outputFormat =
|
||||||
|
checkNotNull(outputFormat)
|
||||||
|
.buildUpon()
|
||||||
|
.setEncoderDelay(numberPreSkipSamples)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
onOutputFormatChanged(outputFormat, /* mediaFormat= */ null);
|
onOutputFormatChanged(outputFormat, /* mediaFormat= */ null);
|
||||||
waitingForFirstSampleInFormat = false;
|
waitingForFirstSampleInFormat = false;
|
||||||
|
|
@ -2362,7 +2386,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
bypassSampleBuffer.format = outputFormat;
|
bypassSampleBuffer.format = outputFormat;
|
||||||
handleInputBufferSupplementalData(bypassSampleBuffer);
|
handleInputBufferSupplementalData(bypassSampleBuffer);
|
||||||
}
|
}
|
||||||
oggOpusAudioPacketizer.packetize(bypassSampleBuffer, outputFormat.initializationData);
|
oggOpusAudioPacketizer.packetize(
|
||||||
|
bypassSampleBuffer, checkNotNull(outputFormat).initializationData);
|
||||||
}
|
}
|
||||||
if (!haveBypassBatchBufferAndNewSampleSameDecodeOnlyState()
|
if (!haveBypassBatchBufferAndNewSampleSameDecodeOnlyState()
|
||||||
|| !bypassBatchBuffer.append(bypassSampleBuffer)) {
|
|| !bypassBatchBuffer.append(bypassSampleBuffer)) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue