Skip to content

Commit

Permalink
Move playback speed update at period transitions to reading period.
Browse files Browse the repository at this point in the history
In some cases we need to update the PlaybackParameters at period
boundaries, for example when switching from live to VOD and live
playback speed adjustment was still active at the point of switching.

Currently, we send the update when the playing MediaPeriod changes in
EPII, which is slightly too late because the new speed gets only applied
after the entire existing AudioTrack buffer has been played out.

We can time the update slightly better by updating the values at the
point where we change the reading period. This makes the update slightly
too early because it also applies to all samples currently in the
decoder. But generally, this is a lot better because the time spent
in the decoder is likely to be considerably lower than the duration of
the AudioTrack buffer.

Note that this change isn't perfectly aligning to the period boundary,
but reduces the number of samples with the wrong speed to a minimum.
If we are getting around to add additional code that allows updating
the speed at exactly the boundary, it also needs to be triggered from
the reading period update, so the new code location is also helpful in
the future.

Issue: #9018
PiperOrigin-RevId: 424540551
  • Loading branch information
tonihei authored and andrewlewis committed Jan 28, 2022
1 parent bfa6886 commit 8c685ab
Showing 1 changed file with 13 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,7 @@ private void seekToInternal(SeekPosition seekPosition) throws ExoPlaybackExcepti
/* forceBufferingState= */ playbackInfo.playbackState == Player.STATE_ENDED);
seekPositionAdjusted |= periodPositionUs != newPeriodPositionUs;
periodPositionUs = newPeriodPositionUs;
updateLivePlaybackSpeedControl(
updatePlaybackSpeedSettingsForNewPeriod(
/* newTimeline= */ playbackInfo.timeline,
/* newPeriodId= */ periodId,
/* oldTimeline= */ playbackInfo.timeline,
Expand Down Expand Up @@ -1866,7 +1866,7 @@ timeline, rendererPositionUs, getMaxRendererReadPositionUs())) {
newPositionUs = seekToPeriodPosition(newPeriodId, newPositionUs, forceBufferingState);
}
} finally {
updateLivePlaybackSpeedControl(
updatePlaybackSpeedSettingsForNewPeriod(
/* newTimeline= */ timeline,
newPeriodId,
/* oldTimeline= */ playbackInfo.timeline,
Expand Down Expand Up @@ -1906,15 +1906,15 @@ timeline, rendererPositionUs, getMaxRendererReadPositionUs())) {
}
}

private void updateLivePlaybackSpeedControl(
private void updatePlaybackSpeedSettingsForNewPeriod(
Timeline newTimeline,
MediaPeriodId newPeriodId,
Timeline oldTimeline,
MediaPeriodId oldPeriodId,
long positionForTargetOffsetOverrideUs) {
if (newTimeline.isEmpty() || !shouldUseLivePlaybackSpeedControl(newTimeline, newPeriodId)) {
if (!shouldUseLivePlaybackSpeedControl(newTimeline, newPeriodId)) {
// Live playback speed control is unused for the current period, reset speed if adjusted.
if (mediaClock.getPlaybackParameters().speed != playbackInfo.playbackParameters.speed) {
if (!mediaClock.getPlaybackParameters().equals(playbackInfo.playbackParameters)) {
mediaClock.setPlaybackParameters(playbackInfo.playbackParameters);
}
return;
Expand Down Expand Up @@ -2046,10 +2046,18 @@ private void maybeUpdateReadingPeriod() {
return;
}

MediaPeriodHolder oldReadingPeriodHolder = readingPeriodHolder;
TrackSelectorResult oldTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();
readingPeriodHolder = queue.advanceReadingPeriod();
TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.getTrackSelectorResult();

updatePlaybackSpeedSettingsForNewPeriod(
/* newTimeline= */ playbackInfo.timeline,
/* newPeriodId= */ readingPeriodHolder.info.id,
/* oldTimeline= */ playbackInfo.timeline,
/* oldPeriodId= */ oldReadingPeriodHolder.info.id,
/* positionForTargetOffsetOverrideUs= */ C.TIME_UNSET);

if (readingPeriodHolder.prepared
&& readingPeriodHolder.mediaPeriod.readDiscontinuity() != C.TIME_UNSET) {
// The new period starts with a discontinuity, so the renderers will play out all data, then
Expand Down Expand Up @@ -2134,7 +2142,6 @@ private void maybeUpdatePlayingPeriod() throws ExoPlaybackException {
// If we advance more than one period at a time, notify listeners after each update.
maybeNotifyPlaybackInfoChanged();
}
MediaPeriodHolder oldPlayingPeriodHolder = queue.getPlayingPeriod();
MediaPeriodHolder newPlayingPeriodHolder = queue.advancePlayingPeriod();
playbackInfo =
handlePositionDiscontinuity(
Expand All @@ -2144,12 +2151,6 @@ private void maybeUpdatePlayingPeriod() throws ExoPlaybackException {
/* discontinuityStartPositionUs= */ newPlayingPeriodHolder.info.startPositionUs,
/* reportDiscontinuity= */ true,
Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
updateLivePlaybackSpeedControl(
/* newTimeline= */ playbackInfo.timeline,
/* newPeriodId= */ newPlayingPeriodHolder.info.id,
/* oldTimeline= */ playbackInfo.timeline,
/* oldPeriodId= */ oldPlayingPeriodHolder.info.id,
/* positionForTargetOffsetOverrideUs= */ C.TIME_UNSET);
resetPendingPauseAtEndOfPeriod();
updatePlaybackPositions();
advancedPlayingPeriod = true;
Expand Down

0 comments on commit 8c685ab

Please sign in to comment.