Commit e044cd67 by andrewlewis Committed by Rohit Singh

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
parent dd6a0c37
...@@ -56,6 +56,12 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -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; ...@@ -128,7 +134,11 @@ import java.util.concurrent.atomic.AtomicInteger;
videoFrameProcessingTaskExecutor.submit( videoFrameProcessingTaskExecutor.submit(
() -> { () -> {
currentFrame = null; currentFrame = null;
maybeQueueFrameToExternalShaderProgram(); if (inputStreamEnded && pendingFrames.isEmpty()) {
maybeSignalEndOfInput();
} else {
maybeQueueFrameToExternalShaderProgram();
}
}); });
} }
...@@ -173,7 +183,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -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; ...@@ -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();
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment