diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java index af7a1979f2..b5c3bd6295 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java @@ -263,7 +263,7 @@ public final class LibopusAudioTrackRenderer extends SampleSourceTrackRenderer } if (inputBuffer == null) { - inputBuffer = decoder.getInputBuffer(); + inputBuffer = decoder.dequeueInputBuffer(); if (inputBuffer == null) { return false; } diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoderWrapper.java b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoderWrapper.java index a28c9b8f78..d4f6c8e306 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoderWrapper.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoderWrapper.java @@ -36,8 +36,10 @@ import java.util.LinkedList; private final Object lock; private final OpusHeader opusHeader; + private final LinkedList dequeuedInputBuffers; private final LinkedList queuedInputBuffers; private final LinkedList queuedOutputBuffers; + private final LinkedList dequeuedOutputBuffers; private final InputBuffer[] availableInputBuffers; private final OutputBuffer[] availableOutputBuffers; private int availableInputBufferCount; @@ -66,10 +68,14 @@ import java.util.LinkedList; long seekPreRollNs) throws OpusDecoderException { lock = new Object(); opusHeader = parseOpusHeader(headerBytes); - skipSamples = (codecDelayNs == -1) ? opusHeader.skipSamples : nsToSamples(codecDelayNs); - seekPreRoll = (seekPreRoll == -1) ? DEFAULT_SEEK_PRE_ROLL : nsToSamples(seekPreRollNs); + skipSamples = (codecDelayNs == -1) ? opusHeader.skipSamples + : nsToSamples(opusHeader, codecDelayNs); + seekPreRoll = (seekPreRoll == -1) ? DEFAULT_SEEK_PRE_ROLL + : nsToSamples(opusHeader, seekPreRollNs); + dequeuedInputBuffers = new LinkedList<>(); queuedInputBuffers = new LinkedList<>(); queuedOutputBuffers = new LinkedList<>(); + dequeuedOutputBuffers = new LinkedList<>(); availableInputBuffers = new InputBuffer[NUM_BUFFERS]; availableOutputBuffers = new OutputBuffer[NUM_BUFFERS]; availableInputBufferCount = NUM_BUFFERS; @@ -80,7 +86,7 @@ import java.util.LinkedList; } } - public InputBuffer getInputBuffer() throws OpusDecoderException { + public InputBuffer dequeueInputBuffer() throws OpusDecoderException { synchronized (lock) { maybeThrowDecoderError(); if (availableInputBufferCount == 0) { @@ -88,6 +94,7 @@ import java.util.LinkedList; } InputBuffer inputBuffer = availableInputBuffers[--availableInputBufferCount]; inputBuffer.reset(); + dequeuedInputBuffers.addLast(inputBuffer); return inputBuffer; } } @@ -95,6 +102,7 @@ import java.util.LinkedList; public void queueInputBuffer(InputBuffer inputBuffer) throws OpusDecoderException { synchronized (lock) { maybeThrowDecoderError(); + dequeuedInputBuffers.remove(inputBuffer); queuedInputBuffers.addLast(inputBuffer); maybeNotifyDecodeLoop(); } @@ -106,7 +114,9 @@ import java.util.LinkedList; if (queuedOutputBuffers.isEmpty()) { return null; } - return queuedOutputBuffers.removeFirst(); + OutputBuffer outputBuffer = queuedOutputBuffers.removeFirst(); + dequeuedOutputBuffers.add(outputBuffer); + return outputBuffer; } } @@ -114,6 +124,7 @@ import java.util.LinkedList; synchronized (lock) { maybeThrowDecoderError(); outputBuffer.reset(); + dequeuedOutputBuffers.remove(outputBuffer); availableOutputBuffers[availableOutputBufferCount++] = outputBuffer; maybeNotifyDecodeLoop(); } @@ -122,12 +133,18 @@ import java.util.LinkedList; public void flush() { synchronized (lock) { flushDecodedOutputBuffer = true; + while (!dequeuedInputBuffers.isEmpty()) { + availableInputBuffers[availableInputBufferCount++] = dequeuedInputBuffers.removeFirst(); + } while (!queuedInputBuffers.isEmpty()) { availableInputBuffers[availableInputBufferCount++] = queuedInputBuffers.removeFirst(); } while (!queuedOutputBuffers.isEmpty()) { availableOutputBuffers[availableOutputBufferCount++] = queuedOutputBuffers.removeFirst(); } + while (!dequeuedOutputBuffers.isEmpty()) { + availableOutputBuffers[availableOutputBufferCount++] = dequeuedOutputBuffers.removeFirst(); + } } } @@ -254,7 +271,7 @@ import java.util.LinkedList; return true; } - private OpusHeader parseOpusHeader(byte[] headerBytes) throws OpusDecoderException { + private static OpusHeader parseOpusHeader(byte[] headerBytes) throws OpusDecoderException { final int maxChannelCount = 8; final int maxChannelCountWithDefaultLayout = 2; final int headerSize = 19; @@ -300,13 +317,13 @@ import java.util.LinkedList; } } - private int readLittleEndian16(byte[] input, int offset) { + private static int readLittleEndian16(byte[] input, int offset) { int value = input[offset]; value |= input[offset + 1] << 8; return value; } - private int nsToSamples(long ns) { + private static int nsToSamples(OpusHeader opusHeader, long ns) { return (int) (ns * opusHeader.sampleRate / 1000000000); } diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java index 0849c27db8..fd2d0579e4 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java @@ -298,7 +298,7 @@ public final class LibvpxVideoTrackRenderer extends SampleSourceTrackRenderer { } if (inputBuffer == null) { - inputBuffer = decoder.getInputBuffer(); + inputBuffer = decoder.dequeueInputBuffer(); if (inputBuffer == null) { return false; } diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoderWrapper.java b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoderWrapper.java index 691ca96f00..5999244da7 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoderWrapper.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoderWrapper.java @@ -32,8 +32,10 @@ import java.util.LinkedList; private final Object lock; + private final LinkedList dequeuedInputBuffers; private final LinkedList queuedInputBuffers; private final LinkedList queuedOutputBuffers; + private final LinkedList dequeuedOutputBuffers; private final InputBuffer[] availableInputBuffers; private final OutputBuffer[] availableOutputBuffers; private int availableInputBufferCount; @@ -52,8 +54,10 @@ import java.util.LinkedList; public VpxDecoderWrapper(int outputMode) { lock = new Object(); this.outputMode = outputMode; + dequeuedInputBuffers = new LinkedList<>(); queuedInputBuffers = new LinkedList<>(); queuedOutputBuffers = new LinkedList<>(); + dequeuedOutputBuffers = new LinkedList<>(); availableInputBuffers = new InputBuffer[NUM_BUFFERS]; availableOutputBuffers = new OutputBuffer[NUM_BUFFERS]; availableInputBufferCount = NUM_BUFFERS; @@ -68,7 +72,7 @@ import java.util.LinkedList; this.outputMode = outputMode; } - public InputBuffer getInputBuffer() throws VpxDecoderException { + public InputBuffer dequeueInputBuffer() throws VpxDecoderException { synchronized (lock) { maybeThrowDecoderError(); if (availableInputBufferCount == 0) { @@ -77,6 +81,7 @@ import java.util.LinkedList; InputBuffer inputBuffer = availableInputBuffers[--availableInputBufferCount]; inputBuffer.flags = 0; inputBuffer.sampleHolder.clearData(); + dequeuedInputBuffers.addLast(inputBuffer); return inputBuffer; } } @@ -84,6 +89,7 @@ import java.util.LinkedList; public void queueInputBuffer(InputBuffer inputBuffer) throws VpxDecoderException { synchronized (lock) { maybeThrowDecoderError(); + dequeuedInputBuffers.remove(inputBuffer); queuedInputBuffers.addLast(inputBuffer); maybeNotifyDecodeLoop(); } @@ -95,13 +101,16 @@ import java.util.LinkedList; if (queuedOutputBuffers.isEmpty()) { return null; } - return queuedOutputBuffers.removeFirst(); + OutputBuffer outputBuffer = queuedOutputBuffers.removeFirst(); + dequeuedOutputBuffers.add(outputBuffer); + return outputBuffer; } } public void releaseOutputBuffer(OutputBuffer outputBuffer) throws VpxDecoderException { synchronized (lock) { maybeThrowDecoderError(); + dequeuedOutputBuffers.remove(outputBuffer); availableOutputBuffers[availableOutputBufferCount++] = outputBuffer; maybeNotifyDecodeLoop(); } @@ -110,12 +119,18 @@ import java.util.LinkedList; public void flush() { synchronized (lock) { flushDecodedOutputBuffer = true; + while (!dequeuedInputBuffers.isEmpty()) { + availableInputBuffers[availableInputBufferCount++] = dequeuedInputBuffers.removeFirst(); + } while (!queuedInputBuffers.isEmpty()) { availableInputBuffers[availableInputBufferCount++] = queuedInputBuffers.removeFirst(); } while (!queuedOutputBuffers.isEmpty()) { availableOutputBuffers[availableOutputBufferCount++] = queuedOutputBuffers.removeFirst(); } + while (!dequeuedOutputBuffers.isEmpty()) { + availableOutputBuffers[availableOutputBufferCount++] = dequeuedOutputBuffers.removeFirst(); + } } }