Move VideoFrameProcessorFactory setter to Transformer

PiperOrigin-RevId: 531123743
This commit is contained in:
kimvde 2023-05-11 07:41:22 +00:00 committed by Tofunmi Adigun-Hameed
parent 82ede47398
commit e8072ca2c7
6 changed files with 39 additions and 57 deletions

View File

@ -121,26 +121,23 @@ public class TransformerEndToEndTest {
String testId = "videoEditing_withTextureInput_completesWithCorrectFrameCountAndDuration"; String testId = "videoEditing_withTextureInput_completesWithCorrectFrameCountAndDuration";
Bitmap bitmap = Bitmap bitmap =
new DataSourceBitmapLoader(context).loadBitmap(Uri.parse(PNG_ASSET_URI_STRING)).get(); new DataSourceBitmapLoader(context).loadBitmap(Uri.parse(PNG_ASSET_URI_STRING)).get();
Transformer transformer =
new Transformer.Builder(context)
.setAssetLoaderFactory(
new TestTextureAssetLoaderFactory(bitmap.getWidth(), bitmap.getHeight()))
.build();
int expectedFrameCount = 2; int expectedFrameCount = 2;
EGLContext currentContext = createOpenGlObjects(); EGLContext currentContext = createOpenGlObjects();
DefaultVideoFrameProcessor.Factory videoFrameProcessorFactory = DefaultVideoFrameProcessor.Factory videoFrameProcessorFactory =
new DefaultVideoFrameProcessor.Factory.Builder() new DefaultVideoFrameProcessor.Factory.Builder()
.setGlObjectsProvider(new DefaultGlObjectsProvider(currentContext)) .setGlObjectsProvider(new DefaultGlObjectsProvider(currentContext))
.build(); .build();
Transformer transformer =
new Transformer.Builder(context)
.setAssetLoaderFactory(
new TestTextureAssetLoaderFactory(bitmap.getWidth(), bitmap.getHeight()))
.setVideoFrameProcessorFactory(videoFrameProcessorFactory)
.build();
ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480)); ImmutableList<Effect> videoEffects = ImmutableList.of(Presentation.createForHeight(480));
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY)) new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY))
.setDurationUs(C.MICROS_PER_SECOND) .setDurationUs(C.MICROS_PER_SECOND)
.setEffects( .setEffects(new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects))
new Effects(
/* audioProcessors= */ ImmutableList.of(),
videoEffects,
videoFrameProcessorFactory))
.build(); .build();
int texId = generateTextureFromBitmap(bitmap); int texId = generateTextureFromBitmap(bitmap);
HandlerThread textureQueuingThread = new HandlerThread("textureQueuingThread"); HandlerThread textureQueuingThread = new HandlerThread("textureQueuingThread");
@ -178,25 +175,21 @@ public class TransformerEndToEndTest {
String testId = "videoTranscoding_withTextureInput_completesWithCorrectFrameCountAndDuration"; String testId = "videoTranscoding_withTextureInput_completesWithCorrectFrameCountAndDuration";
Bitmap bitmap = Bitmap bitmap =
new DataSourceBitmapLoader(context).loadBitmap(Uri.parse(PNG_ASSET_URI_STRING)).get(); new DataSourceBitmapLoader(context).loadBitmap(Uri.parse(PNG_ASSET_URI_STRING)).get();
Transformer transformer =
new Transformer.Builder(context)
.setAssetLoaderFactory(
new TestTextureAssetLoaderFactory(bitmap.getWidth(), bitmap.getHeight()))
.build();
int expectedFrameCount = 2; int expectedFrameCount = 2;
EGLContext currentContext = createOpenGlObjects(); EGLContext currentContext = createOpenGlObjects();
DefaultVideoFrameProcessor.Factory videoFrameProcessorFactory = DefaultVideoFrameProcessor.Factory videoFrameProcessorFactory =
new DefaultVideoFrameProcessor.Factory.Builder() new DefaultVideoFrameProcessor.Factory.Builder()
.setGlObjectsProvider(new DefaultGlObjectsProvider(currentContext)) .setGlObjectsProvider(new DefaultGlObjectsProvider(currentContext))
.build(); .build();
Transformer transformer =
new Transformer.Builder(context)
.setAssetLoaderFactory(
new TestTextureAssetLoaderFactory(bitmap.getWidth(), bitmap.getHeight()))
.setVideoFrameProcessorFactory(videoFrameProcessorFactory)
.build();
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY)) new EditedMediaItem.Builder(MediaItem.fromUri(Uri.EMPTY))
.setDurationUs(C.MICROS_PER_SECOND) .setDurationUs(C.MICROS_PER_SECOND)
.setEffects(
new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(),
videoFrameProcessorFactory))
.build(); .build();
int texId = generateTextureFromBitmap(bitmap); int texId = generateTextureFromBitmap(bitmap);
HandlerThread textureQueuingThread = new HandlerThread("textureQueuingThread"); HandlerThread textureQueuingThread = new HandlerThread("textureQueuingThread");

