Add nullness annotations to MediaCodecRenderer

#fixit

PiperOrigin-RevId: 570403923
(cherry picked from commit 7a91474af9)
This commit is contained in:
rohks 2023-10-03 09:02:40 -07:00 committed by oceanjules
parent 0480b70f36
commit 7957554442

View file

@ -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)) {