Move glObjectsProvider to DefaultVideoFrameProcessor.Factory.Builder
Removes glObjectsProvider from `VideoFrameProcessor` and `Effects`. Apps will set the glObjectsProvider on the DefaultVideoFrameProcessor.Factory.Builder when providing a custom DefaultVideoFrameProcessor.Factory, rather than in `Effects`. PiperOrigin-RevId: 525169059
This commit is contained in:
parent
fae8111f59
commit
9c3d30791a
@ -43,13 +43,6 @@ public interface VideoFrameProcessor {
|
||||
/** A factory for {@link VideoFrameProcessor} instances. */
|
||||
interface Factory {
|
||||
|
||||
/**
|
||||
* Sets the {@link GlObjectsProvider}.
|
||||
*
|
||||
* <p>Must be called before {@link #create}.
|
||||
*/
|
||||
Factory setGlObjectsProvider(GlObjectsProvider glObjectsProvider);
|
||||
|
||||
// TODO(271433904): Turn parameters with default values into setters.
|
||||
/**
|
||||
* Creates a new {@link VideoFrameProcessor} instance.
|
||||
|
@ -78,11 +78,13 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
/** A builder for {@link DefaultVideoFrameProcessor.Factory} instances. */
|
||||
public static final class Builder {
|
||||
private boolean enableColorTransfers;
|
||||
private GlObjectsProvider glObjectsProvider;
|
||||
@Nullable private TextureOutputListener textureOutputListener;
|
||||
|
||||
/** Creates an instance. */
|
||||
public Builder() {
|
||||
enableColorTransfers = true;
|
||||
glObjectsProvider = GlObjectsProvider.DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,6 +98,17 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link GlObjectsProvider}.
|
||||
*
|
||||
* <p>The default value is {@link GlObjectsProvider#DEFAULT}.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Builder setGlObjectsProvider(GlObjectsProvider glObjectsProvider) {
|
||||
this.glObjectsProvider = glObjectsProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TextureOutputListener}.
|
||||
*
|
||||
@ -111,20 +124,23 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
|
||||
/** Builds an {@link DefaultVideoFrameProcessor.Factory} instance. */
|
||||
public DefaultVideoFrameProcessor.Factory build() {
|
||||
return new DefaultVideoFrameProcessor.Factory(enableColorTransfers, textureOutputListener);
|
||||
return new DefaultVideoFrameProcessor.Factory(
|
||||
enableColorTransfers, glObjectsProvider, textureOutputListener);
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean enableColorTransfers;
|
||||
|
||||
private final GlObjectsProvider glObjectsProvider;
|
||||
@Nullable private final TextureOutputListener textureOutputListener;
|
||||
|
||||
private GlObjectsProvider glObjectsProvider = GlObjectsProvider.DEFAULT;
|
||||
|
||||
private Factory(
|
||||
boolean enableColorTransfers, @Nullable TextureOutputListener textureOutputListener) {
|
||||
this.textureOutputListener = textureOutputListener;
|
||||
boolean enableColorTransfers,
|
||||
GlObjectsProvider glObjectsProvider,
|
||||
@Nullable TextureOutputListener textureOutputListener) {
|
||||
this.enableColorTransfers = enableColorTransfers;
|
||||
this.glObjectsProvider = glObjectsProvider;
|
||||
this.textureOutputListener = textureOutputListener;
|
||||
}
|
||||
|
||||
// TODO(276913828): Remove and change all calls to a builder.
|
||||
@ -133,19 +149,10 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
||||
*/
|
||||
@Deprecated
|
||||
public Factory() {
|
||||
this(/* enableColorTransfers= */ true, /* textureOutputListener= */ null);
|
||||
}
|
||||
|
||||
// TODO(276913828): Move this setter to the DefaultVideoFrameProcessor.Factory.Builder.
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default value is {@link GlObjectsProvider#DEFAULT}.
|
||||
*/
|
||||
@Override
|
||||
public Factory setGlObjectsProvider(GlObjectsProvider glObjectsProvider) {
|
||||
this.glObjectsProvider = glObjectsProvider;
|
||||
return this;
|
||||
this(
|
||||
/* enableColorTransfers= */ true,
|
||||
GlObjectsProvider.DEFAULT,
|
||||
/* textureOutputListener= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,6 @@
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import androidx.media3.common.Effect;
|
||||
import androidx.media3.common.GlObjectsProvider;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.VideoFrameProcessor;
|
||||
import androidx.media3.common.audio.AudioProcessor;
|
||||
@ -50,25 +49,15 @@ public final class Effects {
|
||||
* applying the {@code videoEffects} to the video frames.
|
||||
*/
|
||||
public final VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
/**
|
||||
* The {@link GlObjectsProvider} used to create and maintain certain GL Objects in the {@link
|
||||
* VideoFrameProcessor}.
|
||||
*/
|
||||
public final GlObjectsProvider glObjectsProvider;
|
||||
|
||||
/**
|
||||
* Creates an instance using a {@link DefaultVideoFrameProcessor.Factory}.
|
||||
*
|
||||
* <p>This is equivalent to calling {@link Effects#Effects(List, List,
|
||||
* VideoFrameProcessor.Factory, GlObjectsProvider)} with a {@link
|
||||
* DefaultVideoFrameProcessor.Factory} and {@link GlObjectsProvider#DEFAULT}.
|
||||
* VideoFrameProcessor.Factory)} with a {@link DefaultVideoFrameProcessor.Factory}.
|
||||
*/
|
||||
public Effects(List<AudioProcessor> audioProcessors, List<Effect> videoEffects) {
|
||||
this(
|
||||
audioProcessors,
|
||||
videoEffects,
|
||||
new DefaultVideoFrameProcessor.Factory(),
|
||||
GlObjectsProvider.DEFAULT);
|
||||
this(audioProcessors, videoEffects, new DefaultVideoFrameProcessor.Factory.Builder().build());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,16 +66,13 @@ public final class Effects {
|
||||
* @param audioProcessors The {@link #audioProcessors}.
|
||||
* @param videoEffects The {@link #videoEffects}.
|
||||
* @param videoFrameProcessorFactory The {@link #videoFrameProcessorFactory}.
|
||||
* @param glObjectsProvider The {@link GlObjectsProvider}.
|
||||
*/
|
||||
public Effects(
|
||||
List<AudioProcessor> audioProcessors,
|
||||
List<Effect> videoEffects,
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||
GlObjectsProvider glObjectsProvider) {
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory) {
|
||||
this.audioProcessors = ImmutableList.copyOf(audioProcessors);
|
||||
this.videoEffects = ImmutableList.copyOf(videoEffects);
|
||||
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
|
||||
this.glObjectsProvider = glObjectsProvider;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import androidx.annotation.VisibleForTesting;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.DebugViewProvider;
|
||||
import androidx.media3.common.Effect;
|
||||
import androidx.media3.common.GlObjectsProvider;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaLibraryInfo;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
@ -89,7 +88,6 @@ public final class Transformer {
|
||||
private ListenerSet<Transformer.Listener> listeners;
|
||||
private AssetLoader.@MonotonicNonNull Factory assetLoaderFactory;
|
||||
private VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
private GlObjectsProvider glObjectsProvider;
|
||||
private Codec.EncoderFactory encoderFactory;
|
||||
private Muxer.Factory muxerFactory;
|
||||
private Looper looper;
|
||||
@ -106,8 +104,7 @@ public final class Transformer {
|
||||
transformationRequest = new TransformationRequest.Builder().build();
|
||||
audioProcessors = ImmutableList.of();
|
||||
videoEffects = ImmutableList.of();
|
||||
videoFrameProcessorFactory = new DefaultVideoFrameProcessor.Factory();
|
||||
glObjectsProvider = GlObjectsProvider.DEFAULT;
|
||||
videoFrameProcessorFactory = new DefaultVideoFrameProcessor.Factory.Builder().build();
|
||||
encoderFactory = new DefaultEncoderFactory.Builder(this.context).build();
|
||||
muxerFactory = new DefaultMuxer.Factory();
|
||||
looper = Util.getCurrentOrMainLooper();
|
||||
@ -127,7 +124,6 @@ public final class Transformer {
|
||||
this.listeners = transformer.listeners;
|
||||
this.assetLoaderFactory = transformer.assetLoaderFactory;
|
||||
this.videoFrameProcessorFactory = transformer.videoFrameProcessorFactory;
|
||||
this.glObjectsProvider = transformer.glObjectsProvider;
|
||||
this.encoderFactory = transformer.encoderFactory;
|
||||
this.muxerFactory = transformer.muxerFactory;
|
||||
this.looper = transformer.looper;
|
||||
@ -401,7 +397,6 @@ public final class Transformer {
|
||||
listeners,
|
||||
assetLoaderFactory,
|
||||
videoFrameProcessorFactory,
|
||||
glObjectsProvider,
|
||||
encoderFactory,
|
||||
muxerFactory,
|
||||
looper,
|
||||
@ -566,7 +561,6 @@ public final class Transformer {
|
||||
private final ListenerSet<Transformer.Listener> listeners;
|
||||
private final AssetLoader.Factory assetLoaderFactory;
|
||||
private final VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
private final GlObjectsProvider glObjectsProvider;
|
||||
private final Codec.EncoderFactory encoderFactory;
|
||||
private final Muxer.Factory muxerFactory;
|
||||
private final Looper looper;
|
||||
@ -586,7 +580,6 @@ public final class Transformer {
|
||||
ListenerSet<Listener> listeners,
|
||||
AssetLoader.Factory assetLoaderFactory,
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||
GlObjectsProvider glObjectsProvider,
|
||||
Codec.EncoderFactory encoderFactory,
|
||||
Muxer.Factory muxerFactory,
|
||||
Looper looper,
|
||||
@ -603,7 +596,6 @@ public final class Transformer {
|
||||
this.listeners = listeners;
|
||||
this.assetLoaderFactory = assetLoaderFactory;
|
||||
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
|
||||
this.glObjectsProvider = glObjectsProvider;
|
||||
this.encoderFactory = encoderFactory;
|
||||
this.muxerFactory = muxerFactory;
|
||||
this.looper = looper;
|
||||
@ -805,9 +797,7 @@ public final class Transformer {
|
||||
.setRemoveAudio(removeAudio)
|
||||
.setRemoveVideo(removeVideo)
|
||||
.setFlattenForSlowMotion(flattenForSlowMotion)
|
||||
.setEffects(
|
||||
new Effects(
|
||||
audioProcessors, videoEffects, videoFrameProcessorFactory, glObjectsProvider))
|
||||
.setEffects(new Effects(audioProcessors, videoEffects, videoFrameProcessorFactory))
|
||||
.build();
|
||||
start(editedMediaItem, path);
|
||||
}
|
||||
|
@ -566,7 +566,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
firstEditedMediaItem.effects.videoEffects,
|
||||
compositionPresentation,
|
||||
firstEditedMediaItem.effects.videoFrameProcessorFactory,
|
||||
firstEditedMediaItem.effects.glObjectsProvider,
|
||||
encoderFactory,
|
||||
muxerWrapper,
|
||||
/* errorConsumer= */ this::onError,
|
||||
|
@ -35,7 +35,6 @@ import androidx.media3.common.DebugViewProvider;
|
||||
import androidx.media3.common.Effect;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.FrameInfo;
|
||||
import androidx.media3.common.GlObjectsProvider;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.SurfaceInfo;
|
||||
import androidx.media3.common.VideoFrameProcessingException;
|
||||
@ -81,7 +80,6 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
ImmutableList<Effect> effects,
|
||||
@Nullable Presentation presentation,
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||
GlObjectsProvider glObjectsProvider,
|
||||
Codec.EncoderFactory encoderFactory,
|
||||
MuxerWrapper muxerWrapper,
|
||||
Consumer<ExportException> errorConsumer,
|
||||
@ -132,57 +130,55 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
}
|
||||
try {
|
||||
videoFrameProcessor =
|
||||
videoFrameProcessorFactory
|
||||
.setGlObjectsProvider(glObjectsProvider)
|
||||
.create(
|
||||
context,
|
||||
effectsWithPresentation,
|
||||
debugViewProvider,
|
||||
videoFrameProcessorInputColor,
|
||||
videoFrameProcessorOutputColor,
|
||||
MimeTypes.isVideo(firstInputFormat.sampleMimeType),
|
||||
/* releaseFramesAutomatically= */ true,
|
||||
MoreExecutors.directExecutor(),
|
||||
new VideoFrameProcessor.Listener() {
|
||||
private long lastProcessedFramePresentationTimeUs;
|
||||
videoFrameProcessorFactory.create(
|
||||
context,
|
||||
effectsWithPresentation,
|
||||
debugViewProvider,
|
||||
videoFrameProcessorInputColor,
|
||||
videoFrameProcessorOutputColor,
|
||||
MimeTypes.isVideo(firstInputFormat.sampleMimeType),
|
||||
/* releaseFramesAutomatically= */ true,
|
||||
MoreExecutors.directExecutor(),
|
||||
new VideoFrameProcessor.Listener() {
|
||||
private long lastProcessedFramePresentationTimeUs;
|
||||
|
||||
@Override
|
||||
public void onOutputSizeChanged(int width, int height) {
|
||||
try {
|
||||
checkNotNull(videoFrameProcessor)
|
||||
.setOutputSurfaceInfo(encoderWrapper.getSurfaceInfo(width, height));
|
||||
} catch (ExportException exception) {
|
||||
errorConsumer.accept(exception);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onOutputSizeChanged(int width, int height) {
|
||||
try {
|
||||
checkNotNull(videoFrameProcessor)
|
||||
.setOutputSurfaceInfo(encoderWrapper.getSurfaceInfo(width, height));
|
||||
} catch (ExportException exception) {
|
||||
errorConsumer.accept(exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOutputFrameAvailable(long presentationTimeUs) {
|
||||
// Frames are released automatically.
|
||||
if (presentationTimeUs == 0) {
|
||||
encoderExpectsTimestampZero = true;
|
||||
}
|
||||
lastProcessedFramePresentationTimeUs = presentationTimeUs;
|
||||
}
|
||||
@Override
|
||||
public void onOutputFrameAvailable(long presentationTimeUs) {
|
||||
// Frames are released automatically.
|
||||
if (presentationTimeUs == 0) {
|
||||
encoderExpectsTimestampZero = true;
|
||||
}
|
||||
lastProcessedFramePresentationTimeUs = presentationTimeUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VideoFrameProcessingException exception) {
|
||||
errorConsumer.accept(
|
||||
ExportException.createForVideoFrameProcessingException(
|
||||
exception, ExportException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED));
|
||||
}
|
||||
@Override
|
||||
public void onError(VideoFrameProcessingException exception) {
|
||||
errorConsumer.accept(
|
||||
ExportException.createForVideoFrameProcessingException(
|
||||
exception, ExportException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnded() {
|
||||
VideoSamplePipeline.this.finalFramePresentationTimeUs =
|
||||
lastProcessedFramePresentationTimeUs;
|
||||
try {
|
||||
encoderWrapper.signalEndOfInputStream();
|
||||
} catch (ExportException exception) {
|
||||
errorConsumer.accept(exception);
|
||||
}
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void onEnded() {
|
||||
VideoSamplePipeline.this.finalFramePresentationTimeUs =
|
||||
lastProcessedFramePresentationTimeUs;
|
||||
try {
|
||||
encoderWrapper.signalEndOfInputStream();
|
||||
} catch (ExportException exception) {
|
||||
errorConsumer.accept(exception);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (VideoFrameProcessingException e) {
|
||||
throw ExportException.createForVideoFrameProcessingException(
|
||||
e, ExportException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED);
|
||||
|
Loading…
x
Reference in New Issue
Block a user