Rename CompositingVideoSinkProvider and PreviewAudioPipeline

The components are mirror components for video and audio so they should
have a matching name

PiperOrigin-RevId: 673357081
This commit is contained in:
kimvde 2024-09-11 05:46:44 -07:00 committed by Copybara-Service
parent 4be5b74366
commit 8271a5f920
11 changed files with 144 additions and 142 deletions

View File

@ -66,7 +66,7 @@
<init>(); <init>();
} }
# Constructors and methods accessed via reflection in CompositingVideoSinkProvider # Constructors and methods accessed via reflection in PlaybackVideoGraphWrapper
-dontnote androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory -dontnote androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory
-keepclasseswithmembers class androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory { -keepclasseswithmembers class androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory {
<init>(androidx.media3.common.VideoFrameProcessor$Factory); <init>(androidx.media3.common.VideoFrameProcessor$Factory);

View File

@ -410,8 +410,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
* explicitly using {@link MediaFormat#KEY_OPERATING_RATE}). * explicitly using {@link MediaFormat#KEY_OPERATING_RATE}).
* @param videoSink The {@link VideoSink} consuming the frames. If {@code null} and effects are * @param videoSink The {@link VideoSink} consuming the frames. If {@code null} and effects are
* {@linkplain #MSG_SET_VIDEO_EFFECTS set}, a {@link VideoSink} produced by a {@link * {@linkplain #MSG_SET_VIDEO_EFFECTS set}, a {@link VideoSink} produced by a {@link
* CompositingVideoSinkProvider} with its default configuration will be used to apply effects * PlaybackVideoGraphWrapper} with its default configuration will be used to apply effects and
* and render the frames on the output. * render the frames on the output.
*/ */
public MediaCodecVideoRenderer( public MediaCodecVideoRenderer(
Context context, Context context,
@ -677,7 +677,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (!hasSetVideoSink) { if (!hasSetVideoSink) {
if (videoEffects != null && videoSink == null) { if (videoEffects != null && videoSink == null) {
videoSink = videoSink =
new CompositingVideoSinkProvider.Builder(context, videoFrameReleaseControl) new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl)
.setClock(getClock()) .setClock(getClock())
.build() .build()
.getSink(); .getSink();

View File

@ -65,53 +65,56 @@ import java.util.concurrent.Executor;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Handles composition of video sinks. */ /**
* Processes input from {@link VideoSink} instances, plumbing the data through a {@link VideoGraph}
* and rendering the output.
*/
@UnstableApi @UnstableApi
@RestrictTo({Scope.LIBRARY_GROUP}) @RestrictTo({Scope.LIBRARY_GROUP})
public final class CompositingVideoSinkProvider implements VideoSinkProvider, VideoGraph.Listener { public final class PlaybackVideoGraphWrapper implements VideoSinkProvider, VideoGraph.Listener {
/** Listener for {@link CompositingVideoSinkProvider} events. */ /** Listener for {@link PlaybackVideoGraphWrapper} events. */
public interface Listener { public interface Listener {
/** /**
* Called when the video frame processor renders the first frame. * Called when the video frame processor renders the first frame.
* *
* @param compositingVideoSinkProvider The compositing video sink provider which triggered this * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper} which triggered this
* event. * event.
*/ */
void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider); void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper);
/** /**
* Called when the video frame processor dropped a frame. * Called when the video frame processor dropped a frame.
* *
* @param compositingVideoSinkProvider The compositing video sink provider which triggered this * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper} which triggered this
* event. * event.
*/ */
void onFrameDropped(CompositingVideoSinkProvider compositingVideoSinkProvider); void onFrameDropped(PlaybackVideoGraphWrapper playbackVideoGraphWrapper);
/** /**
* Called before a frame is rendered for the first time since setting the surface, and each time * Called before a frame is rendered for the first time since setting the surface, and each time
* there's a change in the size, rotation or pixel aspect ratio of the video being rendered. * there's a change in the size, rotation or pixel aspect ratio of the video being rendered.
* *
* @param compositingVideoSinkProvider The compositing video sink provider which triggered this * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper} which triggered this
* event. * event.
* @param videoSize The video size. * @param videoSize The video size.
*/ */
void onVideoSizeChanged( void onVideoSizeChanged(
CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize); PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize);
/** /**
* Called when the video frame processor encountered an error. * Called when the video frame processor encountered an error.
* *
* @param compositingVideoSinkProvider The compositing video sink provider which triggered this * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper} which triggered this
* event. * event.
* @param videoFrameProcessingException The error. * @param videoFrameProcessingException The error.
*/ */
void onError( void onError(
CompositingVideoSinkProvider compositingVideoSinkProvider, PlaybackVideoGraphWrapper playbackVideoGraphWrapper,
VideoFrameProcessingException videoFrameProcessingException); VideoFrameProcessingException videoFrameProcessingException);
} }
/** A builder for {@link CompositingVideoSinkProvider} instances. */ /** A builder for {@link PlaybackVideoGraphWrapper} instances. */
public static final class Builder { public static final class Builder {
private final Context context; private final Context context;
private final VideoFrameReleaseControl videoFrameReleaseControl; private final VideoFrameReleaseControl videoFrameReleaseControl;
@ -176,12 +179,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
} }
/** /**
* Builds the {@link CompositingVideoSinkProvider}. * Builds the {@link PlaybackVideoGraphWrapper}.
* *
* <p>This method must be called at most once and will throw an {@link IllegalStateException} if * <p>This method must be called at most once and will throw an {@link IllegalStateException} if
* it has already been called. * it has already been called.
*/ */
public CompositingVideoSinkProvider build() { public PlaybackVideoGraphWrapper build() {
checkState(!built); checkState(!built);
if (previewingVideoGraphFactory == null) { if (previewingVideoGraphFactory == null) {
@ -191,10 +194,9 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
previewingVideoGraphFactory = previewingVideoGraphFactory =
new ReflectivePreviewingSingleInputVideoGraphFactory(videoFrameProcessorFactory); new ReflectivePreviewingSingleInputVideoGraphFactory(videoFrameProcessorFactory);
} }
CompositingVideoSinkProvider compositingVideoSinkProvider = PlaybackVideoGraphWrapper playbackVideoGraphWrapper = new PlaybackVideoGraphWrapper(this);
new CompositingVideoSinkProvider(this);
built = true; built = true;
return compositingVideoSinkProvider; return playbackVideoGraphWrapper;
} }
} }
@ -216,7 +218,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
private final VideoFrameRenderControl videoFrameRenderControl; private final VideoFrameRenderControl videoFrameRenderControl;
private final PreviewingVideoGraph.Factory previewingVideoGraphFactory; private final PreviewingVideoGraph.Factory previewingVideoGraphFactory;
private final Clock clock; private final Clock clock;
private final CopyOnWriteArraySet<CompositingVideoSinkProvider.Listener> listeners; private final CopyOnWriteArraySet<PlaybackVideoGraphWrapper.Listener> listeners;
private @MonotonicNonNull Format outputFormat; private @MonotonicNonNull Format outputFormat;
private @MonotonicNonNull VideoFrameMetadataListener videoFrameMetadataListener; private @MonotonicNonNull VideoFrameMetadataListener videoFrameMetadataListener;
@ -233,7 +235,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
*/ */
private long bufferTimestampAdjustmentUs; private long bufferTimestampAdjustmentUs;
private CompositingVideoSinkProvider(Builder builder) { private PlaybackVideoGraphWrapper(Builder builder) {
context = builder.context; context = builder.context;
videoSinkImpl = new VideoSinkImpl(context); videoSinkImpl = new VideoSinkImpl(context);
clock = builder.clock; clock = builder.clock;
@ -248,20 +250,20 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
} }
/** /**
* Adds a {@link CompositingVideoSinkProvider.Listener}. * Adds a {@link PlaybackVideoGraphWrapper.Listener}.
* *
* @param listener The listener to be added. * @param listener The listener to be added.
*/ */
public void addListener(CompositingVideoSinkProvider.Listener listener) { public void addListener(PlaybackVideoGraphWrapper.Listener listener) {
listeners.add(listener); listeners.add(listener);
} }
/** /**
* Removes a {@link CompositingVideoSinkProvider.Listener}. * Removes a {@link PlaybackVideoGraphWrapper.Listener}.
* *
* @param listener The listener to be removed. * @param listener The listener to be removed.
*/ */
public void removeListener(CompositingVideoSinkProvider.Listener listener) { public void removeListener(PlaybackVideoGraphWrapper.Listener listener) {
listeners.remove(listener); listeners.remove(listener);
} }
@ -321,7 +323,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void onOutputFrameAvailableForRendering(long framePresentationTimeUs) { public void onOutputFrameAvailableForRendering(long framePresentationTimeUs) {
if (pendingFlushCount > 0) { if (pendingFlushCount > 0) {
// Ignore available frames while the sink provider is flushing // Ignore available frames while flushing
return; return;
} }
// The frame presentation time is relative to the start of the Composition and without the // The frame presentation time is relative to the start of the Composition and without the
@ -337,8 +339,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void onError(VideoFrameProcessingException exception) { public void onError(VideoFrameProcessingException exception) {
for (CompositingVideoSinkProvider.Listener listener : listeners) { for (PlaybackVideoGraphWrapper.Listener listener : listeners) {
listener.onError(/* compositingVideoSinkProvider= */ this, exception); listener.onError(/* playbackVideoGraphWrapper= */ this, exception);
} }
} }
@ -464,7 +466,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
} }
/** Receives input from an ExoPlayer renderer and forwards it to the video graph. */ /** Receives input from an ExoPlayer renderer and forwards it to the video graph. */
private final class VideoSinkImpl implements VideoSink, CompositingVideoSinkProvider.Listener { private final class VideoSinkImpl implements VideoSink, PlaybackVideoGraphWrapper.Listener {
private final int videoFrameProcessorMaxPendingFrameCount; private final int videoFrameProcessorMaxPendingFrameCount;
private final ArrayList<Effect> videoEffects; private final ArrayList<Effect> videoEffects;
@ -539,7 +541,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void initialize(Format sourceFormat) throws VideoSinkException { public void initialize(Format sourceFormat) throws VideoSinkException {
checkState(!isInitialized()); checkState(!isInitialized());
videoFrameProcessor = CompositingVideoSinkProvider.this.initialize(sourceFormat); videoFrameProcessor = PlaybackVideoGraphWrapper.this.initialize(sourceFormat);
} }
@Override @Override
@ -556,7 +558,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
hasRegisteredFirstInputStream = false; hasRegisteredFirstInputStream = false;
finalBufferPresentationTimeUs = C.TIME_UNSET; finalBufferPresentationTimeUs = C.TIME_UNSET;
lastBufferPresentationTimeUs = C.TIME_UNSET; lastBufferPresentationTimeUs = C.TIME_UNSET;
CompositingVideoSinkProvider.this.flush(); PlaybackVideoGraphWrapper.this.flush();
if (resetPosition) { if (resetPosition) {
videoFrameReleaseControl.reset(); videoFrameReleaseControl.reset();
} }
@ -569,7 +571,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public boolean isReady(boolean rendererOtherwiseReady) { public boolean isReady(boolean rendererOtherwiseReady) {
return CompositingVideoSinkProvider.this.isReady( return PlaybackVideoGraphWrapper.this.isReady(
/* rendererOtherwiseReady= */ rendererOtherwiseReady && isInitialized()); /* rendererOtherwiseReady= */ rendererOtherwiseReady && isInitialized());
} }
@ -577,7 +579,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
public boolean isEnded() { public boolean isEnded() {
return isInitialized() return isInitialized()
&& finalBufferPresentationTimeUs != C.TIME_UNSET && finalBufferPresentationTimeUs != C.TIME_UNSET
&& CompositingVideoSinkProvider.this.hasReleasedFrame(finalBufferPresentationTimeUs); && PlaybackVideoGraphWrapper.this.hasReleasedFrame(finalBufferPresentationTimeUs);
} }
@Override @Override
@ -619,12 +621,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void setVideoFrameMetadataListener( public void setVideoFrameMetadataListener(
VideoFrameMetadataListener videoFrameMetadataListener) { VideoFrameMetadataListener videoFrameMetadataListener) {
CompositingVideoSinkProvider.this.setVideoFrameMetadataListener(videoFrameMetadataListener); PlaybackVideoGraphWrapper.this.setVideoFrameMetadataListener(videoFrameMetadataListener);
} }
@Override @Override
public void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed) { public void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed) {
CompositingVideoSinkProvider.this.setPlaybackSpeed(speed); PlaybackVideoGraphWrapper.this.setPlaybackSpeed(speed);
} }
@Override @Override
@ -660,12 +662,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) { public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) {
CompositingVideoSinkProvider.this.setOutputSurfaceInfo(outputSurface, outputResolution); PlaybackVideoGraphWrapper.this.setOutputSurfaceInfo(outputSurface, outputResolution);
} }
@Override @Override
public void clearOutputSurfaceInfo() { public void clearOutputSurfaceInfo() {
CompositingVideoSinkProvider.this.clearOutputSurfaceInfo(); PlaybackVideoGraphWrapper.this.clearOutputSurfaceInfo();
} }
@Override @Override
@ -734,7 +736,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
// input frame from the next input stream. // input frame from the next input stream.
if (isInputStreamChangePending) { if (isInputStreamChangePending) {
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|| CompositingVideoSinkProvider.this.hasReleasedFrame( || PlaybackVideoGraphWrapper.this.hasReleasedFrame(
pendingInputStreamBufferPresentationTimeUs)) { pendingInputStreamBufferPresentationTimeUs)) {
maybeRegisterInputStream(); maybeRegisterInputStream();
isInputStreamChangePending = false; isInputStreamChangePending = false;
@ -793,7 +795,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void render(long positionUs, long elapsedRealtimeUs) throws VideoSinkException { public void render(long positionUs, long elapsedRealtimeUs) throws VideoSinkException {
try { try {
CompositingVideoSinkProvider.this.render(positionUs, elapsedRealtimeUs); PlaybackVideoGraphWrapper.this.render(positionUs, elapsedRealtimeUs);
} catch (ExoPlaybackException e) { } catch (ExoPlaybackException e) {
throw new VideoSinkException( throw new VideoSinkException(
e, inputFormat != null ? inputFormat : new Format.Builder().build()); e, inputFormat != null ? inputFormat : new Format.Builder().build());
@ -807,14 +809,14 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void release() { public void release() {
CompositingVideoSinkProvider.this.release(); PlaybackVideoGraphWrapper.this.release();
} }
// Other methods // Other methods
private void maybeSetStreamOffsetChange(long bufferPresentationTimeUs) { private void maybeSetStreamOffsetChange(long bufferPresentationTimeUs) {
if (pendingInputStreamOffsetChange) { if (pendingInputStreamOffsetChange) {
CompositingVideoSinkProvider.this.onStreamOffsetChange( PlaybackVideoGraphWrapper.this.onStreamOffsetChange(
inputBufferTimestampAdjustmentUs, inputBufferTimestampAdjustmentUs,
bufferPresentationTimeUs, bufferPresentationTimeUs,
/* streamOffsetUs= */ inputStreamOffsetUs); /* streamOffsetUs= */ inputStreamOffsetUs);
@ -834,7 +836,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
// An input stream is fully decoded, wait until all of its frames are released before queueing // An input stream is fully decoded, wait until all of its frames are released before queueing
// input frame from the next input stream. // input frame from the next input stream.
if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET
|| CompositingVideoSinkProvider.this.hasReleasedFrame( || PlaybackVideoGraphWrapper.this.hasReleasedFrame(
pendingInputStreamBufferPresentationTimeUs)) { pendingInputStreamBufferPresentationTimeUs)) {
maybeRegisterInputStream(); maybeRegisterInputStream();
isInputStreamChangePending = false; isInputStreamChangePending = false;
@ -864,16 +866,16 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
finalBufferPresentationTimeUs = C.TIME_UNSET; finalBufferPresentationTimeUs = C.TIME_UNSET;
} }
// CompositingVideoSinkProvider.Listener implementation // PlaybackVideoGraphWrapper.Listener implementation
@Override @Override
public void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider) { public void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) {
VideoSink.Listener currentListener = listener; VideoSink.Listener currentListener = listener;
listenerExecutor.execute(() -> currentListener.onFirstFrameRendered(/* videoSink= */ this)); listenerExecutor.execute(() -> currentListener.onFirstFrameRendered(/* videoSink= */ this));
} }
@Override @Override
public void onFrameDropped(CompositingVideoSinkProvider compositingVideoSinkProvider) { public void onFrameDropped(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) {
VideoSink.Listener currentListener = listener; VideoSink.Listener currentListener = listener;
listenerExecutor.execute( listenerExecutor.execute(
() -> currentListener.onFrameDropped(checkStateNotNull(/* reference= */ this))); () -> currentListener.onFrameDropped(checkStateNotNull(/* reference= */ this)));
@ -881,7 +883,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void onVideoSizeChanged( public void onVideoSizeChanged(
CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize) { PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize) {
VideoSink.Listener currentListener = listener; VideoSink.Listener currentListener = listener;
listenerExecutor.execute( listenerExecutor.execute(
() -> currentListener.onVideoSizeChanged(/* videoSink= */ this, videoSize)); () -> currentListener.onVideoSizeChanged(/* videoSink= */ this, videoSize));
@ -889,7 +891,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void onError( public void onError(
CompositingVideoSinkProvider compositingVideoSinkProvider, PlaybackVideoGraphWrapper playbackVideoGraphWrapper,
VideoFrameProcessingException videoFrameProcessingException) { VideoFrameProcessingException videoFrameProcessingException) {
VideoSink.Listener currentListener = listener; VideoSink.Listener currentListener = listener;
listenerExecutor.execute( listenerExecutor.execute(
@ -911,8 +913,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
.setHeight(videoSize.height) .setHeight(videoSize.height)
.setSampleMimeType(MimeTypes.VIDEO_RAW) .setSampleMimeType(MimeTypes.VIDEO_RAW)
.build(); .build();
for (CompositingVideoSinkProvider.Listener listener : listeners) { for (PlaybackVideoGraphWrapper.Listener listener : listeners) {
listener.onVideoSizeChanged(CompositingVideoSinkProvider.this, videoSize); listener.onVideoSizeChanged(PlaybackVideoGraphWrapper.this, videoSize);
} }
} }
@ -923,8 +925,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
long streamOffsetUs, long streamOffsetUs,
boolean isFirstFrame) { boolean isFirstFrame) {
if (isFirstFrame && currentSurfaceAndSize != null) { if (isFirstFrame && currentSurfaceAndSize != null) {
for (CompositingVideoSinkProvider.Listener listener : listeners) { for (PlaybackVideoGraphWrapper.Listener listener : listeners) {
listener.onFirstFrameRendered(CompositingVideoSinkProvider.this); listener.onFirstFrameRendered(PlaybackVideoGraphWrapper.this);
} }
} }
if (videoFrameMetadataListener != null) { if (videoFrameMetadataListener != null) {
@ -942,8 +944,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi
@Override @Override
public void dropFrame() { public void dropFrame() {
for (CompositingVideoSinkProvider.Listener listener : listeners) { for (PlaybackVideoGraphWrapper.Listener listener : listeners) {
listener.onFrameDropped(CompositingVideoSinkProvider.this); listener.onFrameDropped(PlaybackVideoGraphWrapper.this);
} }
checkStateNotNull(videoGraph).renderOutputFrame(VideoFrameProcessor.DROP_OUTPUT_FRAME); checkStateNotNull(videoGraph).renderOutputFrame(VideoFrameProcessor.DROP_OUTPUT_FRAME);
} }

View File

@ -35,14 +35,14 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mockito; import org.mockito.Mockito;
/** Unit test for {@link CompositingVideoSinkProvider}. */ /** Unit test for {@link PlaybackVideoGraphWrapper}. */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public final class CompositingVideoSinkProviderTest { public final class PlaybackVideoGraphWrapperTest {
@Test @Test
public void builder_calledMultipleTimes_throws() { public void builder_calledMultipleTimes_throws() {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
CompositingVideoSinkProvider.Builder builder = PlaybackVideoGraphWrapper.Builder builder =
new CompositingVideoSinkProvider.Builder(context, createVideoFrameReleaseControl()); new PlaybackVideoGraphWrapper.Builder(context, createVideoFrameReleaseControl());
builder.build(); builder.build();
@ -51,16 +51,16 @@ public final class CompositingVideoSinkProviderTest {
@Test @Test
public void initializeSink_calledTwice_throws() throws VideoSink.VideoSinkException { public void initializeSink_calledTwice_throws() throws VideoSink.VideoSinkException {
CompositingVideoSinkProvider provider = createCompositingVideoSinkProvider(); PlaybackVideoGraphWrapper provider = createPlaybackVideoGraphWrapper();
VideoSink sink = provider.getSink(); VideoSink sink = provider.getSink();
sink.initialize(new Format.Builder().build()); sink.initialize(new Format.Builder().build());
assertThrows(IllegalStateException.class, () -> sink.initialize(new Format.Builder().build())); assertThrows(IllegalStateException.class, () -> sink.initialize(new Format.Builder().build()));
} }
private static CompositingVideoSinkProvider createCompositingVideoSinkProvider() { private static PlaybackVideoGraphWrapper createPlaybackVideoGraphWrapper() {
Context context = ApplicationProvider.getApplicationContext(); Context context = ApplicationProvider.getApplicationContext();
return new CompositingVideoSinkProvider.Builder(context, createVideoFrameReleaseControl()) return new PlaybackVideoGraphWrapper.Builder(context, createVideoFrameReleaseControl())
.setPreviewingVideoGraphFactory(new TestPreviewingVideoGraphFactory()) .setPreviewingVideoGraphFactory(new TestPreviewingVideoGraphFactory())
.build(); .build();
} }

View File

@ -442,7 +442,7 @@ public class CompositionPlayerTest {
} }
@Test @Test
public void playback_videoSinkProviderFails_playerRaisesError() { public void playback_videoGraphWrapperFails_playerRaisesError() {
PlayerTestListener listener = new PlayerTestListener(TEST_TIMEOUT_MS); PlayerTestListener listener = new PlayerTestListener(TEST_TIMEOUT_MS);
EditedMediaItem video = EditedMediaItem video =
new EditedMediaItem.Builder(MediaItem.fromUri(MP4_ASSET.uri)) new EditedMediaItem.Builder(MediaItem.fromUri(MP4_ASSET.uri))
@ -478,7 +478,7 @@ public class CompositionPlayerTest {
} }
@Test @Test
public void release_videoSinkProviderFailsDuringRelease_playerDoesNotRaiseError() public void release_videoGraphWrapperFailsDuringRelease_playerDoesNotRaiseError()
throws Exception { throws Exception {
PlayerTestListener playerTestListener = new PlayerTestListener(TEST_TIMEOUT_MS); PlayerTestListener playerTestListener = new PlayerTestListener(TEST_TIMEOUT_MS);
EditedMediaItem video = EditedMediaItem video =

View File

@ -36,7 +36,7 @@ import java.util.Objects;
/** /**
* An {@link AudioSink} implementation that feeds an {@link AudioGraphInput}. * An {@link AudioSink} implementation that feeds an {@link AudioGraphInput}.
* *
* <p>Should be used by {@link PreviewAudioPipeline}. * <p>Should be used by {@link PlaybackAudioGraphWrapper}.
*/ */
/* package */ final class AudioGraphInputAudioSink implements AudioSink { /* package */ final class AudioGraphInputAudioSink implements AudioSink {

View File

@ -76,7 +76,7 @@ import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import androidx.media3.exoplayer.upstream.Allocator; import androidx.media3.exoplayer.upstream.Allocator;
import androidx.media3.exoplayer.util.EventLogger; import androidx.media3.exoplayer.util.EventLogger;
import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; import androidx.media3.exoplayer.video.PlaybackVideoGraphWrapper;
import androidx.media3.exoplayer.video.VideoFrameReleaseControl; import androidx.media3.exoplayer.video.VideoFrameReleaseControl;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -109,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@RestrictTo(LIBRARY_GROUP) @RestrictTo(LIBRARY_GROUP)
public final class CompositionPlayer extends SimpleBasePlayer public final class CompositionPlayer extends SimpleBasePlayer
implements CompositionPlayerInternal.Listener, implements CompositionPlayerInternal.Listener,
CompositingVideoSinkProvider.Listener, PlaybackVideoGraphWrapper.Listener,
SurfaceHolder.Callback { SurfaceHolder.Callback {
/** A builder for {@link CompositionPlayer} instances. */ /** A builder for {@link CompositionPlayer} instances. */
@ -369,10 +369,10 @@ public final class CompositionPlayer extends SimpleBasePlayer
setVideoSurfaceInternal(surface, videoOutputSize); setVideoSurfaceInternal(surface, videoOutputSize);
} }
// CompositingVideoSinkProvider.Listener methods. Called on playback thread. // PlaybackVideoGraphWrapper.Listener methods. Called on playback thread.
@Override @Override
public void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider) { public void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) {
applicationHandler.post( applicationHandler.post(
() -> { () -> {
CompositionPlayer.this.renderedFirstFrame = true; CompositionPlayer.this.renderedFirstFrame = true;
@ -381,27 +381,27 @@ public final class CompositionPlayer extends SimpleBasePlayer
} }
@Override @Override
public void onFrameDropped(CompositingVideoSinkProvider compositingVideoSinkProvider) { public void onFrameDropped(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) {
// Do not post to application thread on each dropped frame, because onFrameDropped // Do not post to application thread on each dropped frame, because onFrameDropped
// may be called frequently when resources are already scarce. // may be called frequently when resources are already scarce.
} }
@Override @Override
public void onVideoSizeChanged( public void onVideoSizeChanged(
CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize) { PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize) {
// TODO: b/328219481 - Report video size change to app. // TODO: b/328219481 - Report video size change to app.
} }
@Override @Override
public void onError( public void onError(
CompositingVideoSinkProvider compositingVideoSinkProvider, PlaybackVideoGraphWrapper playbackVideoGraphWrapper,
VideoFrameProcessingException videoFrameProcessingException) { VideoFrameProcessingException videoFrameProcessingException) {
// The error will also be surfaced from the underlying ExoPlayer instance via // The error will also be surfaced from the underlying ExoPlayer instance via
// PlayerListener.onPlayerError, and it will arrive to the composition player twice. // PlayerListener.onPlayerError, and it will arrive to the composition player twice.
applicationHandler.post( applicationHandler.post(
() -> () ->
maybeUpdatePlaybackError( maybeUpdatePlaybackError(
"error from video sink provider", "Error processing video frames",
videoFrameProcessingException, videoFrameProcessingException,
PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED)); PlaybackException.ERROR_CODE_VIDEO_FRAME_PROCESSING_FAILED));
} }
@ -660,23 +660,23 @@ public final class CompositionPlayer extends SimpleBasePlayer
playbackThread = new HandlerThread("CompositionPlaybackThread", Process.THREAD_PRIORITY_AUDIO); playbackThread = new HandlerThread("CompositionPlaybackThread", Process.THREAD_PRIORITY_AUDIO);
playbackThread.start(); playbackThread.start();
// Create the audio and video composition components now in order to setup the audio and video // Create the audio and video composition components now in order to setup the audio and video
// pipelines. Once this method returns, further access to the audio and video pipelines must // pipelines. Once this method returns, further access to the audio and video graph wrappers
// done on the playback thread only, to ensure related components are accessed from one thread // must done on the playback thread only, to ensure related components are accessed from one
// only. // thread only.
PreviewAudioPipeline previewAudioPipeline = PlaybackAudioGraphWrapper playbackAudioGraphWrapper =
new PreviewAudioPipeline( new PlaybackAudioGraphWrapper(
new DefaultAudioMixer.Factory(), new DefaultAudioMixer.Factory(),
composition.effects.audioProcessors, composition.effects.audioProcessors,
checkNotNull(finalAudioSink)); checkNotNull(finalAudioSink));
VideoFrameReleaseControl videoFrameReleaseControl = VideoFrameReleaseControl videoFrameReleaseControl =
new VideoFrameReleaseControl( new VideoFrameReleaseControl(
context, new CompositionFrameTimingEvaluator(), /* allowedJoiningTimeMs= */ 0); context, new CompositionFrameTimingEvaluator(), /* allowedJoiningTimeMs= */ 0);
CompositingVideoSinkProvider compositingVideoSinkProvider = PlaybackVideoGraphWrapper playbackVideoGraphWrapper =
new CompositingVideoSinkProvider.Builder(context, videoFrameReleaseControl) new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl)
.setPreviewingVideoGraphFactory(checkNotNull(previewingVideoGraphFactory)) .setPreviewingVideoGraphFactory(checkNotNull(previewingVideoGraphFactory))
.setClock(clock) .setClock(clock)
.build(); .build();
compositingVideoSinkProvider.addListener(this); playbackVideoGraphWrapper.addListener(this);
// Video playback is disabled when one EditedMediaItem removes video. // Video playback is disabled when one EditedMediaItem removes video.
boolean disableVideoPlayback = shouldDisableVideoPlayback(composition); boolean disableVideoPlayback = shouldDisableVideoPlayback(composition);
@ -687,11 +687,11 @@ public final class CompositionPlayer extends SimpleBasePlayer
? SequencePlayerRenderersWrapper.create( ? SequencePlayerRenderersWrapper.create(
context, context,
editedMediaItemSequence, editedMediaItemSequence,
previewAudioPipeline, playbackAudioGraphWrapper,
compositingVideoSinkProvider.getSink(), playbackVideoGraphWrapper.getSink(),
imageDecoderFactory) imageDecoderFactory)
: SequencePlayerRenderersWrapper.createForAudio( : SequencePlayerRenderersWrapper.createForAudio(
context, editedMediaItemSequence, previewAudioPipeline); context, editedMediaItemSequence, playbackAudioGraphWrapper);
ExoPlayer.Builder playerBuilder = ExoPlayer.Builder playerBuilder =
new ExoPlayer.Builder(context) new ExoPlayer.Builder(context)
.setLooper(getApplicationLooper()) .setLooper(getApplicationLooper())
@ -725,8 +725,8 @@ public final class CompositionPlayer extends SimpleBasePlayer
new CompositionPlayerInternal( new CompositionPlayerInternal(
playbackThread.getLooper(), playbackThread.getLooper(),
clock, clock,
previewAudioPipeline, playbackAudioGraphWrapper,
compositingVideoSinkProvider, playbackVideoGraphWrapper,
/* listener= */ this, /* listener= */ this,
compositionInternalListenerHandler); compositionInternalListenerHandler);
} }

View File

@ -28,7 +28,7 @@ import androidx.media3.common.util.HandlerWrapper;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.Size; import androidx.media3.common.util.Size;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; import androidx.media3.exoplayer.video.PlaybackVideoGraphWrapper;
/** Provides access to the composition preview audio and video components on the playback thread. */ /** Provides access to the composition preview audio and video components on the playback thread. */
/* package */ final class CompositionPlayerInternal implements Handler.Callback { /* package */ final class CompositionPlayerInternal implements Handler.Callback {
@ -57,10 +57,10 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
private final HandlerWrapper handler; private final HandlerWrapper handler;
/** Must be accessed on the playback thread only. */ /** Must be accessed on the playback thread only. */
private final PreviewAudioPipeline previewAudioPipeline; private final PlaybackAudioGraphWrapper playbackAudioGraphWrapper;
/** Must be accessed on the playback thread only. */ /** Must be accessed on the playback thread only. */
private final CompositingVideoSinkProvider compositingVideoSinkProvider; private final PlaybackVideoGraphWrapper playbackVideoGraphWrapper;
private final Listener listener; private final Listener listener;
private final HandlerWrapper listenerHandler; private final HandlerWrapper listenerHandler;
@ -72,22 +72,22 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
* *
* @param playbackLooper The playback thread {@link Looper}. * @param playbackLooper The playback thread {@link Looper}.
* @param clock The {@link Clock} used. * @param clock The {@link Clock} used.
* @param previewAudioPipeline The {@link PreviewAudioPipeline}. * @param playbackAudioGraphWrapper The {@link PlaybackAudioGraphWrapper}.
* @param compositingVideoSinkProvider The {@link CompositingVideoSinkProvider}. * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper}.
* @param listener A {@link Listener} to send callbacks back to the player. * @param listener A {@link Listener} to send callbacks back to the player.
* @param listenerHandler A {@link HandlerWrapper} to dispatch {@link Listener} callbacks. * @param listenerHandler A {@link HandlerWrapper} to dispatch {@link Listener} callbacks.
*/ */
public CompositionPlayerInternal( public CompositionPlayerInternal(
Looper playbackLooper, Looper playbackLooper,
Clock clock, Clock clock,
PreviewAudioPipeline previewAudioPipeline, PlaybackAudioGraphWrapper playbackAudioGraphWrapper,
CompositingVideoSinkProvider compositingVideoSinkProvider, PlaybackVideoGraphWrapper playbackVideoGraphWrapper,
Listener listener, Listener listener,
HandlerWrapper listenerHandler) { HandlerWrapper listenerHandler) {
this.clock = clock; this.clock = clock;
this.handler = clock.createHandler(playbackLooper, /* callback= */ this); this.handler = clock.createHandler(playbackLooper, /* callback= */ this);
this.previewAudioPipeline = previewAudioPipeline; this.playbackAudioGraphWrapper = playbackAudioGraphWrapper;
this.compositingVideoSinkProvider = compositingVideoSinkProvider; this.playbackVideoGraphWrapper = playbackVideoGraphWrapper;
this.listener = listener; this.listener = listener;
this.listenerHandler = listenerHandler; this.listenerHandler = listenerHandler;
} }
@ -149,10 +149,10 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
case MSG_START_SEEK: case MSG_START_SEEK:
// Video seeking is currently handled by the video renderers, specifically in // Video seeking is currently handled by the video renderers, specifically in
// onPositionReset. // onPositionReset.
previewAudioPipeline.startSeek(/* positionUs= */ Util.msToUs((long) message.obj)); playbackAudioGraphWrapper.startSeek(/* positionUs= */ Util.msToUs((long) message.obj));
break; break;
case MSG_END_SEEK: case MSG_END_SEEK:
previewAudioPipeline.endSeek(); playbackAudioGraphWrapper.endSeek();
break; break;
case MSG_RELEASE: case MSG_RELEASE:
releaseInternal(/* conditionVariable= */ (ConditionVariable) message.obj); releaseInternal(/* conditionVariable= */ (ConditionVariable) message.obj);
@ -176,9 +176,9 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
private void releaseInternal(ConditionVariable conditionVariable) { private void releaseInternal(ConditionVariable conditionVariable) {
try { try {
previewAudioPipeline.release(); playbackAudioGraphWrapper.release();
compositingVideoSinkProvider.clearOutputSurfaceInfo(); playbackVideoGraphWrapper.clearOutputSurfaceInfo();
compositingVideoSinkProvider.release(); playbackVideoGraphWrapper.release();
} catch (RuntimeException e) { } catch (RuntimeException e) {
Log.e(TAG, "error while releasing the player", e); Log.e(TAG, "error while releasing the player", e);
} finally { } finally {
@ -188,7 +188,7 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
private void clearOutputSurfaceInternal() { private void clearOutputSurfaceInternal() {
try { try {
compositingVideoSinkProvider.clearOutputSurfaceInfo(); playbackVideoGraphWrapper.clearOutputSurfaceInfo();
} catch (RuntimeException e) { } catch (RuntimeException e) {
maybeRaiseError( maybeRaiseError(
/* message= */ "error clearing video output", /* message= */ "error clearing video output",
@ -199,7 +199,7 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider;
private void setOutputSurfaceInfoOnInternalThread(OutputSurfaceInfo outputSurfaceInfo) { private void setOutputSurfaceInfoOnInternalThread(OutputSurfaceInfo outputSurfaceInfo) {
try { try {
compositingVideoSinkProvider.setOutputSurfaceInfo( playbackVideoGraphWrapper.setOutputSurfaceInfo(
outputSurfaceInfo.surface, outputSurfaceInfo.size); outputSurfaceInfo.surface, outputSurfaceInfo.size);
} catch (RuntimeException e) { } catch (RuntimeException e) {
maybeRaiseError( maybeRaiseError(

View File

@ -34,7 +34,7 @@ import java.util.Objects;
* *
* <p>Multiple streams of {@linkplain #createInput() input} are not currently supported. * <p>Multiple streams of {@linkplain #createInput() input} are not currently supported.
*/ */
/* package */ final class PreviewAudioPipeline { /* package */ final class PlaybackAudioGraphWrapper {
private final AudioSink finalAudioSink; private final AudioSink finalAudioSink;
private final AudioGraph audioGraph; private final AudioGraph audioGraph;
@ -53,7 +53,7 @@ import java.util.Objects;
* @param effects The composition-level audio effects that are applied after mixing. * @param effects The composition-level audio effects that are applied after mixing.
* @param finalAudioSink The {@linkplain AudioSink sink} for processed output audio. * @param finalAudioSink The {@linkplain AudioSink sink} for processed output audio.
*/ */
public PreviewAudioPipeline( public PlaybackAudioGraphWrapper(
AudioMixer.Factory mixerFactory, AudioMixer.Factory mixerFactory,
ImmutableList<AudioProcessor> effects, ImmutableList<AudioProcessor> effects,
AudioSink finalAudioSink) { AudioSink finalAudioSink) {

View File

@ -62,7 +62,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private final Context context; private final Context context;
private final EditedMediaItemSequence sequence; private final EditedMediaItemSequence sequence;
private final PreviewAudioPipeline previewAudioPipeline; private final PlaybackAudioGraphWrapper playbackAudioGraphWrapper;
@Nullable private final VideoSink videoSink; @Nullable private final VideoSink videoSink;
@Nullable private final ImageDecoder.Factory imageDecoderFactory; @Nullable private final ImageDecoder.Factory imageDecoderFactory;
@ -70,22 +70,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public static SequencePlayerRenderersWrapper create( public static SequencePlayerRenderersWrapper create(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PreviewAudioPipeline previewAudioPipeline, PlaybackAudioGraphWrapper playbackAudioGraphWrapper,
VideoSink videoSink, VideoSink videoSink,
ImageDecoder.Factory imageDecoderFactory) { ImageDecoder.Factory imageDecoderFactory) {
return new SequencePlayerRenderersWrapper( return new SequencePlayerRenderersWrapper(
context, sequence, previewAudioPipeline, videoSink, imageDecoderFactory); context, sequence, playbackAudioGraphWrapper, videoSink, imageDecoderFactory);
} }
/** Creates a renderers wrapper that for a player that will only play audio. */ /** Creates a renderers wrapper that for a player that will only play audio. */
public static SequencePlayerRenderersWrapper createForAudio( public static SequencePlayerRenderersWrapper createForAudio(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PreviewAudioPipeline previewAudioPipeline) { PlaybackAudioGraphWrapper playbackAudioGraphWrapper) {
return new SequencePlayerRenderersWrapper( return new SequencePlayerRenderersWrapper(
context, context,
sequence, sequence,
previewAudioPipeline, playbackAudioGraphWrapper,
/* videoSink= */ null, /* videoSink= */ null,
/* imageDecoderFactory= */ null); /* imageDecoderFactory= */ null);
} }
@ -93,12 +93,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private SequencePlayerRenderersWrapper( private SequencePlayerRenderersWrapper(
Context context, Context context,
EditedMediaItemSequence sequence, EditedMediaItemSequence sequence,
PreviewAudioPipeline previewAudioPipeline, PlaybackAudioGraphWrapper playbackAudioGraphWrapper,
@Nullable VideoSink videoSink, @Nullable VideoSink videoSink,
@Nullable ImageDecoder.Factory imageDecoderFactory) { @Nullable ImageDecoder.Factory imageDecoderFactory) {
this.context = context; this.context = context;
this.sequence = sequence; this.sequence = sequence;
this.previewAudioPipeline = previewAudioPipeline; this.playbackAudioGraphWrapper = playbackAudioGraphWrapper;
this.videoSink = videoSink; this.videoSink = videoSink;
this.imageDecoderFactory = imageDecoderFactory; this.imageDecoderFactory = imageDecoderFactory;
} }
@ -117,7 +117,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/* sequencePlayerRenderersWrapper= */ this, /* sequencePlayerRenderersWrapper= */ this,
eventHandler, eventHandler,
audioRendererEventListener, audioRendererEventListener,
previewAudioPipeline.createInput())); playbackAudioGraphWrapper.createInput()));
if (videoSink != null) { if (videoSink != null) {
renderers.add( renderers.add(
@ -177,7 +177,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
super.render(positionUs, elapsedRealtimeUs); super.render(positionUs, elapsedRealtimeUs);
try { try {
while (sequencePlayerRenderersWrapper.previewAudioPipeline.processData()) {} while (sequencePlayerRenderersWrapper.playbackAudioGraphWrapper.processData()) {}
} catch (ExportException } catch (ExportException
| AudioSink.WriteException | AudioSink.WriteException
| AudioSink.InitializationException | AudioSink.InitializationException

View File

@ -36,41 +36,41 @@ import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
/** Unit tests for {@link PreviewAudioPipeline}. */ /** Unit tests for {@link PlaybackAudioGraphWrapper}. */
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class PreviewAudioPipelineTest { public class PlaybackAudioGraphWrapperTest {
@Rule public final MockitoRule mockito = MockitoJUnit.rule(); @Rule public final MockitoRule mockito = MockitoJUnit.rule();
private PreviewAudioPipeline previewAudioPipeline; private PlaybackAudioGraphWrapper playbackAudioGraphWrapper;
@Mock AudioSink outputAudioSink; @Mock AudioSink outputAudioSink;
@Before @Before
public void setUp() { public void setUp() {
previewAudioPipeline = playbackAudioGraphWrapper =
new PreviewAudioPipeline( new PlaybackAudioGraphWrapper(
new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(), outputAudioSink); new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(), outputAudioSink);
} }
@After @After
public void tearDown() { public void tearDown() {
previewAudioPipeline.release(); playbackAudioGraphWrapper.release();
} }
@Test @Test
public void processData_noAudioSinksCreated_returnsFalse() throws Exception { public void processData_noAudioSinksCreated_returnsFalse() throws Exception {
assertThat(previewAudioPipeline.processData()).isFalse(); assertThat(playbackAudioGraphWrapper.processData()).isFalse();
} }
@Test @Test
public void processData_audioSinkHasNotConfiguredYet_returnsFalse() throws Exception { public void processData_audioSinkHasNotConfiguredYet_returnsFalse() throws Exception {
AudioGraphInputAudioSink unused = previewAudioPipeline.createInput(); AudioGraphInputAudioSink unused = playbackAudioGraphWrapper.createInput();
assertThat(previewAudioPipeline.processData()).isFalse(); assertThat(playbackAudioGraphWrapper.processData()).isFalse();
} }
@Test @Test
public void inputPlay_withOneInput_playsOutputSink() throws Exception { public void inputPlay_withOneInput_playsOutputSink() throws Exception {
AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput();
inputAudioSink.play(); inputAudioSink.play();
@ -79,7 +79,7 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void inputPause_withOneInput_pausesOutputSink() throws Exception { public void inputPause_withOneInput_pausesOutputSink() throws Exception {
AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput();
inputAudioSink.play(); inputAudioSink.play();
inputAudioSink.pause(); inputAudioSink.pause();
@ -89,7 +89,7 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void inputReset_withOneInput_pausesOutputSink() { public void inputReset_withOneInput_pausesOutputSink() {
AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput();
inputAudioSink.play(); inputAudioSink.play();
inputAudioSink.reset(); inputAudioSink.reset();
@ -99,7 +99,7 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void inputPlay_whenPlaying_doesNotPlayOutputSink() throws Exception { public void inputPlay_whenPlaying_doesNotPlayOutputSink() throws Exception {
AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput();
inputAudioSink.play(); inputAudioSink.play();
inputAudioSink.play(); inputAudioSink.play();
@ -108,7 +108,7 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void inputPause_whenNotPlaying_doesNotPauseOutputSink() throws Exception { public void inputPause_whenNotPlaying_doesNotPauseOutputSink() throws Exception {
AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput();
inputAudioSink.pause(); inputAudioSink.pause();
@ -117,9 +117,9 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void someInputPlay_withMultipleInputs_doesNotPlayOutputSink() throws Exception { public void someInputPlay_withMultipleInputs_doesNotPlayOutputSink() throws Exception {
AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink unused = previewAudioPipeline.createInput(); AudioGraphInputAudioSink unused = playbackAudioGraphWrapper.createInput();
inputAudioSink1.play(); inputAudioSink1.play();
inputAudioSink2.play(); inputAudioSink2.play();
@ -128,9 +128,9 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void allInputPlay_withMultipleInputs_playsOutputSinkOnce() throws Exception { public void allInputPlay_withMultipleInputs_playsOutputSinkOnce() throws Exception {
AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput();
inputAudioSink1.play(); inputAudioSink1.play();
inputAudioSink2.play(); inputAudioSink2.play();
@ -142,9 +142,9 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void firstInputPause_withMultipleInputs_pausesOutputSink() throws Exception { public void firstInputPause_withMultipleInputs_pausesOutputSink() throws Exception {
InOrder inOrder = inOrder(outputAudioSink); InOrder inOrder = inOrder(outputAudioSink);
AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput();
inputAudioSink1.play(); inputAudioSink1.play();
inputAudioSink2.play(); inputAudioSink2.play();
@ -157,9 +157,9 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void allInputPause_withMultipleInputs_pausesOutputSinkOnce() throws Exception { public void allInputPause_withMultipleInputs_pausesOutputSinkOnce() throws Exception {
AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput();
inputAudioSink1.play(); inputAudioSink1.play();
inputAudioSink2.play(); inputAudioSink2.play();
@ -174,9 +174,9 @@ public class PreviewAudioPipelineTest {
@Test @Test
public void inputPlayAfterPause_withMultipleInputs_playsOutputSink() throws Exception { public void inputPlayAfterPause_withMultipleInputs_playsOutputSink() throws Exception {
InOrder inOrder = inOrder(outputAudioSink); InOrder inOrder = inOrder(outputAudioSink);
AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput();
AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput();
inputAudioSink1.play(); inputAudioSink1.play();
inputAudioSink2.play(); inputAudioSink2.play();