Commit 4188bf30 by tofunmi Committed by Rohit Singh

Change isInputTextureExternal boolean parameter to inputType intDef

PiperOrigin-RevId: 525690361
parent baab3f1b
......@@ -15,12 +15,19 @@
*/
package com.google.android.exoplayer2.util;
import static java.lang.annotation.ElementType.TYPE_USE;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.EGLExt;
import android.view.Surface;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.video.ColorInfo;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;
import java.util.concurrent.Executor;
......@@ -38,6 +45,24 @@ import java.util.concurrent.Executor;
*/
public interface VideoFrameProcessor {
// TODO(b/243036513): Allow effects to be replaced.
/**
* Specifies how the input frames are made available to the {@link VideoFrameProcessor}. One of
* {@link #INPUT_TYPE_SURFACE}, {@link #INPUT_TYPE_BITMAP} or {@link #INPUT_TYPE_TEXID}.
*/
@Documented
@Retention(RetentionPolicy.SOURCE)
@Target(TYPE_USE)
@IntDef({INPUT_TYPE_SURFACE, INPUT_TYPE_BITMAP, INPUT_TYPE_TEXID})
public @interface InputType {}
/** Input frames come from a {@link #getInputSurface surface}. */
public static final int INPUT_TYPE_SURFACE = 1;
/** Input frames come from a {@link Bitmap}. */
public static final int INPUT_TYPE_BITMAP = 2;
/**
* Input frames come from a {@linkplain android.opengl.GLES10#GL_TEXTURE_2D traditional GLES
* texture}.
*/
public static final int INPUT_TYPE_TEXID = 3;
/** A factory for {@link VideoFrameProcessor} instances. */
interface Factory {
......@@ -52,10 +77,7 @@ public interface VideoFrameProcessor {
* @param debugViewProvider A {@link DebugViewProvider}.
* @param inputColorInfo The {@link ColorInfo} for input frames.
* @param outputColorInfo The {@link ColorInfo} for output frames.
* @param isInputTextureExternal Whether the input frames are produced externally (e.g. from a
* video) or not (e.g. from a {@link Bitmap}). See <a
* href="https://source.android.com/docs/core/graphics/arch-st#ext_texture">the
* SurfaceTexture docs</a> for more information on external textures.
* @param inputType The {@link InputType}.
* @param releaseFramesAutomatically If {@code true}, the instance will render output frames to
* the {@linkplain #setOutputSurfaceInfo(SurfaceInfo) output surface} automatically as
* {@link VideoFrameProcessor} is done processing them. If {@code false}, the {@link
......@@ -73,7 +95,7 @@ public interface VideoFrameProcessor {
DebugViewProvider debugViewProvider,
ColorInfo inputColorInfo,
ColorInfo outputColorInfo,
boolean isInputTextureExternal,
@InputType int inputType,
boolean releaseFramesAutomatically,
Executor executor,
Listener listener)
......@@ -128,10 +150,10 @@ public interface VideoFrameProcessor {
long DROP_OUTPUT_FRAME = -2;
/**
* Provides an input {@link Bitmap} to the {@code VideoFrameProcessor}.
* Provides an input {@link Bitmap} to the {@link VideoFrameProcessor}.
*
* <p>This method should only be used for when the {@code VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code false}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_BITMAP}.
*
* <p>Can be called on any thread.
*
......@@ -145,11 +167,11 @@ public interface VideoFrameProcessor {
void queueInputBitmap(Bitmap inputBitmap, long durationUs, float frameRate);
/**
* Returns the input {@link Surface}, where {@code VideoFrameProcessor} consumes input frames
* Returns the input {@link Surface}, where {@link VideoFrameProcessor} consumes input frames
* from.
*
* <p>This method should only be used for when the {@code VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code true}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_SURFACE}.
*
* <p>Can be called on any thread.
*/
......@@ -174,8 +196,8 @@ public interface VideoFrameProcessor {
*
* <p>Must be called before rendering a frame to the input surface.
*
* <p>This method should only be used for when the {@code VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code true}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_SURFACE}.
*
* <p>Can be called on any thread.
*
......@@ -188,8 +210,8 @@ public interface VideoFrameProcessor {
* Returns the number of input frames that have been {@linkplain #registerInputFrame() registered}
* but not processed off the {@linkplain #getInputSurface() input surface} yet.
*
* <p>This method should only be used for when the {@code VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code true}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_SURFACE}.
*
* <p>Can be called on any thread.
*/
......@@ -248,8 +270,8 @@ public interface VideoFrameProcessor {
* <p>All the frames that are {@linkplain #registerInputFrame() registered} prior to calling this
* method are no longer considered to be registered when this method returns.
*
* <p>This method should only be used for when the {@code VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code true}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_SURFACE}.
*
* <p>{@link Listener} methods invoked prior to calling this method should be ignored.
*/
......
......@@ -22,6 +22,7 @@ import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_SURFACE;
import static java.lang.Math.max;
import static java.lang.Math.min;
......@@ -2010,7 +2011,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
DebugViewProvider.NONE,
inputColorInfo,
outputColorInfo,
/* isInputTextureExternal= */ true,
INPUT_TYPE_SURFACE,
/* releaseFramesAutomatically= */ false,
/* executor= */ handler::post,
new VideoFrameProcessor.Listener() {
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.effect;
import static com.google.android.exoplayer2.testutil.BitmapPixelTestUtil.readBitmap;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_BITMAP;
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
......@@ -124,7 +125,7 @@ public class DefaultVideoFrameProcessorImageFrameOutputTest {
return new VideoFrameProcessorTestRunner.Builder()
.setTestId(testId)
.setVideoFrameProcessorFactory(new DefaultVideoFrameProcessor.Factory.Builder().build())
.setIsInputTextureExternal(false)
.setInputType(INPUT_TYPE_BITMAP)
.setOnOutputFrameAvailableListener(
unused -> checkNotNull(framesProduced).incrementAndGet());
}
......
......@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.testutil.BitmapPixelTestUtil.getBitm
import static com.google.android.exoplayer2.testutil.BitmapPixelTestUtil.readBitmap;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_BITMAP;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
......@@ -110,7 +111,7 @@ public final class DefaultVideoFrameProcessorPixelTest {
public void noEffects_withImageInput_matchesGoldenFile() throws Exception {
String testId = "noEffects_withImageInput_matchesGoldenFile";
videoFrameProcessorTestRunner =
getDefaultFrameProcessorTestRunnerBuilder(testId).setIsInputTextureExternal(false).build();
getDefaultFrameProcessorTestRunnerBuilder(testId).setInputType(INPUT_TYPE_BITMAP).build();
Bitmap originalBitmap = readBitmap(IMAGE_PNG_ASSET_PATH);
Bitmap expectedBitmap = readBitmap(IMAGE_TO_VIDEO_PNG_ASSET_PATH);
......@@ -129,7 +130,7 @@ public final class DefaultVideoFrameProcessorPixelTest {
String testId = "wrappedCrop_withImageInput_matchesGoldenFile";
videoFrameProcessorTestRunner =
getDefaultFrameProcessorTestRunnerBuilder(testId)
.setIsInputTextureExternal(false)
.setInputType(INPUT_TYPE_BITMAP)
.setEffects(
new GlEffectWrapper(
new Crop(
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.effect;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_SURFACE;
import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
......@@ -300,7 +301,7 @@ public final class DefaultVideoFrameProcessorVideoFrameReleaseTest {
DebugViewProvider.NONE,
/* inputColorInfo= */ ColorInfo.SDR_BT709_LIMITED,
/* outputColorInfo= */ ColorInfo.SDR_BT709_LIMITED,
/* isInputTextureExternal= */ true,
INPUT_TYPE_SURFACE,
releaseFramesAutomatically,
MoreExecutors.directExecutor(),
new VideoFrameProcessor.Listener() {
......
......@@ -180,7 +180,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
DebugViewProvider debugViewProvider,
ColorInfo inputColorInfo,
ColorInfo outputColorInfo,
boolean isInputTextureExternal,
@InputType int inputType,
boolean releaseFramesAutomatically,
Executor listenerExecutor,
Listener listener)
......@@ -219,7 +219,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
inputColorInfo,
outputColorInfo,
enableColorTransfers,
isInputTextureExternal,
inputType,
releaseFramesAutomatically,
singleThreadExecutorService,
listenerExecutor,
......@@ -257,7 +257,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
private DefaultVideoFrameProcessor(
EGLDisplay eglDisplay,
EGLContext eglContext,
boolean isInputTextureExternal,
@InputType int inputType,
VideoFrameProcessingTaskExecutor videoFrameProcessingTaskExecutor,
ImmutableList<GlShaderProgram> shaderPrograms,
boolean releaseFramesAutomatically)
......@@ -273,16 +273,22 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
GlShaderProgram inputShaderProgram = shaderPrograms.get(0);
if (isInputTextureExternal) {
checkState(inputShaderProgram instanceof ExternalShaderProgram);
inputExternalTextureManager =
new ExternalTextureManager(
(ExternalShaderProgram) inputShaderProgram, videoFrameProcessingTaskExecutor);
inputShaderProgram.setInputListener(inputExternalTextureManager);
} else {
inputBitmapTextureManager =
new BitmapTextureManager(inputShaderProgram, videoFrameProcessingTaskExecutor);
inputShaderProgram.setInputListener(inputBitmapTextureManager);
switch (inputType) {
case VideoFrameProcessor.INPUT_TYPE_SURFACE:
checkState(inputShaderProgram instanceof ExternalShaderProgram);
inputExternalTextureManager =
new ExternalTextureManager(
(ExternalShaderProgram) inputShaderProgram, videoFrameProcessingTaskExecutor);
inputShaderProgram.setInputListener(inputExternalTextureManager);
break;
case VideoFrameProcessor.INPUT_TYPE_BITMAP:
inputBitmapTextureManager =
new BitmapTextureManager(inputShaderProgram, videoFrameProcessingTaskExecutor);
inputShaderProgram.setInputListener(inputBitmapTextureManager);
break;
case VideoFrameProcessor.INPUT_TYPE_TEXID: // fall through
default:
throw new VideoFrameProcessingException("Input type not supported yet");
}
finalShaderProgramWrapper = (FinalShaderProgramWrapper) getLast(shaderPrograms);
......@@ -304,8 +310,8 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
* call this method after instantiation to ensure that buffers are handled at full resolution. See
* {@link SurfaceTexture#setDefaultBufferSize(int, int)} for more information.
*
* <p>This method should only be used for when the {@link VideoFrameProcessor}'s {@code
* isInputTextureExternal} parameter is set to {@code true}.
* <p>This method must only be called when the {@link VideoFrameProcessor} is {@linkplain
* Factory#create created} with {@link #INPUT_TYPE_SURFACE}.
*
* @param width The default width for input buffers, in pixels.
* @param height The default height for input buffers, in pixels.
......@@ -441,7 +447,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
ColorInfo inputColorInfo,
ColorInfo outputColorInfo,
boolean enableColorTransfers,
boolean isInputTextureExternal,
@InputType int inputType,
boolean releaseFramesAutomatically,
ExecutorService singleThreadExecutorService,
Executor executor,
......@@ -485,7 +491,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
inputColorInfo,
outputColorInfo,
enableColorTransfers,
isInputTextureExternal,
inputType,
releaseFramesAutomatically,
executor,
listener,
......@@ -500,7 +506,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
return new DefaultVideoFrameProcessor(
eglDisplay,
eglContext,
isInputTextureExternal,
inputType,
videoFrameProcessingTaskExecutor,
shaderPrograms,
releaseFramesAutomatically);
......@@ -526,7 +532,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
ColorInfo inputColorInfo,
ColorInfo outputColorInfo,
boolean enableColorTransfers,
boolean isInputTextureExternal,
@InputType int inputType,
boolean releaseFramesAutomatically,
Executor executor,
Listener listener,
......@@ -568,7 +574,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
if (!matrixTransformations.isEmpty() || !rgbMatrices.isEmpty() || sampleFromInputTexture) {
DefaultShaderProgram defaultShaderProgram;
if (sampleFromInputTexture) {
if (isInputTextureExternal) {
if (inputType == INPUT_TYPE_SURFACE) {
defaultShaderProgram =
DefaultShaderProgram.createWithExternalSampler(
context,
......@@ -612,7 +618,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
outputColorInfo,
enableColorTransfers,
sampleFromInputTexture,
isInputTextureExternal,
inputType,
releaseFramesAutomatically,
executor,
listener,
......
......@@ -17,6 +17,7 @@ package com.google.android.exoplayer2.effect;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkState;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_SURFACE;
import android.content.Context;
import android.opengl.EGL14;
......@@ -72,7 +73,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final EGLContext eglContext;
private final DebugViewProvider debugViewProvider;
private final boolean sampleFromInputTexture;
private final boolean isInputTextureExternal;
private final @VideoFrameProcessor.InputType int inputType;
private final ColorInfo inputColorInfo;
private final ColorInfo outputColorInfo;
private final boolean enableColorTransfers;
......@@ -115,7 +116,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
ColorInfo outputColorInfo,
boolean enableColorTransfers,
boolean sampleFromInputTexture,
boolean isInputTextureExternal,
@VideoFrameProcessor.InputType int inputType,
boolean releaseFramesAutomatically,
Executor videoFrameProcessorListenerExecutor,
VideoFrameProcessor.Listener videoFrameProcessorListener,
......@@ -128,7 +129,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
this.eglContext = eglContext;
this.debugViewProvider = debugViewProvider;
this.sampleFromInputTexture = sampleFromInputTexture;
this.isInputTextureExternal = isInputTextureExternal;
this.inputType = inputType;
this.inputColorInfo = inputColorInfo;
this.outputColorInfo = outputColorInfo;
this.enableColorTransfers = enableColorTransfers;
......@@ -456,7 +457,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
ImmutableList<GlMatrixTransformation> expandedMatrixTransformations =
matrixTransformationListBuilder.build();
if (sampleFromInputTexture) {
if (isInputTextureExternal) {
if (inputType == INPUT_TYPE_SURFACE) {
defaultShaderProgram =
DefaultShaderProgram.createWithExternalSampler(
context,
......
......@@ -21,6 +21,8 @@ import static com.google.android.exoplayer2.transformer.TransformationRequest.HD
import static com.google.android.exoplayer2.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC;
import static com.google.android.exoplayer2.transformer.TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_BITMAP;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_SURFACE;
import static com.google.android.exoplayer2.video.ColorInfo.isTransferHdr;
import android.content.Context;
......@@ -128,6 +130,9 @@ import org.checkerframework.dataflow.qual.Pure;
if (presentation != null) {
effectsWithPresentation.add(presentation);
}
@VideoFrameProcessor.InputType
int inputType =
MimeTypes.isVideo(firstInputFormat.sampleMimeType) ? INPUT_TYPE_SURFACE : INPUT_TYPE_BITMAP;
try {
videoFrameProcessor =
videoFrameProcessorFactory.create(
......@@ -136,7 +141,7 @@ import org.checkerframework.dataflow.qual.Pure;
debugViewProvider,
videoFrameProcessorInputColor,
videoFrameProcessorOutputColor,
MimeTypes.isVideo(firstInputFormat.sampleMimeType),
inputType,
/* releaseFramesAutomatically= */ true,
MoreExecutors.directExecutor(),
new VideoFrameProcessor.Listener() {
......
......@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.testutil.BitmapPixelTestUtil.createA
import static com.google.android.exoplayer2.testutil.BitmapPixelTestUtil.maybeSaveTestBitmap;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;
import static com.google.android.exoplayer2.util.VideoFrameProcessor.INPUT_TYPE_SURFACE;
import static com.google.common.truth.Truth.assertThat;
import android.annotation.SuppressLint;
......@@ -63,13 +64,13 @@ public final class VideoFrameProcessorTestRunner {
private float pixelWidthHeightRatio;
private @MonotonicNonNull ColorInfo inputColorInfo;
private @MonotonicNonNull ColorInfo outputColorInfo;
private boolean isInputTextureExternal;
private @VideoFrameProcessor.InputType int inputType;
private OnOutputFrameAvailableListener onOutputFrameAvailableListener;
/** Creates a new instance with default values. */
public Builder() {
pixelWidthHeightRatio = DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO;
isInputTextureExternal = true;
inputType = INPUT_TYPE_SURFACE;
onOutputFrameAvailableListener = unused -> {};
}
......@@ -189,11 +190,11 @@ public final class VideoFrameProcessorTestRunner {
* Sets whether input comes from an external texture. See {@link
* VideoFrameProcessor.Factory#create}.
*
* <p>The default value is {@code true}.
* <p>The default value is {@link VideoFrameProcessor#INPUT_TYPE_SURFACE}.
*/
@CanIgnoreReturnValue
public Builder setIsInputTextureExternal(boolean isInputTextureExternal) {
this.isInputTextureExternal = isInputTextureExternal;
public Builder setInputType(@VideoFrameProcessor.InputType int inputType) {
this.inputType = inputType;
return this;
}
......@@ -223,7 +224,7 @@ public final class VideoFrameProcessorTestRunner {
pixelWidthHeightRatio,
inputColorInfo == null ? ColorInfo.SDR_BT709_LIMITED : inputColorInfo,
outputColorInfo == null ? ColorInfo.SDR_BT709_LIMITED : outputColorInfo,
isInputTextureExternal,
inputType,
onOutputFrameAvailableListener);
}
}
......@@ -255,7 +256,7 @@ public final class VideoFrameProcessorTestRunner {
float pixelWidthHeightRatio,
ColorInfo inputColorInfo,
ColorInfo outputColorInfo,
boolean isInputTextureExternal,
@VideoFrameProcessor.InputType int inputType,
OnOutputFrameAvailableListener onOutputFrameAvailableListener)
throws VideoFrameProcessingException {
this.testId = testId;
......@@ -272,7 +273,7 @@ public final class VideoFrameProcessorTestRunner {
DebugViewProvider.NONE,
inputColorInfo,
outputColorInfo,
isInputTextureExternal,
inputType,
/* releaseFramesAutomatically= */ true,
MoreExecutors.directExecutor(),
new VideoFrameProcessor.Listener() {
......
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