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 long lastBufferPresentationTimeUs;
|
||||||
|
|
||||||
private boolean hasRegisteredFirstInputStream;
|
private boolean hasRegisteredFirstInputStream;
|
||||||
|
private boolean isInputStreamChangePending;
|
||||||
private long pendingInputStreamBufferPresentationTimeUs;
|
private long pendingInputStreamBufferPresentationTimeUs;
|
||||||
private VideoSink.Listener listener;
|
private VideoSink.Listener listener;
|
||||||
private Executor listenerExecutor;
|
private Executor listenerExecutor;
|
||||||
@ -559,10 +560,11 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
|
|||||||
if (resetPosition) {
|
if (resetPosition) {
|
||||||
videoFrameReleaseControl.reset();
|
videoFrameReleaseControl.reset();
|
||||||
}
|
}
|
||||||
|
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||||
// Don't change input stream offset or reset the pending input stream offset change so that
|
// Don't change input stream offset or reset the pending input stream offset change so that
|
||||||
// it's announced with the next input frame.
|
// it's announced with the next input frame.
|
||||||
// Don't reset pendingInputStreamBufferPresentationTimeUs because it's not guaranteed to
|
// Don't reset isInputStreamChangePending because it's not guaranteed to receive a new input
|
||||||
// receive a new input stream after seeking.
|
// stream after seeking.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// If an input stream registration is pending and seek causes a format change, execution
|
||||||
// reaches here before registerInputFrame(). Reset pendingInputStreamTimestampUs to
|
// reaches here before registerInputFrame(). Reset pendingInputStreamTimestampUs to
|
||||||
// avoid registering the same input stream again in registerInputFrame().
|
// avoid registering the same input stream again in registerInputFrame().
|
||||||
|
isInputStreamChangePending = false;
|
||||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||||
} else {
|
} else {
|
||||||
// If we reach this point, we must have registered at least one frame for processing.
|
// If we reach this point, we must have registered at least one frame for processing.
|
||||||
checkState(lastBufferPresentationTimeUs != C.TIME_UNSET);
|
checkState(lastBufferPresentationTimeUs != C.TIME_UNSET);
|
||||||
|
isInputStreamChangePending = true;
|
||||||
pendingInputStreamBufferPresentationTimeUs = lastBufferPresentationTimeUs;
|
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
|
// An input stream is fully decoded, wait until all of its frames are released before queueing
|
||||||
// input frame from the next input stream.
|
// input frame from the next input stream.
|
||||||
if (pendingInputStreamBufferPresentationTimeUs != C.TIME_UNSET) {
|
if (isInputStreamChangePending) {
|
||||||
if (CompositingVideoSinkProvider.this.hasReleasedFrame(
|
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|
||||||
|
|| CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||||
pendingInputStreamBufferPresentationTimeUs)) {
|
pendingInputStreamBufferPresentationTimeUs)) {
|
||||||
maybeRegisterInputStream();
|
maybeRegisterInputStream();
|
||||||
|
isInputStreamChangePending = false;
|
||||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
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.
|
* registration, hence it's safe to queue images or frames to the video graph input.
|
||||||
*/
|
*/
|
||||||
private boolean maybeRegisterPendingInputStream() {
|
private boolean maybeRegisterPendingInputStream() {
|
||||||
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET) {
|
if (!isInputStreamChangePending) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// An input stream is fully decoded, wait until all of its frames are released before queueing
|
// An input stream is fully decoded, wait until all of its frames are released before queueing
|
||||||
// input frame from the next input stream.
|
// input frame from the next input stream.
|
||||||
if (CompositingVideoSinkProvider.this.hasReleasedFrame(
|
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|
||||||
|
|| CompositingVideoSinkProvider.this.hasReleasedFrame(
|
||||||
pendingInputStreamBufferPresentationTimeUs)) {
|
pendingInputStreamBufferPresentationTimeUs)) {
|
||||||
maybeRegisterInputStream();
|
maybeRegisterInputStream();
|
||||||
|
isInputStreamChangePending = false;
|
||||||
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
pendingInputStreamBufferPresentationTimeUs = C.TIME_UNSET;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user