Fix bug in SampleQueue.discardTo for duplicate timestamps.
When a stream has duplicate timestamps we currently discard to the last sample with the specified discardTo timestamp, but it should be the first one to adhere to the method doc and the intended usage. #minor-release PiperOrigin-RevId: 343458870
This commit is contained in:
parent
db48a68456
commit
1d2cf6f270
@ -894,6 +894,11 @@ public class SampleQueue implements TrackOutput {
|
||||
if (!keyframe || (flags[searchIndex] & C.BUFFER_FLAG_KEY_FRAME) != 0) {
|
||||
// We've found a suitable sample.
|
||||
sampleCountToTarget = i;
|
||||
if (timesUs[searchIndex] == timeUs) {
|
||||
// Stop the search if we found a sample at the specified time to avoid returning a later
|
||||
// sample with the same exactly matching timestamp.
|
||||
break;
|
||||
}
|
||||
}
|
||||
searchIndex++;
|
||||
if (searchIndex == capacity) {
|
||||
|
@ -861,6 +861,53 @@ public final class SampleQueueTest {
|
||||
assertAllocationCount(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void discardTo_withDuplicateTimestamps_discardsOnlyToFirstMatch() {
|
||||
writeTestData(
|
||||
DATA,
|
||||
SAMPLE_SIZES,
|
||||
SAMPLE_OFFSETS,
|
||||
/* sampleTimestamps= */ new long[] {0, 1000, 1000, 1000, 2000, 2000, 2000, 2000},
|
||||
SAMPLE_FORMATS,
|
||||
/* sampleFlags= */ new int[] {
|
||||
BUFFER_FLAG_KEY_FRAME,
|
||||
0,
|
||||
BUFFER_FLAG_KEY_FRAME,
|
||||
BUFFER_FLAG_KEY_FRAME,
|
||||
0,
|
||||
0,
|
||||
BUFFER_FLAG_KEY_FRAME,
|
||||
BUFFER_FLAG_KEY_FRAME
|
||||
});
|
||||
|
||||
// Discard to first keyframe exactly matching the specified time.
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 1000, /* toKeyframe= */ true, /* stopAtReadPosition= */ false);
|
||||
assertThat(sampleQueue.getFirstIndex()).isEqualTo(2);
|
||||
|
||||
// Do nothing when trying again.
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 1000, /* toKeyframe= */ true, /* stopAtReadPosition= */ false);
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 1000, /* toKeyframe= */ false, /* stopAtReadPosition= */ false);
|
||||
assertThat(sampleQueue.getFirstIndex()).isEqualTo(2);
|
||||
|
||||
// Discard to first frame exactly matching the specified time.
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 2000, /* toKeyframe= */ false, /* stopAtReadPosition= */ false);
|
||||
assertThat(sampleQueue.getFirstIndex()).isEqualTo(4);
|
||||
|
||||
// Do nothing when trying again.
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 2000, /* toKeyframe= */ false, /* stopAtReadPosition= */ false);
|
||||
assertThat(sampleQueue.getFirstIndex()).isEqualTo(4);
|
||||
|
||||
// Discard to first keyframe at same timestamp.
|
||||
sampleQueue.discardTo(
|
||||
/* timeUs= */ 2000, /* toKeyframe= */ true, /* stopAtReadPosition= */ false);
|
||||
assertThat(sampleQueue.getFirstIndex()).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void discardToDontStopAtReadPosition() {
|
||||
writeTestData();
|
||||
|
Loading…
x
Reference in New Issue
Block a user