Commit 5f9a5850 by tonihei Committed by Ian Baker

Fix a bunch of position problems.

There are a couple of problems with how positions in PlaybackInfo are set at
the moment:
1. PositionUs isn't allowed to be C.TIME_UNSET. This is prevented by always
resolving to the current default position if needed.
2. In some places a window position was used as a period position. Use correct
position resolution procedure.
3. When creating a placeholder position to restart playback, we used the first
period in a window, not the one where the default position is.
4. The start position for ads was in some cases set to 0 without checking
the ad resume position.

PiperOrigin-RevId: 290749042
parent 665092e4
...@@ -144,7 +144,7 @@ import java.util.concurrent.TimeoutException; ...@@ -144,7 +144,7 @@ import java.util.concurrent.TimeoutException;
ExoPlayerImpl.this.handleEvent(msg); ExoPlayerImpl.this.handleEvent(msg);
} }
}; };
playbackInfo = PlaybackInfo.createDummy(/* startPositionUs= */ 0, emptyTrackSelectorResult); playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
pendingListenerNotifications = new ArrayDeque<>(); pendingListenerNotifications = new ArrayDeque<>();
if (analyticsCollector != null) { if (analyticsCollector != null) {
analyticsCollector.setPlayer(this); analyticsCollector.setPlayer(this);
...@@ -795,17 +795,6 @@ import java.util.concurrent.TimeoutException; ...@@ -795,17 +795,6 @@ import java.util.concurrent.TimeoutException;
@DiscontinuityReason int positionDiscontinuityReason) { @DiscontinuityReason int positionDiscontinuityReason) {
pendingOperationAcks -= operationAcks; pendingOperationAcks -= operationAcks;
if (pendingOperationAcks == 0) { if (pendingOperationAcks == 0) {
if (playbackInfo.startPositionUs == C.TIME_UNSET) {
// Replace internal unset start position with externally visible start position of zero.
playbackInfo =
playbackInfo.copyWithNewPosition(
playbackInfo.periodId,
/* positionUs= */ 0,
playbackInfo.contentPositionUs,
playbackInfo.totalBufferedDurationUs,
playbackInfo.trackGroups,
playbackInfo.trackSelectorResult);
}
if (!this.playbackInfo.timeline.isEmpty() && playbackInfo.timeline.isEmpty()) { if (!this.playbackInfo.timeline.isEmpty() && playbackInfo.timeline.isEmpty()) {
// Update the masking variables, which are used when the timeline becomes empty. // Update the masking variables, which are used when the timeline becomes empty.
resetMaskingPosition(); resetMaskingPosition();
...@@ -841,7 +830,7 @@ import java.util.concurrent.TimeoutException; ...@@ -841,7 +830,7 @@ import java.util.concurrent.TimeoutException;
timeline = Timeline.EMPTY; timeline = Timeline.EMPTY;
mediaPeriodId = PlaybackInfo.getDummyPeriodForEmptyTimeline(); mediaPeriodId = PlaybackInfo.getDummyPeriodForEmptyTimeline();
contentPositionUs = C.TIME_UNSET; contentPositionUs = C.TIME_UNSET;
startPositionUs = C.TIME_UNSET; startPositionUs = 0;
} }
return new PlaybackInfo( return new PlaybackInfo(
timeline, timeline,
......
...@@ -28,7 +28,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -28,7 +28,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
/** /**
* Dummy media period id used while the timeline is empty and no period id is specified. This id * Dummy media period id used while the timeline is empty and no period id is specified. This id
* is used when playback infos are created with {@link #createDummy(long, TrackSelectorResult)}. * is used when playback infos are created with {@link #createDummy(TrackSelectorResult)}.
*/ */
private static final MediaPeriodId DUMMY_MEDIA_PERIOD_ID = private static final MediaPeriodId DUMMY_MEDIA_PERIOD_ID =
new MediaPeriodId(/* periodUid= */ new Object()); new MediaPeriodId(/* periodUid= */ new Object());
...@@ -83,17 +83,15 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -83,17 +83,15 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
* Creates empty dummy playback info which can be used for masking as long as no real playback * Creates empty dummy playback info which can be used for masking as long as no real playback
* info is available. * info is available.
* *
* @param startPositionUs The start position at which playback should start, in microseconds.
* @param emptyTrackSelectorResult An empty track selector result with null entries for each * @param emptyTrackSelectorResult An empty track selector result with null entries for each
* renderer. * renderer.
* @return A dummy playback info. * @return A dummy playback info.
*/ */
public static PlaybackInfo createDummy( public static PlaybackInfo createDummy(TrackSelectorResult emptyTrackSelectorResult) {
long startPositionUs, TrackSelectorResult emptyTrackSelectorResult) {
return new PlaybackInfo( return new PlaybackInfo(
Timeline.EMPTY, Timeline.EMPTY,
DUMMY_MEDIA_PERIOD_ID, DUMMY_MEDIA_PERIOD_ID,
startPositionUs, /* startPositionUs= */ 0,
/* contentPositionUs= */ C.TIME_UNSET, /* contentPositionUs= */ C.TIME_UNSET,
Player.STATE_IDLE, Player.STATE_IDLE,
/* playbackError= */ null, /* playbackError= */ null,
...@@ -101,9 +99,9 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult; ...@@ -101,9 +99,9 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
TrackGroupArray.EMPTY, TrackGroupArray.EMPTY,
emptyTrackSelectorResult, emptyTrackSelectorResult,
DUMMY_MEDIA_PERIOD_ID, DUMMY_MEDIA_PERIOD_ID,
startPositionUs, /* bufferedPositionUs= */ 0,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
startPositionUs); /* positionUs= */ 0);
} }
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment