Simplfify codec state reset methods in MediaCodecRenderer

Currently, resetting the internal state related to the codec in done in 4 places
in MediaCodecRenderer:
 1. In the constructor to set some sensible initial default.
 2. In flushOrReleaseCodec to reset state after flushing
 3. In releaseCodec to reset state to default values for a released codec.
 4. In initCodec to reset state to defaul values for a new codec.

There are actuall only two types of state reset operations:
 1. Resetting state for a released codec, so that a new codec isn't influenced by
    previous codecs.
 2. Resetting state after flushing an existing codec. This is a subset of (1).

So to simplify the class, this change moves all state resets to two methods
corresponding to the two cases above.

PiperOrigin-RevId: 285731913
This commit is contained in:
tonihei 2019-12-16 10:29:31 +00:00 committed by Oliver Woodman
parent 23bb289237
commit 6512e320fb
3 changed files with 60 additions and 68 deletions

View file

@ -24,6 +24,7 @@ import android.media.MediaCryptoException;
import android.media.MediaFormat;
import android.os.Bundle;
import android.os.SystemClock;
import androidx.annotation.CallSuper;
import androidx.annotation.CheckResult;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@ -440,13 +441,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
formatQueue = new TimedValueQueue<>();
decodeOnlyPresentationTimestamps = new ArrayList<>();
outputBufferInfo = new MediaCodec.BufferInfo();
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
rendererOperatingRate = 1f;
renderTimeLimitMs = C.TIME_UNSET;
mediaCodecOperationMode = MediaCodecOperationMode.SYNCHRONOUS;
resetCodecStateForRelease();
}
/**
@ -681,36 +679,25 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
protected void releaseCodec() {
availableCodecInfos = null;
codecInfo = null;
codecFormat = null;
if (codecAdapter != null) {
codecAdapter.shutdown();
codecAdapter = null;
}
resetInputBuffer();
resetOutputBuffer();
resetCodecBuffers();
waitingForKeys = false;
codecHotswapDeadlineMs = C.TIME_UNSET;
decodeOnlyPresentationTimestamps.clear();
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
try {
if (codecAdapter != null) {
codecAdapter.shutdown();
}
if (codec != null) {
decoderCounters.decoderReleaseCount++;
codec.release();
}
} finally {
codec = null;
codecAdapter = null;
try {
if (mediaCrypto != null) {
mediaCrypto.release();
}
} finally {
mediaCrypto = null;
mediaCryptoRequiresSecureDecoder = false;
setCodecDrmSession(null);
resetCodecStateForRelease();
}
}
}
@ -799,8 +786,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
releaseCodec();
return true;
}
try {
codecAdapter.flush();
} finally {
resetCodecStateForFlush();
}
return false;
}
codecAdapter.flush();
/** Resets the renderer internal state after a codec flush. */
@CallSuper
protected void resetCodecStateForFlush() {
resetInputBuffer();
resetOutputBuffer();
codecHotswapDeadlineMs = C.TIME_UNSET;
@ -811,7 +807,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
shouldSkipAdaptationWorkaroundOutputBuffer = false;
isDecodeOnlyOutputBuffer = false;
isLastOutputBuffer = false;
waitingForKeys = false;
decodeOnlyPresentationTimestamps.clear();
largestQueuedPresentationTimeUs = C.TIME_UNSET;
@ -823,7 +818,38 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
// guarantee that it's processed.
codecReconfigurationState =
codecReconfigured ? RECONFIGURATION_STATE_WRITE_PENDING : RECONFIGURATION_STATE_NONE;
return false;
}
/**
* Resets the renderer internal state after a codec release.
*
* <p>Note that this only needs to reset state variables that are changed in addition to those
* already changed in {@link #resetCodecStateForFlush()}.
*/
@CallSuper
protected void resetCodecStateForRelease() {
resetCodecStateForFlush();
availableCodecInfos = null;
codec = null;
codecInfo = null;
codecFormat = null;
codecAdapter = null;
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
codecAdaptationWorkaroundMode = ADAPTATION_WORKAROUND_MODE_NEVER;
codecNeedsReconfigureWorkaround = false;
codecNeedsDiscardToSpsWorkaround = false;
codecNeedsFlushWorkaround = false;
codecNeedsEosFlushWorkaround = false;
codecNeedsEosOutputExceptionWorkaround = false;
codecNeedsMonoChannelCountWorkaround = false;
codecNeedsEosPropagation = false;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
resetCodecBuffers();
mediaCrypto = null;
mediaCryptoRequiresSecureDecoder = false;
}
protected DecoderException createDecoderException(
@ -997,26 +1023,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
resetInputBuffer();
resetOutputBuffer();
codecHotswapDeadlineMs =
getState() == STATE_STARTED
? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS)
: C.TIME_UNSET;
codecReconfigured = false;
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
codecReceivedEos = false;
codecReceivedBuffers = false;
largestQueuedPresentationTimeUs = C.TIME_UNSET;
lastBufferInStreamPresentationTimeUs = C.TIME_UNSET;
codecDrainState = DRAIN_STATE_NONE;
codecDrainAction = DRAIN_ACTION_NONE;
codecNeedsAdaptationWorkaroundBuffer = false;
shouldSkipAdaptationWorkaroundOutputBuffer = false;
isDecodeOnlyOutputBuffer = false;
isLastOutputBuffer = false;
waitingForFirstSyncSample = true;
if (getState() == STATE_STARTED) {
codecHotswapDeadlineMs = SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS;
}
decoderCounters.decoderInitCount++;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;

View file

@ -708,22 +708,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@CallSuper
@Override
protected void releaseCodec() {
try {
super.releaseCodec();
} finally {
buffersInCodecCount = 0;
}
}
@CallSuper
@Override
protected boolean flushOrReleaseCodec() {
try {
return super.flushOrReleaseCodec();
} finally {
buffersInCodecCount = 0;
}
protected void resetCodecStateForFlush() {
super.resetCodecStateForFlush();
buffersInCodecCount = 0;
}
@Override

View file

@ -125,19 +125,15 @@ import java.util.ArrayList;
}
@Override
protected void releaseCodec() {
super.releaseCodec();
protected void resetCodecStateForFlush() {
super.resetCodecStateForFlush();
clearTimestamps();
skipToPositionBeforeRenderingFirstFrame = false;
}
@Override
protected boolean flushOrReleaseCodec() {
try {
return super.flushOrReleaseCodec();
} finally {
clearTimestamps();
}
protected void resetCodecStateForRelease() {
super.resetCodecStateForRelease();
skipToPositionBeforeRenderingFirstFrame = false;
}
@Override