View File

@ -17,10 +17,8 @@ package androidx.media3.transformer;
import androidx.media3.common.Effect; import androidx.media3.common.Effect;
import androidx.media3.common.MediaItem; import androidx.media3.common.MediaItem;
import androidx.media3.common.VideoFrameProcessor;
import androidx.media3.common.audio.AudioProcessor; import androidx.media3.common.audio.AudioProcessor;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.effect.DefaultVideoFrameProcessor;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.List; import java.util.List;
@ -44,35 +42,15 @@ public final class Effects {
* order of the list. * order of the list.
*/ */
public final ImmutableList<Effect> videoEffects; public final ImmutableList<Effect> videoEffects;
/**
* The {@link VideoFrameProcessor.Factory} for the {@link VideoFrameProcessor} to use when
* applying the {@code videoEffects} to the video frames.
*/
public final VideoFrameProcessor.Factory videoFrameProcessorFactory;
/**
* Creates an instance using a {@link DefaultVideoFrameProcessor.Factory}.
*
* <p>This is equivalent to calling {@link Effects#Effects(List, List,
* VideoFrameProcessor.Factory)} with a {@link DefaultVideoFrameProcessor.Factory}.
*/
public Effects(List<AudioProcessor> audioProcessors, List<Effect> videoEffects) {
this(audioProcessors, videoEffects, new DefaultVideoFrameProcessor.Factory.Builder().build());
}
/** /**
* Creates an instance. * Creates an instance.
* *
* @param audioProcessors The {@link #audioProcessors}. * @param audioProcessors The {@link #audioProcessors}.
* @param videoEffects The {@link #videoEffects}. * @param videoEffects The {@link #videoEffects}.
* @param videoFrameProcessorFactory The {@link #videoFrameProcessorFactory}.
*/ */
public Effects( public Effects(List<AudioProcessor> audioProcessors, List<Effect> videoEffects) {
List<AudioProcessor> audioProcessors,
List<Effect> videoEffects,
VideoFrameProcessor.Factory videoFrameProcessorFactory) {
this.audioProcessors = ImmutableList.copyOf(audioProcessors); this.audioProcessors = ImmutableList.copyOf(audioProcessors);
this.videoEffects = ImmutableList.copyOf(videoEffects); this.videoEffects = ImmutableList.copyOf(videoEffects);
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
} }
} }

View File

