From bbffa8ae2767debb4b0846d1992286d832e46e71 Mon Sep 17 00:00:00 2001 From: kimvde Date: Wed, 11 Jan 2023 12:27:33 +0000 Subject: [PATCH] Remove setDecoderFactory from Transformer It makes more sense to have it in the AssetLoader now that decoding is done there, particularly as the decoder factory should rarely be customized. Also remove the setter from the AssetLoader.Factory because it's uncommon to have setters in a factory. PiperOrigin-RevId: 501244974 --- .../exoplayer2/transformer/AssetLoader.java | 13 +++- .../DefaultAssetLoaderFactory.java | 16 ++-- .../transformer/ExoPlayerAssetLoader.java | 42 +++++++---- .../exoplayer2/transformer/Transformer.java | 73 +++++++------------ .../transformer/TransformerInternal.java | 16 ++-- .../transformer/ExoPlayerAssetLoaderTest.java | 4 +- .../transformer/TransformerEndToEndTest.java | 14 ++-- 7 files changed, 89 insertions(+), 89 deletions(-) diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java index d6a5b5e132..d1b6893c0e 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AssetLoader.java @@ -23,6 +23,7 @@ import androidx.annotation.IntDef; import androidx.annotation.IntRange; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.MediaItem; +import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -78,10 +79,6 @@ public interface AssetLoader { @CanIgnoreReturnValue Factory setFlattenVideoForSlowMotion(boolean flattenVideoForSlowMotion); - /** Sets the {@link Codec.DecoderFactory} to be used to decode the samples (if necessary). */ - @CanIgnoreReturnValue - Factory setDecoderFactory(Codec.DecoderFactory decoderFactory); - /** * Creates an {@link AssetLoader} instance. All the setters in this factory must be called * before creating the {@link AssetLoader}. @@ -176,6 +173,14 @@ public interface AssetLoader { @Transformer.ProgressState int getProgress(ProgressHolder progressHolder); + /** + * Return the used decoders' names. + * + * @return The decoders' names keyed by {@linkplain com.google.android.exoplayer2.C.TrackType + * track type}. + */ + ImmutableMap getDecoderNames(); + /** Stops loading data and releases all resources associated with the asset loader. */ void release(); } diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java index 10aed52478..6f36bfa81c 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/DefaultAssetLoaderFactory.java @@ -34,12 +34,18 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { * @param context The {@link Context}. * @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to * transform when an {@link ExoPlayerAssetLoader} is used. + * @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if + * necessary). * @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for * testing. */ public DefaultAssetLoaderFactory( - Context context, MediaSource.Factory mediaSourceFactory, Clock clock) { - assetLoaderFactory = new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock); + Context context, + MediaSource.Factory mediaSourceFactory, + Codec.DecoderFactory decoderFactory, + Clock clock) { + assetLoaderFactory = + new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, decoderFactory, clock); } @Override @@ -61,12 +67,6 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory { return this; } - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) { - return assetLoaderFactory.setDecoderFactory(decoderFactory); - } - @Override public AssetLoader createAssetLoader( MediaItem mediaItem, Looper looper, AssetLoader.Listener listener) { diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java index 72a8f19f80..db1883cba0 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoader.java @@ -27,7 +27,6 @@ import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STA import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_UNAVAILABLE; import static com.google.android.exoplayer2.transformer.Transformer.PROGRESS_STATE_WAITING_FOR_AVAILABILITY; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; -import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull; import static java.lang.Math.min; import android.content.Context; @@ -51,6 +50,7 @@ import com.google.android.exoplayer2.text.TextOutput; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.video.VideoRendererEventListener; +import com.google.common.collect.ImmutableMap; import com.google.errorprone.annotations.CanIgnoreReturnValue; /** An {@link AssetLoader} implementation that uses an {@link ExoPlayer} to load samples. */ @@ -61,12 +61,12 @@ public final class ExoPlayerAssetLoader implements AssetLoader { private final Context context; private final MediaSource.Factory mediaSourceFactory; + private final Codec.DecoderFactory decoderFactory; private final Clock clock; private boolean removeAudio; private boolean removeVideo; private boolean flattenVideoForSlowMotion; - @Nullable private Codec.DecoderFactory decoderFactory; /** * Creates an instance. @@ -74,12 +74,19 @@ public final class ExoPlayerAssetLoader implements AssetLoader { * @param context The {@link Context}. * @param mediaSourceFactory The {@link MediaSource.Factory} to use to retrieve the samples to * transform. + * @param decoderFactory The {@link Codec.DecoderFactory} to use to decode the samples (if + * necessary). * @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for * testing. */ - public Factory(Context context, MediaSource.Factory mediaSourceFactory, Clock clock) { + public Factory( + Context context, + MediaSource.Factory mediaSourceFactory, + Codec.DecoderFactory decoderFactory, + Clock clock) { this.context = context; this.mediaSourceFactory = mediaSourceFactory; + this.decoderFactory = decoderFactory; this.clock = clock; } @@ -104,13 +111,6 @@ public final class ExoPlayerAssetLoader implements AssetLoader { return this; } - @Override - @CanIgnoreReturnValue - public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) { - this.decoderFactory = decoderFactory; - return this; - } - @Override public AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener) { return new ExoPlayerAssetLoader( @@ -120,7 +120,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader { removeVideo, flattenVideoForSlowMotion, mediaSourceFactory, - checkStateNotNull(decoderFactory), + decoderFactory, looper, listener, clock); @@ -128,6 +128,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader { } private final MediaItem mediaItem; + private final CapturingDecoderFactory decoderFactory; private final ExoPlayer player; private @Transformer.ProgressState int progressState; @@ -144,6 +145,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader { Listener listener, Clock clock) { this.mediaItem = mediaItem; + this.decoderFactory = new CapturingDecoderFactory(decoderFactory); + DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); trackSelector.setParameters( new DefaultTrackSelector.Parameters.Builder(context) @@ -163,7 +166,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader { new ExoPlayer.Builder( context, new RenderersFactoryImpl( - removeAudio, removeVideo, flattenForSlowMotion, decoderFactory, listener)) + removeAudio, removeVideo, flattenForSlowMotion, this.decoderFactory, listener)) .setMediaSourceFactory(mediaSourceFactory) .setTrackSelector(trackSelector) .setLoadControl(loadControl) @@ -174,7 +177,6 @@ public final class ExoPlayerAssetLoader implements AssetLoader { @SuppressWarnings("VisibleForTests") ExoPlayer.Builder unusedForAnnotation = playerBuilder.setClock(clock); } - player = playerBuilder.build(); player.addListener(new PlayerListener(listener)); @@ -198,6 +200,20 @@ public final class ExoPlayerAssetLoader implements AssetLoader { return progressState; } + @Override + public ImmutableMap getDecoderNames() { + ImmutableMap.Builder decoderNamesByTrackType = new ImmutableMap.Builder<>(); + @Nullable String audioDecoderName = decoderFactory.getAudioDecoderName(); + if (audioDecoderName != null) { + decoderNamesByTrackType.put(C.TRACK_TYPE_AUDIO, audioDecoderName); + } + @Nullable String videoDecoderName = decoderFactory.getVideoDecoderName(); + if (videoDecoderName != null) { + decoderNamesByTrackType.put(C.TRACK_TYPE_VIDEO, videoDecoderName); + } + return decoderNamesByTrackType.buildOrThrow(); + } + @Override public void release() { player.release(); diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java index 05733563b2..428b209f94 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/Transformer.java @@ -89,9 +89,8 @@ public final class Transformer { private boolean forceSilentAudio; private ListenerSet listeners; @Nullable private AssetLoader.Factory assetLoaderFactory; - private Codec.DecoderFactory decoderFactory; - private Codec.EncoderFactory encoderFactory; private FrameProcessor.Factory frameProcessorFactory; + private Codec.EncoderFactory encoderFactory; private Muxer.Factory muxerFactory; private Looper looper; private DebugViewProvider debugViewProvider; @@ -107,9 +106,8 @@ public final class Transformer { transformationRequest = new TransformationRequest.Builder().build(); audioProcessors = ImmutableList.of(); videoEffects = ImmutableList.of(); - decoderFactory = new DefaultDecoderFactory(this.context); - encoderFactory = new DefaultEncoderFactory.Builder(this.context).build(); frameProcessorFactory = new GlEffectsFrameProcessor.Factory(); + encoderFactory = new DefaultEncoderFactory.Builder(this.context).build(); muxerFactory = new DefaultMuxer.Factory(); looper = Util.getCurrentOrMainLooper(); debugViewProvider = DebugViewProvider.NONE; @@ -128,9 +126,8 @@ public final class Transformer { this.forceSilentAudio = transformer.forceSilentAudio; this.listeners = transformer.listeners; this.assetLoaderFactory = transformer.assetLoaderFactory; - this.decoderFactory = transformer.decoderFactory; - this.encoderFactory = transformer.encoderFactory; this.frameProcessorFactory = transformer.frameProcessorFactory; + this.encoderFactory = transformer.encoderFactory; this.muxerFactory = transformer.muxerFactory; this.looper = transformer.looper; this.debugViewProvider = transformer.debugViewProvider; @@ -292,7 +289,7 @@ public final class Transformer { * Sets the {@link AssetLoader.Factory} to be used to retrieve the samples to transform. * *

The default value is a {@link DefaultAssetLoaderFactory} built with a {@link - * DefaultMediaSourceFactory}. + * DefaultMediaSourceFactory} and a {@link DefaultDecoderFactory}. * * @param assetLoaderFactory An {@link AssetLoader.Factory}. * @return This builder. @@ -303,34 +300,6 @@ public final class Transformer { return this; } - /** - * Sets the {@link Codec.DecoderFactory} that will be used by the transformer. - * - *

The default value is a {@link DefaultDecoderFactory} instance. - * - * @param decoderFactory The {@link Codec.DecoderFactory} instance. - * @return This builder. - */ - @CanIgnoreReturnValue - public Builder setDecoderFactory(Codec.DecoderFactory decoderFactory) { - this.decoderFactory = decoderFactory; - return this; - } - - /** - * Sets the {@link Codec.EncoderFactory} that will be used by the transformer. - * - *

The default value is a {@link DefaultEncoderFactory} instance. - * - * @param encoderFactory The {@link Codec.EncoderFactory} instance. - * @return This builder. - */ - @CanIgnoreReturnValue - public Builder setEncoderFactory(Codec.EncoderFactory encoderFactory) { - this.encoderFactory = encoderFactory; - return this; - } - /** * Sets the {@link FrameProcessor.Factory} for the {@link FrameProcessor} to use when applying * {@linkplain Effect effects} to the video frames. @@ -351,6 +320,20 @@ public final class Transformer { return this; } + /** + * Sets the {@link Codec.EncoderFactory} that will be used by the transformer. + * + *

The default value is a {@link DefaultEncoderFactory} instance. + * + * @param encoderFactory The {@link Codec.EncoderFactory} instance. + * @return This builder. + */ + @CanIgnoreReturnValue + public Builder setEncoderFactory(Codec.EncoderFactory encoderFactory) { + this.encoderFactory = encoderFactory; + return this; + } + /** * Sets the factory for muxers that write the media container. * @@ -465,7 +448,9 @@ public final class Transformer { } MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context, defaultExtractorsFactory); - assetLoaderFactory = new DefaultAssetLoaderFactory(context, mediaSourceFactory, clock); + Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context); + assetLoaderFactory = + new DefaultAssetLoaderFactory(context, mediaSourceFactory, decoderFactory, clock); } return new Transformer( context, @@ -477,9 +462,8 @@ public final class Transformer { forceSilentAudio, listeners, assetLoaderFactory, - decoderFactory, - encoderFactory, frameProcessorFactory, + encoderFactory, muxerFactory, looper, debugViewProvider, @@ -589,9 +573,6 @@ public final class Transformer { /** Indicates that the progress is permanently unavailable. */ public static final int PROGRESS_STATE_UNAVAILABLE = 3; - @VisibleForTesting /* package */ final Codec.DecoderFactory decoderFactory; - @VisibleForTesting /* package */ final Codec.EncoderFactory encoderFactory; - private final Context context; private final TransformationRequest transformationRequest; private final ImmutableList audioProcessors; @@ -602,6 +583,7 @@ public final class Transformer { private final ListenerSet listeners; private final AssetLoader.Factory assetLoaderFactory; private final FrameProcessor.Factory frameProcessorFactory; + private final Codec.EncoderFactory encoderFactory; private final Muxer.Factory muxerFactory; private final Looper looper; private final DebugViewProvider debugViewProvider; @@ -619,9 +601,8 @@ public final class Transformer { boolean forceSilentAudio, ListenerSet listeners, AssetLoader.Factory assetLoaderFactory, - Codec.DecoderFactory decoderFactory, - Codec.EncoderFactory encoderFactory, FrameProcessor.Factory frameProcessorFactory, + Codec.EncoderFactory encoderFactory, Muxer.Factory muxerFactory, Looper looper, DebugViewProvider debugViewProvider, @@ -640,9 +621,8 @@ public final class Transformer { this.forceSilentAudio = forceSilentAudio; this.listeners = listeners; this.assetLoaderFactory = assetLoaderFactory; - this.decoderFactory = decoderFactory; - this.encoderFactory = encoderFactory; this.frameProcessorFactory = frameProcessorFactory; + this.encoderFactory = encoderFactory; this.muxerFactory = muxerFactory; this.looper = looper; this.debugViewProvider = debugViewProvider; @@ -783,9 +763,8 @@ public final class Transformer { removeVideo, forceSilentAudio, assetLoaderFactory, - decoderFactory, - encoderFactory, frameProcessorFactory, + encoderFactory, muxerFactory, transformerInternalListener, fallbackListener, diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java index 824f8a9e17..3dd4cf0afa 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/TransformerInternal.java @@ -45,6 +45,7 @@ import com.google.android.exoplayer2.util.FrameProcessor; import com.google.android.exoplayer2.util.HandlerWrapper; import com.google.android.exoplayer2.util.MimeTypes; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -93,9 +94,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final ImmutableList audioProcessors; private final ImmutableList videoEffects; private final boolean forceSilentAudio; - private final CapturingDecoderFactory decoderFactory; - private final CapturingEncoderFactory encoderFactory; private final FrameProcessor.Factory frameProcessorFactory; + private final CapturingEncoderFactory encoderFactory; private final Listener listener; private final HandlerWrapper applicationHandler; private final DebugViewProvider debugViewProvider; @@ -126,9 +126,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; boolean removeVideo, boolean forceSilentAudio, AssetLoader.Factory assetLoaderFactory, - Codec.DecoderFactory decoderFactory, - Codec.EncoderFactory encoderFactory, FrameProcessor.Factory frameProcessorFactory, + Codec.EncoderFactory encoderFactory, Muxer.Factory muxerFactory, Listener listener, FallbackListener fallbackListener, @@ -140,9 +139,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; this.audioProcessors = audioProcessors; this.videoEffects = videoEffects; this.forceSilentAudio = forceSilentAudio; - this.decoderFactory = new CapturingDecoderFactory(decoderFactory); - this.encoderFactory = new CapturingEncoderFactory(encoderFactory); this.frameProcessorFactory = frameProcessorFactory; + this.encoderFactory = new CapturingEncoderFactory(encoderFactory); this.listener = listener; this.applicationHandler = applicationHandler; this.debugViewProvider = debugViewProvider; @@ -156,7 +154,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; .setRemoveAudio(removeAudio) .setRemoveVideo(removeVideo) .setFlattenVideoForSlowMotion(transformationRequest.flattenForSlowMotion) - .setDecoderFactory(this.decoderFactory) .createAssetLoader(mediaItem, internalLooper, componentListener); samplePipelines = new ArrayList<>(); muxerWrapper = @@ -263,9 +260,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private void endInternal( @EndReason int endReason, @Nullable TransformationException transformationException) { + ImmutableMap decoderNames = assetLoader.getDecoderNames(); transformationResultBuilder - .setAudioDecoderName(decoderFactory.getAudioDecoderName()) - .setVideoDecoderName(decoderFactory.getVideoDecoderName()) + .setAudioDecoderName(decoderNames.get(C.TRACK_TYPE_AUDIO)) + .setVideoDecoderName(decoderNames.get(C.TRACK_TYPE_VIDEO)) .setAudioEncoderName(encoderFactory.getAudioEncoderName()) .setVideoEncoderName(encoderFactory.getVideoEncoderName()); diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java index c1888a35f8..d6ef89220d 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderTest.java @@ -119,12 +119,12 @@ public class ExoPlayerAssetLoaderTest { Looper looper, AssetLoader.Listener listener, Clock clock) { Context context = ApplicationProvider.getApplicationContext(); MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(context); + Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context); MediaItem mediaItem = MediaItem.fromUri("asset:///media/mp4/sample.mp4"); - return new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock) + return new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, decoderFactory, clock) .setRemoveAudio(false) .setRemoveVideo(false) .setFlattenVideoForSlowMotion(false) - .setDecoderFactory(new DefaultDecoderFactory(context)) .createAssetLoader(mediaItem, looper, listener); } diff --git a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java index ab3cbae661..c0c07f04e5 100644 --- a/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java +++ b/library/transformer/src/test/java/com/google/android/exoplayer2/transformer/TransformerEndToEndTest.java @@ -61,6 +61,7 @@ import com.google.android.exoplayer2.testutil.FakeClock; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.Util; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.primitives.Ints; import java.io.IOException; @@ -527,8 +528,9 @@ public final class TransformerEndToEndTest { MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory( context, new SlowExtractorsFactory(/* delayBetweenReadsMs= */ 10)); + Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory(context); AssetLoader.Factory assetLoaderFactory = - new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, clock); + new ExoPlayerAssetLoader.Factory(context, mediaSourceFactory, decoderFactory, clock); Muxer.Factory muxerFactory = new TestMuxerFactory(/* maxDelayBetweenSamplesMs= */ 1); Transformer transformer = createTransformerBuilder(/* enableFallback= */ false) @@ -1101,11 +1103,6 @@ public final class TransformerEndToEndTest { return this; } - @Override - public AssetLoader.Factory setDecoderFactory(Codec.DecoderFactory decoderFactory) { - return this; - } - @Override public AssetLoader createAssetLoader(MediaItem mediaItem, Looper looper, Listener listener) { return new FakeAssetLoader(listener, supportedOutputTypes, sampleConsumerRef); @@ -1155,6 +1152,11 @@ public final class TransformerEndToEndTest { return 0; } + @Override + public ImmutableMap getDecoderNames() { + return ImmutableMap.of(); + } + @Override public void release() {} }