From aa72b45cdf6de1f8400ec772275de25c46e6754a Mon Sep 17 00:00:00 2001 From: kimvde Date: Wed, 18 Jan 2023 16:53:05 +0000 Subject: [PATCH] Make startTransformation methods take an EditedMediaItem Usages of the deprecated methods in Transformer.Builder will be removed in a follow-up CL. PiperOrigin-RevId: 502889423 --- .../media3/transformer/Transformer.java | 98 ++++++++++--------- .../transformer/TransformerInternal.java | 29 ++---- 2 files changed, 62 insertions(+), 65 deletions(-) diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java index 25ec93ef22..c2a605661d 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java @@ -40,9 +40,7 @@ import androidx.media3.common.util.HandlerWrapper; import androidx.media3.common.util.ListenerSet; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; -import androidx.media3.effect.GlEffect; import androidx.media3.effect.GlEffectsFrameProcessor; -import androidx.media3.effect.GlMatrixTransformation; import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.extractor.DefaultExtractorsFactory; @@ -153,34 +151,24 @@ public final class Transformer { } /** - * Sets the {@link AudioProcessor} instances to apply to audio buffers. - * - *

The {@link AudioProcessor} instances are applied in the order of the list, and buffers - * will only be modified by that {@link AudioProcessor} if it {@link AudioProcessor#isActive()} - * based on the current configuration. + * @deprecated Set the {@linkplain AudioProcessor audio processors} in an {@link + * EditedMediaItem}, and pass it to {@link #startTransformation(EditedMediaItem, String)} or + * {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead. */ @CanIgnoreReturnValue + @Deprecated public Builder setAudioProcessors(List audioProcessors) { this.audioProcessors = ImmutableList.copyOf(audioProcessors); return this; } /** - * Sets the {@link Effect} instances to apply to each video frame. - * - *

The {@link Effect} instances are applied before any {@linkplain - * TransformationRequest.Builder#setResolution(int) resolution} change specified in the {@link - * #setTransformationRequest(TransformationRequest) TransformationRequest} but after {@linkplain - * TransformationRequest.Builder#setFlattenForSlowMotion(boolean) slow-motion flattening}. - * - *

The default {@link FrameProcessor} only supports {@link GlEffect} instances. To use other - * effects, call {@link #setFrameProcessorFactory(FrameProcessor.Factory)} with a custom {@link - * FrameProcessor.Factory}. - * - * @param effects The {@link Effect} instances to apply to each video frame. - * @return This builder. + * @deprecated Set the {@linkplain Effect video effects} in an {@link EditedMediaItem}, and pass + * it to {@link #startTransformation(EditedMediaItem, String)} or {@link + * #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead. */ @CanIgnoreReturnValue + @Deprecated public Builder setVideoEffects(List effects) { this.videoEffects = ImmutableList.copyOf(effects); return this; @@ -301,20 +289,12 @@ public final class Transformer { } /** - * Sets the {@link FrameProcessor.Factory} for the {@link FrameProcessor} to use when applying - * {@linkplain Effect effects} to the video frames. - * - *

This factory will be used to create the {@link FrameProcessor} used for applying the - * {@link Effect} instances passed to {@link #setVideoEffects(List)} and any additional {@link - * GlMatrixTransformation} instances derived from the {@link TransformationRequest} set using - * {@link #setTransformationRequest(TransformationRequest)}. - * - *

The default is {@link GlEffectsFrameProcessor.Factory}. - * - * @param frameProcessorFactory The {@link FrameProcessor.Factory} to use. - * @return This builder. + * @deprecated Set the {@link FrameProcessor.Factory} in an {@link EditedMediaItem}, and pass it + * to {@link #startTransformation(EditedMediaItem, String)} or {@link + * #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead. */ @CanIgnoreReturnValue + @Deprecated public Builder setFrameProcessorFactory(FrameProcessor.Factory frameProcessorFactory) { this.frameProcessorFactory = frameProcessorFactory; return this; @@ -412,11 +392,13 @@ public final class Transformer { *

  • Duration will match duration of the input media. *
  • Sample mime type will match {@link TransformationRequest#audioMimeType}, or {@link * MimeTypes#AUDIO_AAC} if {@code null}. - *
  • Sample rate will be {@code 44100} hz. This can be modified by passing a {@link - * SonicAudioProcessor} to {@link #setAudioProcessors(List)}, using {@link - * SonicAudioProcessor#setOutputSampleRateHz(int)}. + *
  • Sample rate will be {@code 44100} hz. This can be modified by creating a {@link + * SonicAudioProcessor}, setting its {@linkplain + * SonicAudioProcessor#setOutputSampleRateHz(int) sample rate}, and passing it to the + * {@link EditedMediaItem} used to start the transformation. *
  • Channel count will be {@code 2}. This can be modified by implementing a custom {@link - * AudioProcessor} and passing it to {@link #setAudioProcessors(List)}. + * AudioProcessor} and passing it to the {@link EditedMediaItem} used to start the + * transformation. * * * @param generateSilentAudio Whether to generate silent audio for the output file if there is @@ -690,15 +672,16 @@ public final class Transformer { * ignored. For adaptive bitrate, if no custom {@link AssetLoader.Factory} is specified, the * highest bitrate video and audio streams are selected. * - * @param mediaItem The {@link MediaItem} to transform. + * @param editedMediaItem The {@link MediaItem} to transform, with the transformations to apply to + * it. * @param path The path to the output file. * @throws IllegalArgumentException If the path is invalid. * @throws IllegalArgumentException If the {@link MediaItem} is not supported. * @throws IllegalStateException If this method is called from the wrong thread. * @throws IllegalStateException If a transformation is already in progress. */ - public void startTransformation(MediaItem mediaItem, String path) { - startTransformationInternal(mediaItem, path, /* parcelFileDescriptor= */ null); + public void startTransformation(EditedMediaItem editedMediaItem, String path) { + startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null); } /** @@ -715,7 +698,8 @@ public final class Transformer { * ignored. For adaptive bitrate, if no custom {@link AssetLoader.Factory} is specified, the * highest bitrate video and audio streams are selected. * - * @param mediaItem The {@link MediaItem} to transform. + * @param editedMediaItem The {@link MediaItem} to transform, with the transformations to apply to + * it. * @param parcelFileDescriptor A readable and writable {@link ParcelFileDescriptor} of the output. * The file referenced by this ParcelFileDescriptor should not be used before the * transformation is completed. It is the responsibility of the caller to close the @@ -726,14 +710,39 @@ public final class Transformer { * @throws IllegalStateException If a transformation is already in progress. */ @RequiresApi(26) + public void startTransformation( + EditedMediaItem editedMediaItem, ParcelFileDescriptor parcelFileDescriptor) { + startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor); + } + + /** + * @deprecated Use {@link #startTransformation(EditedMediaItem, String)} instead. + */ + @Deprecated + public void startTransformation(MediaItem mediaItem, String path) { + EditedMediaItem editedMediaItem = + new EditedMediaItem( + mediaItem, new Effects(audioProcessors, videoEffects, frameProcessorFactory)); + startTransformationInternal(editedMediaItem, path, /* parcelFileDescriptor= */ null); + } + + /** + * @deprecated Use {@link #startTransformation(EditedMediaItem, ParcelFileDescriptor)} instead. + */ + @Deprecated + @RequiresApi(26) public void startTransformation(MediaItem mediaItem, ParcelFileDescriptor parcelFileDescriptor) { - startTransformationInternal(mediaItem, /* path= */ null, parcelFileDescriptor); + EditedMediaItem editedMediaItem = + new EditedMediaItem( + mediaItem, new Effects(audioProcessors, videoEffects, frameProcessorFactory)); + startTransformationInternal(editedMediaItem, /* path= */ null, parcelFileDescriptor); } private void startTransformationInternal( - MediaItem mediaItem, + EditedMediaItem editedMediaItem, @Nullable String path, @Nullable ParcelFileDescriptor parcelFileDescriptor) { + MediaItem mediaItem = editedMediaItem.mediaItem; if (!mediaItem.clippingConfiguration.equals(MediaItem.ClippingConfiguration.UNSET) && transformationRequest.flattenForSlowMotion) { // TODO(b/233986762): Support clipping with SEF flattening. @@ -752,17 +761,14 @@ public final class Transformer { transformerInternal = new TransformerInternal( context, - mediaItem, + editedMediaItem, path, parcelFileDescriptor, transformationRequest, - audioProcessors, - videoEffects, removeAudio, removeVideo, generateSilentAudio, assetLoaderFactory, - frameProcessorFactory, encoderFactory, muxerFactory, transformerInternalListener, diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java index 215317d711..029682adaa 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java @@ -35,11 +35,9 @@ import androidx.media3.common.C; import androidx.media3.common.DebugViewProvider; import androidx.media3.common.Effect; import androidx.media3.common.Format; -import androidx.media3.common.FrameProcessor; import androidx.media3.common.MediaItem; import androidx.media3.common.Metadata; import androidx.media3.common.MimeTypes; -import androidx.media3.common.audio.AudioProcessor; import androidx.media3.common.util.Clock; import androidx.media3.common.util.ConditionVariable; import androidx.media3.common.util.HandlerWrapper; @@ -47,7 +45,6 @@ import androidx.media3.common.util.Size; import androidx.media3.effect.Presentation; import androidx.media3.effect.ScaleToFitTransformation; import androidx.media3.extractor.metadata.mp4.SlowMotionData; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -94,9 +91,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final Context context; private final TransformationRequest transformationRequest; - private final ImmutableList audioProcessors; - private final ImmutableList videoEffects; - private final FrameProcessor.Factory frameProcessorFactory; private final CapturingEncoderFactory encoderFactory; private final Listener listener; private final HandlerWrapper applicationHandler; @@ -105,6 +99,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final HandlerThread internalHandlerThread; private final HandlerWrapper internalHandler; private final AssetLoader assetLoader; + private final Effects effects; private final List samplePipelines; private final MuxerWrapper muxerWrapper; private final ConditionVariable transformerConditionVariable; @@ -119,17 +114,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; public TransformerInternal( Context context, - MediaItem mediaItem, + EditedMediaItem editedMediaItem, @Nullable String outputPath, @Nullable ParcelFileDescriptor outputParcelFileDescriptor, TransformationRequest transformationRequest, - ImmutableList audioProcessors, - ImmutableList videoEffects, boolean removeAudio, boolean removeVideo, boolean generateSilentAudio, AssetLoader.Factory assetLoaderFactory, - FrameProcessor.Factory frameProcessorFactory, Codec.EncoderFactory encoderFactory, Muxer.Factory muxerFactory, Listener listener, @@ -139,10 +131,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; Clock clock) { this.context = context; this.transformationRequest = transformationRequest; - this.audioProcessors = audioProcessors; - this.videoEffects = videoEffects; this.generateSilentAudio = generateSilentAudio; - this.frameProcessorFactory = frameProcessorFactory; this.encoderFactory = new CapturingEncoderFactory(encoderFactory); this.listener = listener; this.applicationHandler = applicationHandler; @@ -151,6 +140,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; internalHandlerThread = new HandlerThread("Transformer:Internal"); internalHandlerThread.start(); Looper internalLooper = internalHandlerThread.getLooper(); + MediaItem mediaItem = editedMediaItem.mediaItem; ComponentListener componentListener = new ComponentListener(mediaItem, fallbackListener); assetLoader = assetLoaderFactory @@ -158,6 +148,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; .setRemoveVideo(removeVideo) .setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion) .createAssetLoader(mediaItem, internalLooper, componentListener); + effects = editedMediaItem.effects; samplePipelines = new ArrayList<>(); muxerWrapper = new MuxerWrapper(outputPath, outputParcelFileDescriptor, muxerFactory, componentListener); @@ -490,7 +481,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; streamStartPositionUs, streamOffsetUs, transformationRequest, - audioProcessors, + effects.audioProcessors, generateSilentAudio ? durationUs : C.TIME_UNSET, encoderFactory, muxerWrapper, @@ -502,8 +493,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; streamStartPositionUs, streamOffsetUs, transformationRequest, - videoEffects, - frameProcessorFactory, + effects.videoEffects, + effects.frameProcessorFactory, encoderFactory, muxerWrapper, /* errorConsumer= */ this::onTransformationError, @@ -534,7 +525,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; if (transformationRequest.flattenForSlowMotion && isSlowMotion(inputFormat)) { return true; } - if (!audioProcessors.isEmpty()) { + if (!effects.audioProcessors.isEmpty()) { return true; } if (generateSilentAudio) { @@ -582,8 +573,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } // TODO(b/265927935): consider generalizing this logic. - for (int i = 0; i < videoEffects.size(); i++) { - Effect videoEffect = videoEffects.get(i); + for (int i = 0; i < effects.videoEffects.size(); i++) { + Effect videoEffect = effects.videoEffects.get(i); if (videoEffect instanceof Presentation) { Presentation presentation = (Presentation) videoEffect; // The decoder rotates encoded frames for display by inputFormat.rotationDegrees.