From 8271a5f92081b89b4fdd0200342e38ea37c7dc7e Mon Sep 17 00:00:00 2001 From: kimvde Date: Wed, 11 Sep 2024 05:46:44 -0700 Subject: [PATCH] Rename CompositingVideoSinkProvider and PreviewAudioPipeline The components are mirror components for video and audio so they should have a matching name PiperOrigin-RevId: 673357081 --- libraries/exoplayer/proguard-rules.txt | 2 +- .../video/MediaCodecVideoRenderer.java | 6 +- ...er.java => PlaybackVideoGraphWrapper.java} | 104 +++++++++--------- ...ava => PlaybackVideoGraphWrapperTest.java} | 14 +-- .../transformer/CompositionPlayerTest.java | 4 +- .../transformer/AudioGraphInputAudioSink.java | 2 +- .../media3/transformer/CompositionPlayer.java | 42 +++---- .../CompositionPlayerInternal.java | 32 +++--- ...ne.java => PlaybackAudioGraphWrapper.java} | 4 +- .../SequencePlayerRenderersWrapper.java | 18 +-- ...ava => PlaybackAudioGraphWrapperTest.java} | 58 +++++----- 11 files changed, 144 insertions(+), 142 deletions(-) rename libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/{CompositingVideoSinkProvider.java => PlaybackVideoGraphWrapper.java} (90%) rename libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/{CompositingVideoSinkProviderTest.java => PlaybackVideoGraphWrapperTest.java} (88%) rename libraries/transformer/src/main/java/androidx/media3/transformer/{PreviewAudioPipeline.java => PlaybackAudioGraphWrapper.java} (98%) rename libraries/transformer/src/test/java/androidx/media3/transformer/{PreviewAudioPipelineTest.java => PlaybackAudioGraphWrapperTest.java} (66%) diff --git a/libraries/exoplayer/proguard-rules.txt b/libraries/exoplayer/proguard-rules.txt index 30727719f8..d4c8491751 100644 --- a/libraries/exoplayer/proguard-rules.txt +++ b/libraries/exoplayer/proguard-rules.txt @@ -66,7 +66,7 @@ (); } -# Constructors and methods accessed via reflection in CompositingVideoSinkProvider +# Constructors and methods accessed via reflection in PlaybackVideoGraphWrapper -dontnote androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory -keepclasseswithmembers class androidx.media3.effect.PreviewingSingleInputVideoGraph$Factory { (androidx.media3.common.VideoFrameProcessor$Factory); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java index a7c31e671e..087d443ac2 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/MediaCodecVideoRenderer.java @@ -410,8 +410,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer * explicitly using {@link MediaFormat#KEY_OPERATING_RATE}). * @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 - * CompositingVideoSinkProvider} with its default configuration will be used to apply effects - * and render the frames on the output. + * PlaybackVideoGraphWrapper} with its default configuration will be used to apply effects and + * render the frames on the output. */ public MediaCodecVideoRenderer( Context context, @@ -677,7 +677,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer if (!hasSetVideoSink) { if (videoEffects != null && videoSink == null) { videoSink = - new CompositingVideoSinkProvider.Builder(context, videoFrameReleaseControl) + new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl) .setClock(getClock()) .build() .getSink(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java similarity index 90% rename from libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java rename to libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java index 7ce4a53609..5f790ec70a 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/CompositingVideoSinkProvider.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapper.java @@ -65,53 +65,56 @@ import java.util.concurrent.Executor; import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf; 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 @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 { /** * 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. */ - void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider); + void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper); /** * 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. */ - 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 * 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. * @param videoSize The video size. */ void onVideoSizeChanged( - CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize); + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize); /** * 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. * @param videoFrameProcessingException The error. */ void onError( - CompositingVideoSinkProvider compositingVideoSinkProvider, + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoFrameProcessingException videoFrameProcessingException); } - /** A builder for {@link CompositingVideoSinkProvider} instances. */ + /** A builder for {@link PlaybackVideoGraphWrapper} instances. */ public static final class Builder { private final Context context; private final VideoFrameReleaseControl videoFrameReleaseControl; @@ -176,12 +179,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi } /** - * Builds the {@link CompositingVideoSinkProvider}. + * Builds the {@link PlaybackVideoGraphWrapper}. * *

