Discard upstream allocations more aggressively + doc cleanup

- If we have <s1>garbage<s2> and discard <s2>, throw away
  the garbage too.
- Cleanup some documentation to consistently refer to the
  queue as "queue" rather than "buffer".

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=159816309
This commit is contained in:
olly 2017-06-22 05:41:02 -07:00 committed by Oliver Woodman
parent aca80b8347
commit 950c2159b0
3 changed files with 40 additions and 44 deletions

View file

@ -364,7 +364,7 @@ public class SampleQueueTest extends TestCase {
sampleQueue.discardUpstreamSamples(7);
assertAllocationCount(9);
sampleQueue.discardUpstreamSamples(6);
assertAllocationCount(8); // Byte not belonging to sample prevents 7.
assertAllocationCount(7);
sampleQueue.discardUpstreamSamples(5);
assertAllocationCount(5);
sampleQueue.discardUpstreamSamples(4);
@ -372,11 +372,11 @@ public class SampleQueueTest extends TestCase {
sampleQueue.discardUpstreamSamples(3);
assertAllocationCount(3);
sampleQueue.discardUpstreamSamples(2);
assertAllocationCount(3); // Byte not belonging to sample prevents 2.
assertAllocationCount(2);
sampleQueue.discardUpstreamSamples(1);
assertAllocationCount(2); // Byte not belonging to sample prevents 1.
assertAllocationCount(1);
sampleQueue.discardUpstreamSamples(0);
assertAllocationCount(1); // Byte not belonging to sample prevents 0.
assertAllocationCount(0);
assertReadFormat(false, TEST_FORMAT_2);
assertNoSamplesToRead(TEST_FORMAT_2);
}
@ -386,7 +386,7 @@ public class SampleQueueTest extends TestCase {
sampleQueue.discardUpstreamSamples(4);
assertAllocationCount(4);
sampleQueue.discardUpstreamSamples(0);
assertAllocationCount(1); // Byte not belonging to sample prevents 0.
assertAllocationCount(0);
assertReadFormat(false, TEST_FORMAT_2);
assertNoSamplesToRead(TEST_FORMAT_2);
}
@ -410,7 +410,7 @@ public class SampleQueueTest extends TestCase {
sampleQueue.discardUpstreamSamples(7);
assertAllocationCount(6);
sampleQueue.discardUpstreamSamples(6);
assertAllocationCount(5); // Byte not belonging to sample prevents 4.
assertAllocationCount(4);
sampleQueue.discardUpstreamSamples(5);
assertAllocationCount(2);
sampleQueue.discardUpstreamSamples(4);

View file

@ -100,30 +100,23 @@ import com.google.android.exoplayer2.util.Util;
}
/**
* Discards samples from the write side of the buffer.
* Discards samples from the write side of the queue.
*
* @param discardFromIndex The absolute index of the first sample to be discarded.
* @return The reduced total number of bytes written, after the samples have been discarded.
* @return The reduced total number of bytes written after the samples have been discarded, or 0
* if the queue is now empty.
*/
public long discardUpstreamSamples(int discardFromIndex) {
int discardCount = getWriteIndex() - discardFromIndex;
Assertions.checkArgument(0 <= discardCount && discardCount <= (length - readPosition));
int relativeEndIndex = (relativeStartIndex + length) % capacity;
if (discardCount == 0) {
if (absoluteStartIndex == 0 && length == 0) {
// Nothing has been written to the queue.
return 0;
}
int lastWriteIndex = (relativeEndIndex == 0 ? capacity : relativeEndIndex) - 1;
return offsets[lastWriteIndex] + sizes[lastWriteIndex];
}
length -= discardCount;
relativeEndIndex = (relativeEndIndex + capacity - discardCount) % capacity;
largestQueuedTimestampUs = Math.max(largestDiscardedTimestampUs,
getLargestTimestamp(relativeStartIndex, length));
return offsets[relativeEndIndex];
largestQueuedTimestampUs = Math.max(largestDiscardedTimestampUs, getLargestTimestamp(length));
if (length == 0) {
return 0;
} else {
int relativeLastWriteIndex = (relativeStartIndex + length - 1) % capacity;
return offsets[relativeLastWriteIndex] + sizes[relativeLastWriteIndex];
}
}
public void sourceId(int sourceId) {
@ -140,8 +133,10 @@ import com.google.android.exoplayer2.util.Util;
}
/**
* Peeks the source id of the next sample, or the current upstream source id if
* {@link #hasNextSample()} is {@code false}.
* Peeks the source id of the next sample to be read, or the current upstream source id if the
* queue is empty or if the read position is at the end of the queue.
*
* @return The source id.
*/
public int peekSourceId() {
int relativeReadIndex = (relativeStartIndex + readPosition) % capacity;
@ -249,8 +244,8 @@ import com.google.android.exoplayer2.util.Util;
* @param toKeyframe If true then attempts to advance to the keyframe before or at the specified
* time, rather than to any sample before or at that time.
* @param allowTimeBeyondBuffer Whether the operation can succeed if {@code timeUs} is beyond the
* end of the buffer, by advancing the read position to the last sample (or keyframe) in the
* buffer.
* end of the queue, by advancing the read position to the last sample (or keyframe) in the
* queue.
* @return Whether the operation was a success. A successful advance is one in which the read
* position was unchanged or advanced, and is now at a sample meeting the specified criteria.
*/
@ -418,8 +413,11 @@ import com.google.android.exoplayer2.util.Util;
* @return Whether the splice was successful.
*/
public synchronized boolean attemptSplice(long timeUs) {
if (length == 0) {
return timeUs > largestDiscardedTimestampUs;
}
long largestReadTimestampUs = Math.max(largestDiscardedTimestampUs,
getLargestTimestamp(relativeStartIndex, readPosition));
getLargestTimestamp(readPosition));
if (largestReadTimestampUs >= timeUs) {
return false;
}
@ -470,7 +468,7 @@ import com.google.android.exoplayer2.util.Util;
*/
private long discardSamples(int discardCount) {
largestDiscardedTimestampUs = Math.max(largestDiscardedTimestampUs,
getLargestTimestamp(relativeStartIndex, discardCount));
getLargestTimestamp(discardCount));
length -= discardCount;
absoluteStartIndex += discardCount;
relativeStartIndex += discardCount;
@ -482,22 +480,22 @@ import com.google.android.exoplayer2.util.Util;
readPosition = 0;
}
if (length == 0) {
int relativeLastDiscardedIndex = (relativeStartIndex - 1 + capacity) % capacity;
return offsets[relativeLastDiscardedIndex] + sizes[relativeLastDiscardedIndex];
int relativeLastDiscardIndex = (relativeStartIndex == 0 ? capacity : relativeStartIndex) - 1;
return offsets[relativeLastDiscardIndex] + sizes[relativeLastDiscardIndex];
} else {
return offsets[relativeStartIndex];
}
}
/**
* Finds the largest timestamp in the specified range, assuming that the timestamps prior to a
* keyframe are always less than the timestamp of the keyframe itself, and of subsequent frames.
* Finds the largest timestamp of any sample from the start of the queue up to the specified
* length, assuming that the timestamps prior to a keyframe are always less than the timestamp of
* the keyframe itself, and of subsequent frames.
*
* @param relativeStartIndex The relative index from which to start searching.
* @param length The length of the range being searched.
* @return The largest timestamp, or {@link Long#MIN_VALUE} if {@code length <= 0}.
*/
private long getLargestTimestamp(int relativeStartIndex, int length) {
private long getLargestTimestamp(int length) {
long largestTimestampUs = Long.MIN_VALUE;
for (int i = length - 1; i >= 0; i--) {
int sampleIndex = (relativeStartIndex + i) % capacity;

View file

@ -120,8 +120,7 @@ public final class SampleQueue implements TrackOutput {
}
/**
* Indicates that samples subsequently queued to the buffer should be spliced into those already
* queued.
* Indicates samples that are subsequently queued should be spliced into those already queued.
*/
public void splice() {
pendingSplice = true;
@ -135,14 +134,14 @@ public final class SampleQueue implements TrackOutput {
}
/**
* Discards samples from the write side of the buffer.
* Discards samples from the write side of the queue.
*
* @param discardFromIndex The absolute index of the first sample to be discarded. Must be in the
* range [{@link #getReadIndex()}, {@link #getWriteIndex()}].
*/
public void discardUpstreamSamples(int discardFromIndex) {
totalBytesWritten = metadataQueue.discardUpstreamSamples(discardFromIndex);
if (totalBytesWritten == firstAllocationNode.startPosition) {
if (totalBytesWritten == 0 || totalBytesWritten == firstAllocationNode.startPosition) {
clearAllocationNodes(firstAllocationNode);
firstAllocationNode = new AllocationNode(totalBytesWritten, allocationLength);
readAllocationNode = firstAllocationNode;
@ -193,8 +192,8 @@ public final class SampleQueue implements TrackOutput {
}
/**
* Peeks the source id of the next sample, or the current upstream source id if the buffer is
* empty.
* Peeks the source id of the next sample to be read, or the current upstream source id if the
* queue is empty or if the read position is at the end of the queue.
*
* @return The source id.
*/
@ -293,8 +292,7 @@ public final class SampleQueue implements TrackOutput {
* @param toKeyframe If true then attempts to advance to the keyframe before or at the specified
* time, rather than to any sample before or at that time.
* @param allowTimeBeyondBuffer Whether the operation can succeed if {@code timeUs} is beyond the
* end of the buffer, by advancing the read position to the last sample (or keyframe) in the
* buffer.
* end of the queue, by advancing the read position to the last sample (or keyframe).
* @return Whether the operation was a success. A successful advance is one in which the read
* position was unchanged or advanced, and is now at a sample meeting the specified criteria.
*/
@ -528,7 +526,7 @@ public final class SampleQueue implements TrackOutput {
/**
* Sets an offset that will be added to the timestamps (and sub-sample timestamps) of samples
* subsequently queued to the buffer.
* that are subsequently queued.
*
* @param sampleOffsetUs The timestamp offset in microseconds.
*/