diff --git a/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java b/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java index 58f9146f17..82056d65dd 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java @@ -298,9 +298,6 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { // CountDownLatch to wait for the current input stream to finish processing. private volatile @MonotonicNonNull CountDownLatch latch; - // TODO(b/274109008) Use InputSwither to interact with texture manager. - // Owned and released by inputSwitcher. - private @MonotonicNonNull TextureManager textureManager; private volatile @MonotonicNonNull FrameInfo nextInputFrameInfo; private volatile boolean inputStreamEnded; private volatile boolean hasRefreshedNextInputFrameInfo; @@ -363,7 +360,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { * @param height The default height for input buffers, in pixels. */ public void setInputDefaultBufferSize(int width, int height) { - checkNotNull(textureManager).setDefaultBufferSize(width, height); + inputSwitcher.activeTextureManager().setDefaultBufferSize(width, height); } @Override @@ -371,7 +368,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { checkState( hasRefreshedNextInputFrameInfo, "setInputFrameInfo must be called before queueing another bitmap"); - checkNotNull(textureManager) + inputSwitcher + .activeTextureManager() .queueInputBitmap( inputBitmap, durationUs, @@ -383,24 +381,24 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { @Override public void queueInputTexture(int textureId, long presentationTimeUs) { - checkNotNull(textureManager).queueInputTexture(textureId, presentationTimeUs); + inputSwitcher.activeTextureManager().queueInputTexture(textureId, presentationTimeUs); } @Override public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) { - checkNotNull(textureManager).setOnInputFrameProcessedListener(listener); + inputSwitcher.activeTextureManager().setOnInputFrameProcessedListener(listener); } @Override public Surface getInputSurface() { - return checkNotNull(textureManager).getInputSurface(); + return inputSwitcher.activeTextureManager().getInputSurface(); } @Override public void registerInputStream(@InputType int inputType) { synchronized (lock) { if (unprocessedInputStreams.isEmpty()) { - textureManager = inputSwitcher.switchToInput(inputType); + inputSwitcher.switchToInput(inputType); unprocessedInputStreams.add(inputType); return; } @@ -408,14 +406,14 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { // Wait until the current input stream is processed before continuing to the next input. latch = new CountDownLatch(1); - checkNotNull(textureManager).signalEndOfCurrentInputStream(); + inputSwitcher.activeTextureManager().signalEndOfCurrentInputStream(); try { latch.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); listenerExecutor.execute(() -> listener.onError(VideoFrameProcessingException.from(e))); } - textureManager = inputSwitcher.switchToInput(inputType); + inputSwitcher.switchToInput(inputType); synchronized (lock) { unprocessedInputStreams.add(inputType); } @@ -424,7 +422,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { @Override public void setInputFrameInfo(FrameInfo inputFrameInfo) { nextInputFrameInfo = adjustForPixelWidthHeightRatio(inputFrameInfo); - checkNotNull(textureManager).setInputFrameInfo(nextInputFrameInfo); + inputSwitcher.activeTextureManager().setInputFrameInfo(nextInputFrameInfo); hasRefreshedNextInputFrameInfo = true; } @@ -434,13 +432,13 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { checkStateNotNull( nextInputFrameInfo, "setInputFrameInfo must be called before registering input frames"); - checkNotNull(textureManager).registerInputFrame(nextInputFrameInfo); + inputSwitcher.activeTextureManager().registerInputFrame(nextInputFrameInfo); hasRefreshedNextInputFrameInfo = false; } @Override public int getPendingInputFrameCount() { - return checkNotNull(textureManager).getPendingFrameCount(); + return inputSwitcher.activeTextureManager().getPendingFrameCount(); } /** @@ -481,7 +479,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { if (allInputStreamsProcessed) { inputSwitcher.signalEndOfInput(); } else { - checkNotNull(textureManager).signalEndOfCurrentInputStream(); + inputSwitcher.signalEndOfCurrentInputStream(); } } @@ -490,10 +488,10 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor { try { videoFrameProcessingTaskExecutor.flush(); CountDownLatch latch = new CountDownLatch(1); - checkNotNull(textureManager).setOnFlushCompleteListener(latch::countDown); + inputSwitcher.activeTextureManager().setOnFlushCompleteListener(latch::countDown); videoFrameProcessingTaskExecutor.submit(finalShaderProgramWrapper::flush); latch.await(); - checkNotNull(textureManager).setOnFlushCompleteListener(null); + inputSwitcher.activeTextureManager().setOnFlushCompleteListener(null); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/InputSwitcher.java b/libraries/effect/src/main/java/androidx/media3/effect/InputSwitcher.java index 4b3d33aba3..eadcf9cecd 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/InputSwitcher.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/InputSwitcher.java @@ -23,7 +23,6 @@ import static androidx.media3.common.util.Assertions.checkStateNotNull; import android.content.Context; import android.util.SparseArray; -import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.ColorInfo; import androidx.media3.common.GlObjectsProvider; @@ -46,6 +45,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final boolean enableColorTransfers; private @MonotonicNonNull GlShaderProgram downstreamShaderProgram; + private @MonotonicNonNull TextureManager activeTextureManager; private boolean inputEnded; private int activeInputType; @@ -159,17 +159,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; * registered}. * * @param newInputType The new {@link VideoFrameProcessor.InputType} to switch to. - * @return The {@link TextureManager} associated with the {@code newInputType}. */ - public TextureManager switchToInput(@VideoFrameProcessor.InputType int newInputType) { + public void switchToInput(@VideoFrameProcessor.InputType int newInputType) { checkStateNotNull(downstreamShaderProgram); checkState(inputs.indexOfKey(newInputType) >= 0, "Input type not registered: " + newInputType); if (newInputType == activeInputType) { - return inputs.get(activeInputType).textureManager; + activeTextureManager = inputs.get(activeInputType).textureManager; } - @Nullable TextureManager activeTextureManager = null; for (int i = 0; i < inputs.size(); i++) { @VideoFrameProcessor.InputType int inputType = inputs.keyAt(i); Input input = inputs.get(inputType); @@ -181,11 +179,26 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; input.setActive(false); } } - activeInputType = newInputType; + } + + /** + * Returns the {@link TextureManager} that is currently being used. + * + *
Must call {@link #switchToInput} before calling this method. + */ + public TextureManager activeTextureManager() { return checkNotNull(activeTextureManager); } + /** + * Invokes {@link TextureManager#signalEndOfCurrentInputStream} on the active {@link + * TextureManager}. + */ + public void signalEndOfCurrentInputStream() { + checkNotNull(activeTextureManager).signalEndOfCurrentInputStream(); + } + /** Signals end of input to all {@linkplain #registerInput registered inputs}. */ public void signalEndOfInput() { checkState(!inputEnded);