This method must be called at most once and will throw an {@link IllegalStateException} if * it has already been called. */ - public CompositingVideoSinkProvider build() { + public PlaybackVideoGraphWrapper build() { checkState(!built); if (previewingVideoGraphFactory == null) { @@ -191,10 +194,9 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi previewingVideoGraphFactory = new ReflectivePreviewingSingleInputVideoGraphFactory(videoFrameProcessorFactory); } - CompositingVideoSinkProvider compositingVideoSinkProvider = - new CompositingVideoSinkProvider(this); + PlaybackVideoGraphWrapper playbackVideoGraphWrapper = new PlaybackVideoGraphWrapper(this); built = true; - return compositingVideoSinkProvider; + return playbackVideoGraphWrapper; } } @@ -216,7 +218,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi private final VideoFrameRenderControl videoFrameRenderControl; private final PreviewingVideoGraph.Factory previewingVideoGraphFactory; private final Clock clock; - private final CopyOnWriteArraySet listeners; + private final CopyOnWriteArraySet listeners; private @MonotonicNonNull Format outputFormat; private @MonotonicNonNull VideoFrameMetadataListener videoFrameMetadataListener; @@ -233,7 +235,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi */ private long bufferTimestampAdjustmentUs; - private CompositingVideoSinkProvider(Builder builder) { + private PlaybackVideoGraphWrapper(Builder builder) { context = builder.context; videoSinkImpl = new VideoSinkImpl(context); 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. */ - public void addListener(CompositingVideoSinkProvider.Listener listener) { + public void addListener(PlaybackVideoGraphWrapper.Listener listener) { listeners.add(listener); } /** - * Removes a {@link CompositingVideoSinkProvider.Listener}. + * Removes a {@link PlaybackVideoGraphWrapper.Listener}. * * @param listener The listener to be removed. */ - public void removeListener(CompositingVideoSinkProvider.Listener listener) { + public void removeListener(PlaybackVideoGraphWrapper.Listener listener) { listeners.remove(listener); } @@ -321,7 +323,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void onOutputFrameAvailableForRendering(long framePresentationTimeUs) { if (pendingFlushCount > 0) { - // Ignore available frames while the sink provider is flushing + // Ignore available frames while flushing return; } // 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 public void onError(VideoFrameProcessingException exception) { - for (CompositingVideoSinkProvider.Listener listener : listeners) { - listener.onError(/* compositingVideoSinkProvider= */ this, exception); + for (PlaybackVideoGraphWrapper.Listener listener : listeners) { + 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. */ - private final class VideoSinkImpl implements VideoSink, CompositingVideoSinkProvider.Listener { + private final class VideoSinkImpl implements VideoSink, PlaybackVideoGraphWrapper.Listener { private final int videoFrameProcessorMaxPendingFrameCount; private final ArrayList videoEffects; @@ -539,7 +541,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void initialize(Format sourceFormat) throws VideoSinkException { checkState(!isInitialized()); - videoFrameProcessor = CompositingVideoSinkProvider.this.initialize(sourceFormat); + videoFrameProcessor = PlaybackVideoGraphWrapper.this.initialize(sourceFormat); } @Override @@ -556,7 +558,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi hasRegisteredFirstInputStream = false; finalBufferPresentationTimeUs = C.TIME_UNSET; lastBufferPresentationTimeUs = C.TIME_UNSET; - CompositingVideoSinkProvider.this.flush(); + PlaybackVideoGraphWrapper.this.flush(); if (resetPosition) { videoFrameReleaseControl.reset(); } @@ -569,7 +571,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public boolean isReady(boolean rendererOtherwiseReady) { - return CompositingVideoSinkProvider.this.isReady( + return PlaybackVideoGraphWrapper.this.isReady( /* rendererOtherwiseReady= */ rendererOtherwiseReady && isInitialized()); } @@ -577,7 +579,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi public boolean isEnded() { return isInitialized() && finalBufferPresentationTimeUs != C.TIME_UNSET - && CompositingVideoSinkProvider.this.hasReleasedFrame(finalBufferPresentationTimeUs); + && PlaybackVideoGraphWrapper.this.hasReleasedFrame(finalBufferPresentationTimeUs); } @Override @@ -619,12 +621,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void setVideoFrameMetadataListener( VideoFrameMetadataListener videoFrameMetadataListener) { - CompositingVideoSinkProvider.this.setVideoFrameMetadataListener(videoFrameMetadataListener); + PlaybackVideoGraphWrapper.this.setVideoFrameMetadataListener(videoFrameMetadataListener); } @Override public void setPlaybackSpeed(@FloatRange(from = 0, fromInclusive = false) float speed) { - CompositingVideoSinkProvider.this.setPlaybackSpeed(speed); + PlaybackVideoGraphWrapper.this.setPlaybackSpeed(speed); } @Override @@ -660,12 +662,12 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void setOutputSurfaceInfo(Surface outputSurface, Size outputResolution) { - CompositingVideoSinkProvider.this.setOutputSurfaceInfo(outputSurface, outputResolution); + PlaybackVideoGraphWrapper.this.setOutputSurfaceInfo(outputSurface, outputResolution); } @Override public void clearOutputSurfaceInfo() { - CompositingVideoSinkProvider.this.clearOutputSurfaceInfo(); + PlaybackVideoGraphWrapper.this.clearOutputSurfaceInfo(); } @Override @@ -734,7 +736,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi // input frame from the next input stream. if (isInputStreamChangePending) { if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET - || CompositingVideoSinkProvider.this.hasReleasedFrame( + || PlaybackVideoGraphWrapper.this.hasReleasedFrame( pendingInputStreamBufferPresentationTimeUs)) { maybeRegisterInputStream(); isInputStreamChangePending = false; @@ -793,7 +795,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void render(long positionUs, long elapsedRealtimeUs) throws VideoSinkException { try { - CompositingVideoSinkProvider.this.render(positionUs, elapsedRealtimeUs); + PlaybackVideoGraphWrapper.this.render(positionUs, elapsedRealtimeUs); } catch (ExoPlaybackException e) { throw new VideoSinkException( e, inputFormat != null ? inputFormat : new Format.Builder().build()); @@ -807,14 +809,14 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void release() { - CompositingVideoSinkProvider.this.release(); + PlaybackVideoGraphWrapper.this.release(); } // Other methods private void maybeSetStreamOffsetChange(long bufferPresentationTimeUs) { if (pendingInputStreamOffsetChange) { - CompositingVideoSinkProvider.this.onStreamOffsetChange( + PlaybackVideoGraphWrapper.this.onStreamOffsetChange( inputBufferTimestampAdjustmentUs, bufferPresentationTimeUs, /* 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 // input frame from the next input stream. if (pendingInputStreamBufferPresentationTimeUs == C.TIME_UNSET - || CompositingVideoSinkProvider.this.hasReleasedFrame( + || PlaybackVideoGraphWrapper.this.hasReleasedFrame( pendingInputStreamBufferPresentationTimeUs)) { maybeRegisterInputStream(); isInputStreamChangePending = false; @@ -864,16 +866,16 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi finalBufferPresentationTimeUs = C.TIME_UNSET; } - // CompositingVideoSinkProvider.Listener implementation + // PlaybackVideoGraphWrapper.Listener implementation @Override - public void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider) { + public void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) { VideoSink.Listener currentListener = listener; listenerExecutor.execute(() -> currentListener.onFirstFrameRendered(/* videoSink= */ this)); } @Override - public void onFrameDropped(CompositingVideoSinkProvider compositingVideoSinkProvider) { + public void onFrameDropped(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) { VideoSink.Listener currentListener = listener; listenerExecutor.execute( () -> currentListener.onFrameDropped(checkStateNotNull(/* reference= */ this))); @@ -881,7 +883,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void onVideoSizeChanged( - CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize) { + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize) { VideoSink.Listener currentListener = listener; listenerExecutor.execute( () -> currentListener.onVideoSizeChanged(/* videoSink= */ this, videoSize)); @@ -889,7 +891,7 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void onError( - CompositingVideoSinkProvider compositingVideoSinkProvider, + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoFrameProcessingException videoFrameProcessingException) { VideoSink.Listener currentListener = listener; listenerExecutor.execute( @@ -911,8 +913,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi .setHeight(videoSize.height) .setSampleMimeType(MimeTypes.VIDEO_RAW) .build(); - for (CompositingVideoSinkProvider.Listener listener : listeners) { - listener.onVideoSizeChanged(CompositingVideoSinkProvider.this, videoSize); + for (PlaybackVideoGraphWrapper.Listener listener : listeners) { + listener.onVideoSizeChanged(PlaybackVideoGraphWrapper.this, videoSize); } } @@ -923,8 +925,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi long streamOffsetUs, boolean isFirstFrame) { if (isFirstFrame && currentSurfaceAndSize != null) { - for (CompositingVideoSinkProvider.Listener listener : listeners) { - listener.onFirstFrameRendered(CompositingVideoSinkProvider.this); + for (PlaybackVideoGraphWrapper.Listener listener : listeners) { + listener.onFirstFrameRendered(PlaybackVideoGraphWrapper.this); } } if (videoFrameMetadataListener != null) { @@ -942,8 +944,8 @@ public final class CompositingVideoSinkProvider implements VideoSinkProvider, Vi @Override public void dropFrame() { - for (CompositingVideoSinkProvider.Listener listener : listeners) { - listener.onFrameDropped(CompositingVideoSinkProvider.this); + for (PlaybackVideoGraphWrapper.Listener listener : listeners) { + listener.onFrameDropped(PlaybackVideoGraphWrapper.this); } checkStateNotNull(videoGraph).renderOutputFrame(VideoFrameProcessor.DROP_OUTPUT_FRAME); } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/CompositingVideoSinkProviderTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapperTest.java similarity index 88% rename from libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/CompositingVideoSinkProviderTest.java rename to libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapperTest.java index f630c49af8..0c776c30c8 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/CompositingVideoSinkProviderTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/video/PlaybackVideoGraphWrapperTest.java @@ -35,14 +35,14 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; -/** Unit test for {@link CompositingVideoSinkProvider}. */ +/** Unit test for {@link PlaybackVideoGraphWrapper}. */ @RunWith(AndroidJUnit4.class) -public final class CompositingVideoSinkProviderTest { +public final class PlaybackVideoGraphWrapperTest { @Test public void builder_calledMultipleTimes_throws() { Context context = ApplicationProvider.getApplicationContext(); - CompositingVideoSinkProvider.Builder builder = - new CompositingVideoSinkProvider.Builder(context, createVideoFrameReleaseControl()); + PlaybackVideoGraphWrapper.Builder builder = + new PlaybackVideoGraphWrapper.Builder(context, createVideoFrameReleaseControl()); builder.build(); @@ -51,16 +51,16 @@ public final class CompositingVideoSinkProviderTest { @Test public void initializeSink_calledTwice_throws() throws VideoSink.VideoSinkException { - CompositingVideoSinkProvider provider = createCompositingVideoSinkProvider(); + PlaybackVideoGraphWrapper provider = createPlaybackVideoGraphWrapper(); VideoSink sink = provider.getSink(); 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(); - return new CompositingVideoSinkProvider.Builder(context, createVideoFrameReleaseControl()) + return new PlaybackVideoGraphWrapper.Builder(context, createVideoFrameReleaseControl()) .setPreviewingVideoGraphFactory(new TestPreviewingVideoGraphFactory()) .build(); } diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/CompositionPlayerTest.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/CompositionPlayerTest.java index c17664771f..bfafc40863 100644 --- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/CompositionPlayerTest.java +++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/CompositionPlayerTest.java @@ -442,7 +442,7 @@ public class CompositionPlayerTest { } @Test - public void playback_videoSinkProviderFails_playerRaisesError() { + public void playback_videoGraphWrapperFails_playerRaisesError() { PlayerTestListener listener = new PlayerTestListener(TEST_TIMEOUT_MS); EditedMediaItem video = new EditedMediaItem.Builder(MediaItem.fromUri(MP4_ASSET.uri)) @@ -478,7 +478,7 @@ public class CompositionPlayerTest { } @Test - public void release_videoSinkProviderFailsDuringRelease_playerDoesNotRaiseError() + public void release_videoGraphWrapperFailsDuringRelease_playerDoesNotRaiseError() throws Exception { PlayerTestListener playerTestListener = new PlayerTestListener(TEST_TIMEOUT_MS); EditedMediaItem video = diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraphInputAudioSink.java b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraphInputAudioSink.java index 1c389d126f..4f9b1d8aa8 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraphInputAudioSink.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/AudioGraphInputAudioSink.java @@ -36,7 +36,7 @@ import java.util.Objects; /** * An {@link AudioSink} implementation that feeds an {@link AudioGraphInput}. * - *

Should be used by {@link PreviewAudioPipeline}. + *

Should be used by {@link PlaybackAudioGraphWrapper}. */ /* package */ final class AudioGraphInputAudioSink implements AudioSink { diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java index 29d46e1d02..3e17b902d9 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayer.java @@ -76,7 +76,7 @@ import androidx.media3.exoplayer.trackselection.DefaultTrackSelector; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.upstream.Allocator; 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 com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -109,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; @RestrictTo(LIBRARY_GROUP) public final class CompositionPlayer extends SimpleBasePlayer implements CompositionPlayerInternal.Listener, - CompositingVideoSinkProvider.Listener, + PlaybackVideoGraphWrapper.Listener, SurfaceHolder.Callback { /** A builder for {@link CompositionPlayer} instances. */ @@ -369,10 +369,10 @@ public final class CompositionPlayer extends SimpleBasePlayer setVideoSurfaceInternal(surface, videoOutputSize); } - // CompositingVideoSinkProvider.Listener methods. Called on playback thread. + // PlaybackVideoGraphWrapper.Listener methods. Called on playback thread. @Override - public void onFirstFrameRendered(CompositingVideoSinkProvider compositingVideoSinkProvider) { + public void onFirstFrameRendered(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) { applicationHandler.post( () -> { CompositionPlayer.this.renderedFirstFrame = true; @@ -381,27 +381,27 @@ public final class CompositionPlayer extends SimpleBasePlayer } @Override - public void onFrameDropped(CompositingVideoSinkProvider compositingVideoSinkProvider) { + public void onFrameDropped(PlaybackVideoGraphWrapper playbackVideoGraphWrapper) { // Do not post to application thread on each dropped frame, because onFrameDropped // may be called frequently when resources are already scarce. } @Override public void onVideoSizeChanged( - CompositingVideoSinkProvider compositingVideoSinkProvider, VideoSize videoSize) { + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoSize videoSize) { // TODO: b/328219481 - Report video size change to app. } @Override public void onError( - CompositingVideoSinkProvider compositingVideoSinkProvider, + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, VideoFrameProcessingException videoFrameProcessingException) { // The error will also be surfaced from the underlying ExoPlayer instance via // PlayerListener.onPlayerError, and it will arrive to the composition player twice. applicationHandler.post( () -> maybeUpdatePlaybackError( - "error from video sink provider", + "Error processing video frames", videoFrameProcessingException, 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.start(); // 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 - // done on the playback thread only, to ensure related components are accessed from one thread - // only. - PreviewAudioPipeline previewAudioPipeline = - new PreviewAudioPipeline( + // pipelines. Once this method returns, further access to the audio and video graph wrappers + // must done on the playback thread only, to ensure related components are accessed from one + // thread only. + PlaybackAudioGraphWrapper playbackAudioGraphWrapper = + new PlaybackAudioGraphWrapper( new DefaultAudioMixer.Factory(), composition.effects.audioProcessors, checkNotNull(finalAudioSink)); VideoFrameReleaseControl videoFrameReleaseControl = new VideoFrameReleaseControl( context, new CompositionFrameTimingEvaluator(), /* allowedJoiningTimeMs= */ 0); - CompositingVideoSinkProvider compositingVideoSinkProvider = - new CompositingVideoSinkProvider.Builder(context, videoFrameReleaseControl) + PlaybackVideoGraphWrapper playbackVideoGraphWrapper = + new PlaybackVideoGraphWrapper.Builder(context, videoFrameReleaseControl) .setPreviewingVideoGraphFactory(checkNotNull(previewingVideoGraphFactory)) .setClock(clock) .build(); - compositingVideoSinkProvider.addListener(this); + playbackVideoGraphWrapper.addListener(this); // Video playback is disabled when one EditedMediaItem removes video. boolean disableVideoPlayback = shouldDisableVideoPlayback(composition); @@ -687,11 +687,11 @@ public final class CompositionPlayer extends SimpleBasePlayer ? SequencePlayerRenderersWrapper.create( context, editedMediaItemSequence, - previewAudioPipeline, - compositingVideoSinkProvider.getSink(), + playbackAudioGraphWrapper, + playbackVideoGraphWrapper.getSink(), imageDecoderFactory) : SequencePlayerRenderersWrapper.createForAudio( - context, editedMediaItemSequence, previewAudioPipeline); + context, editedMediaItemSequence, playbackAudioGraphWrapper); ExoPlayer.Builder playerBuilder = new ExoPlayer.Builder(context) .setLooper(getApplicationLooper()) @@ -725,8 +725,8 @@ public final class CompositionPlayer extends SimpleBasePlayer new CompositionPlayerInternal( playbackThread.getLooper(), clock, - previewAudioPipeline, - compositingVideoSinkProvider, + playbackAudioGraphWrapper, + playbackVideoGraphWrapper, /* listener= */ this, compositionInternalListenerHandler); } diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayerInternal.java b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayerInternal.java index fbcbe8e987..910bb23134 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayerInternal.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/CompositionPlayerInternal.java @@ -28,7 +28,7 @@ import androidx.media3.common.util.HandlerWrapper; import androidx.media3.common.util.Log; import androidx.media3.common.util.Size; 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. */ /* package */ final class CompositionPlayerInternal implements Handler.Callback { @@ -57,10 +57,10 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; private final HandlerWrapper handler; /** Must be accessed on the playback thread only. */ - private final PreviewAudioPipeline previewAudioPipeline; + private final PlaybackAudioGraphWrapper playbackAudioGraphWrapper; /** Must be accessed on the playback thread only. */ - private final CompositingVideoSinkProvider compositingVideoSinkProvider; + private final PlaybackVideoGraphWrapper playbackVideoGraphWrapper; private final Listener listener; private final HandlerWrapper listenerHandler; @@ -72,22 +72,22 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; * * @param playbackLooper The playback thread {@link Looper}. * @param clock The {@link Clock} used. - * @param previewAudioPipeline The {@link PreviewAudioPipeline}. - * @param compositingVideoSinkProvider The {@link CompositingVideoSinkProvider}. + * @param playbackAudioGraphWrapper The {@link PlaybackAudioGraphWrapper}. + * @param playbackVideoGraphWrapper The {@link PlaybackVideoGraphWrapper}. * @param listener A {@link Listener} to send callbacks back to the player. * @param listenerHandler A {@link HandlerWrapper} to dispatch {@link Listener} callbacks. */ public CompositionPlayerInternal( Looper playbackLooper, Clock clock, - PreviewAudioPipeline previewAudioPipeline, - CompositingVideoSinkProvider compositingVideoSinkProvider, + PlaybackAudioGraphWrapper playbackAudioGraphWrapper, + PlaybackVideoGraphWrapper playbackVideoGraphWrapper, Listener listener, HandlerWrapper listenerHandler) { this.clock = clock; this.handler = clock.createHandler(playbackLooper, /* callback= */ this); - this.previewAudioPipeline = previewAudioPipeline; - this.compositingVideoSinkProvider = compositingVideoSinkProvider; + this.playbackAudioGraphWrapper = playbackAudioGraphWrapper; + this.playbackVideoGraphWrapper = playbackVideoGraphWrapper; this.listener = listener; this.listenerHandler = listenerHandler; } @@ -149,10 +149,10 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; case MSG_START_SEEK: // Video seeking is currently handled by the video renderers, specifically in // onPositionReset. - previewAudioPipeline.startSeek(/* positionUs= */ Util.msToUs((long) message.obj)); + playbackAudioGraphWrapper.startSeek(/* positionUs= */ Util.msToUs((long) message.obj)); break; case MSG_END_SEEK: - previewAudioPipeline.endSeek(); + playbackAudioGraphWrapper.endSeek(); break; case MSG_RELEASE: releaseInternal(/* conditionVariable= */ (ConditionVariable) message.obj); @@ -176,9 +176,9 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; private void releaseInternal(ConditionVariable conditionVariable) { try { - previewAudioPipeline.release(); - compositingVideoSinkProvider.clearOutputSurfaceInfo(); - compositingVideoSinkProvider.release(); + playbackAudioGraphWrapper.release(); + playbackVideoGraphWrapper.clearOutputSurfaceInfo(); + playbackVideoGraphWrapper.release(); } catch (RuntimeException e) { Log.e(TAG, "error while releasing the player", e); } finally { @@ -188,7 +188,7 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; private void clearOutputSurfaceInternal() { try { - compositingVideoSinkProvider.clearOutputSurfaceInfo(); + playbackVideoGraphWrapper.clearOutputSurfaceInfo(); } catch (RuntimeException e) { maybeRaiseError( /* message= */ "error clearing video output", @@ -199,7 +199,7 @@ import androidx.media3.exoplayer.video.CompositingVideoSinkProvider; private void setOutputSurfaceInfoOnInternalThread(OutputSurfaceInfo outputSurfaceInfo) { try { - compositingVideoSinkProvider.setOutputSurfaceInfo( + playbackVideoGraphWrapper.setOutputSurfaceInfo( outputSurfaceInfo.surface, outputSurfaceInfo.size); } catch (RuntimeException e) { maybeRaiseError( diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/PreviewAudioPipeline.java b/libraries/transformer/src/main/java/androidx/media3/transformer/PlaybackAudioGraphWrapper.java similarity index 98% rename from libraries/transformer/src/main/java/androidx/media3/transformer/PreviewAudioPipeline.java rename to libraries/transformer/src/main/java/androidx/media3/transformer/PlaybackAudioGraphWrapper.java index 89afedd949..9a03ad6f36 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/PreviewAudioPipeline.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/PlaybackAudioGraphWrapper.java @@ -34,7 +34,7 @@ import java.util.Objects; * *

Multiple streams of {@linkplain #createInput() input} are not currently supported. */ -/* package */ final class PreviewAudioPipeline { +/* package */ final class PlaybackAudioGraphWrapper { private final AudioSink finalAudioSink; 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 finalAudioSink The {@linkplain AudioSink sink} for processed output audio. */ - public PreviewAudioPipeline( + public PlaybackAudioGraphWrapper( AudioMixer.Factory mixerFactory, ImmutableList effects, AudioSink finalAudioSink) { diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/SequencePlayerRenderersWrapper.java b/libraries/transformer/src/main/java/androidx/media3/transformer/SequencePlayerRenderersWrapper.java index 72ab98ce23..7a25c29a8d 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/SequencePlayerRenderersWrapper.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/SequencePlayerRenderersWrapper.java @@ -62,7 +62,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private final Context context; private final EditedMediaItemSequence sequence; - private final PreviewAudioPipeline previewAudioPipeline; + private final PlaybackAudioGraphWrapper playbackAudioGraphWrapper; @Nullable private final VideoSink videoSink; @Nullable private final ImageDecoder.Factory imageDecoderFactory; @@ -70,22 +70,22 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; public static SequencePlayerRenderersWrapper create( Context context, EditedMediaItemSequence sequence, - PreviewAudioPipeline previewAudioPipeline, + PlaybackAudioGraphWrapper playbackAudioGraphWrapper, VideoSink videoSink, ImageDecoder.Factory imageDecoderFactory) { 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. */ public static SequencePlayerRenderersWrapper createForAudio( Context context, EditedMediaItemSequence sequence, - PreviewAudioPipeline previewAudioPipeline) { + PlaybackAudioGraphWrapper playbackAudioGraphWrapper) { return new SequencePlayerRenderersWrapper( context, sequence, - previewAudioPipeline, + playbackAudioGraphWrapper, /* videoSink= */ null, /* imageDecoderFactory= */ null); } @@ -93,12 +93,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; private SequencePlayerRenderersWrapper( Context context, EditedMediaItemSequence sequence, - PreviewAudioPipeline previewAudioPipeline, + PlaybackAudioGraphWrapper playbackAudioGraphWrapper, @Nullable VideoSink videoSink, @Nullable ImageDecoder.Factory imageDecoderFactory) { this.context = context; this.sequence = sequence; - this.previewAudioPipeline = previewAudioPipeline; + this.playbackAudioGraphWrapper = playbackAudioGraphWrapper; this.videoSink = videoSink; this.imageDecoderFactory = imageDecoderFactory; } @@ -117,7 +117,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /* sequencePlayerRenderersWrapper= */ this, eventHandler, audioRendererEventListener, - previewAudioPipeline.createInput())); + playbackAudioGraphWrapper.createInput())); if (videoSink != null) { renderers.add( @@ -177,7 +177,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { super.render(positionUs, elapsedRealtimeUs); try { - while (sequencePlayerRenderersWrapper.previewAudioPipeline.processData()) {} + while (sequencePlayerRenderersWrapper.playbackAudioGraphWrapper.processData()) {} } catch (ExportException | AudioSink.WriteException | AudioSink.InitializationException diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/PreviewAudioPipelineTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/PlaybackAudioGraphWrapperTest.java similarity index 66% rename from libraries/transformer/src/test/java/androidx/media3/transformer/PreviewAudioPipelineTest.java rename to libraries/transformer/src/test/java/androidx/media3/transformer/PlaybackAudioGraphWrapperTest.java index b0f9565ebb..b1fef373aa 100644 --- a/libraries/transformer/src/test/java/androidx/media3/transformer/PreviewAudioPipelineTest.java +++ b/libraries/transformer/src/test/java/androidx/media3/transformer/PlaybackAudioGraphWrapperTest.java @@ -36,41 +36,41 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -/** Unit tests for {@link PreviewAudioPipeline}. */ +/** Unit tests for {@link PlaybackAudioGraphWrapper}. */ @RunWith(AndroidJUnit4.class) -public class PreviewAudioPipelineTest { +public class PlaybackAudioGraphWrapperTest { @Rule public final MockitoRule mockito = MockitoJUnit.rule(); - private PreviewAudioPipeline previewAudioPipeline; + private PlaybackAudioGraphWrapper playbackAudioGraphWrapper; @Mock AudioSink outputAudioSink; @Before public void setUp() { - previewAudioPipeline = - new PreviewAudioPipeline( + playbackAudioGraphWrapper = + new PlaybackAudioGraphWrapper( new DefaultAudioMixer.Factory(), /* effects= */ ImmutableList.of(), outputAudioSink); } @After public void tearDown() { - previewAudioPipeline.release(); + playbackAudioGraphWrapper.release(); } @Test public void processData_noAudioSinksCreated_returnsFalse() throws Exception { - assertThat(previewAudioPipeline.processData()).isFalse(); + assertThat(playbackAudioGraphWrapper.processData()).isFalse(); } @Test public void processData_audioSinkHasNotConfiguredYet_returnsFalse() throws Exception { - AudioGraphInputAudioSink unused = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink unused = playbackAudioGraphWrapper.createInput(); - assertThat(previewAudioPipeline.processData()).isFalse(); + assertThat(playbackAudioGraphWrapper.processData()).isFalse(); } @Test public void inputPlay_withOneInput_playsOutputSink() throws Exception { - AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput(); inputAudioSink.play(); @@ -79,7 +79,7 @@ public class PreviewAudioPipelineTest { @Test public void inputPause_withOneInput_pausesOutputSink() throws Exception { - AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput(); inputAudioSink.play(); inputAudioSink.pause(); @@ -89,7 +89,7 @@ public class PreviewAudioPipelineTest { @Test public void inputReset_withOneInput_pausesOutputSink() { - AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput(); inputAudioSink.play(); inputAudioSink.reset(); @@ -99,7 +99,7 @@ public class PreviewAudioPipelineTest { @Test public void inputPlay_whenPlaying_doesNotPlayOutputSink() throws Exception { - AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput(); inputAudioSink.play(); inputAudioSink.play(); @@ -108,7 +108,7 @@ public class PreviewAudioPipelineTest { @Test public void inputPause_whenNotPlaying_doesNotPauseOutputSink() throws Exception { - AudioGraphInputAudioSink inputAudioSink = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink = playbackAudioGraphWrapper.createInput(); inputAudioSink.pause(); @@ -117,9 +117,9 @@ public class PreviewAudioPipelineTest { @Test public void someInputPlay_withMultipleInputs_doesNotPlayOutputSink() throws Exception { - AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink unused = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink unused = playbackAudioGraphWrapper.createInput(); inputAudioSink1.play(); inputAudioSink2.play(); @@ -128,9 +128,9 @@ public class PreviewAudioPipelineTest { @Test public void allInputPlay_withMultipleInputs_playsOutputSinkOnce() throws Exception { - AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput(); inputAudioSink1.play(); inputAudioSink2.play(); @@ -142,9 +142,9 @@ public class PreviewAudioPipelineTest { @Test public void firstInputPause_withMultipleInputs_pausesOutputSink() throws Exception { InOrder inOrder = inOrder(outputAudioSink); - AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput(); inputAudioSink1.play(); inputAudioSink2.play(); @@ -157,9 +157,9 @@ public class PreviewAudioPipelineTest { @Test public void allInputPause_withMultipleInputs_pausesOutputSinkOnce() throws Exception { - AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput(); inputAudioSink1.play(); inputAudioSink2.play(); @@ -174,9 +174,9 @@ public class PreviewAudioPipelineTest { @Test public void inputPlayAfterPause_withMultipleInputs_playsOutputSink() throws Exception { InOrder inOrder = inOrder(outputAudioSink); - AudioGraphInputAudioSink inputAudioSink1 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink2 = previewAudioPipeline.createInput(); - AudioGraphInputAudioSink inputAudioSink3 = previewAudioPipeline.createInput(); + AudioGraphInputAudioSink inputAudioSink1 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink2 = playbackAudioGraphWrapper.createInput(); + AudioGraphInputAudioSink inputAudioSink3 = playbackAudioGraphWrapper.createInput(); inputAudioSink1.play(); inputAudioSink2.play();