mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
23bb289237
commit
6512e320fb
3 changed files with 60 additions and 68 deletions
|
|
@ -24,6 +24,7 @@ import android.media.MediaCryptoException;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import androidx.annotation.CallSuper;
|
||||||
import androidx.annotation.CheckResult;
|
import androidx.annotation.CheckResult;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
@ -440,13 +441,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
formatQueue = new TimedValueQueue<>();
|
formatQueue = new TimedValueQueue<>();
|
||||||
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
||||||
outputBufferInfo = new MediaCodec.BufferInfo();
|
outputBufferInfo = new MediaCodec.BufferInfo();
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_NONE;
|
|
||||||
codecDrainState = DRAIN_STATE_NONE;
|
|
||||||
codecDrainAction = DRAIN_ACTION_NONE;
|
|
||||||
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
|
|
||||||
rendererOperatingRate = 1f;
|
rendererOperatingRate = 1f;
|
||||||
renderTimeLimitMs = C.TIME_UNSET;
|
renderTimeLimitMs = C.TIME_UNSET;
|
||||||
mediaCodecOperationMode = MediaCodecOperationMode.SYNCHRONOUS;
|
mediaCodecOperationMode = MediaCodecOperationMode.SYNCHRONOUS;
|
||||||
|
resetCodecStateForRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -681,36 +679,25 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void releaseCodec() {
|
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 {
|
try {
|
||||||
|
if (codecAdapter != null) {
|
||||||
|
codecAdapter.shutdown();
|
||||||
|
}
|
||||||
if (codec != null) {
|
if (codec != null) {
|
||||||
decoderCounters.decoderReleaseCount++;
|
decoderCounters.decoderReleaseCount++;
|
||||||
codec.release();
|
codec.release();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
codec = null;
|
codec = null;
|
||||||
|
codecAdapter = null;
|
||||||
try {
|
try {
|
||||||
if (mediaCrypto != null) {
|
if (mediaCrypto != null) {
|
||||||
mediaCrypto.release();
|
mediaCrypto.release();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
mediaCrypto = null;
|
mediaCrypto = null;
|
||||||
mediaCryptoRequiresSecureDecoder = false;
|
|
||||||
setCodecDrmSession(null);
|
setCodecDrmSession(null);
|
||||||
|
resetCodecStateForRelease();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -799,8 +786,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
releaseCodec();
|
releaseCodec();
|
||||||
return true;
|
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();
|
resetInputBuffer();
|
||||||
resetOutputBuffer();
|
resetOutputBuffer();
|
||||||
codecHotswapDeadlineMs = C.TIME_UNSET;
|
codecHotswapDeadlineMs = C.TIME_UNSET;
|
||||||
|
|
@ -811,7 +807,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
shouldSkipAdaptationWorkaroundOutputBuffer = false;
|
shouldSkipAdaptationWorkaroundOutputBuffer = false;
|
||||||
isDecodeOnlyOutputBuffer = false;
|
isDecodeOnlyOutputBuffer = false;
|
||||||
isLastOutputBuffer = false;
|
isLastOutputBuffer = false;
|
||||||
|
|
||||||
waitingForKeys = false;
|
waitingForKeys = false;
|
||||||
decodeOnlyPresentationTimestamps.clear();
|
decodeOnlyPresentationTimestamps.clear();
|
||||||
largestQueuedPresentationTimeUs = C.TIME_UNSET;
|
largestQueuedPresentationTimeUs = C.TIME_UNSET;
|
||||||
|
|
@ -823,7 +818,38 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
// guarantee that it's processed.
|
// guarantee that it's processed.
|
||||||
codecReconfigurationState =
|
codecReconfigurationState =
|
||||||
codecReconfigured ? RECONFIGURATION_STATE_WRITE_PENDING : RECONFIGURATION_STATE_NONE;
|
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(
|
protected DecoderException createDecoderException(
|
||||||
|
|
@ -997,26 +1023,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
|
codecNeedsMonoChannelCountWorkaround(codecName, codecFormat);
|
||||||
codecNeedsEosPropagation =
|
codecNeedsEosPropagation =
|
||||||
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
|
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
|
||||||
|
if (getState() == STATE_STARTED) {
|
||||||
resetInputBuffer();
|
codecHotswapDeadlineMs = SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS;
|
||||||
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;
|
|
||||||
|
|
||||||
decoderCounters.decoderInitCount++;
|
decoderCounters.decoderInitCount++;
|
||||||
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
|
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
|
||||||
|
|
|
||||||
|
|
@ -708,22 +708,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@Override
|
@Override
|
||||||
protected void releaseCodec() {
|
protected void resetCodecStateForFlush() {
|
||||||
try {
|
super.resetCodecStateForFlush();
|
||||||
super.releaseCodec();
|
buffersInCodecCount = 0;
|
||||||
} finally {
|
|
||||||
buffersInCodecCount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@CallSuper
|
|
||||||
@Override
|
|
||||||
protected boolean flushOrReleaseCodec() {
|
|
||||||
try {
|
|
||||||
return super.flushOrReleaseCodec();
|
|
||||||
} finally {
|
|
||||||
buffersInCodecCount = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -125,19 +125,15 @@ import java.util.ArrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void releaseCodec() {
|
protected void resetCodecStateForFlush() {
|
||||||
super.releaseCodec();
|
super.resetCodecStateForFlush();
|
||||||
clearTimestamps();
|
clearTimestamps();
|
||||||
skipToPositionBeforeRenderingFirstFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean flushOrReleaseCodec() {
|
protected void resetCodecStateForRelease() {
|
||||||
try {
|
super.resetCodecStateForRelease();
|
||||||
return super.flushOrReleaseCodec();
|
skipToPositionBeforeRenderingFirstFrame = false;
|
||||||
} finally {
|
|
||||||
clearTimestamps();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue