Allow codec flushing without re-initialization
For decoder reuse, we want disable() to flush the decoder. However, if the flush needs to release the decoder for some reason, it seems non-ideal to immediately re-initialize it. Re-initialization can also throw ExoPlaybackException, which we don't want for disabling. This change allows a variant of flush that wont re-initialize the decoder if it has to be released, which will be used from disable(). Issue: #2826 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=216834862
This commit is contained in:
parent
42c3ff3934
commit
842f622d29
@ -546,9 +546,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
|
||||
inputStreamEnded = false;
|
||||
outputStreamEnded = false;
|
||||
if (codec != null) {
|
||||
flushCodec();
|
||||
}
|
||||
flushOrReinitCodec();
|
||||
formatQueue.clear();
|
||||
}
|
||||
|
||||
@ -687,10 +685,36 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
decoderCounters.ensureUpdated();
|
||||
}
|
||||
|
||||
protected void flushCodec() throws ExoPlaybackException {
|
||||
/**
|
||||
* Flushes the codec. If flushing is not possible, the codec will be released and re-instantiated.
|
||||
* This method is a no-op if the codec is {@code null}.
|
||||
*
|
||||
* <p>The implementation of this method calls {@link #flushOrReleaseCodec()}, and {@link
|
||||
* #maybeInitCodec()} if the codec needs to be re-instantiated.
|
||||
*
|
||||
* @throws ExoPlaybackException If an error occurs re-instantiating the codec.
|
||||
*/
|
||||
protected final void flushOrReinitCodec() throws ExoPlaybackException {
|
||||
if (flushOrReleaseCodec()) {
|
||||
maybeInitCodec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the codec. If flushing is not possible, the codec will be released. This method is a
|
||||
* no-op if the codec is {@code null}.
|
||||
*
|
||||
* @return Whether the codec was released.
|
||||
*/
|
||||
protected boolean flushOrReleaseCodec() {
|
||||
if (codec == null) {
|
||||
// Nothing to do.
|
||||
return false;
|
||||
}
|
||||
codecHotswapDeadlineMs = C.TIME_UNSET;
|
||||
resetInputBuffer();
|
||||
resetOutputBuffer();
|
||||
codecReceivedBuffers = false;
|
||||
waitingForFirstSyncFrame = true;
|
||||
waitingForKeys = false;
|
||||
shouldSkipOutputBuffer = false;
|
||||
@ -699,28 +723,27 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
shouldSkipAdaptationWorkaroundOutputBuffer = false;
|
||||
if (codecNeedsFlushWorkaround || (codecNeedsEosFlushWorkaround && codecReceivedEos)) {
|
||||
releaseCodec();
|
||||
maybeInitCodec();
|
||||
return true;
|
||||
} else if (codecReinitializationState != REINITIALIZATION_STATE_NONE) {
|
||||
// We're already waiting to re-initialize the codec. Since we're now flushing, there's no need
|
||||
// to wait any longer.
|
||||
if (codecReinitializationIsRelease) {
|
||||
releaseCodec();
|
||||
maybeInitCodec();
|
||||
return true;
|
||||
} else {
|
||||
codec.flush();
|
||||
codecReceivedBuffers = false;
|
||||
codecReinitializationState = REINITIALIZATION_STATE_NONE;
|
||||
}
|
||||
} else {
|
||||
// We can flush and re-use the existing decoder.
|
||||
codec.flush();
|
||||
codecReceivedBuffers = false;
|
||||
}
|
||||
if (codecReconfigured && format != null) {
|
||||
// Any reconfiguration data that we send shortly before the flush may be discarded. We
|
||||
// avoid this issue by sending reconfiguration data following every flush.
|
||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean initCodecWithFallback(MediaCrypto crypto, boolean drmSessionRequiresSecureDecoder)
|
||||
@ -1496,7 +1519,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||
releaseCodec();
|
||||
maybeInitCodec();
|
||||
} else {
|
||||
flushCodec();
|
||||
flushOrReinitCodec();
|
||||
}
|
||||
} else {
|
||||
outputStreamEnded = true;
|
||||
|
@ -520,9 +520,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
||||
|
||||
@CallSuper
|
||||
@Override
|
||||
protected void flushCodec() throws ExoPlaybackException {
|
||||
super.flushCodec();
|
||||
buffersInCodecCount = 0;
|
||||
protected boolean flushOrReleaseCodec() {
|
||||
try {
|
||||
return super.flushOrReleaseCodec();
|
||||
} finally {
|
||||
buffersInCodecCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -859,7 +862,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
||||
// We dropped some buffers to catch up, so update the decoder counters and flush the codec,
|
||||
// which releases all pending buffers buffers including the current output buffer.
|
||||
updateDroppedBufferCounters(buffersInCodecCount + droppedSourceBufferCount);
|
||||
flushCodec();
|
||||
flushOrReinitCodec();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,12 @@ public class DebugRenderersFactory extends DefaultRenderersFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void flushCodec() throws ExoPlaybackException {
|
||||
super.flushCodec();
|
||||
clearTimestamps();
|
||||
protected boolean flushOrReleaseCodec() {
|
||||
try {
|
||||
return super.flushOrReleaseCodec();
|
||||
} finally {
|
||||
clearTimestamps();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user