Fix possible lost end of stream notification
In `ExternalTextureManager` in seemingly rare cases end of stream is signaled at the point where a frame is currently pending processing. In that case the video end of stream signal was lost. If the muxer timeout was enabled this case would result in throwing an exception, but otherwise the operation would get stuck Add code to signal end of stream in `onInputFrameProcessed` as well, so that we signal end of stream when the pending frame is handled. Tested by running `TransformerEndToEndTest.loopingTranscodedVideo_producesExpectedResult` several times. PiperOrigin-RevId: 524361069
This commit is contained in:
parent
0e85491d4e
commit
011fc9d5d3
@ -89,6 +89,9 @@
|
|||||||
instead.
|
instead.
|
||||||
* Remove `Transformer.startTransformation(MediaItem,
|
* Remove `Transformer.startTransformation(MediaItem,
|
||||||
ParcelFileDescriptor)`.
|
ParcelFileDescriptor)`.
|
||||||
|
* Fix a bug where transformation could get stuck (leading to muxer
|
||||||
|
timeout) if the end of the video stream was signaled at the moment when
|
||||||
|
an input frame was pending processing.
|
||||||
* DASH:
|
* DASH:
|
||||||
* Fix handling of empty segment timelines
|
* Fix handling of empty segment timelines
|
||||||
([#11014](https://github.com/google/ExoPlayer/issues/11014)).
|
([#11014](https://github.com/google/ExoPlayer/issues/11014)).
|
||||||
|
@ -56,6 +56,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
// Read and written on the GL thread only.
|
// Read and written on the GL thread only.
|
||||||
private boolean inputStreamEnded;
|
private boolean inputStreamEnded;
|
||||||
|
|
||||||
|
// TODO(b/278273122): Remove this flag and the signal end of input call after queueing a frame if
|
||||||
|
// all frames notify that they've been processed.
|
||||||
|
|
||||||
|
// Read and written on the GL thread only.
|
||||||
|
private boolean hasSignaledEndOfInput;
|
||||||
// The frame that is sent downstream and is not done processing yet.
|
// The frame that is sent downstream and is not done processing yet.
|
||||||
// Set to null on any thread. Read and set to non-null on the GL thread only.
|
// Set to null on any thread. Read and set to non-null on the GL thread only.
|
||||||
@Nullable private volatile FrameInfo currentFrame;
|
@Nullable private volatile FrameInfo currentFrame;
|
||||||
@ -128,7 +134,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
videoFrameProcessingTaskExecutor.submit(
|
videoFrameProcessingTaskExecutor.submit(
|
||||||
() -> {
|
() -> {
|
||||||
currentFrame = null;
|
currentFrame = null;
|
||||||
|
if (inputStreamEnded && pendingFrames.isEmpty()) {
|
||||||
|
maybeSignalEndOfInput();
|
||||||
|
} else {
|
||||||
maybeQueueFrameToExternalShaderProgram();
|
maybeQueueFrameToExternalShaderProgram();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +183,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
() -> {
|
() -> {
|
||||||
inputStreamEnded = true;
|
inputStreamEnded = true;
|
||||||
if (pendingFrames.isEmpty() && currentFrame == null) {
|
if (pendingFrames.isEmpty() && currentFrame == null) {
|
||||||
externalShaderProgram.signalEndOfCurrentInputStream();
|
maybeSignalEndOfInput();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -235,6 +245,13 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
checkStateNotNull(pendingFrames.remove());
|
checkStateNotNull(pendingFrames.remove());
|
||||||
|
|
||||||
if (inputStreamEnded && pendingFrames.isEmpty()) {
|
if (inputStreamEnded && pendingFrames.isEmpty()) {
|
||||||
|
maybeSignalEndOfInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeSignalEndOfInput() {
|
||||||
|
if (!hasSignaledEndOfInput) {
|
||||||
|
hasSignaledEndOfInput = true;
|
||||||
externalShaderProgram.signalEndOfCurrentInputStream();
|
externalShaderProgram.signalEndOfCurrentInputStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user