Fix player hanging when seeking at MediaItem transition
Before this CL, the video sink was stuck if a flush was executed: - after VideoSink.onInputStreamChanged, which is setting pendingInputStreamBufferPresentationTimeUs and - before the previous stream was fully rendered. This is because pendingInputStreamBufferPresentationTimeUs was not reset to TIME_UNSET when flushing the sink, so that the sink was still waiting for the last frame of the previous stream to be rendered in handleInputFrame/Bitmap. PiperOrigin-RevId: 667924517
This commit is contained in:
parent
c4930c4bb6
commit
a4d0735d4c
@ -488,6 +488,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
||||
private long lastBufferPresentationTimeUs;
|
||||
|
||||
private boolean hasRegisteredFirstInputStream;
|
||||
private boolean isInputStreamChangePending;
|
||||
private long pendingInputStreamBufferPresentationTimeUs;
|
||||
private VideoSink.Listener listener;
|
||||
private Executor listenerExecutor;
|
||||
@ -559,10 +560,11 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
||||
if (resetPosition) {
|
||||
videoFrameReleaseControl.reset();
|
||||
}
|
||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||
// Don't change input stream offset or reset the pending input stream offset change so that
|
||||
// it's announced with the next input frame.
|
||||
// Don't reset pendingInputStreamBufferPresentationTimeUs because it's not guaranteed to
|
||||
// receive a new input stream after seeking.
|
||||
// Don't reset isInputStreamChangePending because it's not guaranteed to receive a new input
|
||||
// stream after seeking.
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -598,10 +600,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
||||
// If an input stream registration is pending and seek causes a format change, execution
|
||||
// reaches here before registerInputFrame(). Reset pendingInputStreamTimestampUs to
|
||||
// avoid registering the same input stream again in registerInputFrame().
|
||||
isInputStreamChangePending = false;
|
||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||
} else {
|
||||
// If we reach this point, we must have registered at least one frame for processing.
|
||||
checkState(lastBufferPresentationTimeUs != C.TIME_UNSET);
|
||||
isInputStreamChangePending = true;
|
||||
pendingInputStreamBufferPresentationTimeUs = lastBufferPresentationTimeUs;
|
||||
}
|
||||
}
|
||||
@ -728,10 +732,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
||||
|
||||
// An input stream is fully decoded, wait until all of its frames are released before queueing
|
||||
// input frame from the next input stream.
|
||||
if (pendingInputStreamBufferPresentationTimeUs != C.TIME_UNSET) {
|
||||
if (CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||
pendingInputStreamBufferPresentationTimeUs)) {
|
||||
if (isInputStreamChangePending) {
|
||||
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|
||||
|| CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||
pendingInputStreamBufferPresentationTimeUs)) {
|
||||
maybeRegisterInputStream();
|
||||
isInputStreamChangePending = false;
|
||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||
} else {
|
||||
return false;
|
||||
@ -822,14 +828,16 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
||||
* registration, hence it's safe to queue images or frames to the video graph input.
|
||||
*/
|
||||
private boolean maybeRegisterPendingInputStream() {
|
||||
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET) {
|
||||
if (!isInputStreamChangePending) {
|
||||
return true;
|
||||
}
|
||||
// An input stream is fully decoded, wait until all of its frames are released before queueing
|
||||
// input frame from the next input stream.
|
||||
if (CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||
pendingInputStreamBufferPresentationTimeUs)) {
|
||||
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|
||||
|| CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||
pendingInputStreamBufferPresentationTimeUs)) {
|
||||
maybeRegisterInputStream();
|
||||
isInputStreamChangePending = false;
|
||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user