Set correct start time for newly enabled renderers during playback

We currently pass in the time at which the stream originally started,
but newly enabled renderers should get the current playback position
instead.

PiperOrigin-RevId: 550894630
This commit is contained in:
tonihei 2023-07-25 16:29:44 +01:00 committed by Rohit Singh
parent 54093a152e
commit 79c8b0e0f8
2 changed files with 58 additions and 6 deletions

View File

@ -1830,7 +1830,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
}
enableRenderers(rendererWasEnabledFlags);
enableRenderers(rendererWasEnabledFlags, /* startPositionUs= */ rendererPositionUs);
} else {
// Release and re-prepare/buffer periods after the one whose selection changed.
queue.removeAfter(periodHolder);
@ -2558,10 +2558,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
private void enableRenderers() throws ExoPlaybackException {
enableRenderers(/* rendererWasEnabledFlags= */ new boolean[renderers.length]);
enableRenderers(
/* rendererWasEnabledFlags= */ new boolean[renderers.length],
queue.getReadingPeriod().getStartPositionRendererTime());
}
private void enableRenderers(boolean[] rendererWasEnabledFlags) throws ExoPlaybackException {
private void enableRenderers(boolean[] rendererWasEnabledFlags, long startPositionUs)
throws ExoPlaybackException {
MediaPeriodHolder readingMediaPeriod = queue.getReadingPeriod();
TrackSelectorResult trackSelectorResult = readingMediaPeriod.getTrackSelectorResult();
// Reset all disabled renderers before enabling any new ones. This makes sure resources released
@ -2574,13 +2577,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Enable the renderers.
for (int i = 0; i < renderers.length; i++) {
if (trackSelectorResult.isRendererEnabled(i)) {
enableRenderer(i, rendererWasEnabledFlags[i]);
enableRenderer(i, rendererWasEnabledFlags[i], startPositionUs);
}
}
readingMediaPeriod.allRenderersInCorrectState = true;
}
private void enableRenderer(int rendererIndex, boolean wasRendererEnabled)
private void enableRenderer(int rendererIndex, boolean wasRendererEnabled, long startPositionUs)
throws ExoPlaybackException {
Renderer renderer = renderers[rendererIndex];
if (isRendererEnabled(renderer)) {
@ -2607,7 +2610,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
rendererPositionUs,
joining,
mayRenderStartOfStream,
periodHolder.getStartPositionRendererTime(),
startPositionUs,
periodHolder.getRendererOffset());
renderer.handleMessage(
Renderer.MSG_SET_WAKEUP_LISTENER,

View File

@ -13843,6 +13843,55 @@ public final class ExoPlayerTest {
verify(listener, times(2)).onPlaybackStateChanged(Player.STATE_BUFFERING);
}
@Test
public void newlyEnabledRendererMidPlayback_receivesCurrentPlaybackPositionAsStartTime()
throws Exception {
AtomicLong startPositionInRendererUs = new AtomicLong();
AtomicLong rendererOffsetUs = new AtomicLong();
FakeRenderer newlyEnabledRenderer =
new FakeRenderer(C.TRACK_TYPE_AUDIO) {
@Override
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
throws ExoPlaybackException {
super.onStreamChanged(formats, startPositionUs, offsetUs);
startPositionInRendererUs.set(startPositionUs);
rendererOffsetUs.set(offsetUs);
}
};
Timeline timeline = new FakeTimeline();
ExoPlayer player =
new TestExoPlayerBuilder(context)
.setRenderers(new FakeRenderer(C.TRACK_TYPE_VIDEO), newlyEnabledRenderer)
.build();
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ true)
.build());
player.setMediaSource(
new FakeMediaSource(
timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT));
player.prepare();
playUntilPosition(player, /* mediaItemIndex= */ 0, /* positionMs= */ 1_250);
player.setTrackSelectionParameters(
player
.getTrackSelectionParameters()
.buildUpon()
.setTrackTypeDisabled(C.TRACK_TYPE_AUDIO, /* disabled= */ false)
.build());
player.play();
runUntilPlaybackState(player, STATE_ENDED);
player.release();
long expectedStartPositionInRendererUs =
1_250_000
+ rendererOffsetUs.get()
+ timeline.getWindow(/* windowIndex= */ 0, new Window()).positionInFirstPeriodUs;
assertThat(startPositionInRendererUs.get()).isEqualTo(expectedStartPositionInRendererUs);
}
// Internal methods.
private void addWatchAsSystemFeature() {