Commit 3bb97f4b by bachinger Committed by Oliver Woodman

deliver player messages only once when at start position

ISSUE: #6550
PiperOrigin-RevId: 275842161
parent 7ccbc4c4
...@@ -122,6 +122,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -122,6 +122,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private SeekPosition pendingInitialSeekPosition; private SeekPosition pendingInitialSeekPosition;
private long rendererPositionUs; private long rendererPositionUs;
private int nextPendingMessageIndex; private int nextPendingMessageIndex;
private boolean deliverPendingMessageAtStartPositionRequired;
public ExoPlayerImplInternal( public ExoPlayerImplInternal(
Renderer[] renderers, Renderer[] renderers,
...@@ -171,6 +172,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -171,6 +172,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
new HandlerThread("ExoPlayerImplInternal:Handler", Process.THREAD_PRIORITY_AUDIO); new HandlerThread("ExoPlayerImplInternal:Handler", Process.THREAD_PRIORITY_AUDIO);
internalPlaybackThread.start(); internalPlaybackThread.start();
handler = clock.createHandler(internalPlaybackThread.getLooper(), this); handler = clock.createHandler(internalPlaybackThread.getLooper(), this);
deliverPendingMessageAtStartPositionRequired = true;
} }
public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) { public void prepare(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
...@@ -487,12 +489,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -487,12 +489,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
long newPositionUs = long newPositionUs =
seekToPeriodPosition(periodId, playbackInfo.positionUs, /* forceDisableRenderers= */ true); seekToPeriodPosition(periodId, playbackInfo.positionUs, /* forceDisableRenderers= */ true);
if (newPositionUs != playbackInfo.positionUs) { if (newPositionUs != playbackInfo.positionUs) {
playbackInfo = playbackInfo = copyWithNewPosition(periodId, newPositionUs, playbackInfo.contentPositionUs);
playbackInfo.copyWithNewPosition(
periodId,
newPositionUs,
playbackInfo.contentPositionUs,
getTotalBufferedDurationUs());
if (sendDiscontinuity) { if (sendDiscontinuity) {
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL); playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL);
} }
...@@ -531,11 +528,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -531,11 +528,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
// renderers are flushed. Only report the discontinuity externally if the position changed. // renderers are flushed. Only report the discontinuity externally if the position changed.
if (discontinuityPositionUs != playbackInfo.positionUs) { if (discontinuityPositionUs != playbackInfo.positionUs) {
playbackInfo = playbackInfo =
playbackInfo.copyWithNewPosition( copyWithNewPosition(
playbackInfo.periodId, playbackInfo.periodId, discontinuityPositionUs, playbackInfo.contentPositionUs);
discontinuityPositionUs,
playbackInfo.contentPositionUs,
getTotalBufferedDurationUs());
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL); playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL);
} }
} else { } else {
...@@ -722,9 +716,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -722,9 +716,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
periodPositionUs = newPeriodPositionUs; periodPositionUs = newPeriodPositionUs;
} }
} finally { } finally {
playbackInfo = playbackInfo = copyWithNewPosition(periodId, periodPositionUs, contentPositionUs);
playbackInfo.copyWithNewPosition(
periodId, periodPositionUs, contentPositionUs, getTotalBufferedDurationUs());
if (seekPositionAdjusted) { if (seekPositionAdjusted) {
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT); playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT);
} }
...@@ -1062,10 +1054,13 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1062,10 +1054,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
return; return;
} }
// If this is the first call from the start position, include oldPeriodPositionUs in potential // If this is the first call from the start position, include oldPeriodPositionUs in potential
// trigger positions. // trigger positions, but make sure we deliver it only once.
if (playbackInfo.startPositionUs == oldPeriodPositionUs) { if (playbackInfo.startPositionUs == oldPeriodPositionUs
&& deliverPendingMessageAtStartPositionRequired) {
oldPeriodPositionUs--; oldPeriodPositionUs--;
} }
deliverPendingMessageAtStartPositionRequired = false;
// Correct next index if necessary (e.g. after seeking, timeline changes, or new messages) // Correct next index if necessary (e.g. after seeking, timeline changes, or new messages)
int currentPeriodIndex = int currentPeriodIndex =
playbackInfo.timeline.getIndexOfPeriod(playbackInfo.periodId.periodUid); playbackInfo.timeline.getIndexOfPeriod(playbackInfo.periodId.periodUid);
...@@ -1164,11 +1159,8 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1164,11 +1159,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
if (playbackInfo.playbackState != Player.STATE_ENDED if (playbackInfo.playbackState != Player.STATE_ENDED
&& periodPositionUs != playbackInfo.positionUs) { && periodPositionUs != playbackInfo.positionUs) {
playbackInfo = playbackInfo =
playbackInfo.copyWithNewPosition( copyWithNewPosition(
playbackInfo.periodId, playbackInfo.periodId, periodPositionUs, playbackInfo.contentPositionUs);
periodPositionUs,
playbackInfo.contentPositionUs,
getTotalBufferedDurationUs());
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL); playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL);
resetRendererPosition(periodPositionUs); resetRendererPosition(periodPositionUs);
} }
...@@ -1371,9 +1363,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1371,9 +1363,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Actually do the seek. // Actually do the seek.
long newPositionUs = newPeriodId.isAd() ? 0 : newContentPositionUs; long newPositionUs = newPeriodId.isAd() ? 0 : newContentPositionUs;
long seekedToPositionUs = seekToPeriodPosition(newPeriodId, newPositionUs); long seekedToPositionUs = seekToPeriodPosition(newPeriodId, newPositionUs);
playbackInfo = playbackInfo = copyWithNewPosition(newPeriodId, seekedToPositionUs, newContentPositionUs);
playbackInfo.copyWithNewPosition(
newPeriodId, seekedToPositionUs, newContentPositionUs, getTotalBufferedDurationUs());
} }
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false); handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
} }
...@@ -1649,11 +1639,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1649,11 +1639,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
MediaPeriodHolder newPlayingPeriodHolder = queue.advancePlayingPeriod(); MediaPeriodHolder newPlayingPeriodHolder = queue.advancePlayingPeriod();
updatePlayingPeriodRenderers(oldPlayingPeriodHolder); updatePlayingPeriodRenderers(oldPlayingPeriodHolder);
playbackInfo = playbackInfo =
playbackInfo.copyWithNewPosition( copyWithNewPosition(
newPlayingPeriodHolder.info.id, newPlayingPeriodHolder.info.id,
newPlayingPeriodHolder.info.startPositionUs, newPlayingPeriodHolder.info.startPositionUs,
newPlayingPeriodHolder.info.contentPositionUs, newPlayingPeriodHolder.info.contentPositionUs);
getTotalBufferedDurationUs());
int discontinuityReason = int discontinuityReason =
oldPlayingPeriodHolder.info.isLastInTimelinePeriod oldPlayingPeriodHolder.info.isLastInTimelinePeriod
? Player.DISCONTINUITY_REASON_PERIOD_TRANSITION ? Player.DISCONTINUITY_REASON_PERIOD_TRANSITION
...@@ -1789,6 +1778,13 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1789,6 +1778,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
} }
private PlaybackInfo copyWithNewPosition(
MediaPeriodId mediaPeriodId, long positionUs, long contentPositionUs) {
deliverPendingMessageAtStartPositionRequired = true;
return playbackInfo.copyWithNewPosition(
mediaPeriodId, positionUs, contentPositionUs, getTotalBufferedDurationUs());
}
@SuppressWarnings("ParameterNotNullable") @SuppressWarnings("ParameterNotNullable")
private void updatePlayingPeriodRenderers(@Nullable MediaPeriodHolder oldPlayingPeriodHolder) private void updatePlayingPeriodRenderers(@Nullable MediaPeriodHolder oldPlayingPeriodHolder)
throws ExoPlaybackException { throws ExoPlaybackException {
......
...@@ -1577,6 +1577,34 @@ public final class ExoPlayerTest { ...@@ -1577,6 +1577,34 @@ public final class ExoPlayerTest {
} }
@Test @Test
public void testSendMessagesFromStartPositionOnlyOnce() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
AtomicInteger counter = new AtomicInteger();
ActionSchedule actionSchedule =
new ActionSchedule.Builder("testSendMessagesFromStartPositionOnlyOnce")
.pause()
.sendMessage(
(messageType, payload) -> {
counter.getAndIncrement();
},
/* windowIndex= */ 0,
/* positionMs= */ 2000,
/* deleteAfterDelivery= */ false)
.seek(/* positionMs= */ 2000)
.delay(/* delayMs= */ 2000)
.play()
.build();
new Builder()
.setTimeline(timeline)
.setActionSchedule(actionSchedule)
.build(context)
.start()
.blockUntilActionScheduleFinished(TIMEOUT_MS)
.blockUntilEnded(TIMEOUT_MS);
assertThat(counter.get()).isEqualTo(1);
}
@Test
public void testMultipleSendMessagesAtSameTime() throws Exception { public void testMultipleSendMessagesAtSameTime() throws Exception {
Timeline timeline = new FakeTimeline(/* windowCount= */ 1); Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
PositionGrabbingMessageTarget target1 = new PositionGrabbingMessageTarget(); PositionGrabbingMessageTarget target1 = new PositionGrabbingMessageTarget();
......
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