Remove duplications from handleSourceInfoRefreshed.
handleSourceInfoRefreshed checks for various conditions which may trigger a change in position. In all cases, we need to resolve the new position for ads, and if the corresponding MediaPeriods already exist, perform the seek to the new position. This change simplified the code by 1. Moving all conditions in a single if-else structure which just determines the new playback position. This makes it easier to read and to follow. 2. Doing the subsequent seek and position update in one final step to remove duplicated code. As a side effect, it also improves some edge cases. For example when skipping an ad to an already prebuffered period, we now properly update the existing prebuffered period. PiperOrigin-RevId: 243588014
This commit is contained in:
parent
1bf1790edc
commit
75238e5e4f
@ -1262,6 +1262,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
// Stale event.
|
||||
return;
|
||||
}
|
||||
playbackInfoUpdate.incrementPendingOperationAcks(pendingPrepareCount);
|
||||
pendingPrepareCount = 0;
|
||||
|
||||
Timeline oldTimeline = playbackInfo.timeline;
|
||||
Timeline timeline = sourceRefreshInfo.timeline;
|
||||
@ -1270,119 +1272,75 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
playbackInfo = playbackInfo.copyWithTimeline(timeline, manifest);
|
||||
resolvePendingMessagePositions();
|
||||
|
||||
if (pendingPrepareCount > 0) {
|
||||
playbackInfoUpdate.incrementPendingOperationAcks(pendingPrepareCount);
|
||||
pendingPrepareCount = 0;
|
||||
if (pendingInitialSeekPosition != null) {
|
||||
Pair<Object, Long> periodPosition =
|
||||
resolveSeekPosition(pendingInitialSeekPosition, /* trySubsequentPeriods= */ true);
|
||||
pendingInitialSeekPosition = null;
|
||||
if (periodPosition == null) {
|
||||
// The seek position was valid for the timeline that it was performed into, but the
|
||||
// timeline has changed and a suitable seek position could not be resolved in the new one.
|
||||
handleSourceInfoRefreshEndedPlayback();
|
||||
} else {
|
||||
Object periodUid = periodPosition.first;
|
||||
long positionUs = periodPosition.second;
|
||||
MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, positionUs);
|
||||
playbackInfo =
|
||||
playbackInfo.resetToNewPosition(
|
||||
periodId, periodId.isAd() ? 0 : positionUs, /* contentPositionUs= */ positionUs);
|
||||
}
|
||||
} else if (playbackInfo.startPositionUs == C.TIME_UNSET) {
|
||||
if (timeline.isEmpty()) {
|
||||
handleSourceInfoRefreshEndedPlayback();
|
||||
} else {
|
||||
Pair<Object, Long> defaultPosition =
|
||||
getPeriodPosition(
|
||||
timeline, timeline.getFirstWindowIndex(shuffleModeEnabled), C.TIME_UNSET);
|
||||
Object periodUid = defaultPosition.first;
|
||||
long startPositionUs = defaultPosition.second;
|
||||
MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, startPositionUs);
|
||||
playbackInfo =
|
||||
playbackInfo.resetToNewPosition(
|
||||
periodId,
|
||||
periodId.isAd() ? 0 : startPositionUs,
|
||||
/* contentPositionUs= */ startPositionUs);
|
||||
}
|
||||
MediaPeriodId newPeriodId = playbackInfo.periodId;
|
||||
long oldContentPositionUs =
|
||||
playbackInfo.periodId.isAd() ? playbackInfo.contentPositionUs : playbackInfo.positionUs;
|
||||
long newContentPositionUs = oldContentPositionUs;
|
||||
if (pendingInitialSeekPosition != null) {
|
||||
// Resolve initial seek position.
|
||||
Pair<Object, Long> periodPosition =
|
||||
resolveSeekPosition(pendingInitialSeekPosition, /* trySubsequentPeriods= */ true);
|
||||
pendingInitialSeekPosition = null;
|
||||
if (periodPosition == null) {
|
||||
// The seek position was valid for the timeline that it was performed into, but the
|
||||
// timeline has changed and a suitable seek position could not be resolved in the new one.
|
||||
handleSourceInfoRefreshEndedPlayback();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldTimeline.isEmpty()) {
|
||||
// If the old timeline is empty, the period queue is also empty.
|
||||
if (!timeline.isEmpty()) {
|
||||
Pair<Object, Long> defaultPosition =
|
||||
getPeriodPosition(
|
||||
timeline, timeline.getFirstWindowIndex(shuffleModeEnabled), C.TIME_UNSET);
|
||||
Object periodUid = defaultPosition.first;
|
||||
long startPositionUs = defaultPosition.second;
|
||||
MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, startPositionUs);
|
||||
playbackInfo =
|
||||
playbackInfo.resetToNewPosition(
|
||||
periodId,
|
||||
/* startPositionUs= */ periodId.isAd() ? 0 : startPositionUs,
|
||||
/* contentPositionUs= */ startPositionUs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
MediaPeriodHolder periodHolder = queue.getFrontPeriod();
|
||||
long contentPositionUs = playbackInfo.contentPositionUs;
|
||||
Object playingPeriodUid =
|
||||
periodHolder == null ? playbackInfo.periodId.periodUid : periodHolder.uid;
|
||||
int periodIndex = timeline.getIndexOfPeriod(playingPeriodUid);
|
||||
if (periodIndex == C.INDEX_UNSET) {
|
||||
// We didn't find the current period in the new timeline. Attempt to resolve a subsequent
|
||||
// period whose window we can restart from.
|
||||
Object newPeriodUid = resolveSubsequentPeriod(playingPeriodUid, oldTimeline, timeline);
|
||||
newContentPositionUs = periodPosition.second;
|
||||
newPeriodId = queue.resolveMediaPeriodIdForAds(periodPosition.first, newContentPositionUs);
|
||||
} else if (oldContentPositionUs == C.TIME_UNSET && !timeline.isEmpty()) {
|
||||
// Resolve unset start position to default position.
|
||||
Pair<Object, Long> defaultPosition =
|
||||
getPeriodPosition(
|
||||
timeline, timeline.getFirstWindowIndex(shuffleModeEnabled), C.TIME_UNSET);
|
||||
newContentPositionUs = defaultPosition.second;
|
||||
newPeriodId = queue.resolveMediaPeriodIdForAds(defaultPosition.first, newContentPositionUs);
|
||||
} else if (timeline.getIndexOfPeriod(newPeriodId.periodUid) == C.INDEX_UNSET) {
|
||||
// The current period isn't in the new timeline. Attempt to resolve a subsequent period whose
|
||||
// window we can restart from.
|
||||
Object newPeriodUid = resolveSubsequentPeriod(newPeriodId.periodUid, oldTimeline, timeline);
|
||||
if (newPeriodUid == null) {
|
||||
// We failed to resolve a suitable restart position.
|
||||
handleSourceInfoRefreshEndedPlayback();
|
||||
return;
|
||||
}
|
||||
// We resolved a subsequent period. Seek to the default position in the corresponding window.
|
||||
// We resolved a subsequent period. Start at the default position in the corresponding window.
|
||||
Pair<Object, Long> defaultPosition =
|
||||
getPeriodPosition(
|
||||
timeline, timeline.getPeriodByUid(newPeriodUid, period).windowIndex, C.TIME_UNSET);
|
||||
newPeriodUid = defaultPosition.first;
|
||||
contentPositionUs = defaultPosition.second;
|
||||
MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(newPeriodUid, contentPositionUs);
|
||||
newContentPositionUs = defaultPosition.second;
|
||||
newPeriodId = queue.resolveMediaPeriodIdForAds(defaultPosition.first, newContentPositionUs);
|
||||
} else if (newPeriodId.isAd()) {
|
||||
// Recheck if the current ad still needs to be played.
|
||||
newPeriodId = queue.resolveMediaPeriodIdForAds(newPeriodId.periodUid, newContentPositionUs);
|
||||
}
|
||||
|
||||
if (playbackInfo.periodId.equals(newPeriodId) && oldContentPositionUs == newContentPositionUs) {
|
||||
// We can keep the current playing period. Update the rest of the queued periods.
|
||||
if (!queue.updateQueuedPeriods(rendererPositionUs, getMaxRendererReadPositionUs())) {
|
||||
seekToCurrentPosition(/* sendDiscontinuity= */ false);
|
||||
}
|
||||
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
|
||||
} else {
|
||||
// Something changed. Seek to new start position.
|
||||
MediaPeriodHolder periodHolder = queue.getFrontPeriod();
|
||||
if (periodHolder != null) {
|
||||
// Update the new playing media period info if it already exists.
|
||||
while (periodHolder.getNext() != null) {
|
||||
periodHolder = periodHolder.getNext();
|
||||
if (periodHolder.info.id.equals(periodId)) {
|
||||
if (periodHolder.info.id.equals(newPeriodId)) {
|
||||
periodHolder.info = queue.getUpdatedMediaPeriodInfo(periodHolder.info);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Actually do the seek.
|
||||
long seekPositionUs = seekToPeriodPosition(periodId, periodId.isAd() ? 0 : contentPositionUs);
|
||||
long newPositionUs = newPeriodId.isAd() ? 0 : newContentPositionUs;
|
||||
long seekedToPositionUs = seekToPeriodPosition(newPeriodId, newPositionUs);
|
||||
playbackInfo =
|
||||
playbackInfo.copyWithNewPosition(
|
||||
periodId, seekPositionUs, contentPositionUs, getTotalBufferedDurationUs());
|
||||
return;
|
||||
newPeriodId, seekedToPositionUs, newContentPositionUs, getTotalBufferedDurationUs());
|
||||
}
|
||||
|
||||
MediaPeriodId playingPeriodId = playbackInfo.periodId;
|
||||
if (playingPeriodId.isAd()) {
|
||||
MediaPeriodId periodId =
|
||||
queue.resolveMediaPeriodIdForAds(playingPeriodUid, contentPositionUs);
|
||||
if (!periodId.equals(playingPeriodId)) {
|
||||
// The previously playing ad should no longer be played, so skip it.
|
||||
long seekPositionUs =
|
||||
seekToPeriodPosition(periodId, periodId.isAd() ? 0 : contentPositionUs);
|
||||
playbackInfo =
|
||||
playbackInfo.copyWithNewPosition(
|
||||
periodId, seekPositionUs, contentPositionUs, getTotalBufferedDurationUs());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!queue.updateQueuedPeriods(rendererPositionUs, getMaxRendererReadPositionUs())) {
|
||||
seekToCurrentPosition(/* sendDiscontinuity= */ false);
|
||||
}
|
||||
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
|
||||
}
|
||||
|
||||
private long getMaxRendererReadPositionUs() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user