Misc small fixes

- Improve AssetLoader Javadoc
- Fix Javadoc of sample pipelines
- Improve Javadoc of Transformer.startTransformation
- Move thread hops for Transformer listener callbacks to
  TransformerInternal

PiperOrigin-RevId: 499156604
This commit is contained in:
kimvde 2023-01-03 09:47:47 +00:00 committed by Marc Baechinger
parent 4541db3541
commit bd0d61d80d
7 changed files with 36 additions and 45 deletions

View File

@ -123,14 +123,6 @@ public interface AssetLoader {
/** /**
* A listener of {@link AssetLoader} events. * A listener of {@link AssetLoader} events.
* *
* <p>This listener is typically used in the following way:
*
* <ul>
* <li>{@linkplain #onDurationUs(long)} Report} the duration of the input media.
* <li>{@linkplain #onTrackCount(int) Report} the number of output tracks.
* <li>{@linkplain #onTrackAdded(Format, int, long, long) Add} the information for each track.
* </ul>
*
* <p>This listener can be called from any thread. * <p>This listener can be called from any thread.
*/ */
interface Listener { interface Listener {

View File

@ -35,9 +35,7 @@ import java.util.List;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import org.checkerframework.dataflow.qual.Pure; import org.checkerframework.dataflow.qual.Pure;
/** /** Pipeline to apply audio processing to raw audio samples, encode them and mux them. */
* Pipeline to decode audio samples, apply audio processing to the raw samples, and re-encode them.
*/
/* package */ final class AudioTranscodingSamplePipeline extends BaseSamplePipeline { /* package */ final class AudioTranscodingSamplePipeline extends BaseSamplePipeline {
private static final int DEFAULT_ENCODER_BITRATE = 128 * 1024; private static final int DEFAULT_ENCODER_BITRATE = 128 * 1024;

View File

@ -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. * @return Whether it may be possible to read more data immediately by calling this method again.
*/ */

View File

@ -20,7 +20,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.decoder.DecoderInputBuffer; import androidx.media3.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 { /* package */ final class PassthroughSamplePipeline extends BaseSamplePipeline {
private final DecoderInputBuffer buffer; private final DecoderInputBuffer buffer;

View File

@ -21,7 +21,7 @@ import androidx.media3.common.util.UnstableApi;
import androidx.media3.decoder.DecoderInputBuffer; import androidx.media3.decoder.DecoderInputBuffer;
/** /**
* Pipeline for processing {@link DecoderInputBuffer DecoderInputBuffers}. * Pipeline for processing media data.
* *
* <p>This pipeline can be used to implement transformations of audio or video samples. * <p>This pipeline can be used to implement transformations of audio or video samples.
*/ */

View File

@ -43,7 +43,6 @@ import androidx.media3.effect.GlEffect;
import androidx.media3.effect.GlEffectsFrameProcessor; import androidx.media3.effect.GlEffectsFrameProcessor;
import androidx.media3.effect.GlMatrixTransformation; import androidx.media3.effect.GlMatrixTransformation;
import androidx.media3.exoplayer.audio.SonicAudioProcessor; import androidx.media3.exoplayer.audio.SonicAudioProcessor;
import androidx.media3.exoplayer.source.MediaSource;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
@ -695,8 +694,10 @@ public final class Transformer {
* *
* <p>Concurrent transformations on the same Transformer object are not allowed. * <p>Concurrent transformations on the same Transformer object are not allowed.
* *
* <p>The output is an MP4 file. It can contain at most one video track and one audio track. Other * <p>If no custom {@link Muxer.Factory} is specified, the output is an MP4 file.
* track types are ignored. For adaptive bitrate {@linkplain MediaSource media sources}, the *
* <p>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. * highest bitrate video and audio streams are selected.
* *
* @param mediaItem The {@link MediaItem} to transform. * @param mediaItem The {@link MediaItem} to transform.
@ -718,8 +719,10 @@ public final class Transformer {
* *
* <p>Concurrent transformations on the same Transformer object are not allowed. * <p>Concurrent transformations on the same Transformer object are not allowed.
* *
* <p>The output is an MP4 file. It can contain at most one video track and one audio track. Other * <p>If no custom {@link Muxer.Factory} is specified, the output is an MP4 file.
* track types are ignored. For adaptive bitrate {@linkplain MediaSource media sources}, the *
* <p>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. * highest bitrate video and audio streams are selected.
* *
* @param mediaItem The {@link MediaItem} to transform. * @param mediaItem The {@link MediaItem} to transform.
@ -753,12 +756,9 @@ public final class Transformer {
} }
TransformerInternalListener transformerInternalListener = TransformerInternalListener transformerInternalListener =
new TransformerInternalListener(mediaItem); new TransformerInternalListener(mediaItem);
HandlerWrapper applicationHandler = clock.createHandler(looper, /* callback= */ null);
FallbackListener fallbackListener = FallbackListener fallbackListener =
new FallbackListener( new FallbackListener(mediaItem, listeners, applicationHandler, transformationRequest);
mediaItem,
listeners,
clock.createHandler(looper, /* callback= */ null),
transformationRequest);
transformerInternal = transformerInternal =
new TransformerInternal( new TransformerInternal(
context, context,
@ -778,6 +778,7 @@ public final class Transformer {
muxerFactory, muxerFactory,
transformerInternalListener, transformerInternalListener,
fallbackListener, fallbackListener,
applicationHandler,
debugViewProvider, debugViewProvider,
clock); clock);
transformerInternal.start(); transformerInternal.start();
@ -836,37 +837,29 @@ public final class Transformer {
private final class TransformerInternalListener implements TransformerInternal.Listener { private final class TransformerInternalListener implements TransformerInternal.Listener {
private final MediaItem mediaItem; private final MediaItem mediaItem;
private final HandlerWrapper handler;
public TransformerInternalListener(MediaItem mediaItem) { public TransformerInternalListener(MediaItem mediaItem) {
this.mediaItem = mediaItem; this.mediaItem = mediaItem;
handler = clock.createHandler(looper, /* callback= */ null);
} }
@Override @Override
public void onTransformationCompleted(TransformationResult transformationResult) { public void onTransformationCompleted(TransformationResult transformationResult) {
// TODO(b/213341814): Add event flags for Transformer events. // TODO(b/213341814): Add event flags for Transformer events.
handler.post( transformerInternal = null;
() -> { listeners.queueEvent(
transformerInternal = null; /* eventFlag= */ C.INDEX_UNSET,
listeners.queueEvent( listener -> listener.onTransformationCompleted(mediaItem, transformationResult));
/* eventFlag= */ C.INDEX_UNSET, listeners.flushEvents();
listener -> listener.onTransformationCompleted(mediaItem, transformationResult));
listeners.flushEvents();
});
} }
@Override @Override
public void onTransformationError( public void onTransformationError(
TransformationResult result, TransformationException exception) { TransformationResult result, TransformationException exception) {
handler.post( transformerInternal = null;
() -> { listeners.queueEvent(
transformerInternal = null; /* eventFlag= */ C.INDEX_UNSET,
listeners.queueEvent( listener -> listener.onTransformationError(mediaItem, result, exception));
/* eventFlag= */ C.INDEX_UNSET, listeners.flushEvents();
listener -> listener.onTransformationError(mediaItem, result, exception));
listeners.flushEvents();
});
} }
} }
} }

View File

@ -100,6 +100,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final CapturingEncoderFactory encoderFactory; private final CapturingEncoderFactory encoderFactory;
private final FrameProcessor.Factory frameProcessorFactory; private final FrameProcessor.Factory frameProcessorFactory;
private final Listener listener; private final Listener listener;
private final HandlerWrapper applicationHandler;
private final DebugViewProvider debugViewProvider; private final DebugViewProvider debugViewProvider;
private final Clock clock; private final Clock clock;
private final HandlerThread internalHandlerThread; private final HandlerThread internalHandlerThread;
@ -137,6 +138,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
Muxer.Factory muxerFactory, Muxer.Factory muxerFactory,
Listener listener, Listener listener,
FallbackListener fallbackListener, FallbackListener fallbackListener,
HandlerWrapper applicationHandler,
DebugViewProvider debugViewProvider, DebugViewProvider debugViewProvider,
Clock clock) { Clock clock) {
this.context = context; this.context = context;
@ -148,6 +150,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
this.encoderFactory = new CapturingEncoderFactory(encoderFactory); this.encoderFactory = new CapturingEncoderFactory(encoderFactory);
this.frameProcessorFactory = frameProcessorFactory; this.frameProcessorFactory = frameProcessorFactory;
this.listener = listener; this.listener = listener;
this.applicationHandler = applicationHandler;
this.debugViewProvider = debugViewProvider; this.debugViewProvider = debugViewProvider;
this.clock = clock; this.clock = clock;
internalHandlerThread = new HandlerThread("Transformer:Internal"); internalHandlerThread = new HandlerThread("Transformer:Internal");
@ -349,10 +352,15 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
if (exception != null) { if (exception != null) {
listener.onTransformationError( TransformationException finalException = exception;
transformationResultBuilder.setTransformationException(exception).build(), exception); applicationHandler.post(
() ->
listener.onTransformationError(
transformationResultBuilder.setTransformationException(finalException).build(),
finalException));
} else { } else {
listener.onTransformationCompleted(transformationResultBuilder.build()); applicationHandler.post(
() -> listener.onTransformationCompleted(transformationResultBuilder.build()));
} }
} }