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 15e2b13e04..1f86217b7d 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 @@ -121,14 +121,6 @@ public interface AssetLoader { /** * A listener of {@link AssetLoader} events. * - *
This listener is typically used in the following way: - * - *
This listener can be called from any thread. */ interface Listener { diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java index 4459e64d6a..15da9b13f7 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/AudioTranscodingSamplePipeline.java @@ -35,9 +35,7 @@ import java.util.List; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.dataflow.qual.Pure; -/** - * Pipeline to decode audio samples, apply audio processing to the raw samples, and re-encode them. - */ +/** Pipeline to apply audio processing to raw audio samples, encode them and mux them. */ /* package */ final class AudioTranscodingSamplePipeline extends BaseSamplePipeline { private static final int DEFAULT_ENCODER_BITRATE = 128 * 1024; diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderRenderer.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderRenderer.java index f6eaa5e132..d74628355a 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderRenderer.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/ExoPlayerAssetLoaderRenderer.java @@ -248,7 +248,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } /** - * Attempts to read input data and pass the input data to the sample pipeline. + * Attempts to read input data and pass it to the sample pipeline. * * @return Whether it may be possible to read more data immediately by calling this method again. */ diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java index 837725ccb2..67672774cf 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/PassthroughSamplePipeline.java @@ -20,7 +20,7 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; -/** Pipeline that passes through the samples without any re-encoding or transformation. */ +/** Pipeline that muxes encoded samples without any transcoding or transformation. */ /* package */ final class PassthroughSamplePipeline extends BaseSamplePipeline { private final DecoderInputBuffer buffer; diff --git a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java index 1b95caddfc..f822da2c0b 100644 --- a/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java +++ b/library/transformer/src/main/java/com/google/android/exoplayer2/transformer/SamplePipeline.java @@ -20,7 +20,7 @@ import androidx.annotation.Nullable; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; /** - * Pipeline for processing {@link DecoderInputBuffer DecoderInputBuffers}. + * Pipeline for processing media data. * *
This pipeline can be used to implement transformations of audio or video samples. */ 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 10ade5224a..d025d823a3 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 @@ -34,7 +34,6 @@ import com.google.android.exoplayer2.audio.SonicAudioProcessor; import com.google.android.exoplayer2.effect.GlEffect; import com.google.android.exoplayer2.effect.GlEffectsFrameProcessor; import com.google.android.exoplayer2.effect.GlMatrixTransformation; -import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.util.Clock; import com.google.android.exoplayer2.util.DebugViewProvider; import com.google.android.exoplayer2.util.Effect; @@ -693,8 +692,10 @@ public final class Transformer { * *
Concurrent transformations on the same Transformer object are not allowed. * - *
The output is an MP4 file. It can contain at most one video track and one audio track. Other - * track types are ignored. For adaptive bitrate {@linkplain MediaSource media sources}, the + *
If no custom {@link Muxer.Factory} is specified, the output is an MP4 file. + * + *
The output can contain at most one video track and one audio track. Other track types are + * 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. @@ -716,8 +717,10 @@ public final class Transformer { * *
Concurrent transformations on the same Transformer object are not allowed. * - *
The output is an MP4 file. It can contain at most one video track and one audio track. Other - * track types are ignored. For adaptive bitrate {@linkplain MediaSource media sources}, the + *
If no custom {@link Muxer.Factory} is specified, the output is an MP4 file. + * + *
The output can contain at most one video track and one audio track. Other track types are + * 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. @@ -751,12 +754,9 @@ public final class Transformer { } TransformerInternalListener transformerInternalListener = new TransformerInternalListener(mediaItem); + HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null); FallbackListener fallbackListener = - new FallbackListener( - mediaItem, - listeners, - clock.createHandler(looper, /* callback= */ null), - transformationRequest); + new FallbackListener(mediaItem, listeners, applicationHandler, transformationRequest); transformerInternal = new TransformerInternal( context, @@ -776,6 +776,7 @@ public final class Transformer { muxerFactory, transformerInternalListener, fallbackListener, + applicationHandler, debugViewProvider, clock); transformerInternal.start(); @@ -834,37 +835,29 @@ public final class Transformer { private final class TransformerInternalListener implements TransformerInternal.Listener { private final MediaItem mediaItem; - private final HandlerWrapper handler; public TransformerInternalListener(MediaItem mediaItem) { this.mediaItem = mediaItem; - handler = clock.createHandler(looper, /* callback= */ null); } @Override public void onTransformationCompleted(TransformationResult transformationResult) { // TODO(b/213341814): Add event flags for Transformer events. - handler.post( - () -> { - transformerInternal = null; - listeners.queueEvent( - /* eventFlag= */ C.INDEX_UNSET, - listener -> listener.onTransformationCompleted(mediaItem, transformationResult)); - listeners.flushEvents(); - }); + transformerInternal = null; + listeners.queueEvent( + /* eventFlag= */ C.INDEX_UNSET, + listener -> listener.onTransformationCompleted(mediaItem, transformationResult)); + listeners.flushEvents(); } @Override public void onTransformationError( TransformationResult result, TransformationException exception) { - handler.post( - () -> { - transformerInternal = null; - listeners.queueEvent( - /* eventFlag= */ C.INDEX_UNSET, - listener -> listener.onTransformationError(mediaItem, result, exception)); - listeners.flushEvents(); - }); + transformerInternal = null; + listeners.queueEvent( + /* eventFlag= */ C.INDEX_UNSET, + listener -> listener.onTransformationError(mediaItem, result, exception)); + listeners.flushEvents(); } } } 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 42f9b22fdd..4fa7167935 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 @@ -100,6 +100,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final CapturingEncoderFactory encoderFactory; private final FrameProcessor.Factory frameProcessorFactory; private final Listener listener; + private final HandlerWrapper applicationHandler; private final DebugViewProvider debugViewProvider; private final Clock clock; private final HandlerThread internalHandlerThread; @@ -137,6 +138,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; Muxer.Factory muxerFactory, Listener listener, FallbackListener fallbackListener, + HandlerWrapper applicationHandler, DebugViewProvider debugViewProvider, Clock clock) { this.context = context; @@ -148,6 +150,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; this.encoderFactory = new CapturingEncoderFactory(encoderFactory); this.frameProcessorFactory = frameProcessorFactory; this.listener = listener; + this.applicationHandler = applicationHandler; this.debugViewProvider = debugViewProvider; this.clock = clock; internalHandlerThread = new HandlerThread("Transformer:Internal"); @@ -349,10 +352,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; } if (exception != null) { - listener.onTransformationError( - transformationResultBuilder.setTransformationException(exception).build(), exception); + TransformationException finalException = exception; + applicationHandler.post( + () -> + listener.onTransformationError( + transformationResultBuilder.setTransformationException(finalException).build(), + finalException)); } else { - listener.onTransformationCompleted(transformationResultBuilder.build()); + applicationHandler.post( + () -> listener.onTransformationCompleted(transformationResultBuilder.build())); } }