mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Fix ReplacingCuesResolver.discardCuesBeforeTimeUs to retain active cue
The method previously discarded the cue that was active at `timeUs`, meaning it had started before but had not ended by `timeUs`. Issue: androidx/media#1939 #cherrypick PiperOrigin-RevId: 702707611
This commit is contained in:
parent
06b94f5448
commit
e927d7b986
@ -46,6 +46,9 @@
|
||||
`MediaItem.Builder.setSubtitleConfigurations`, and instead only load one
|
||||
if it is selected by track selection
|
||||
([#1721](https://github.com/androidx/media/issues/1721)).
|
||||
* Fix bug in `ReplacingCuesResolver.discardCuesBeforeTimeUs` where the cue
|
||||
active at `timeUs` (started before but not yet ended) was incorrectly
|
||||
discarded ([#1939](https://github.com/androidx/media/issues/1939)).
|
||||
* Metadata:
|
||||
* Image:
|
||||
* DRM:
|
||||
|
@ -80,9 +80,15 @@ import java.util.ArrayList;
|
||||
@Override
|
||||
public void discardCuesBeforeTimeUs(long timeUs) {
|
||||
int indexToDiscardTo = getIndexOfCuesStartingAfter(timeUs);
|
||||
if (indexToDiscardTo > 0) {
|
||||
cuesWithTimingList.subList(0, indexToDiscardTo).clear();
|
||||
if (indexToDiscardTo == 0) {
|
||||
// Either the first cue starts after timeUs, or the cues list is empty.
|
||||
return;
|
||||
}
|
||||
CuesWithTiming lastCueToDiscard = cuesWithTimingList.get(indexToDiscardTo - 1);
|
||||
if (lastCueToDiscard.endTimeUs == C.TIME_UNSET || lastCueToDiscard.endTimeUs >= timeUs) {
|
||||
indexToDiscardTo--;
|
||||
}
|
||||
cuesWithTimingList.subList(0, indexToDiscardTo).clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -142,7 +148,7 @@ import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Returns the index of the first {@link CuesWithTiming} in {@link #cuesWithTimingList} where
|
||||
* {@link CuesWithTiming#startTimeUs} is strictly less than {@code timeUs}.
|
||||
* {@link CuesWithTiming#startTimeUs} is strictly greater than {@code timeUs}.
|
||||
*
|
||||
* <p>Returns the size of {@link #cuesWithTimingList} if all cues are before timeUs
|
||||
*/
|
||||
|
@ -217,6 +217,47 @@ public final class ReplacingCuesResolverTest {
|
||||
assertThat(replacingCuesResolver.getNextCueChangeTimeUs(4_999_990)).isEqualTo(6_000_000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void discardCuesBeforeTimeUs_retainsActiveCueWithSetDuration() {
|
||||
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();
|
||||
CuesWithTiming activeCue =
|
||||
new CuesWithTiming(FIRST_CUES, /* startTimeUs= */ 3_000_000, /* durationUs= */ 4_000_000);
|
||||
CuesWithTiming laterCue =
|
||||
new CuesWithTiming(SECOND_CUES, /* startTimeUs= */ 8_000_000, /* durationUs= */ 2_000_000);
|
||||
replacingCuesResolver.addCues(activeCue, /* currentPositionUs= */ 5_000_000);
|
||||
replacingCuesResolver.addCues(laterCue, /* currentPositionUs= */ 5_000_000);
|
||||
|
||||
// Discard cues before 5_000_000. activeCue should remain active because it ends at 7_000_000.
|
||||
replacingCuesResolver.discardCuesBeforeTimeUs(5_000_000);
|
||||
|
||||
// Query at a time within activeCue's range to verify it's still there.
|
||||
assertThat(replacingCuesResolver.getCuesAtTimeUs(6_000_000)).isEqualTo(FIRST_CUES);
|
||||
// Ensure that laterCue is unaffected.
|
||||
assertThat(replacingCuesResolver.getCuesAtTimeUs(9_000_000)).isEqualTo(SECOND_CUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void discardCuesBeforeTimeUs_retainsActiveCueWithUnsetDuration() {
|
||||
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();
|
||||
CuesWithTiming activeCue =
|
||||
new CuesWithTiming(
|
||||
FIRST_CUES, /* startTimeUs= */ 3_000_000, /* durationUs= */ C.TIME_UNSET);
|
||||
CuesWithTiming laterCue =
|
||||
new CuesWithTiming(SECOND_CUES, /* startTimeUs= */ 8_000_000, /* durationUs= */ 2_000_000);
|
||||
replacingCuesResolver.addCues(activeCue, /* currentPositionUs= */ 5_000_000);
|
||||
replacingCuesResolver.addCues(laterCue, /* currentPositionUs= */ 5_000_000);
|
||||
|
||||
// Discard cues before 5_000_000. activeCue should remain active because its
|
||||
// duration is unset, meaning it should remain visible until replaced by a subsequent cue
|
||||
// starting at 8_000_000.
|
||||
replacingCuesResolver.discardCuesBeforeTimeUs(5_000_000);
|
||||
|
||||
// Query at a time within activeCue's range to verify it's still there.
|
||||
assertThat(replacingCuesResolver.getCuesAtTimeUs(6_000_000)).isEqualTo(FIRST_CUES);
|
||||
// Ensure that laterCue is unaffected.
|
||||
assertThat(replacingCuesResolver.getCuesAtTimeUs(9_000_000)).isEqualTo(SECOND_CUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clear_clearsAllCues() {
|
||||
ReplacingCuesResolver replacingCuesResolver = new ReplacingCuesResolver();
|
||||
|
Loading…
x
Reference in New Issue
Block a user