mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
aca80b8347
commit
950c2159b0
3 changed files with 40 additions and 44 deletions
|
|
@ -364,7 +364,7 @@ public class SampleQueueTest extends TestCase {
|
||||||
sampleQueue.discardUpstreamSamples(7);
|
sampleQueue.discardUpstreamSamples(7);
|
||||||
assertAllocationCount(9);
|
assertAllocationCount(9);
|
||||||
sampleQueue.discardUpstreamSamples(6);
|
sampleQueue.discardUpstreamSamples(6);
|
||||||
assertAllocationCount(8); // Byte not belonging to sample prevents 7.
|
assertAllocationCount(7);
|
||||||
sampleQueue.discardUpstreamSamples(5);
|
sampleQueue.discardUpstreamSamples(5);
|
||||||
assertAllocationCount(5);
|
assertAllocationCount(5);
|
||||||
sampleQueue.discardUpstreamSamples(4);
|
sampleQueue.discardUpstreamSamples(4);
|
||||||
|
|
@ -372,11 +372,11 @@ public class SampleQueueTest extends TestCase {
|
||||||
sampleQueue.discardUpstreamSamples(3);
|
sampleQueue.discardUpstreamSamples(3);
|
||||||
assertAllocationCount(3);
|
assertAllocationCount(3);
|
||||||
sampleQueue.discardUpstreamSamples(2);
|
sampleQueue.discardUpstreamSamples(2);
|
||||||
assertAllocationCount(3); // Byte not belonging to sample prevents 2.
|
assertAllocationCount(2);
|
||||||
sampleQueue.discardUpstreamSamples(1);
|
sampleQueue.discardUpstreamSamples(1);
|
||||||
assertAllocationCount(2); // Byte not belonging to sample prevents 1.
|
assertAllocationCount(1);
|
||||||
sampleQueue.discardUpstreamSamples(0);
|
sampleQueue.discardUpstreamSamples(0);
|
||||||
assertAllocationCount(1); // Byte not belonging to sample prevents 0.
|
assertAllocationCount(0);
|
||||||
assertReadFormat(false, TEST_FORMAT_2);
|
assertReadFormat(false, TEST_FORMAT_2);
|
||||||
assertNoSamplesToRead(TEST_FORMAT_2);
|
assertNoSamplesToRead(TEST_FORMAT_2);
|
||||||
}
|
}
|
||||||
|
|
@ -386,7 +386,7 @@ public class SampleQueueTest extends TestCase {
|
||||||
sampleQueue.discardUpstreamSamples(4);
|
sampleQueue.discardUpstreamSamples(4);
|
||||||
assertAllocationCount(4);
|
assertAllocationCount(4);
|
||||||
sampleQueue.discardUpstreamSamples(0);
|
sampleQueue.discardUpstreamSamples(0);
|
||||||
assertAllocationCount(1); // Byte not belonging to sample prevents 0.
|
assertAllocationCount(0);
|
||||||
assertReadFormat(false, TEST_FORMAT_2);
|
assertReadFormat(false, TEST_FORMAT_2);
|
||||||
assertNoSamplesToRead(TEST_FORMAT_2);
|
assertNoSamplesToRead(TEST_FORMAT_2);
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +410,7 @@ public class SampleQueueTest extends TestCase {
|
||||||
sampleQueue.discardUpstreamSamples(7);
|
sampleQueue.discardUpstreamSamples(7);
|
||||||
assertAllocationCount(6);
|
assertAllocationCount(6);
|
||||||
sampleQueue.discardUpstreamSamples(6);
|
sampleQueue.discardUpstreamSamples(6);
|
||||||
assertAllocationCount(5); // Byte not belonging to sample prevents 4.
|
assertAllocationCount(4);
|
||||||
sampleQueue.discardUpstreamSamples(5);
|
sampleQueue.discardUpstreamSamples(5);
|
||||||
assertAllocationCount(2);
|
assertAllocationCount(2);
|
||||||
sampleQueue.discardUpstreamSamples(4);
|
sampleQueue.discardUpstreamSamples(4);
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* @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) {
|
public long discardUpstreamSamples(int discardFromIndex) {
|
||||||
int discardCount = getWriteIndex() - discardFromIndex;
|
int discardCount = getWriteIndex() - discardFromIndex;
|
||||||
Assertions.checkArgument(0 <= discardCount && discardCount <= (length - readPosition));
|
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;
|
length -= discardCount;
|
||||||
relativeEndIndex = (relativeEndIndex + capacity - discardCount) % capacity;
|
largestQueuedTimestampUs = Math.max(largestDiscardedTimestampUs, getLargestTimestamp(length));
|
||||||
largestQueuedTimestampUs = Math.max(largestDiscardedTimestampUs,
|
if (length == 0) {
|
||||||
getLargestTimestamp(relativeStartIndex, length));
|
return 0;
|
||||||
return offsets[relativeEndIndex];
|
} else {
|
||||||
|
int relativeLastWriteIndex = (relativeStartIndex + length - 1) % capacity;
|
||||||
|
return offsets[relativeLastWriteIndex] + sizes[relativeLastWriteIndex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sourceId(int sourceId) {
|
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
|
* Peeks the source id of the next sample to be read, or the current upstream source id if the
|
||||||
* {@link #hasNextSample()} is {@code false}.
|
* queue is empty or if the read position is at the end of the queue.
|
||||||
|
*
|
||||||
|
* @return The source id.
|
||||||
*/
|
*/
|
||||||
public int peekSourceId() {
|
public int peekSourceId() {
|
||||||
int relativeReadIndex = (relativeStartIndex + readPosition) % capacity;
|
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
|
* @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.
|
* time, rather than to any sample before or at that time.
|
||||||
* @param allowTimeBeyondBuffer Whether the operation can succeed if {@code timeUs} is beyond the
|
* @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
|
* end of the queue, by advancing the read position to the last sample (or keyframe) in the
|
||||||
* buffer.
|
* queue.
|
||||||
* @return Whether the operation was a success. A successful advance is one in which the read
|
* @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.
|
* 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.
|
* @return Whether the splice was successful.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean attemptSplice(long timeUs) {
|
public synchronized boolean attemptSplice(long timeUs) {
|
||||||
|
if (length == 0) {
|
||||||
|
return timeUs > largestDiscardedTimestampUs;
|
||||||
|
}
|
||||||
long largestReadTimestampUs = Math.max(largestDiscardedTimestampUs,
|
long largestReadTimestampUs = Math.max(largestDiscardedTimestampUs,
|
||||||
getLargestTimestamp(relativeStartIndex, readPosition));
|
getLargestTimestamp(readPosition));
|
||||||
if (largestReadTimestampUs >= timeUs) {
|
if (largestReadTimestampUs >= timeUs) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -470,7 +468,7 @@ import com.google.android.exoplayer2.util.Util;
|
||||||
*/
|
*/
|
||||||
private long discardSamples(int discardCount) {
|
private long discardSamples(int discardCount) {
|
||||||
largestDiscardedTimestampUs = Math.max(largestDiscardedTimestampUs,
|
largestDiscardedTimestampUs = Math.max(largestDiscardedTimestampUs,
|
||||||
getLargestTimestamp(relativeStartIndex, discardCount));
|
getLargestTimestamp(discardCount));
|
||||||
length -= discardCount;
|
length -= discardCount;
|
||||||
absoluteStartIndex += discardCount;
|
absoluteStartIndex += discardCount;
|
||||||
relativeStartIndex += discardCount;
|
relativeStartIndex += discardCount;
|
||||||
|
|
@ -482,22 +480,22 @@ import com.google.android.exoplayer2.util.Util;
|
||||||
readPosition = 0;
|
readPosition = 0;
|
||||||
}
|
}
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
int relativeLastDiscardedIndex = (relativeStartIndex - 1 + capacity) % capacity;
|
int relativeLastDiscardIndex = (relativeStartIndex == 0 ? capacity : relativeStartIndex) - 1;
|
||||||
return offsets[relativeLastDiscardedIndex] + sizes[relativeLastDiscardedIndex];
|
return offsets[relativeLastDiscardIndex] + sizes[relativeLastDiscardIndex];
|
||||||
} else {
|
} else {
|
||||||
return offsets[relativeStartIndex];
|
return offsets[relativeStartIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the largest timestamp in the specified range, assuming that the timestamps prior to a
|
* Finds the largest timestamp of any sample from the start of the queue up to the specified
|
||||||
* keyframe are always less than the timestamp of the keyframe itself, and of subsequent frames.
|
* 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.
|
* @param length The length of the range being searched.
|
||||||
* @return The largest timestamp, or {@link Long#MIN_VALUE} if {@code length <= 0}.
|
* @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;
|
long largestTimestampUs = Long.MIN_VALUE;
|
||||||
for (int i = length - 1; i >= 0; i--) {
|
for (int i = length - 1; i >= 0; i--) {
|
||||||
int sampleIndex = (relativeStartIndex + i) % capacity;
|
int sampleIndex = (relativeStartIndex + i) % capacity;
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,7 @@ public final class SampleQueue implements TrackOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that samples subsequently queued to the buffer should be spliced into those already
|
* Indicates samples that are subsequently queued should be spliced into those already queued.
|
||||||
* queued.
|
|
||||||
*/
|
*/
|
||||||
public void splice() {
|
public void splice() {
|
||||||
pendingSplice = true;
|
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
|
* @param discardFromIndex The absolute index of the first sample to be discarded. Must be in the
|
||||||
* range [{@link #getReadIndex()}, {@link #getWriteIndex()}].
|
* range [{@link #getReadIndex()}, {@link #getWriteIndex()}].
|
||||||
*/
|
*/
|
||||||
public void discardUpstreamSamples(int discardFromIndex) {
|
public void discardUpstreamSamples(int discardFromIndex) {
|
||||||
totalBytesWritten = metadataQueue.discardUpstreamSamples(discardFromIndex);
|
totalBytesWritten = metadataQueue.discardUpstreamSamples(discardFromIndex);
|
||||||
if (totalBytesWritten == firstAllocationNode.startPosition) {
|
if (totalBytesWritten == 0 || totalBytesWritten == firstAllocationNode.startPosition) {
|
||||||
clearAllocationNodes(firstAllocationNode);
|
clearAllocationNodes(firstAllocationNode);
|
||||||
firstAllocationNode = new AllocationNode(totalBytesWritten, allocationLength);
|
firstAllocationNode = new AllocationNode(totalBytesWritten, allocationLength);
|
||||||
readAllocationNode = firstAllocationNode;
|
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
|
* Peeks the source id of the next sample to be read, or the current upstream source id if the
|
||||||
* empty.
|
* queue is empty or if the read position is at the end of the queue.
|
||||||
*
|
*
|
||||||
* @return The source id.
|
* @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
|
* @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.
|
* time, rather than to any sample before or at that time.
|
||||||
* @param allowTimeBeyondBuffer Whether the operation can succeed if {@code timeUs} is beyond the
|
* @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
|
* end of the queue, by advancing the read position to the last sample (or keyframe).
|
||||||
* buffer.
|
|
||||||
* @return Whether the operation was a success. A successful advance is one in which the read
|
* @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.
|
* 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
|
* 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.
|
* @param sampleOffsetUs The timestamp offset in microseconds.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue