diff --git a/libraries/common/src/main/java/androidx/media3/common/VideoFrameProcessor.java b/libraries/common/src/main/java/androidx/media3/common/VideoFrameProcessor.java index d8a5d1136e..86fec35cae 100644 --- a/libraries/common/src/main/java/androidx/media3/common/VideoFrameProcessor.java +++ b/libraries/common/src/main/java/androidx/media3/common/VideoFrameProcessor.java @@ -208,11 +208,8 @@ public interface VideoFrameProcessor { void registerInputFrame(); /** - * Returns the number of input frames that have been {@linkplain #registerInputFrame() registered} - * but not processed off the {@linkplain #getInputSurface() input surface} yet. - * - *
This method must only be called when the {@link VideoFrameProcessor} is {@linkplain - * Factory#create created} with {@link #INPUT_TYPE_SURFACE}. + * returns the number of input frames that have been made available to the {@code + * VideoFrameProcessor} but have not been processed yet. * *
Can be called on any thread. */ diff --git a/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java index 9a239a735c..720ade53be 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java @@ -21,10 +21,12 @@ import static java.lang.Math.round; import android.graphics.Bitmap; import android.opengl.GLES20; import android.opengl.GLUtils; +import android.view.Surface; +import androidx.annotation.Nullable; import androidx.media3.common.C; +import androidx.media3.common.FrameInfo; import androidx.media3.common.GlTextureInfo; import androidx.media3.common.VideoFrameProcessingException; -import androidx.media3.common.VideoFrameProcessor; import androidx.media3.common.util.GlUtil; import androidx.media3.common.util.UnstableApi; import java.util.Queue; @@ -38,7 +40,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; *
Public methods in this class can be called from any thread.
*/
@UnstableApi
-/* package */ final class BitmapTextureManager implements GlShaderProgram.InputListener {
+/* package */ final class BitmapTextureManager implements InputHandler {
private final GlShaderProgram shaderProgram;
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
// The queue holds all bitmaps with one or more frames pending to be sent downstream.
@@ -77,22 +79,35 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
});
}
- /**
- * Provides an input {@link Bitmap} to put into the video frames.
- *
- * @see VideoFrameProcessor#queueInputBitmap
- */
+ @Override
+ public void setDefaultBufferSize(int width, int height) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void queueInputBitmap(
Bitmap inputBitmap, long durationUs, float frameRate, boolean useHdr) {
videoFrameProcessingTaskExecutor.submit(
() -> setupBitmap(inputBitmap, durationUs, frameRate, useHdr));
}
- /**
- * Signals the end of the input.
- *
- * @see VideoFrameProcessor#signalEndOfInput()
- */
+ @Override
+ public Surface getInputSurface() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void registerInputFrame(FrameInfo frameInfo) {
+ // Do nothing.
+ }
+
+ @Override
+ public int getPendingFrameCount() {
+ // Always treat all queued bitmaps as immediately processed.
+ return 0;
+ }
+
+ @Override
public void signalEndOfInput() {
videoFrameProcessingTaskExecutor.submit(
() -> {
@@ -101,11 +116,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
});
}
- /**
- * Releases all resources.
- *
- * @see VideoFrameProcessor#release()
- */
+ @Override
+ public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task) {
+ // Do nothing.
+ }
+
+ @Override
public void release() {
videoFrameProcessingTaskExecutor.submit(
() -> {
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 eb783fe19d..5dbec3d81b 100644
--- a/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java
+++ b/libraries/effect/src/main/java/androidx/media3/effect/DefaultVideoFrameProcessor.java
@@ -17,7 +17,6 @@ package androidx.media3.effect;
import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
import static androidx.media3.common.util.Assertions.checkArgument;
-import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static androidx.media3.common.util.Assertions.checkStateNotNull;
import static com.google.common.collect.Iterables.getLast;
@@ -247,8 +246,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
private final EGLDisplay eglDisplay;
private final EGLContext eglContext;
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
- private @MonotonicNonNull BitmapTextureManager inputBitmapTextureManager;
- private @MonotonicNonNull ExternalTextureManager inputExternalTextureManager;
+ private final InputHandler inputHandler;
private final boolean releaseFramesAutomatically;
private final FinalShaderProgramWrapper finalShaderProgramWrapper;
private final ImmutableList Can be called on any thread. The caller must ensure that frames are registered in the
* correct order.
*/
+ @Override
public void registerInputFrame(FrameInfo frame) {
pendingFrames.add(frame);
}
@@ -164,15 +171,12 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* Can be called on any thread.
*/
+ @Override
public int getPendingFrameCount() {
return pendingFrames.size();
}
- /**
- * Signals the end of the input.
- *
- * @see VideoFrameProcessor#signalEndOfInput()
- */
+ @Override
public void signalEndOfInput() {
videoFrameProcessingTaskExecutor.submit(
() -> {
@@ -183,11 +187,7 @@ import java.util.concurrent.atomic.AtomicInteger;
});
}
- /**
- * Releases all resources.
- *
- * @see VideoFrameProcessor#release()
- */
+ @Override
public void release() {
surfaceTexture.release();
surface.release();
diff --git a/libraries/effect/src/main/java/androidx/media3/effect/InputHandler.java b/libraries/effect/src/main/java/androidx/media3/effect/InputHandler.java
new file mode 100644
index 0000000000..ed9a7d4e97
--- /dev/null
+++ b/libraries/effect/src/main/java/androidx/media3/effect/InputHandler.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package androidx.media3.effect;
+
+import android.graphics.Bitmap;
+import android.graphics.SurfaceTexture;
+import android.view.Surface;
+import androidx.annotation.Nullable;
+import androidx.media3.common.FrameInfo;
+import androidx.media3.common.VideoFrameProcessor;
+
+/** A component that handles {@code DefaultVideoFrameProcessor}'s input. */
+/* package */ interface InputHandler extends GlShaderProgram.InputListener {
+
+ /**
+ * See {@link DefaultVideoFrameProcessor#setInputDefaultBufferSize}.
+ *
+ * Only works when the input is received on a {@link SurfaceTexture}.
+ */
+ void setDefaultBufferSize(int width, int height);
+
+ /**
+ * Provides an input {@link Bitmap} to put into the video frames.
+ *
+ * @see VideoFrameProcessor#queueInputBitmap
+ */
+ void queueInputBitmap(Bitmap inputBitmap, long durationUs, float frameRate, boolean useHdr);
+
+ /**
+ * See {@link VideoFrameProcessor#getInputSurface}.
+ *
+ * Only works when the input is received on a {@link SurfaceTexture}.
+ */
+ Surface getInputSurface();
+
+ /** Informs the {@code InputHandler} that a frame will be queued. */
+ void registerInputFrame(FrameInfo frameInfo);
+
+ /** See {@link VideoFrameProcessor#getPendingInputFrameCount}. */
+ int getPendingFrameCount();
+
+ /**
+ * Signals the end of the input.
+ *
+ * @see VideoFrameProcessor#signalEndOfInput()
+ */
+ void signalEndOfInput();
+
+ /** Sets the task to run on completing flushing, or {@code null} to clear any task. */
+ void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task);
+
+ /**
+ * Releases all resources.
+ *
+ * @see VideoFrameProcessor#release()
+ */
+ void release();
+}