Compositor: Move Settings to DefaultVideoCompositor.

This previously was in the VideoCompositor class, but wasn't
referenced at all from that interface.

PiperOrigin-RevId: 565409646
This commit is contained in:
huangdarwin 2023-09-14 10:31:14 -07:00 committed by Copybara-Service
parent 03b793e2ee
commit 5ef5d46708
5 changed files with 83 additions and 49 deletions

View File

@ -76,19 +76,6 @@ public final class DefaultVideoCompositor implements VideoCompositor {
// * Add support for mixing SDR streams with different ColorInfo.
// * Add support for HDR input.
/** A default implementation of {@link VideoCompositor.Settings}. */
public static final class Settings implements VideoCompositor.Settings {
@Override
public Size getOutputSize(List<Size> inputSizes) {
return inputSizes.get(PRIMARY_INPUT_ID);
}
@Override
public OverlaySettings getOverlaySettings(int inputId, long presentationTimeUs) {
return new OverlaySettings.Builder().build();
}
}
private static final String THREAD_NAME = "Effect:DefaultVideoCompositor:GlThread";
private static final String TAG = "DefaultVideoCompositor";
private static final String VERTEX_SHADER_PATH = "shaders/vertex_shader_transformation_es2.glsl";
@ -99,7 +86,7 @@ public final class DefaultVideoCompositor implements VideoCompositor {
private final VideoCompositor.Listener listener;
private final GlTextureProducer.Listener textureOutputListener;
private final GlObjectsProvider glObjectsProvider;
private final VideoCompositor.Settings settings;
private final VideoCompositorSettings settings;
private final OverlayMatrixProvider overlayMatrixProvider;
private final VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor;
@ -130,7 +117,7 @@ public final class DefaultVideoCompositor implements VideoCompositor {
public DefaultVideoCompositor(
Context context,
GlObjectsProvider glObjectsProvider,
VideoCompositor.Settings settings,
VideoCompositorSettings settings,
@Nullable ExecutorService executorService,
VideoCompositor.Listener listener,
GlTextureProducer.Listener textureOutputListener,

View File

@ -18,9 +18,7 @@ package androidx.media3.effect;
import androidx.media3.common.ColorInfo;
import androidx.media3.common.GlTextureInfo;
import androidx.media3.common.VideoFrameProcessingException;
import androidx.media3.common.util.Size;
import androidx.media3.common.util.UnstableApi;
import java.util.List;
/**
* Interface for a video compositor that combines frames from multiple input sources to produce
@ -47,23 +45,6 @@ public interface VideoCompositor extends GlTextureProducer {
void onEnded();
}
/** Settings for the {@link VideoCompositor}. */
interface Settings {
// TODO: b/262694346 - Consider adding more features, like selecting a:
// * custom order for drawing (instead of primary stream on top), and
// * different primary source.
/**
* Returns an output texture {@link Size}, based on {@code inputSizes}.
*
* @param inputSizes The {@link Size} of each input frame, ordered by {@code inputId}.
*/
Size getOutputSize(List<Size> inputSizes);
/** Returns {@link OverlaySettings} for {@code inputId} at time {@code presentationTimeUs}. */
OverlaySettings getOverlaySettings(int inputId, long presentationTimeUs);
}
/**
* Registers a new input source, and returns a unique {@code inputId} corresponding to this
* source, to be used in {@link #queueInputTexture}.

View File

@ -0,0 +1,61 @@
/*
* 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
*
* https://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.util.Size;
import androidx.media3.common.util.UnstableApi;
import java.util.List;
/** Settings for the {@link VideoCompositor}. */
@UnstableApi
public interface VideoCompositorSettings {
// TODO: b/262694346 - Consider adding more features, like selecting a:
// * custom order for drawing (instead of primary stream on top), and
// * different primary source.
VideoCompositorSettings DEFAULT =
new VideoCompositorSettings() {
/**
* {@inheritDoc}
*
* <p>Returns the primary stream's {@link Size}.
*/
@Override
public Size getOutputSize(List<Size> inputSizes) {
return inputSizes.get(0);
}
/**
* {@inheritDoc}
*
* <p>Returns a default {@link OverlaySettings} instance.
*/
@Override
public OverlaySettings getOverlaySettings(int inputId, long presentationTimeUs) {
return new OverlaySettings.Builder().build();
}
};
/**
* Returns an output texture {@link Size}, based on {@code inputSizes}.
*
* @param inputSizes The {@link Size} of each input frame, ordered by {@code inputId}.
*/
Size getOutputSize(List<Size> inputSizes);
/** Returns {@link OverlaySettings} for {@code inputId} at time {@code presentationTimeUs}. */
OverlaySettings getOverlaySettings(int inputId, long presentationTimeUs);
}

View File

@ -58,6 +58,7 @@ import androidx.media3.effect.RgbFilter;
import androidx.media3.effect.ScaleAndRotateTransformation;
import androidx.media3.effect.TextOverlay;
import androidx.media3.effect.VideoCompositor;
import androidx.media3.effect.VideoCompositorSettings;
import androidx.media3.test.utils.BitmapPixelTestUtil;
import androidx.media3.test.utils.TextureBitmapReader;
import androidx.media3.test.utils.VideoFrameProcessorTestRunner;
@ -548,8 +549,8 @@ public final class DefaultVideoCompositorPixelTest {
public void compositeTwoInputs_pictureInPicture_matchesExpectedBitmap() throws Exception {
ImmutableList<ImmutableList<Effect>> inputEffectLists =
ImmutableList.of(ImmutableList.of(), ImmutableList.of(RgbFilter.createGrayscaleFilter()));
VideoCompositor.Settings pictureInPictureSettings =
new VideoCompositor.Settings() {
VideoCompositorSettings pictureInPictureVideoCompositorSettings =
new VideoCompositorSettings() {
@Override
public Size getOutputSize(List<Size> inputSizes) {
return inputSizes.get(0);
@ -573,7 +574,7 @@ public final class DefaultVideoCompositorPixelTest {
};
compositorTestRunner =
new VideoCompositorTestRunner(
testId, useSharedExecutor, inputEffectLists, pictureInPictureSettings);
testId, useSharedExecutor, inputEffectLists, pictureInPictureVideoCompositorSettings);
compositorTestRunner.queueBitmapToAllInputs(1);
compositorTestRunner.endCompositing();
@ -590,8 +591,8 @@ public final class DefaultVideoCompositorPixelTest {
ImmutableList.of(
Presentation.createForWidthAndHeight(100, 100, Presentation.LAYOUT_STRETCH_TO_FIT)),
ImmutableList.of(RgbFilter.createGrayscaleFilter()));
VideoCompositor.Settings secondStreamAsOutputSizeSettings =
new VideoCompositor.Settings() {
VideoCompositorSettings secondStreamAsOutputSizeVideoCompositorSettings =
new VideoCompositorSettings() {
@Override
public Size getOutputSize(List<Size> inputSizes) {
return Iterables.getLast(inputSizes);
@ -604,7 +605,10 @@ public final class DefaultVideoCompositorPixelTest {
};
compositorTestRunner =
new VideoCompositorTestRunner(
testId, useSharedExecutor, inputEffectLists, secondStreamAsOutputSizeSettings);
testId,
useSharedExecutor,
inputEffectLists,
secondStreamAsOutputSizeVideoCompositorSettings);
compositorTestRunner.queueBitmapToAllInputs(1);
compositorTestRunner.endCompositing();
@ -621,8 +625,8 @@ public final class DefaultVideoCompositorPixelTest {
ImmutableList.of(RgbFilter.createGrayscaleFilter()),
ImmutableList.of(),
ImmutableList.of(RgbFilter.createInvertedFilter()));
VideoCompositor.Settings stackedFrameSettings =
new VideoCompositor.Settings() {
VideoCompositorSettings stackedFrameVideoCompositorSettings =
new VideoCompositorSettings() {
private static final int NUMBER_OF_INPUT_STREAMS = 3;
@Override
@ -647,7 +651,7 @@ public final class DefaultVideoCompositorPixelTest {
};
compositorTestRunner =
new VideoCompositorTestRunner(
testId, useSharedExecutor, inputEffectLists, stackedFrameSettings);
testId, useSharedExecutor, inputEffectLists, stackedFrameVideoCompositorSettings);
compositorTestRunner.queueBitmapToAllInputs(1);
compositorTestRunner.endCompositing();
@ -673,7 +677,7 @@ public final class DefaultVideoCompositorPixelTest {
private final String testId;
/**
* Creates an instance using {@link DefaultVideoCompositor.Settings}.
* Creates an instance using {@link VideoCompositorSettings}.
*
* @param testId The {@link String} identifier for the test, used to name output files.
* @param useSharedExecutor Whether to use a shared executor for {@link
@ -688,7 +692,7 @@ public final class DefaultVideoCompositorPixelTest {
boolean useSharedExecutor,
ImmutableList<ImmutableList<Effect>> inputEffectLists)
throws GlUtil.GlException, VideoFrameProcessingException {
this(testId, useSharedExecutor, inputEffectLists, new DefaultVideoCompositor.Settings());
this(testId, useSharedExecutor, inputEffectLists, VideoCompositorSettings.DEFAULT);
}
/**
@ -701,13 +705,13 @@ public final class DefaultVideoCompositorPixelTest {
* The size of this outer {@link List} is the amount of inputs. One inner list of {@link
* Effect}s is used for each input. For each input, the frame timestamp and {@code inputId}
* are overlaid via {@link TextOverlay} prior to its effects being applied.
* @param settings The {@link VideoCompositor.Settings}.
* @param videoCompositorSettings The {@link VideoCompositorSettings}.
*/
public VideoCompositorTestRunner(
String testId,
boolean useSharedExecutor,
ImmutableList<ImmutableList<Effect>> inputEffectLists,
VideoCompositor.Settings settings)
VideoCompositorSettings videoCompositorSettings)
throws GlUtil.GlException, VideoFrameProcessingException {
this.testId = testId;
timeoutMs = inputEffectLists.size() * VIDEO_FRAME_PROCESSING_WAIT_MS;
@ -725,7 +729,7 @@ public final class DefaultVideoCompositorPixelTest {
new DefaultVideoCompositor(
getApplicationContext(),
glObjectsProvider,
settings,
videoCompositorSettings,
sharedExecutorService,
new VideoCompositor.Listener() {
@Override

View File

@ -49,6 +49,7 @@ import androidx.media3.effect.DefaultVideoCompositor;
import androidx.media3.effect.DefaultVideoFrameProcessor;
import androidx.media3.effect.GlTextureProducer;
import androidx.media3.effect.VideoCompositor;
import androidx.media3.effect.VideoCompositorSettings;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -225,7 +226,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
new DefaultVideoCompositor(
context,
glObjectsProvider,
new DefaultVideoCompositor.Settings(),
VideoCompositorSettings.DEFAULT,
sharedExecutorService,
new VideoCompositor.Listener() {
// All of this listener's methods are called on the sharedExecutorService.