Call PreloadControl.onSourcePrepared only once for each preload request

PiperOrigin-RevId: 638677090
This commit is contained in:
tianyifeng 2024-05-30 09:19:32 -07:00 committed by Copybara-Service
parent 9e0f533a11
commit e879c4ac43
2 changed files with 23 additions and 14 deletions

View File

@ -216,6 +216,7 @@ public final class PreloadMediaSource extends WrappingMediaSource {
@Nullable private Timeline timeline; @Nullable private Timeline timeline;
@Nullable private Pair<PreloadMediaPeriod, MediaPeriodKey> preloadingMediaPeriodAndKey; @Nullable private Pair<PreloadMediaPeriod, MediaPeriodKey> preloadingMediaPeriodAndKey;
@Nullable private Pair<PreloadMediaPeriod, MediaPeriodId> playingPreloadedMediaPeriodAndId; @Nullable private Pair<PreloadMediaPeriod, MediaPeriodId> playingPreloadedMediaPeriodAndId;
private boolean onSourcePreparedNotified;
private boolean onUsedByPlayerNotified; private boolean onUsedByPlayerNotified;
private PreloadMediaSource( private PreloadMediaSource(
@ -250,6 +251,7 @@ public final class PreloadMediaSource extends WrappingMediaSource {
() -> { () -> {
preloadCalled = true; preloadCalled = true;
this.startPositionUs = startPositionUs; this.startPositionUs = startPositionUs;
onSourcePreparedNotified = false;
if (isUsedByPlayer()) { if (isUsedByPlayer()) {
notifyOnUsedByPlayer(); notifyOnUsedByPlayer();
} else { } else {
@ -291,7 +293,11 @@ public final class PreloadMediaSource extends WrappingMediaSource {
protected void onChildSourceInfoRefreshed(Timeline newTimeline) { protected void onChildSourceInfoRefreshed(Timeline newTimeline) {
this.timeline = newTimeline; this.timeline = newTimeline;
refreshSourceInfo(newTimeline); refreshSourceInfo(newTimeline);
if (isUsedByPlayer() || !preloadControl.onSourcePrepared(PreloadMediaSource.this)) { if (isUsedByPlayer() || onSourcePreparedNotified) {
return;
}
onSourcePreparedNotified = true;
if (!preloadControl.onSourcePrepared(this)) {
return; return;
} }
Pair<Object, Long> periodPosition = Pair<Object, Long> periodPosition =
@ -377,6 +383,7 @@ public final class PreloadMediaSource extends WrappingMediaSource {
() -> { () -> {
preloadCalled = false; preloadCalled = false;
startPositionUs = C.TIME_UNSET; startPositionUs = C.TIME_UNSET;
onSourcePreparedNotified = false;
if (preloadingMediaPeriodAndKey != null) { if (preloadingMediaPeriodAndKey != null) {
mediaSource.releasePeriod(preloadingMediaPeriodAndKey.first.mediaPeriod); mediaSource.releasePeriod(preloadingMediaPeriodAndKey.first.mediaPeriod);
preloadingMediaPeriodAndKey = null; preloadingMediaPeriodAndKey = null;
@ -397,10 +404,10 @@ public final class PreloadMediaSource extends WrappingMediaSource {
@Override @Override
public void onPrepared(MediaPeriod mediaPeriod) { public void onPrepared(MediaPeriod mediaPeriod) {
prepared = true;
if (isUsedByPlayer()) { if (isUsedByPlayer()) {
return; return;
} }
prepared = true;
PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod; PreloadMediaPeriod preloadMediaPeriod = (PreloadMediaPeriod) mediaPeriod;
TrackGroupArray trackGroups = preloadMediaPeriod.getTrackGroups(); TrackGroupArray trackGroups = preloadMediaPeriod.getTrackGroups();
@Nullable TrackSelectorResult trackSelectorResult = null; @Nullable TrackSelectorResult trackSelectorResult = null;

View File

@ -72,6 +72,7 @@ import androidx.media3.test.utils.FakeVideoRenderer;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -107,7 +108,7 @@ public final class PreloadMediaSourceTest {
@Test @Test
public void preload_loadPeriodToTargetPreloadPosition() throws Exception { public void preload_loadPeriodToTargetPreloadPosition() throws Exception {
AtomicBoolean onSourcePreparedCalled = new AtomicBoolean(); AtomicInteger onSourcePreparedCounter = new AtomicInteger();
AtomicBoolean onTracksSelectedCalled = new AtomicBoolean(); AtomicBoolean onTracksSelectedCalled = new AtomicBoolean();
AtomicBoolean onContinueLoadingStopped = new AtomicBoolean(); AtomicBoolean onContinueLoadingStopped = new AtomicBoolean();
AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>(); AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>();
@ -116,7 +117,7 @@ public final class PreloadMediaSourceTest {
new PreloadMediaSource.PreloadControl() { new PreloadMediaSource.PreloadControl() {
@Override @Override
public boolean onSourcePrepared(PreloadMediaSource mediaSource) { public boolean onSourcePrepared(PreloadMediaSource mediaSource) {
onSourcePreparedCalled.set(true); onSourcePreparedCounter.addAndGet(1);
return true; return true;
} }
@ -167,7 +168,7 @@ public final class PreloadMediaSourceTest {
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(onContinueLoadingStopped::get); runMainLooperUntil(onContinueLoadingStopped::get);
assertThat(onSourcePreparedCalled.get()).isTrue(); assertThat(onSourcePreparedCounter.get()).isEqualTo(1);
assertThat(onTracksSelectedCalled.get()).isTrue(); assertThat(onTracksSelectedCalled.get()).isTrue();
assertThat(onUsedByPlayerCalled.get()).isFalse(); assertThat(onUsedByPlayerCalled.get()).isFalse();
assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource);
@ -175,7 +176,7 @@ public final class PreloadMediaSourceTest {
@Test @Test
public void preload_stopWhenTracksSelectedByPreloadControl() throws Exception { public void preload_stopWhenTracksSelectedByPreloadControl() throws Exception {
AtomicBoolean onSourcePreparedCalled = new AtomicBoolean(); AtomicInteger onSourcePreparedCounter = new AtomicInteger();
AtomicBoolean onTracksSelectedCalled = new AtomicBoolean(); AtomicBoolean onTracksSelectedCalled = new AtomicBoolean();
AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>(); AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>();
AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean(); AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean();
@ -184,7 +185,7 @@ public final class PreloadMediaSourceTest {
new PreloadMediaSource.PreloadControl() { new PreloadMediaSource.PreloadControl() {
@Override @Override
public boolean onSourcePrepared(PreloadMediaSource mediaSource) { public boolean onSourcePrepared(PreloadMediaSource mediaSource) {
onSourcePreparedCalled.set(true); onSourcePreparedCounter.addAndGet(1);
return true; return true;
} }
@ -232,7 +233,7 @@ public final class PreloadMediaSourceTest {
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(onTracksSelectedCalled::get); runMainLooperUntil(onTracksSelectedCalled::get);
assertThat(onSourcePreparedCalled.get()).isTrue(); assertThat(onSourcePreparedCounter.get()).isEqualTo(1);
assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource);
assertThat(onContinueLoadingRequestedCalled.get()).isFalse(); assertThat(onContinueLoadingRequestedCalled.get()).isFalse();
assertThat(onUsedByPlayerCalled.get()).isFalse(); assertThat(onUsedByPlayerCalled.get()).isFalse();
@ -240,7 +241,7 @@ public final class PreloadMediaSourceTest {
@Test @Test
public void preload_stopWhenSourcePreparedByPreloadControl() throws Exception { public void preload_stopWhenSourcePreparedByPreloadControl() throws Exception {
AtomicBoolean onSourcePreparedCalled = new AtomicBoolean(); AtomicInteger onSourcePreparedCounter = new AtomicInteger();
AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>(); AtomicReference<PreloadMediaSource> preloadMediaSourceReference = new AtomicReference<>();
AtomicBoolean onTracksSelectedCalled = new AtomicBoolean(); AtomicBoolean onTracksSelectedCalled = new AtomicBoolean();
AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean(); AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean();
@ -250,7 +251,7 @@ public final class PreloadMediaSourceTest {
@Override @Override
public boolean onSourcePrepared(PreloadMediaSource mediaSource) { public boolean onSourcePrepared(PreloadMediaSource mediaSource) {
preloadMediaSourceReference.set(mediaSource); preloadMediaSourceReference.set(mediaSource);
onSourcePreparedCalled.set(true); onSourcePreparedCounter.addAndGet(1);
return false; return false;
} }
@ -294,9 +295,10 @@ public final class PreloadMediaSourceTest {
.build()); .build());
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(onSourcePreparedCalled::get); shadowOf(Looper.getMainLooper()).idle();
assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource); assertThat(preloadMediaSourceReference.get()).isSameInstanceAs(preloadMediaSource);
assertThat(onSourcePreparedCounter.get()).isEqualTo(1);
assertThat(onTracksSelectedCalled.get()).isFalse(); assertThat(onTracksSelectedCalled.get()).isFalse();
assertThat(onContinueLoadingRequestedCalled.get()).isFalse(); assertThat(onContinueLoadingRequestedCalled.get()).isFalse();
assertThat(onUsedByPlayerCalled.get()).isFalse(); assertThat(onUsedByPlayerCalled.get()).isFalse();
@ -366,7 +368,7 @@ public final class PreloadMediaSourceTest {
@Test @Test
public void preload_loadToTheEndOfSource() throws Exception { public void preload_loadToTheEndOfSource() throws Exception {
AtomicBoolean onSourcePreparedCalled = new AtomicBoolean(); AtomicInteger onSourcePreparedCounter = new AtomicInteger();
AtomicBoolean onTracksSelectedCalled = new AtomicBoolean(); AtomicBoolean onTracksSelectedCalled = new AtomicBoolean();
AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean(); AtomicBoolean onContinueLoadingRequestedCalled = new AtomicBoolean();
AtomicBoolean onLoadedToTheEndOfSourceCalled = new AtomicBoolean(); AtomicBoolean onLoadedToTheEndOfSourceCalled = new AtomicBoolean();
@ -375,7 +377,7 @@ public final class PreloadMediaSourceTest {
new PreloadMediaSource.PreloadControl() { new PreloadMediaSource.PreloadControl() {
@Override @Override
public boolean onSourcePrepared(PreloadMediaSource mediaSource) { public boolean onSourcePrepared(PreloadMediaSource mediaSource) {
onSourcePreparedCalled.set(true); onSourcePreparedCounter.addAndGet(1);
return true; return true;
} }
@ -432,7 +434,7 @@ public final class PreloadMediaSourceTest {
preloadMediaSource.preload(/* startPositionUs= */ 0L); preloadMediaSource.preload(/* startPositionUs= */ 0L);
runMainLooperUntil(onLoadedToTheEndOfSourceCalled::get); runMainLooperUntil(onLoadedToTheEndOfSourceCalled::get);
assertThat(onSourcePreparedCalled.get()).isTrue(); assertThat(onSourcePreparedCounter.get()).isEqualTo(1);
assertThat(onTracksSelectedCalled.get()).isTrue(); assertThat(onTracksSelectedCalled.get()).isTrue();
assertThat(onContinueLoadingRequestedCalled.get()).isTrue(); assertThat(onContinueLoadingRequestedCalled.get()).isTrue();
assertThat(onUsedByPlayerCalled.get()).isFalse(); assertThat(onUsedByPlayerCalled.get()).isFalse();