diff --git a/extensions/gvr/build.gradle b/extensions/gvr/build.gradle
index f146ba4df6..87e72939c5 100644
--- a/extensions/gvr/build.gradle
+++ b/extensions/gvr/build.gradle
@@ -26,6 +26,7 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
+ implementation 'com.android.support:support-annotations:' + supportLibraryVersion
implementation 'com.google.vr:sdk-audio:1.80.0'
}
diff --git a/extensions/gvr/src/main/java/com/google/android/exoplayer2/ext/gvr/GvrAudioProcessor.java b/extensions/gvr/src/main/java/com/google/android/exoplayer2/ext/gvr/GvrAudioProcessor.java
index 8d71f551cd..1b595d6886 100644
--- a/extensions/gvr/src/main/java/com/google/android/exoplayer2/ext/gvr/GvrAudioProcessor.java
+++ b/extensions/gvr/src/main/java/com/google/android/exoplayer2/ext/gvr/GvrAudioProcessor.java
@@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.ext.gvr;
+import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.Format;
@@ -39,7 +40,7 @@ public final class GvrAudioProcessor implements AudioProcessor {
private int sampleRateHz;
private int channelCount;
- private GvrAudioSurround gvrAudioSurround;
+ @Nullable private GvrAudioSurround gvrAudioSurround;
private ByteBuffer buffer;
private boolean inputEnded;
@@ -48,14 +49,13 @@ public final class GvrAudioProcessor implements AudioProcessor {
private float y;
private float z;
- /**
- * Creates a new GVR audio processor.
- */
+ /** Creates a new GVR audio processor. */
public GvrAudioProcessor() {
// Use the identity for the initial orientation.
w = 1f;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
+ buffer = EMPTY_BUFFER;
}
/**
@@ -77,9 +77,11 @@ public final class GvrAudioProcessor implements AudioProcessor {
}
}
+ @SuppressWarnings("ReferenceEquality")
@Override
- public synchronized boolean configure(int sampleRateHz, int channelCount,
- @C.Encoding int encoding) throws UnhandledFormatException {
+ public synchronized boolean configure(
+ int sampleRateHz, int channelCount, @C.Encoding int encoding)
+ throws UnhandledFormatException {
if (encoding != C.ENCODING_PCM_16BIT) {
maybeReleaseGvrAudioSurround();
throw new UnhandledFormatException(sampleRateHz, channelCount, encoding);
@@ -116,7 +118,7 @@ public final class GvrAudioProcessor implements AudioProcessor {
gvrAudioSurround = new GvrAudioSurround(surroundFormat, sampleRateHz, channelCount,
FRAMES_PER_OUTPUT_BUFFER);
gvrAudioSurround.updateNativeOrientation(w, x, y, z);
- if (buffer == null) {
+ if (buffer == EMPTY_BUFFER) {
buffer = ByteBuffer.allocateDirect(FRAMES_PER_OUTPUT_BUFFER * OUTPUT_FRAME_SIZE)
.order(ByteOrder.nativeOrder());
}
@@ -179,10 +181,11 @@ public final class GvrAudioProcessor implements AudioProcessor {
@Override
public synchronized void reset() {
maybeReleaseGvrAudioSurround();
+ updateOrientation(/* w= */ 1f, /* x= */ 0f, /* y= */ 0f, /* z= */ 0f);
inputEnded = false;
- buffer = null;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
+ buffer = EMPTY_BUFFER;
}
private void maybeReleaseGvrAudioSurround() {
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioProcessor.java
index 8a3d624222..7aa4a8e6c8 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioProcessor.java
@@ -22,19 +22,17 @@ import java.nio.ByteOrder;
/**
* Interface for audio processors, which take audio data as input and transform it, potentially
* modifying its channel count, encoding and/or sample rate.
- *
- * Call {@link #configure(int, int, int)} to configure the processor to receive input audio, then
- * call {@link #isActive()} to determine whether the processor is active.
- * {@link #queueInput(ByteBuffer)}, {@link #queueEndOfStream()}, {@link #getOutput()},
- * {@link #isEnded()}, {@link #getOutputChannelCount()}, {@link #getOutputEncoding()} and
- * {@link #getOutputSampleRateHz()} may only be called if the processor is active. Call
- * {@link #reset()} to reset the processor to its unconfigured state.
+ *
+ *
Call {@link #configure(int, int, int)} to configure the processor to receive input audio, then
+ * call {@link #isActive()} to determine whether the processor is active. {@link
+ * #queueInput(ByteBuffer)}, {@link #queueEndOfStream()}, {@link #getOutput()}, {@link #isEnded()},
+ * {@link #getOutputChannelCount()}, {@link #getOutputEncoding()} and {@link
+ * #getOutputSampleRateHz()} may only be called if the processor is active. Call {@link #reset()} to
+ * reset the processor to its unconfigured state and release any resources.
*/
public interface AudioProcessor {
- /**
- * Exception thrown when a processor can't be configured for a given input audio format.
- */
+ /** Exception thrown when a processor can't be configured for a given input audio format. */
final class UnhandledFormatException extends Exception {
public UnhandledFormatException(int sampleRateHz, int channelCount, @C.Encoding int encoding) {
@@ -44,33 +42,26 @@ public interface AudioProcessor {
}
- /**
- * An empty, direct {@link ByteBuffer}.
- */
+ /** An empty, direct {@link ByteBuffer}. */
ByteBuffer EMPTY_BUFFER = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
/**
- * Configures the processor to process input audio with the specified format. After calling this
- * method, {@link #isActive()} returns whether the processor needs to handle buffers; if not, the
- * processor will not accept any buffers until it is reconfigured. Returns {@code true} if the
- * processor must be flushed, or if the value returned by {@link #isActive()} has changed as a
- * result of the call. If it's active, {@link #getOutputSampleRateHz()},
- * {@link #getOutputChannelCount()} and {@link #getOutputEncoding()} return the processor's output
- * format.
+ * Configures the processor to process input audio with the specified format and returns whether
+ * to {@link #flush()} it. After calling this method, {@link #isActive()} returns whether the
+ * processor needs to handle buffers; if not, the processor will not accept any buffers until it
+ * is reconfigured. If the processor is active, {@link #getOutputSampleRateHz()}, {@link
+ * #getOutputChannelCount()} and {@link #getOutputEncoding()} return its output format.
*
* @param sampleRateHz The sample rate of input audio in Hz.
* @param channelCount The number of interleaved channels in input audio.
* @param encoding The encoding of input audio.
- * @return {@code true} if the processor must be flushed or the value returned by
- * {@link #isActive()} has changed as a result of the call.
+ * @return Whether to {@link #flush()} the processor.
* @throws UnhandledFormatException Thrown if the specified format can't be handled as input.
*/
boolean configure(int sampleRateHz, int channelCount, @C.Encoding int encoding)
throws UnhandledFormatException;
- /**
- * Returns whether the processor is configured and active.
- */
+ /** Returns whether the processor is configured and active. */
boolean isActive();
/**
@@ -130,14 +121,9 @@ public interface AudioProcessor {
*/
boolean isEnded();
- /**
- * Clears any state in preparation for receiving a new stream of input buffers.
- */
+ /** Clears any state in preparation for receiving a new stream of input buffers. */
void flush();
- /**
- * Resets the processor to its unconfigured state.
- */
+ /** Resets the processor to its unconfigured state. */
void reset();
-
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java
index 50b484b938..e53eb08c83 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java
@@ -15,9 +15,11 @@
*/
package com.google.android.exoplayer2.audio;
+import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.Encoding;
import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.util.Assertions;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
@@ -30,17 +32,15 @@ import java.util.Arrays;
private int channelCount;
private int sampleRateHz;
- private int[] pendingOutputChannels;
+ private @Nullable int[] pendingOutputChannels;
private boolean active;
- private int[] outputChannels;
+ private @Nullable int[] outputChannels;
private ByteBuffer buffer;
private ByteBuffer outputBuffer;
private boolean inputEnded;
- /**
- * Creates a new processor that applies a channel mapping.
- */
+ /** Creates a new processor that applies a channel mapping. */
public ChannelMappingAudioProcessor() {
buffer = EMPTY_BUFFER;
outputBuffer = EMPTY_BUFFER;
@@ -52,9 +52,11 @@ import java.util.Arrays;
* Resets the channel mapping. After calling this method, call {@link #configure(int, int, int)}
* to start using the new channel map.
*
+ * @param outputChannels The mapping from input to output channel indices, or {@code null} to
+ * leave the input unchanged.
* @see AudioSink#configure(int, int, int, int, int[], int, int)
*/
- public void setChannelMap(int[] outputChannels) {
+ public void setChannelMap(@Nullable int[] outputChannels) {
pendingOutputChannels = outputChannels;
}
@@ -110,6 +112,7 @@ import java.util.Arrays;
@Override
public void queueInput(ByteBuffer inputBuffer) {
+ Assertions.checkState(outputChannels != null);
int position = inputBuffer.position();
int limit = inputBuffer.limit();
int frameCount = (limit - position) / (2 * channelCount);
@@ -161,6 +164,7 @@ import java.util.Arrays;
channelCount = Format.NO_VALUE;
sampleRateHz = Format.NO_VALUE;
outputChannels = null;
+ pendingOutputChannels = null;
active = false;
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
index ac62ce0951..7270336a08 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java
@@ -147,10 +147,9 @@ public final class DefaultAudioSink implements AudioSink {
private final ArrayDeque playbackParametersCheckpoints;
@Nullable private Listener listener;
- /**
- * Used to keep the audio session active on pre-V21 builds (see {@link #initialize()}).
- */
- private AudioTrack keepSessionIdAudioTrack;
+ /** Used to keep the audio session active on pre-V21 builds (see {@link #initialize()}). */
+ @Nullable private AudioTrack keepSessionIdAudioTrack;
+
private AudioTrack audioTrack;
private boolean isInputPcm;
private boolean shouldConvertHighResIntPcmToFloat;
@@ -163,12 +162,12 @@ public final class DefaultAudioSink implements AudioSink {
private boolean canApplyPlaybackParameters;
private int bufferSize;
- private PlaybackParameters drainingPlaybackParameters;
+ @Nullable private PlaybackParameters drainingPlaybackParameters;
private PlaybackParameters playbackParameters;
private long playbackParametersOffsetUs;
private long playbackParametersPositionUs;
- private ByteBuffer avSyncHeader;
+ @Nullable private ByteBuffer avSyncHeader;
private int bytesUntilNextAvSync;
private int pcmFrameSize;
@@ -184,8 +183,8 @@ public final class DefaultAudioSink implements AudioSink {
private AudioProcessor[] audioProcessors;
private ByteBuffer[] outputBuffers;
- private ByteBuffer inputBuffer;
- private ByteBuffer outputBuffer;
+ @Nullable private ByteBuffer inputBuffer;
+ @Nullable private ByteBuffer outputBuffer;
private byte[] preV21OutputBuffer;
private int preV21OutputBufferOffset;
private int drainingAudioProcessorIndex;
@@ -408,7 +407,7 @@ public final class DefaultAudioSink implements AudioSink {
}
}
- private void resetAudioProcessors() {
+ private void setupAudioProcessors() {
ArrayList newAudioProcessors = new ArrayList<>();
for (AudioProcessor audioProcessor : getAvailableAudioProcessors()) {
if (audioProcessor.isActive()) {
@@ -420,7 +419,11 @@ public final class DefaultAudioSink implements AudioSink {
int count = newAudioProcessors.size();
audioProcessors = newAudioProcessors.toArray(new AudioProcessor[count]);
outputBuffers = new ByteBuffer[count];
- for (int i = 0; i < count; i++) {
+ flushAudioProcessors();
+ }
+
+ private void flushAudioProcessors() {
+ for (int i = 0; i < audioProcessors.length; i++) {
AudioProcessor audioProcessor = audioProcessors[i];
audioProcessor.flush();
outputBuffers[i] = audioProcessor.getOutput();
@@ -436,13 +439,6 @@ public final class DefaultAudioSink implements AudioSink {
releasingConditionVariable.block();
audioTrack = initializeAudioTrack();
-
- // The old playback parameters may no longer be applicable so try to reset them now.
- setPlaybackParameters(playbackParameters);
-
- // Flush and reset active audio processors.
- resetAudioProcessors();
-
int audioSessionId = audioTrack.getAudioSessionId();
if (enablePreV21AudioSessionWorkaround) {
if (Util.SDK_INT < 21) {
@@ -464,6 +460,10 @@ public final class DefaultAudioSink implements AudioSink {
}
}
+ // The old playback parameters may no longer be applicable so try to reset them now.
+ setPlaybackParameters(playbackParameters);
+ setupAudioProcessors();
+
audioTrackPositionTracker.setAudioTrack(
audioTrack, outputEncoding, outputPcmFrameSize, bufferSize);
setVolumeInternal();
@@ -533,7 +533,7 @@ public final class DefaultAudioSink implements AudioSink {
drainingPlaybackParameters = null;
// The audio processors have drained, so flush them. This will cause any active speed
// adjustment audio processor to start producing audio with the new parameters.
- resetAudioProcessors();
+ setupAudioProcessors();
}
if (startMediaTimeState == START_NOT_SET) {
@@ -849,11 +849,7 @@ public final class DefaultAudioSink implements AudioSink {
playbackParametersPositionUs = 0;
inputBuffer = null;
outputBuffer = null;
- for (int i = 0; i < audioProcessors.length; i++) {
- AudioProcessor audioProcessor = audioProcessors[i];
- audioProcessor.flush();
- outputBuffers[i] = audioProcessor.getOutput();
- }
+ flushAudioProcessors();
handledEndOfStream = false;
drainingAudioProcessorIndex = C.INDEX_UNSET;
avSyncHeader = null;
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/FloatResamplingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/FloatResamplingAudioProcessor.java
index 215b04821b..e3c91cd344 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/FloatResamplingAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/FloatResamplingAudioProcessor.java
@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.audio;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
-import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -86,8 +85,6 @@ import java.nio.ByteOrder;
@Override
public void queueInput(ByteBuffer inputBuffer) {
- Assertions.checkState(isActive());
-
boolean isInput32Bit = sourceEncoding == C.ENCODING_PCM_32BIT;
int position = inputBuffer.position();
int limit = inputBuffer.limit();
@@ -150,10 +147,10 @@ import java.nio.ByteOrder;
@Override
public void reset() {
flush();
- buffer = EMPTY_BUFFER;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
sourceEncoding = C.ENCODING_INVALID;
+ buffer = EMPTY_BUFFER;
}
/**
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java
index 01123f3c59..eac0bffd65 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/ResamplingAudioProcessor.java
@@ -28,15 +28,12 @@ import java.nio.ByteOrder;
private int sampleRateHz;
private int channelCount;
- @C.PcmEncoding
- private int encoding;
+ private @C.PcmEncoding int encoding;
private ByteBuffer buffer;
private ByteBuffer outputBuffer;
private boolean inputEnded;
- /**
- * Creates a new audio processor that converts audio data to {@link C#ENCODING_PCM_16BIT}.
- */
+ /** Creates a new audio processor that converts audio data to {@link C#ENCODING_PCM_16BIT}. */
public ResamplingAudioProcessor() {
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
@@ -59,9 +56,6 @@ import java.nio.ByteOrder;
this.sampleRateHz = sampleRateHz;
this.channelCount = channelCount;
this.encoding = encoding;
- if (encoding == C.ENCODING_PCM_16BIT) {
- buffer = EMPTY_BUFFER;
- }
return true;
}
@@ -139,6 +133,7 @@ import java.nio.ByteOrder;
}
break;
case C.ENCODING_PCM_16BIT:
+ case C.ENCODING_PCM_FLOAT:
case C.ENCODING_INVALID:
case Format.NO_VALUE:
default:
@@ -177,10 +172,10 @@ import java.nio.ByteOrder;
@Override
public void reset() {
flush();
- buffer = EMPTY_BUFFER;
sampleRateHz = Format.NO_VALUE;
channelCount = Format.NO_VALUE;
encoding = C.ENCODING_INVALID;
+ buffer = EMPTY_BUFFER;
}
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessor.java
index b0550777a2..c2af535838 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessor.java
@@ -72,7 +72,6 @@ import java.nio.ByteOrder;
private int bytesPerFrame;
private boolean enabled;
- private boolean isActive;
private ByteBuffer buffer;
private ByteBuffer outputBuffer;
@@ -103,11 +102,13 @@ import java.nio.ByteOrder;
outputBuffer = EMPTY_BUFFER;
channelCount = Format.NO_VALUE;
sampleRateHz = Format.NO_VALUE;
+ maybeSilenceBuffer = new byte[0];
+ paddingBuffer = new byte[0];
}
/**
- * Sets whether to skip silence in the input. After calling this method, call {@link
- * #configure(int, int, int)} to apply the new setting.
+ * Sets whether to skip silence in the input. The new setting will take effect after calling
+ * {@link #flush()}.
*
* @param enabled Whether to skip silence in the input.
*/
@@ -131,33 +132,18 @@ import java.nio.ByteOrder;
if (encoding != C.ENCODING_PCM_16BIT) {
throw new UnhandledFormatException(sampleRateHz, channelCount, encoding);
}
-
- boolean wasActive = isActive;
- isActive = enabled;
- if (!isActive) {
- return wasActive;
- }
-
- if (wasActive && this.sampleRateHz == sampleRateHz && this.channelCount == channelCount) {
+ if (this.sampleRateHz == sampleRateHz && this.channelCount == channelCount) {
return false;
}
-
this.sampleRateHz = sampleRateHz;
this.channelCount = channelCount;
bytesPerFrame = channelCount * 2;
- int maybeSilenceBufferSize = durationUsToFrames(MINIMUM_SILENCE_DURATION_US) * bytesPerFrame;
- if (maybeSilenceBuffer == null || maybeSilenceBuffer.length != maybeSilenceBufferSize) {
- maybeSilenceBuffer = new byte[maybeSilenceBufferSize];
- }
- paddingSize = durationUsToFrames(PADDING_SILENCE_US) * bytesPerFrame;
- paddingBuffer = new byte[paddingSize];
- state = STATE_NOISY;
return true;
}
@Override
public boolean isActive() {
- return isActive;
+ return enabled;
}
@Override
@@ -221,6 +207,17 @@ import java.nio.ByteOrder;
@Override
public void flush() {
+ if (isActive()) {
+ int maybeSilenceBufferSize = durationUsToFrames(MINIMUM_SILENCE_DURATION_US) * bytesPerFrame;
+ if (maybeSilenceBuffer.length != maybeSilenceBufferSize) {
+ maybeSilenceBuffer = new byte[maybeSilenceBufferSize];
+ }
+ paddingSize = durationUsToFrames(PADDING_SILENCE_US) * bytesPerFrame;
+ if (paddingBuffer.length != paddingSize) {
+ paddingBuffer = new byte[paddingSize];
+ }
+ }
+ state = STATE_NOISY;
outputBuffer = EMPTY_BUFFER;
inputEnded = false;
skippedFrames = 0;
@@ -230,11 +227,14 @@ import java.nio.ByteOrder;
@Override
public void reset() {
+ enabled = false;
flush();
buffer = EMPTY_BUFFER;
channelCount = Format.NO_VALUE;
sampleRateHz = Format.NO_VALUE;
- maybeSilenceBuffer = null;
+ paddingSize = 0;
+ maybeSilenceBuffer = new byte[0];
+ paddingBuffer = new byte[0];
}
// Internal methods.
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/SonicAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/SonicAudioProcessor.java
index 370ddb2809..9beb65bec6 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/SonicAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/SonicAudioProcessor.java
@@ -15,9 +15,11 @@
*/
package com.google.android.exoplayer2.audio;
+import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.Encoding;
import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -64,7 +66,7 @@ public final class SonicAudioProcessor implements AudioProcessor {
private int channelCount;
private int sampleRateHz;
- private Sonic sonic;
+ private @Nullable Sonic sonic;
private float speed;
private float pitch;
private int outputSampleRateHz;
@@ -185,6 +187,7 @@ public final class SonicAudioProcessor implements AudioProcessor {
@Override
public void queueInput(ByteBuffer inputBuffer) {
+ Assertions.checkState(sonic != null);
if (inputBuffer.hasRemaining()) {
ShortBuffer shortBuffer = inputBuffer.asShortBuffer();
int inputSize = inputBuffer.remaining();
@@ -210,6 +213,7 @@ public final class SonicAudioProcessor implements AudioProcessor {
@Override
public void queueEndOfStream() {
+ Assertions.checkState(sonic != null);
sonic.queueEndOfStream();
inputEnded = true;
}
@@ -228,7 +232,8 @@ public final class SonicAudioProcessor implements AudioProcessor {
@Override
public void flush() {
- sonic = new Sonic(sampleRateHz, channelCount, speed, pitch, outputSampleRateHz);
+ sonic =
+ isActive() ? new Sonic(sampleRateHz, channelCount, speed, pitch, outputSampleRateHz) : null;
outputBuffer = EMPTY_BUFFER;
inputBytes = 0;
outputBytes = 0;
@@ -237,17 +242,19 @@ public final class SonicAudioProcessor implements AudioProcessor {
@Override
public void reset() {
- sonic = null;
- buffer = EMPTY_BUFFER;
- shortBuffer = buffer.asShortBuffer();
- outputBuffer = EMPTY_BUFFER;
+ speed = 1f;
+ pitch = 1f;
channelCount = Format.NO_VALUE;
sampleRateHz = Format.NO_VALUE;
outputSampleRateHz = Format.NO_VALUE;
+ buffer = EMPTY_BUFFER;
+ shortBuffer = buffer.asShortBuffer();
+ outputBuffer = EMPTY_BUFFER;
+ pendingOutputSampleRateHz = SAMPLE_RATE_NO_CHANGE;
+ sonic = null;
inputBytes = 0;
outputBytes = 0;
inputEnded = false;
- pendingOutputSampleRateHz = SAMPLE_RATE_NO_CHANGE;
}
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/TrimmingAudioProcessor.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/TrimmingAudioProcessor.java
index 9ff1c158dd..25db5fc871 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/audio/TrimmingAudioProcessor.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/TrimmingAudioProcessor.java
@@ -22,9 +22,7 @@ import com.google.android.exoplayer2.util.Util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-/**
- * Audio processor for trimming samples from the start/end of data.
- */
+/** Audio processor for trimming samples from the start/end of data. */
/* package */ final class TrimmingAudioProcessor implements AudioProcessor {
private boolean isActive;
@@ -40,13 +38,13 @@ import java.nio.ByteOrder;
private int endBufferSize;
private boolean inputEnded;
- /**
- * Creates a new audio processor for trimming samples from the start/end of data.
- */
+ /** Creates a new audio processor for trimming samples from the start/end of data. */
public TrimmingAudioProcessor() {
buffer = EMPTY_BUFFER;
outputBuffer = EMPTY_BUFFER;
channelCount = Format.NO_VALUE;
+ sampleRateHz = Format.NO_VALUE;
+ endBuffer = new byte[0];
}
/**
@@ -182,7 +180,7 @@ import java.nio.ByteOrder;
buffer = EMPTY_BUFFER;
channelCount = Format.NO_VALUE;
sampleRateHz = Format.NO_VALUE;
- endBuffer = null;
+ endBuffer = new byte[0];
}
}
diff --git a/library/core/src/test/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessorTest.java
index 21106e13f4..ab926029f1 100644
--- a/library/core/src/test/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessorTest.java
+++ b/library/core/src/test/java/com/google/android/exoplayer2/audio/SilenceSkippingAudioProcessorTest.java
@@ -68,12 +68,10 @@ public final class SilenceSkippingAudioProcessorTest {
silenceSkippingAudioProcessor.setEnabled(false);
// When configuring it.
- boolean reconfigured =
- silenceSkippingAudioProcessor.configure(
- TEST_SIGNAL_SAMPLE_RATE_HZ, TEST_SIGNAL_CHANNEL_COUNT, C.ENCODING_PCM_16BIT);
+ silenceSkippingAudioProcessor.configure(
+ TEST_SIGNAL_SAMPLE_RATE_HZ, TEST_SIGNAL_CHANNEL_COUNT, C.ENCODING_PCM_16BIT);
// It's not active.
- assertThat(reconfigured).isFalse();
assertThat(silenceSkippingAudioProcessor.isActive()).isFalse();
}
@@ -81,12 +79,10 @@ public final class SilenceSkippingAudioProcessorTest {
public void testDefaultProcessor_isNotEnabled() throws Exception {
// Given a processor in its default state.
// When reconfigured.
- boolean reconfigured =
- silenceSkippingAudioProcessor.configure(
- TEST_SIGNAL_SAMPLE_RATE_HZ, TEST_SIGNAL_CHANNEL_COUNT, C.ENCODING_PCM_16BIT);
+ silenceSkippingAudioProcessor.configure(
+ TEST_SIGNAL_SAMPLE_RATE_HZ, TEST_SIGNAL_CHANNEL_COUNT, C.ENCODING_PCM_16BIT);
// It's not active.
- assertThat(reconfigured).isFalse();
assertThat(silenceSkippingAudioProcessor.isActive()).isFalse();
}
@@ -97,7 +93,9 @@ public final class SilenceSkippingAudioProcessorTest {
boolean reconfigured =
silenceSkippingAudioProcessor.configure(
TEST_SIGNAL_SAMPLE_RATE_HZ, TEST_SIGNAL_CHANNEL_COUNT, C.ENCODING_PCM_16BIT);
- assertThat(reconfigured).isTrue();
+ if (reconfigured) {
+ silenceSkippingAudioProcessor.flush();
+ }
// When reconfiguring it with a different sample rate.
reconfigured =
@@ -305,6 +303,7 @@ public final class SilenceSkippingAudioProcessorTest {
InputBufferProvider inputBufferProvider,
int inputBufferSize)
throws UnhandledFormatException {
+ processor.flush();
long totalOutputFrames = 0;
while (inputBufferProvider.hasRemaining()) {
ByteBuffer inputBuffer = inputBufferProvider.getNextInputBuffer(inputBufferSize);