From d2c5a1bfb9c6cdb93668787f1c5b90a403d68d46 Mon Sep 17 00:00:00 2001 From: samrobinson Date: Thu, 12 Jan 2023 14:11:04 +0000 Subject: [PATCH] Move BaseAudioProcessor abstract class to common. This is a prerequisite step to making the `ResamplingAudioProcessor` public. PiperOrigin-RevId: 501545561 --- .../common/audio/BaseAudioProcessor.java | 148 ++++++++++++++++++ .../exoplayer/audio/BaseAudioProcessor.java | 130 +-------------- .../audio/ChannelMappingAudioProcessor.java | 1 + .../audio/FloatResamplingAudioProcessor.java | 1 + .../audio/ResamplingAudioProcessor.java | 1 + .../audio/SilenceSkippingAudioProcessor.java | 1 + .../exoplayer/audio/TeeAudioProcessor.java | 1 + .../audio/TrimmingAudioProcessor.java | 1 + .../SpeedChangingAudioProcessor.java | 2 +- 9 files changed, 158 insertions(+), 128 deletions(-) create mode 100644 libraries/common/src/main/java/androidx/media3/common/audio/BaseAudioProcessor.java diff --git a/libraries/common/src/main/java/androidx/media3/common/audio/BaseAudioProcessor.java b/libraries/common/src/main/java/androidx/media3/common/audio/BaseAudioProcessor.java new file mode 100644 index 0000000000..0939e6fce2 --- /dev/null +++ b/libraries/common/src/main/java/androidx/media3/common/audio/BaseAudioProcessor.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2019 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.annotation.CallSuper; +import androidx.media3.common.util.UnstableApi; +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +/** + * Base class for audio processors that keep an output buffer and an internal buffer that is reused + * whenever input is queued. Subclasses should override {@link #onConfigure(AudioFormat)} to return + * the output audio format for the processor if it's active. + */ +@UnstableApi +public abstract class BaseAudioProcessor implements AudioProcessor { + + /** The current input audio format. */ + protected AudioFormat inputAudioFormat; + /** The current output audio format. */ + protected AudioFormat outputAudioFormat; + + private AudioFormat pendingInputAudioFormat; + private AudioFormat pendingOutputAudioFormat; + private ByteBuffer buffer; + private ByteBuffer outputBuffer; + private boolean inputEnded; + + public BaseAudioProcessor() { + buffer = EMPTY_BUFFER; + outputBuffer = EMPTY_BUFFER; + pendingInputAudioFormat = AudioFormat.NOT_SET; + pendingOutputAudioFormat = AudioFormat.NOT_SET; + inputAudioFormat = AudioFormat.NOT_SET; + outputAudioFormat = AudioFormat.NOT_SET; + } + + @Override + @CanIgnoreReturnValue + public final AudioFormat configure(AudioFormat inputAudioFormat) + throws UnhandledAudioFormatException { + pendingInputAudioFormat = inputAudioFormat; + pendingOutputAudioFormat = onConfigure(inputAudioFormat); + return isActive() ? pendingOutputAudioFormat : AudioFormat.NOT_SET; + } + + @Override + public boolean isActive() { + return pendingOutputAudioFormat != AudioFormat.NOT_SET; + } + + @Override + public final void queueEndOfStream() { + inputEnded = true; + onQueueEndOfStream(); + } + + @CallSuper + @Override + public ByteBuffer getOutput() { + ByteBuffer outputBuffer = this.outputBuffer; + this.outputBuffer = EMPTY_BUFFER; + return outputBuffer; + } + + @CallSuper + @SuppressWarnings("ReferenceEquality") + @Override + public boolean isEnded() { + return inputEnded && outputBuffer == EMPTY_BUFFER; + } + + @Override + public final void flush() { + outputBuffer = EMPTY_BUFFER; + inputEnded = false; + inputAudioFormat = pendingInputAudioFormat; + outputAudioFormat = pendingOutputAudioFormat; + onFlush(); + } + + @Override + public final void reset() { + flush(); + buffer = EMPTY_BUFFER; + pendingInputAudioFormat = AudioFormat.NOT_SET; + pendingOutputAudioFormat = AudioFormat.NOT_SET; + inputAudioFormat = AudioFormat.NOT_SET; + outputAudioFormat = AudioFormat.NOT_SET; + onReset(); + } + + /** + * Replaces the current output buffer with a buffer of at least {@code size} bytes and returns it. + * Callers should write to the returned buffer then {@link ByteBuffer#flip()} it so it can be read + * via {@link #getOutput()}. + */ + protected final ByteBuffer replaceOutputBuffer(int size) { + if (buffer.capacity() < size) { + buffer = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()); + } else { + buffer.clear(); + } + outputBuffer = buffer; + return buffer; + } + + /** Returns whether the current output buffer has any data remaining. */ + protected final boolean hasPendingOutput() { + return outputBuffer.hasRemaining(); + } + + /** Called when the processor is configured for a new input format. */ + @CanIgnoreReturnValue + protected AudioFormat onConfigure(AudioFormat inputAudioFormat) + throws UnhandledAudioFormatException { + return AudioFormat.NOT_SET; + } + + /** Called when the end-of-stream is queued to the processor. */ + protected void onQueueEndOfStream() { + // Do nothing. + } + + /** Called when the processor is flushed, directly or as part of resetting. */ + protected void onFlush() { + // Do nothing. + } + + /** Called when the processor is reset. */ + protected void onReset() { + // Do nothing. + } +} diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/BaseAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/BaseAudioProcessor.java index 46040e90e5..1ea89f58d3 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/BaseAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/BaseAudioProcessor.java @@ -15,135 +15,11 @@ */ package androidx.media3.exoplayer.audio; -import androidx.annotation.CallSuper; -import androidx.media3.common.audio.AudioProcessor; import androidx.media3.common.util.UnstableApi; -import com.google.errorprone.annotations.CanIgnoreReturnValue; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; /** - * Base class for audio processors that keep an output buffer and an internal buffer that is reused - * whenever input is queued. Subclasses should override {@link #onConfigure(AudioFormat)} to return - * the output audio format for the processor if it's active. + * @deprecated Use {@link androidx.media3.common.audio.BaseAudioProcessor}. */ +@Deprecated @UnstableApi -public abstract class BaseAudioProcessor implements AudioProcessor { - - /** The current input audio format. */ - protected AudioFormat inputAudioFormat; - /** The current output audio format. */ - protected AudioFormat outputAudioFormat; - - private AudioFormat pendingInputAudioFormat; - private AudioFormat pendingOutputAudioFormat; - private ByteBuffer buffer; - private ByteBuffer outputBuffer; - private boolean inputEnded; - - public BaseAudioProcessor() { - buffer = EMPTY_BUFFER; - outputBuffer = EMPTY_BUFFER; - pendingInputAudioFormat = AudioFormat.NOT_SET; - pendingOutputAudioFormat = AudioFormat.NOT_SET; - inputAudioFormat = AudioFormat.NOT_SET; - outputAudioFormat = AudioFormat.NOT_SET; - } - - @Override - @CanIgnoreReturnValue - public final AudioFormat configure(AudioFormat inputAudioFormat) - throws UnhandledAudioFormatException { - pendingInputAudioFormat = inputAudioFormat; - pendingOutputAudioFormat = onConfigure(inputAudioFormat); - return isActive() ? pendingOutputAudioFormat : AudioFormat.NOT_SET; - } - - @Override - public boolean isActive() { - return pendingOutputAudioFormat != AudioFormat.NOT_SET; - } - - @Override - public final void queueEndOfStream() { - inputEnded = true; - onQueueEndOfStream(); - } - - @CallSuper - @Override - public ByteBuffer getOutput() { - ByteBuffer outputBuffer = this.outputBuffer; - this.outputBuffer = EMPTY_BUFFER; - return outputBuffer; - } - - @CallSuper - @SuppressWarnings("ReferenceEquality") - @Override - public boolean isEnded() { - return inputEnded && outputBuffer == EMPTY_BUFFER; - } - - @Override - public final void flush() { - outputBuffer = EMPTY_BUFFER; - inputEnded = false; - inputAudioFormat = pendingInputAudioFormat; - outputAudioFormat = pendingOutputAudioFormat; - onFlush(); - } - - @Override - public final void reset() { - flush(); - buffer = EMPTY_BUFFER; - pendingInputAudioFormat = AudioFormat.NOT_SET; - pendingOutputAudioFormat = AudioFormat.NOT_SET; - inputAudioFormat = AudioFormat.NOT_SET; - outputAudioFormat = AudioFormat.NOT_SET; - onReset(); - } - - /** - * Replaces the current output buffer with a buffer of at least {@code size} bytes and returns it. - * Callers should write to the returned buffer then {@link ByteBuffer#flip()} it so it can be read - * via {@link #getOutput()}. - */ - protected final ByteBuffer replaceOutputBuffer(int size) { - if (buffer.capacity() < size) { - buffer = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()); - } else { - buffer.clear(); - } - outputBuffer = buffer; - return buffer; - } - - /** Returns whether the current output buffer has any data remaining. */ - protected final boolean hasPendingOutput() { - return outputBuffer.hasRemaining(); - } - - /** Called when the processor is configured for a new input format. */ - @CanIgnoreReturnValue - protected AudioFormat onConfigure(AudioFormat inputAudioFormat) - throws UnhandledAudioFormatException { - return AudioFormat.NOT_SET; - } - - /** Called when the end-of-stream is queued to the processor. */ - protected void onQueueEndOfStream() { - // Do nothing. - } - - /** Called when the processor is flushed, directly or as part of resetting. */ - protected void onFlush() { - // Do nothing. - } - - /** Called when the processor is reset. */ - protected void onReset() { - // Do nothing. - } -} +public abstract class BaseAudioProcessor extends androidx.media3.common.audio.BaseAudioProcessor {} diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ChannelMappingAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ChannelMappingAudioProcessor.java index 2d5f0536ee..e4e43f5d14 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ChannelMappingAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ChannelMappingAudioProcessor.java @@ -19,6 +19,7 @@ import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.audio.AudioProcessor; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Assertions; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.nio.ByteBuffer; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/FloatResamplingAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/FloatResamplingAudioProcessor.java index 16bcbd9a72..c1554f508e 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/FloatResamplingAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/FloatResamplingAudioProcessor.java @@ -18,6 +18,7 @@ package androidx.media3.exoplayer.audio; import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.audio.AudioProcessor; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Util; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.nio.ByteBuffer; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ResamplingAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ResamplingAudioProcessor.java index 173138b42b..549fa0f888 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ResamplingAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/ResamplingAudioProcessor.java @@ -18,6 +18,7 @@ package androidx.media3.exoplayer.audio; import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.audio.AudioProcessor; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Util; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.nio.ByteBuffer; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/SilenceSkippingAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/SilenceSkippingAudioProcessor.java index e50750e5b4..84700fe658 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/SilenceSkippingAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/SilenceSkippingAudioProcessor.java @@ -21,6 +21,7 @@ import static java.lang.annotation.ElementType.TYPE_USE; import androidx.annotation.IntDef; import androidx.media3.common.C; import androidx.media3.common.audio.AudioProcessor; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; 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 ba02eea83a..e83caf7ab3 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 @@ -20,6 +20,7 @@ import static java.lang.Math.min; import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.audio.AudioProcessorChain; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; import androidx.media3.common.util.UnstableApi; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TrimmingAudioProcessor.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TrimmingAudioProcessor.java index 9e734f5230..0e0f5f06f4 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TrimmingAudioProcessor.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/TrimmingAudioProcessor.java @@ -19,6 +19,7 @@ import static java.lang.Math.min; import androidx.media3.common.C; import androidx.media3.common.Format; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Util; import java.nio.ByteBuffer; diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/SpeedChangingAudioProcessor.java b/libraries/transformer/src/main/java/androidx/media3/transformer/SpeedChangingAudioProcessor.java index 90bcac836d..85efa27d9a 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/SpeedChangingAudioProcessor.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/SpeedChangingAudioProcessor.java @@ -20,8 +20,8 @@ import static java.lang.Math.min; import androidx.media3.common.C; import androidx.media3.common.audio.AudioProcessor; +import androidx.media3.common.audio.BaseAudioProcessor; import androidx.media3.common.util.Util; -import androidx.media3.exoplayer.audio.BaseAudioProcessor; import androidx.media3.exoplayer.audio.SonicAudioProcessor; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.nio.ByteBuffer;