@ -423,6 +423,11 @@ import java.util.concurrent.atomic.AtomicInteger;
return sampleConsumer.queueInputBitmap(inputBitmap, durationUs, frameRate); return sampleConsumer.queueInputBitmap(inputBitmap, durationUs, frameRate);
} }
@Override
public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {
sampleConsumer.setOnInputFrameProcessedListener(listener);
}
@Override @Override
public boolean queueInputTexture(int texId, long presentationTimeUs) { public boolean queueInputTexture(int texId, long presentationTimeUs) {
long globalTimestampUs = totalDurationUs + presentationTimeUs; long globalTimestampUs = totalDurationUs + presentationTimeUs;
@ -436,11 +441,6 @@ import java.util.concurrent.atomic.AtomicInteger;
return sampleConsumer.queueInputTexture(texId, presentationTimeUs); return sampleConsumer.queueInputTexture(texId, presentationTimeUs);
} }
@Override
public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {
sampleConsumer.setOnInputFrameProcessedListener(listener);
}
@Override @Override
public Surface getInputSurface() { public Surface getInputSurface() {
return sampleConsumer.getInputSurface(); return sampleConsumer.getInputSurface();

View File

@ -274,12 +274,16 @@ public final class Transformer {
} }
/** /**
* @deprecated Set the {@link VideoFrameProcessor.Factory} in an {@link EditedMediaItem}, and * Sets the factory to be used to create {@link VideoFrameProcessor} instances.
* pass it to {@link #start(EditedMediaItem, String)} instead. *
* <p>The default value is a {@link DefaultVideoFrameProcessor.Factory} built with default
* values.
*
* @param videoFrameProcessorFactory A {@link VideoFrameProcessor.Factory}.
* @return This builder.
*/ */
@CanIgnoreReturnValue @CanIgnoreReturnValue
@Deprecated public Builder setVideoFrameProcessorFactory(
public Builder setFrameProcessorFactory(
VideoFrameProcessor.Factory videoFrameProcessorFactory) { VideoFrameProcessor.Factory videoFrameProcessorFactory) {
this.videoFrameProcessorFactory = videoFrameProcessorFactory; this.videoFrameProcessorFactory = videoFrameProcessorFactory;
return this; return this;
@ -721,6 +725,7 @@ public final class Transformer {
path, path,
transformationRequest, transformationRequest,
assetLoaderFactory, assetLoaderFactory,
videoFrameProcessorFactory,
encoderFactory, encoderFactory,
muxerFactory, muxerFactory,
transformerInternalListener, transformerInternalListener,
@ -799,7 +804,7 @@ public final class Transformer {
.setRemoveAudio(removeAudio) .setRemoveAudio(removeAudio)
.setRemoveVideo(removeVideo) .setRemoveVideo(removeVideo)
.setFlattenForSlowMotion(flattenForSlowMotion) .setFlattenForSlowMotion(flattenForSlowMotion)
.setEffects(new Effects(audioProcessors, videoEffects, videoFrameProcessorFactory)) .setEffects(new Effects(audioProcessors, videoEffects))
.build(); .build();
start(editedMediaItem, path); start(editedMediaItem, path);
} }

View File

@ -43,6 +43,7 @@ import androidx.media3.common.DebugViewProvider;
import androidx.media3.common.Effect; import androidx.media3.common.Effect;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes; import androidx.media3.common.MimeTypes;
import androidx.media3.common.VideoFrameProcessor;
import androidx.media3.common.util.Clock; import androidx.media3.common.util.Clock;
import androidx.media3.common.util.ConditionVariable; import androidx.media3.common.util.ConditionVariable;
import androidx.media3.common.util.HandlerWrapper; import androidx.media3.common.util.HandlerWrapper;
@ -131,6 +132,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
String outputPath, String outputPath,
TransformationRequest transformationRequest, TransformationRequest transformationRequest,
AssetLoader.Factory assetLoaderFactory, AssetLoader.Factory assetLoaderFactory,
VideoFrameProcessor.Factory videoFrameProcessorFactory,
Codec.EncoderFactory encoderFactory, Codec.EncoderFactory encoderFactory,
Muxer.Factory muxerFactory, Muxer.Factory muxerFactory,
Listener listener, Listener listener,
@ -154,6 +156,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* sequenceIndex= */ i, /* sequenceIndex= */ i,
composition, composition,
transformationRequest, transformationRequest,
videoFrameProcessorFactory,
fallbackListener, fallbackListener,
debugViewProvider); debugViewProvider);
EditedMediaItemSequence sequence = composition.sequences.get(i); EditedMediaItemSequence sequence = composition.sequences.get(i);
@ -444,6 +447,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final ImmutableList<EditedMediaItem> editedMediaItems; private final ImmutableList<EditedMediaItem> editedMediaItems;
private final Composition composition; private final Composition composition;
private final TransformationRequest transformationRequest; private final TransformationRequest transformationRequest;
private final VideoFrameProcessor.Factory videoFrameProcessorFactory;
private final FallbackListener fallbackListener; private final FallbackListener fallbackListener;
private final DebugViewProvider debugViewProvider; private final DebugViewProvider debugViewProvider;
private final Map<Integer, AddedTrackInfo> addedTrackInfoByTrackType; private final Map<Integer, AddedTrackInfo> addedTrackInfoByTrackType;
@ -454,12 +458,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
int sequenceIndex, int sequenceIndex,
Composition composition, Composition composition,
TransformationRequest transformationRequest, TransformationRequest transformationRequest,
VideoFrameProcessor.Factory videoFrameProcessorFactory,
FallbackListener fallbackListener, FallbackListener fallbackListener,
DebugViewProvider debugViewProvider) { DebugViewProvider debugViewProvider) {
this.sequenceIndex = sequenceIndex; this.sequenceIndex = sequenceIndex;
editedMediaItems = composition.sequences.get(sequenceIndex).editedMediaItems; editedMediaItems = composition.sequences.get(sequenceIndex).editedMediaItems;
this.composition = composition; this.composition = composition;
this.transformationRequest = transformationRequest; this.transformationRequest = transformationRequest;
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
this.fallbackListener = fallbackListener; this.fallbackListener = fallbackListener;
this.debugViewProvider = debugViewProvider; this.debugViewProvider = debugViewProvider;
addedTrackInfoByTrackType = new HashMap<>(); addedTrackInfoByTrackType = new HashMap<>();
@ -565,7 +571,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
transformationRequest, transformationRequest,
firstEditedMediaItem.effects.videoEffects, firstEditedMediaItem.effects.videoEffects,
compositionPresentation, compositionPresentation,
firstEditedMediaItem.effects.videoFrameProcessorFactory, videoFrameProcessorFactory,
encoderFactory, encoderFactory,
muxerWrapper, muxerWrapper,
/* errorConsumer= */ this::onError, /* errorConsumer= */ this::onError,

View File

@ -134,14 +134,14 @@ public class TextureAssetLoaderTest {
private static final class FakeSampleConsumer implements SampleConsumer { private static final class FakeSampleConsumer implements SampleConsumer {
@Override
public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {}
@Override @Override
public boolean queueInputTexture(int texId, long presentationTimeUs) { public boolean queueInputTexture(int texId, long presentationTimeUs) {
return true; return true;
} }
@Override
public void setOnInputFrameProcessedListener(OnInputFrameProcessedListener listener) {}
@Override @Override
public void signalEndOfVideoInput() {} public void signalEndOfVideoInput() {}
} }