From 4178d61ccd8b9287f0ad5a7d3f4f536680c8797c Mon Sep 17 00:00:00 2001 From: huangdarwin Date: Fri, 16 Jun 2023 13:33:13 +0100 Subject: [PATCH] Effect: Move VideoFrameProcessingTask to VFPTaskexecutor Group things that are closely related. VFPTask is only ever used alongside VFPTaskExecutor. PiperOrigin-RevId: 540850948 --- .../media3/effect/BitmapTextureManager.java | 2 +- .../media3/effect/ExternalTextureManager.java | 4 +- .../effect/FinalShaderProgramWrapper.java | 2 +- .../media3/effect/TexIdTextureManager.java | 2 +- .../media3/effect/TextureManager.java | 2 +- .../effect/VideoFrameProcessingTask.java | 30 ----------- .../VideoFrameProcessingTaskExecutor.java | 54 +++++++++---------- 7 files changed, 33 insertions(+), 63 deletions(-) delete mode 100644 libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTask.java 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 b1ce7a47da..42b215aa4b 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/BitmapTextureManager.java @@ -118,7 +118,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } @Override - public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task) { + public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) { // Do nothing. } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java index 4b107291d8..a4f0c43cb4 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/ExternalTextureManager.java @@ -85,7 +85,7 @@ import java.util.concurrent.atomic.AtomicInteger; @Nullable private volatile FrameInfo currentFrame; // TODO(b/238302341) Remove the use of after flush task, block the calling thread instead. - @Nullable private volatile VideoFrameProcessingTask onFlushCompleteTask; + @Nullable private volatile VideoFrameProcessingTaskExecutor.Task onFlushCompleteTask; @Nullable private Future forceSignalEndOfStreamFuture; // Whether to reject frames from the SurfaceTexture. Accessed only on GL thread. @@ -180,7 +180,7 @@ import java.util.concurrent.atomic.AtomicInteger; } @Override - public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task) { + public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) { onFlushCompleteTask = task; } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/FinalShaderProgramWrapper.java b/libraries/effect/src/main/java/androidx/media3/effect/FinalShaderProgramWrapper.java index e8615df432..449b8a6dc6 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/FinalShaderProgramWrapper.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/FinalShaderProgramWrapper.java @@ -621,7 +621,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; *

Must be called on the GL thread. */ public synchronized void maybeRenderToSurfaceView( - VideoFrameProcessingTask renderingTask, GlObjectsProvider glObjectsProvider) + VideoFrameProcessingTaskExecutor.Task renderingTask, GlObjectsProvider glObjectsProvider) throws GlUtil.GlException, VideoFrameProcessingException { if (surface == null) { return; diff --git a/libraries/effect/src/main/java/androidx/media3/effect/TexIdTextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/TexIdTextureManager.java index a9e7e729a6..d2e59ebcd3 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/TexIdTextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/TexIdTextureManager.java @@ -112,7 +112,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } @Override - public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task) { + public void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task) { // Do nothing. } diff --git a/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java b/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java index 78e1f42898..56e91a67e7 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/TextureManager.java @@ -111,7 +111,7 @@ import androidx.media3.common.VideoFrameProcessor; void signalEndOfInput(); /** Sets the task to run on completing flushing, or {@code null} to clear any task. */ - void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTask task); + void setOnFlushCompleteListener(@Nullable VideoFrameProcessingTaskExecutor.Task task); /** * Releases all resources. diff --git a/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTask.java b/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTask.java deleted file mode 100644 index d62e78195c..0000000000 --- a/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTask.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2022 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 androidx.media3.common.VideoFrameProcessingException; -import androidx.media3.common.util.GlUtil; -import androidx.media3.common.util.UnstableApi; - -/** - * Interface for tasks that may throw a {@link GlUtil.GlException} or {@link - * VideoFrameProcessingException}. - */ -@UnstableApi -/* package */ interface VideoFrameProcessingTask { - /** Runs the task. */ - void run() throws VideoFrameProcessingException, GlUtil.GlException; -} diff --git a/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTaskExecutor.java b/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTaskExecutor.java index a5fdf33f6e..26bfd82375 100644 --- a/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTaskExecutor.java +++ b/libraries/effect/src/main/java/androidx/media3/effect/VideoFrameProcessingTaskExecutor.java @@ -21,6 +21,7 @@ import androidx.annotation.GuardedBy; import androidx.annotation.Nullable; 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.ArrayDeque; import java.util.Queue; @@ -31,8 +32,7 @@ import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; /** - * Wrapper around a single thread {@link ExecutorService} for executing {@link - * VideoFrameProcessingTask} instances. + * Wrapper around a single thread {@link ExecutorService} for executing {@link Task} instances. * *

Public methods can be called from any thread. * @@ -42,19 +42,27 @@ import java.util.concurrent.RejectedExecutionException; * non-recoverable, so the {@code VideoFrameProcessingTaskExecutor} should be released if an error * occurs. * - *

{@linkplain #submitWithHighPriority(VideoFrameProcessingTask) High priority tasks} are always - * executed before {@linkplain #submit(VideoFrameProcessingTask) default priority tasks}. Tasks with - * equal priority are executed in FIFO order. + *

{@linkplain #submitWithHighPriority(Task) High priority tasks} are always executed before + * {@linkplain #submit(Task) default priority tasks}. Tasks with equal priority are executed in FIFO + * order. */ @UnstableApi /* package */ final class VideoFrameProcessingTaskExecutor { + /** + * Interface for tasks that may throw a {@link GlUtil.GlException} or {@link + * VideoFrameProcessingException}. + */ + public interface Task { + /** Runs the task. */ + void run() throws VideoFrameProcessingException, GlUtil.GlException; + } private final ExecutorService singleThreadExecutorService; private final VideoFrameProcessor.Listener listener; private final Object lock; @GuardedBy("lock") - private final Queue highPriorityTasks; + private final Queue highPriorityTasks; @GuardedBy("lock") private boolean shouldCancelTasks; @@ -68,12 +76,9 @@ import java.util.concurrent.RejectedExecutionException; highPriorityTasks = new ArrayDeque<>(); } - /** - * Submits the given {@link VideoFrameProcessingTask} to be executed after all pending tasks have - * completed. - */ + /** Submits the given {@link Task} to be executed after all pending tasks have completed. */ @SuppressWarnings("FutureReturnValueIgnored") - public void submit(VideoFrameProcessingTask task) { + public void submit(Task task) { @Nullable RejectedExecutionException executionException = null; synchronized (lock) { if (shouldCancelTasks) { @@ -91,11 +96,8 @@ import java.util.concurrent.RejectedExecutionException; } } - /** - * Submits the given {@link VideoFrameProcessingTask} to execute, and returns after the task is - * executed. - */ - public void submitAndBlock(VideoFrameProcessingTask task) { + /** Submits the given {@link Task} to execute, and returns after the task is executed. */ + public void submitAndBlock(Task task) { synchronized (lock) { if (shouldCancelTasks) { return; @@ -114,13 +116,13 @@ import java.util.concurrent.RejectedExecutionException; } /** - * Submits the given {@link VideoFrameProcessingTask} to be executed after the currently running - * task and all previously submitted high-priority tasks have completed. + * Submits the given {@link Task} to be executed after the currently running task and all + * previously submitted high-priority tasks have completed. * - *

Tasks that were previously {@linkplain #submit(VideoFrameProcessingTask) submitted} without - * high-priority and have not started executing will be executed after this task is complete. + *

Tasks that were previously {@linkplain #submit(Task) submitted} without high-priority and + * have not started executing will be executed after this task is complete. */ - public void submitWithHighPriority(VideoFrameProcessingTask task) { + public void submitWithHighPriority(Task task) { synchronized (lock) { if (shouldCancelTasks) { return; @@ -162,13 +164,11 @@ import java.util.concurrent.RejectedExecutionException; /** * Cancels remaining tasks, runs the given release task, and shuts down the background thread. * - * @param releaseTask A {@link VideoFrameProcessingTask} to execute before shutting down the - * background thread. + * @param releaseTask A {@link Task} to execute before shutting down the background thread. * @param releaseWaitTimeMs How long to wait for the release task to terminate, in milliseconds. * @throws InterruptedException If interrupted while releasing resources. */ - public void release(VideoFrameProcessingTask releaseTask, long releaseWaitTimeMs) - throws InterruptedException { + public void release(Task releaseTask, long releaseWaitTimeMs) throws InterruptedException { synchronized (lock) { shouldCancelTasks = true; highPriorityTasks.clear(); @@ -184,7 +184,7 @@ import java.util.concurrent.RejectedExecutionException; } private Future wrapTaskAndSubmitToExecutorService( - VideoFrameProcessingTask defaultPriorityTask, boolean isFlushOrReleaseTask) { + Task defaultPriorityTask, boolean isFlushOrReleaseTask) { return singleThreadExecutorService.submit( () -> { try { @@ -194,7 +194,7 @@ import java.util.concurrent.RejectedExecutionException; } } - @Nullable VideoFrameProcessingTask nextHighPriorityTask; + @Nullable Task nextHighPriorityTask; while (true) { synchronized (lock) { // Lock only polling to prevent blocking the public method calls.