diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleMetadataQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleMetadataQueue.java index d70c59b195..65c443d425 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleMetadataQueue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleMetadataQueue.java @@ -51,8 +51,8 @@ import com.google.android.exoplayer2.util.Util; private Format[] formats; private int length; - private int absoluteStartIndex; - private int relativeStartIndex; + private int absoluteFirstIndex; + private int relativeFirstIndex; private int readPosition; private long largestDiscardedTimestampUs; @@ -87,8 +87,8 @@ import com.google.android.exoplayer2.util.Util; */ public void reset(boolean resetUpstreamFormat) { length = 0; - absoluteStartIndex = 0; - relativeStartIndex = 0; + absoluteFirstIndex = 0; + relativeFirstIndex = 0; readPosition = 0; upstreamKeyframeRequired = true; largestDiscardedTimestampUs = Long.MIN_VALUE; @@ -103,7 +103,7 @@ import com.google.android.exoplayer2.util.Util; * Returns the current absolute write index. */ public int getWriteIndex() { - return absoluteStartIndex + length; + return absoluteFirstIndex + length; } /** @@ -132,11 +132,18 @@ import com.google.android.exoplayer2.util.Util; // Called by the consuming thread. + /** + * Returns the current absolute start index. + */ + public int getFirstIndex() { + return absoluteFirstIndex; + } + /** * Returns the current absolute read index. */ public int getReadIndex() { - return absoluteStartIndex + readPosition; + return absoluteFirstIndex + readPosition; } /** @@ -297,11 +304,11 @@ import com.google.android.exoplayer2.util.Util; * {@link C#POSITION_UNSET} if no discarding of data is necessary. */ public synchronized long discardTo(long timeUs, boolean toKeyframe, boolean stopAtReadPosition) { - if (length == 0 || timeUs < timesUs[relativeStartIndex]) { + if (length == 0 || timeUs < timesUs[relativeFirstIndex]) { return C.POSITION_UNSET; } int searchLength = stopAtReadPosition && readPosition != length ? readPosition + 1 : length; - int discardCount = findSampleBefore(relativeStartIndex, searchLength, timeUs, toKeyframe); + int discardCount = findSampleBefore(relativeFirstIndex, searchLength, timeUs, toKeyframe); if (discardCount == -1) { return C.POSITION_UNSET; } @@ -382,15 +389,15 @@ import com.google.android.exoplayer2.util.Util; int[] newSizes = new int[newCapacity]; CryptoData[] newCryptoDatas = new CryptoData[newCapacity]; Format[] newFormats = new Format[newCapacity]; - int beforeWrap = capacity - relativeStartIndex; - System.arraycopy(offsets, relativeStartIndex, newOffsets, 0, beforeWrap); - System.arraycopy(timesUs, relativeStartIndex, newTimesUs, 0, beforeWrap); - System.arraycopy(flags, relativeStartIndex, newFlags, 0, beforeWrap); - System.arraycopy(sizes, relativeStartIndex, newSizes, 0, beforeWrap); - System.arraycopy(cryptoDatas, relativeStartIndex, newCryptoDatas, 0, beforeWrap); - System.arraycopy(formats, relativeStartIndex, newFormats, 0, beforeWrap); - System.arraycopy(sourceIds, relativeStartIndex, newSourceIds, 0, beforeWrap); - int afterWrap = relativeStartIndex; + int beforeWrap = capacity - relativeFirstIndex; + System.arraycopy(offsets, relativeFirstIndex, newOffsets, 0, beforeWrap); + System.arraycopy(timesUs, relativeFirstIndex, newTimesUs, 0, beforeWrap); + System.arraycopy(flags, relativeFirstIndex, newFlags, 0, beforeWrap); + System.arraycopy(sizes, relativeFirstIndex, newSizes, 0, beforeWrap); + System.arraycopy(cryptoDatas, relativeFirstIndex, newCryptoDatas, 0, beforeWrap); + System.arraycopy(formats, relativeFirstIndex, newFormats, 0, beforeWrap); + System.arraycopy(sourceIds, relativeFirstIndex, newSourceIds, 0, beforeWrap); + int afterWrap = relativeFirstIndex; System.arraycopy(offsets, 0, newOffsets, beforeWrap, afterWrap); System.arraycopy(timesUs, 0, newTimesUs, beforeWrap, afterWrap); System.arraycopy(flags, 0, newFlags, beforeWrap, afterWrap); @@ -405,7 +412,7 @@ import com.google.android.exoplayer2.util.Util; cryptoDatas = newCryptoDatas; formats = newFormats; sourceIds = newSourceIds; - relativeStartIndex = 0; + relativeFirstIndex = 0; length = capacity; capacity = newCapacity; } @@ -440,7 +447,7 @@ import com.google.android.exoplayer2.util.Util; relativeSampleIndex = capacity - 1; } } - discardUpstreamSamples(absoluteStartIndex + retainCount); + discardUpstreamSamples(absoluteFirstIndex + retainCount); return true; } @@ -454,7 +461,7 @@ import com.google.android.exoplayer2.util.Util; * @param length The length of the range being searched. * @param timeUs The specified time. * @param keyframe Whether only keyframes should be considered. - * @return The offset from {@code relativeStartIndex} to the found sample, or -1 if no matching + * @return The offset from {@code relativeFirstIndex} to the found sample, or -1 if no matching * sample was found. */ private int findSampleBefore(int relativeStartIndex, int length, long timeUs, boolean keyframe) { @@ -487,20 +494,20 @@ import com.google.android.exoplayer2.util.Util; largestDiscardedTimestampUs = Math.max(largestDiscardedTimestampUs, getLargestTimestamp(discardCount)); length -= discardCount; - absoluteStartIndex += discardCount; - relativeStartIndex += discardCount; - if (relativeStartIndex >= capacity) { - relativeStartIndex -= capacity; + absoluteFirstIndex += discardCount; + relativeFirstIndex += discardCount; + if (relativeFirstIndex >= capacity) { + relativeFirstIndex -= capacity; } readPosition -= discardCount; if (readPosition < 0) { readPosition = 0; } if (length == 0) { - int relativeLastDiscardIndex = (relativeStartIndex == 0 ? capacity : relativeStartIndex) - 1; + int relativeLastDiscardIndex = (relativeFirstIndex == 0 ? capacity : relativeFirstIndex) - 1; return offsets[relativeLastDiscardIndex] + sizes[relativeLastDiscardIndex]; } else { - return offsets[relativeStartIndex]; + return offsets[relativeFirstIndex]; } } @@ -537,7 +544,7 @@ import com.google.android.exoplayer2.util.Util; * @param offset The offset, which must be in the range [0, length]. */ private int getRelativeIndex(int offset) { - int relativeIndex = relativeStartIndex + offset; + int relativeIndex = relativeFirstIndex + offset; return relativeIndex < capacity ? relativeIndex : relativeIndex - capacity; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java index b83cf7df5b..78b16bf377 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SampleQueue.java @@ -181,6 +181,13 @@ public final class SampleQueue implements TrackOutput { return metadataQueue.hasNextSample(); } + /** + * Returns the absolute index of the first sample. + */ + public int getFirstIndex() { + return metadataQueue.getFirstIndex(); + } + /** * Returns the current absolute read index. */ diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java index 49983fae30..6030238131 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/SampleQueueTest.java @@ -215,12 +215,14 @@ public final class SampleQueueTest { public void testReadMultiWithRewind() { writeTestData(); assertReadTestData(); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(0); assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertAllocationCount(10); // Rewind. sampleQueue.rewind(); assertAllocationCount(10); // Read again. + assertThat(sampleQueue.getFirstIndex()).isEqualTo(0); assertThat(sampleQueue.getReadIndex()).isEqualTo(0); assertReadTestData(); } @@ -230,11 +232,14 @@ public final class SampleQueueTest { writeTestData(); assertReadTestData(); sampleQueue.discardToRead(); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(8); + assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertAllocationCount(0); // Rewind. sampleQueue.rewind(); assertAllocationCount(0); // Can't read again. + assertThat(sampleQueue.getFirstIndex()).isEqualTo(8); assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertReadEndOfStream(false); } @@ -332,6 +337,7 @@ public final class SampleQueueTest { writeTestData(); // Should discard everything. sampleQueue.discardToEnd(); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(8); assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertAllocationCount(0); // We should still be able to read the upstream format. @@ -346,28 +352,39 @@ public final class SampleQueueTest { writeTestData(); // Shouldn't discard anything. sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP, false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(0); assertThat(sampleQueue.getReadIndex()).isEqualTo(0); assertAllocationCount(10); // Read the first sample. assertReadTestData(null, 0, 1); // Shouldn't discard anything. sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(0); assertThat(sampleQueue.getReadIndex()).isEqualTo(1); assertAllocationCount(10); // Should discard the read sample. sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(1); + assertThat(sampleQueue.getReadIndex()).isEqualTo(1); assertAllocationCount(9); // Shouldn't discard anything. sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP, false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(1); + assertThat(sampleQueue.getReadIndex()).isEqualTo(1); assertAllocationCount(9); // Should be able to read the remaining samples. assertReadTestData(TEST_FORMAT_1, 1, 7); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(1); assertThat(sampleQueue.getReadIndex()).isEqualTo(8); // Should discard up to the second last sample sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP - 1, false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(6); + assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertAllocationCount(3); // Should discard up the last sample sampleQueue.discardTo(LAST_SAMPLE_TIMESTAMP, false, true); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(7); + assertThat(sampleQueue.getReadIndex()).isEqualTo(8); assertAllocationCount(1); } @@ -376,10 +393,12 @@ public final class SampleQueueTest { writeTestData(); // Shouldn't discard anything. sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1] - 1, false, false); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(0); assertThat(sampleQueue.getReadIndex()).isEqualTo(0); assertAllocationCount(10); // Should discard the first sample. sampleQueue.discardTo(TEST_SAMPLE_TIMESTAMPS[1], false, false); + assertThat(sampleQueue.getFirstIndex()).isEqualTo(1); assertThat(sampleQueue.getReadIndex()).isEqualTo(1); assertAllocationCount(9); // Should be able to read the remaining samples.