diff --git a/libraries/common/src/main/java/androidx/media3/common/audio/AudioProcessorChain.java b/libraries/common/src/main/java/androidx/media3/common/audio/AudioProcessorChain.java new file mode 100644 index 00000000000..0c776c727fe --- /dev/null +++ b/libraries/common/src/main/java/androidx/media3/common/audio/AudioProcessorChain.java @@ -0,0 +1,74 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.common.audio; + +import androidx.media3.common.PlaybackParameters; +import androidx.media3.common.util.UnstableApi; + +/** + * Provides a chain of audio processors, which are used for any user-defined processing and applying + * playback parameters (if supported). Because applying playback parameters can skip and + * stretch/compress audio, the sink will query the chain for information on how to transform its + * output position to map it onto a media position, via {@link #getMediaDuration(long)} and {@link + * #getSkippedOutputFrameCount()}. + */ +@UnstableApi +public interface AudioProcessorChain { + + /** + * Returns the fixed chain of audio processors that will process audio. This method is called once + * during initialization, but audio processors may change state to become active/inactive during + * playback. + */ + AudioProcessor[] getAudioProcessors(); + + /** + * Configures audio processors to apply the specified playback parameters immediately, returning + * the new playback parameters, which may differ from those passed in. Only called when processors + * have no input pending. + * + * @param playbackParameters The playback parameters to try to apply. + * @return The playback parameters that were actually applied. + */ + PlaybackParameters applyPlaybackParameters(PlaybackParameters playbackParameters); + + /** + * Configures audio processors to apply whether to skip silences immediately, returning the new + * value. Only called when processors have no input pending. + * + * @param skipSilenceEnabled Whether silences should be skipped in the audio stream. + * @return The new value. + */ + boolean applySkipSilenceEnabled(boolean skipSilenceEnabled); + + /** + * Returns the media duration corresponding to the specified playout duration, taking speed + * adjustment due to audio processing into account. + * + *

The scaling performed by this method will use the actual playback speed achieved by the + * audio processor chain, on average, since it was last flushed. This may differ very slightly + * from the target playback speed. + * + * @param playoutDuration The playout duration to scale. + * @return The corresponding media duration, in the same units as {@code duration}. + */ + long getMediaDuration(long playoutDuration); + + /** + * Returns the number of output audio frames skipped since the audio processors were last flushed. + */ + long getSkippedOutputFrameCount(); +} diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index f0d6ccd3e85..67d436c6fbb 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -111,64 +111,16 @@ private InvalidAudioTrackTimestampException(String message) { } /** - * Provides a chain of audio processors, which are used for any user-defined processing and - * applying playback parameters (if supported). Because applying playback parameters can skip and - * stretch/compress audio, the sink will query the chain for information on how to transform its - * output position to map it onto a media position, via {@link #getMediaDuration(long)} and {@link - * #getSkippedOutputFrameCount()}. + * @deprecated Use {@link androidx.media3.common.audio.AudioProcessorChain}. */ - public interface AudioProcessorChain { - - /** - * Returns the fixed chain of audio processors that will process audio. This method is called - * once during initialization, but audio processors may change state to become active/inactive - * during playback. - */ - AudioProcessor[] getAudioProcessors(); - - /** - * Configures audio processors to apply the specified playback parameters immediately, returning - * the new playback parameters, which may differ from those passed in. Only called when - * processors have no input pending. - * - * @param playbackParameters The playback parameters to try to apply. - * @return The playback parameters that were actually applied. - */ - PlaybackParameters applyPlaybackParameters(PlaybackParameters playbackParameters); - - /** - * Configures audio processors to apply whether to skip silences immediately, returning the new - * value. Only called when processors have no input pending. - * - * @param skipSilenceEnabled Whether silences should be skipped in the audio stream. - * @return The new value. - */ - boolean applySkipSilenceEnabled(boolean skipSilenceEnabled); - - /** - * Returns the media duration corresponding to the specified playout duration, taking speed - * adjustment due to audio processing into account. - * - *

The scaling performed by this method will use the actual playback speed achieved by the - * audio processor chain, on average, since it was last flushed. This may differ very slightly - * from the target playback speed. - * - * @param playoutDuration The playout duration to scale. - * @return The corresponding media duration, in the same units as {@code duration}. - */ - long getMediaDuration(long playoutDuration); - - /** - * Returns the number of output audio frames skipped since the audio processors were last - * flushed. - */ - long getSkippedOutputFrameCount(); - } + @Deprecated + public interface AudioProcessorChain extends androidx.media3.common.audio.AudioProcessorChain {} /** * The default audio processor chain, which applies a (possibly empty) chain of user-defined audio * processors followed by {@link SilenceSkippingAudioProcessor} and {@link SonicAudioProcessor}. */ + @SuppressWarnings("deprecation") public static class DefaultAudioProcessorChain implements AudioProcessorChain { private final AudioProcessor[] audioProcessors; @@ -272,7 +224,7 @@ int getBufferSizeInBytes( public static final class Builder { private AudioCapabilities audioCapabilities; - @Nullable private AudioProcessorChain audioProcessorChain; + @Nullable private androidx.media3.common.audio.AudioProcessorChain audioProcessorChain; private boolean enableFloatOutput; private boolean enableAudioTrackPlaybackParams; private int offloadMode; @@ -313,14 +265,15 @@ public Builder setAudioProcessors(AudioProcessor[] audioProcessors) { } /** - * Sets the {@link AudioProcessorChain} to process audio before playback. The instance passed in - * must not be reused in other sinks. Processing chains are only supported for PCM playback (not - * passthrough or offload). + * Sets the {@link androidx.media3.common.audio.AudioProcessorChain} to process audio before + * playback. The instance passed in must not be reused in other sinks. Processing chains are + * only supported for PCM playback (not passthrough or offload). * *

By default, no processing will be applied. */ @CanIgnoreReturnValue - public Builder setAudioProcessorChain(AudioProcessorChain audioProcessorChain) { + public Builder setAudioProcessorChain( + androidx.media3.common.audio.AudioProcessorChain audioProcessorChain) { checkNotNull(audioProcessorChain); this.audioProcessorChain = audioProcessorChain; return this; @@ -510,7 +463,7 @@ public DefaultAudioSink build() { private static int pendingReleaseCount; private final AudioCapabilities audioCapabilities; - private final AudioProcessorChain audioProcessorChain; + private final androidx.media3.common.audio.AudioProcessorChain audioProcessorChain; private final boolean enableFloatOutput; private final ChannelMappingAudioProcessor channelMappingAudioProcessor; private final TrimmingAudioProcessor trimmingAudioProcessor; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TeeAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TeeAudioProcessor.java index aa9c5e87e98..ba02eea83af 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TeeAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TeeAudioProcessor.java @@ -19,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.media3.common.C; +import androidx.media3.common.audio.AudioProcessorChain; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; import androidx.media3.common.util.UnstableApi; @@ -36,8 +37,8 @@ *

This audio processor can be inserted into the audio processor chain to access audio data * before/after particular processing steps have been applied. For example, to get audio output * after playback speed adjustment and silence skipping have been applied it is necessary to pass a - * custom {@link DefaultAudioSink.AudioProcessorChain} when creating the audio sink, and include - * this audio processor after all other audio processors. + * custom {@link AudioProcessorChain} when creating the audio sink, and include this audio processor + * after all other audio processors. */ @UnstableApi public final class TeeAudioProcessor extends BaseAudioProcessor {