mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Split SampleQueue.advanceTo into two operations.
The method currently advances the read position and returns the number of skipped samples. This prevents checking how many samples are skipped before the operation is executed. Instead, we have a new method that returns the number of to be skipped samples and a skip method that executes the skipping. PiperOrigin-RevId: 320953439
This commit is contained in:
parent
92437f3a0f
commit
29b12e2f8d
@ -499,12 +499,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
}
|
||||
maybeNotifyDownstreamFormat(track);
|
||||
SampleQueue sampleQueue = sampleQueues[track];
|
||||
int skipCount;
|
||||
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
|
||||
skipCount = sampleQueue.advanceToEnd();
|
||||
} else {
|
||||
skipCount = sampleQueue.advanceTo(positionUs);
|
||||
}
|
||||
int skipCount = sampleQueue.getSkipCount(positionUs, loadingFinished);
|
||||
sampleQueue.skip(skipCount);
|
||||
if (skipCount == 0) {
|
||||
maybeStartDeferredRetry(track);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.source;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkArgument;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.CallSuper;
|
||||
@ -402,34 +404,39 @@ public class SampleQueue implements TrackOutput {
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the read position to the keyframe before or at the specified time.
|
||||
* Returns the number of samples that need to be {@link #skip(int) skipped} to advance the read
|
||||
* position to the keyframe before or at the specified time.
|
||||
*
|
||||
* @param timeUs The time to advance to.
|
||||
* @return The number of samples that were skipped, which may be equal to 0.
|
||||
* @param allowEndOfQueue Whether the end of the queue is considered a keyframe when {@code
|
||||
* timeUs} is larger than the largest queued timestamp.
|
||||
* @return The number of samples that need to be skipped, which may be equal to 0.
|
||||
*/
|
||||
public final synchronized int advanceTo(long timeUs) {
|
||||
public final synchronized int getSkipCount(long timeUs, boolean allowEndOfQueue) {
|
||||
int relativeReadIndex = getRelativeIndex(readPosition);
|
||||
if (!hasNextSample() || timeUs < timesUs[relativeReadIndex]) {
|
||||
return 0;
|
||||
}
|
||||
if (timeUs > largestQueuedTimestampUs && allowEndOfQueue) {
|
||||
return length - readPosition;
|
||||
}
|
||||
int offset =
|
||||
findSampleBefore(relativeReadIndex, length - readPosition, timeUs, /* keyframe= */ true);
|
||||
if (offset == -1) {
|
||||
return 0;
|
||||
}
|
||||
readPosition += offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the read position to the end of the queue.
|
||||
* Advances the read position by the specified number of samples.
|
||||
*
|
||||
* @return The number of samples that were skipped.
|
||||
* @param count The number of samples to advance the read position by. Must be at least 0 and at
|
||||
* most {@link #getWriteIndex()} - {@link #getReadIndex()}.
|
||||
*/
|
||||
public final synchronized int advanceToEnd() {
|
||||
int skipCount = length - readPosition;
|
||||
readPosition = length;
|
||||
return skipCount;
|
||||
public final synchronized void skip(int count) {
|
||||
checkArgument(count >= 0 && readPosition + count <= length);
|
||||
readPosition += count;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -788,7 +795,7 @@ public class SampleQueue implements TrackOutput {
|
||||
|
||||
private long discardUpstreamSampleMetadata(int discardFromIndex) {
|
||||
int discardCount = getWriteIndex() - discardFromIndex;
|
||||
Assertions.checkArgument(0 <= discardCount && discardCount <= (length - readPosition));
|
||||
checkArgument(0 <= discardCount && discardCount <= (length - readPosition));
|
||||
length -= discardCount;
|
||||
largestQueuedTimestampUs = Math.max(largestDiscardedTimestampUs, getLargestTimestamp(length));
|
||||
isLastSampleQueued = discardCount == 0 && isLastSampleQueued;
|
||||
|
@ -392,12 +392,8 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
if (isPendingReset()) {
|
||||
return 0;
|
||||
}
|
||||
int skipCount;
|
||||
if (loadingFinished && positionUs > primarySampleQueue.getLargestQueuedTimestampUs()) {
|
||||
skipCount = primarySampleQueue.advanceToEnd();
|
||||
} else {
|
||||
skipCount = primarySampleQueue.advanceTo(positionUs);
|
||||
}
|
||||
int skipCount = primarySampleQueue.getSkipCount(positionUs, loadingFinished);
|
||||
primarySampleQueue.skip(skipCount);
|
||||
maybeNotifyPrimaryTrackFormatChanged();
|
||||
return skipCount;
|
||||
}
|
||||
@ -789,12 +785,8 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
return 0;
|
||||
}
|
||||
maybeNotifyDownstreamFormat();
|
||||
int skipCount;
|
||||
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
|
||||
skipCount = sampleQueue.advanceToEnd();
|
||||
} else {
|
||||
skipCount = sampleQueue.advanceTo(positionUs);
|
||||
}
|
||||
int skipCount = sampleQueue.getSkipCount(positionUs, loadingFinished);
|
||||
sampleQueue.skip(skipCount);
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import static com.google.android.exoplayer2.C.RESULT_BUFFER_READ;
|
||||
import static com.google.android.exoplayer2.C.RESULT_FORMAT_READ;
|
||||
import static com.google.android.exoplayer2.C.RESULT_NOTHING_READ;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.lang.Long.MAX_VALUE;
|
||||
import static java.lang.Long.MIN_VALUE;
|
||||
import static java.util.Arrays.copyOfRange;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
@ -590,9 +591,10 @@ public final class SampleQueueTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToEnd() {
|
||||
public void skipToEnd() {
|
||||
writeTestData();
|
||||
sampleQueue.advanceToEnd();
|
||||
sampleQueue.skip(
|
||||
sampleQueue.getSkipCount(/* timeUs= */ MAX_VALUE, /* allowEndOfQueue= */ true));
|
||||
assertAllocationCount(10);
|
||||
sampleQueue.discardToRead();
|
||||
assertAllocationCount(0);
|
||||
@ -604,10 +606,11 @@ public final class SampleQueueTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToEndRetainsUnassignedData() {
|
||||
public void skipToEndRetainsUnassignedData() {
|
||||
sampleQueue.format(FORMAT_1);
|
||||
sampleQueue.sampleData(new ParsableByteArray(DATA), ALLOCATION_SIZE);
|
||||
sampleQueue.advanceToEnd();
|
||||
sampleQueue.skip(
|
||||
sampleQueue.getSkipCount(/* timeUs= */ MAX_VALUE, /* allowEndOfQueue= */ true));
|
||||
assertAllocationCount(1);
|
||||
sampleQueue.discardToRead();
|
||||
// Skipping shouldn't discard data that may belong to a sample whose metadata has yet to be
|
||||
@ -635,41 +638,47 @@ public final class SampleQueueTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToBeforeBuffer() {
|
||||
public void skipToBeforeBuffer() {
|
||||
writeTestData();
|
||||
int skipCount = sampleQueue.advanceTo(SAMPLE_TIMESTAMPS[0] - 1);
|
||||
int skipCount =
|
||||
sampleQueue.getSkipCount(SAMPLE_TIMESTAMPS[0] - 1, /* allowEndOfQueue= */ false);
|
||||
// Should have no effect (we're already at the first frame).
|
||||
assertThat(skipCount).isEqualTo(0);
|
||||
sampleQueue.skip(skipCount);
|
||||
assertReadTestData();
|
||||
assertNoSamplesToRead(FORMAT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToStartOfBuffer() {
|
||||
public void skipToStartOfBuffer() {
|
||||
writeTestData();
|
||||
int skipCount = sampleQueue.advanceTo(SAMPLE_TIMESTAMPS[0]);
|
||||
int skipCount = sampleQueue.getSkipCount(SAMPLE_TIMESTAMPS[0], /* allowEndOfQueue= */ false);
|
||||
// Should have no effect (we're already at the first frame).
|
||||
assertThat(skipCount).isEqualTo(0);
|
||||
sampleQueue.skip(skipCount);
|
||||
assertReadTestData();
|
||||
assertNoSamplesToRead(FORMAT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToEndOfBuffer() {
|
||||
public void skipToEndOfBuffer() {
|
||||
writeTestData();
|
||||
int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP);
|
||||
int skipCount = sampleQueue.getSkipCount(LAST_SAMPLE_TIMESTAMP, /* allowEndOfQueue= */ false);
|
||||
// Should advance to 2nd keyframe (the 4th frame).
|
||||
assertThat(skipCount).isEqualTo(4);
|
||||
sampleQueue.skip(skipCount);
|
||||
assertReadTestData(/* startFormat= */ null, DATA_SECOND_KEYFRAME_INDEX);
|
||||
assertNoSamplesToRead(FORMAT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void advanceToAfterBuffer() {
|
||||
public void skipToAfterBuffer() {
|
||||
writeTestData();
|
||||
int skipCount = sampleQueue.advanceTo(LAST_SAMPLE_TIMESTAMP + 1);
|
||||
int skipCount =
|
||||
sampleQueue.getSkipCount(LAST_SAMPLE_TIMESTAMP + 1, /* allowEndOfQueue= */ false);
|
||||
// Should advance to 2nd keyframe (the 4th frame).
|
||||
assertThat(skipCount).isEqualTo(4);
|
||||
sampleQueue.skip(skipCount);
|
||||
assertReadTestData(/* startFormat= */ null, DATA_SECOND_KEYFRAME_INDEX);
|
||||
assertNoSamplesToRead(FORMAT_2);
|
||||
}
|
||||
|
@ -595,11 +595,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
}
|
||||
|
||||
SampleQueue sampleQueue = sampleQueues[sampleQueueIndex];
|
||||
if (loadingFinished && positionUs > sampleQueue.getLargestQueuedTimestampUs()) {
|
||||
return sampleQueue.advanceToEnd();
|
||||
} else {
|
||||
return sampleQueue.advanceTo(positionUs);
|
||||
}
|
||||
int skipCount = sampleQueue.getSkipCount(positionUs, loadingFinished);
|
||||
sampleQueue.skip(skipCount);
|
||||
return skipCount;
|
||||
}
|
||||
|
||||
// SequenceableLoader implementation
|
||||
|
Loading…
x
Reference in New Issue
Block a user