mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Expose first index in SampleQueue
This will be needed when retaining a back-buffer. Being able to query the first index allows us to work out when we've discarded all samples that were obtained from a particular chunk, which we'll use to determine when to remove chunks from ChunkSampleStream.mediaChunks. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=175172085
This commit is contained in:
parent
694bd997cb
commit
eb4e05199f
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user