Commit fa3052d3 by olly Committed by Oliver Woodman

Report additional position discontinuities

- Properly report internal discontinuities
- Add DISCONTINUITY_REASON_SEEK_ADJUSTMENT to distinguish
  seek adjustments from other internal discontinuity events

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=176367365
parent b688a562
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
* SimpleExoPlayer: Support for multiple video, text and metadata outputs. * SimpleExoPlayer: Support for multiple video, text and metadata outputs.
* Support for `Renderer`s that don't consume any media * Support for `Renderer`s that don't consume any media
([#3212](https://github.com/google/ExoPlayer/issues/3212)). ([#3212](https://github.com/google/ExoPlayer/issues/3212)).
* Fix reporting of internal position discontinuities via
`Player.onPositionDiscontinuity`. `DISCONTINUITY_REASON_SEEK_ADJUSTMENT` is
added to disambiguate position adjustments during seeks from other types of
internal position discontinuity.
* Fix potential `IndexOutOfBoundsException` when calling `ExoPlayer.getDuration` * Fix potential `IndexOutOfBoundsException` when calling `ExoPlayer.getDuration`
([#3362](https://github.com/google/ExoPlayer/issues/3362)). ([#3362](https://github.com/google/ExoPlayer/issues/3362)).
* Fix playbacks involving looping, concatenation and ads getting stuck when * Fix playbacks involving looping, concatenation and ads getting stuck when
......
...@@ -496,6 +496,8 @@ import java.util.Locale; ...@@ -496,6 +496,8 @@ import java.util.Locale;
return "PERIOD_TRANSITION"; return "PERIOD_TRANSITION";
case Player.DISCONTINUITY_REASON_SEEK: case Player.DISCONTINUITY_REASON_SEEK:
return "SEEK"; return "SEEK";
case Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT:
return "SEEK_ADJUSTMENT";
case Player.DISCONTINUITY_REASON_INTERNAL: case Player.DISCONTINUITY_REASON_INTERNAL:
return "INTERNAL"; return "INTERNAL";
default: default:
......
...@@ -473,7 +473,8 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -473,7 +473,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
case ExoPlayerImplInternal.MSG_SOURCE_INFO_REFRESHED: { case ExoPlayerImplInternal.MSG_SOURCE_INFO_REFRESHED: {
int prepareAcks = msg.arg1; int prepareAcks = msg.arg1;
int seekAcks = msg.arg2; int seekAcks = msg.arg2;
handlePlaybackInfo((PlaybackInfo) msg.obj, prepareAcks, seekAcks, false); handlePlaybackInfo((PlaybackInfo) msg.obj, prepareAcks, seekAcks, false,
/* ignored */ DISCONTINUITY_REASON_INTERNAL);
break; break;
} }
case ExoPlayerImplInternal.MSG_TRACKS_CHANGED: { case ExoPlayerImplInternal.MSG_TRACKS_CHANGED: {
...@@ -491,11 +492,13 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -491,11 +492,13 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
case ExoPlayerImplInternal.MSG_SEEK_ACK: { case ExoPlayerImplInternal.MSG_SEEK_ACK: {
boolean seekPositionAdjusted = msg.arg1 != 0; boolean seekPositionAdjusted = msg.arg1 != 0;
handlePlaybackInfo((PlaybackInfo) msg.obj, 0, 1, seekPositionAdjusted); handlePlaybackInfo((PlaybackInfo) msg.obj, 0, 1, seekPositionAdjusted,
DISCONTINUITY_REASON_SEEK_ADJUSTMENT);
break; break;
} }
case ExoPlayerImplInternal.MSG_POSITION_DISCONTINUITY: { case ExoPlayerImplInternal.MSG_POSITION_DISCONTINUITY: {
handlePlaybackInfo((PlaybackInfo) msg.obj, 0, 0, true); @DiscontinuityReason int discontinuityReason = msg.arg1;
handlePlaybackInfo((PlaybackInfo) msg.obj, 0, 0, true, discontinuityReason);
break; break;
} }
case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED: { case ExoPlayerImplInternal.MSG_PLAYBACK_PARAMETERS_CHANGED: {
...@@ -521,7 +524,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -521,7 +524,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
private void handlePlaybackInfo(PlaybackInfo playbackInfo, int prepareAcks, int seekAcks, private void handlePlaybackInfo(PlaybackInfo playbackInfo, int prepareAcks, int seekAcks,
boolean positionDiscontinuity) { boolean positionDiscontinuity, @DiscontinuityReason int positionDiscontinuityReason) {
Assertions.checkNotNull(playbackInfo.timeline); Assertions.checkNotNull(playbackInfo.timeline);
pendingPrepareAcks -= prepareAcks; pendingPrepareAcks -= prepareAcks;
pendingSeekAcks -= seekAcks; pendingSeekAcks -= seekAcks;
...@@ -542,9 +545,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -542,9 +545,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
} }
if (positionDiscontinuity) { if (positionDiscontinuity) {
for (Player.EventListener listener : listeners) { for (Player.EventListener listener : listeners) {
listener.onPositionDiscontinuity( listener.onPositionDiscontinuity(positionDiscontinuityReason);
seekAcks > 0 ? DISCONTINUITY_REASON_INTERNAL : DISCONTINUITY_REASON_PERIOD_TRANSITION
);
} }
} }
} }
......
...@@ -503,6 +503,10 @@ import java.io.IOException; ...@@ -503,6 +503,10 @@ import java.io.IOException;
long periodPositionUs = playingPeriodHolder.mediaPeriod.readDiscontinuity(); long periodPositionUs = playingPeriodHolder.mediaPeriod.readDiscontinuity();
if (periodPositionUs != C.TIME_UNSET) { if (periodPositionUs != C.TIME_UNSET) {
resetRendererPosition(periodPositionUs); resetRendererPosition(periodPositionUs);
playbackInfo = playbackInfo.fromNewPosition(playbackInfo.periodId, periodPositionUs,
playbackInfo.contentPositionUs);
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, Player.DISCONTINUITY_REASON_INTERNAL,
0, playbackInfo).sendToTarget();
} else { } else {
// Use the standalone clock if there's no renderer clock, or if the providing renderer has // Use the standalone clock if there's no renderer clock, or if the providing renderer has
// ended or needs the next sample stream to reenter the ready state. The latter case uses the // ended or needs the next sample stream to reenter the ready state. The latter case uses the
...@@ -893,7 +897,10 @@ import java.io.IOException; ...@@ -893,7 +897,10 @@ import java.io.IOException;
long periodPositionUs = playingPeriodHolder.updatePeriodTrackSelection( long periodPositionUs = playingPeriodHolder.updatePeriodTrackSelection(
playbackInfo.positionUs, recreateStreams, streamResetFlags); playbackInfo.positionUs, recreateStreams, streamResetFlags);
if (periodPositionUs != playbackInfo.positionUs) { if (periodPositionUs != playbackInfo.positionUs) {
playbackInfo.positionUs = periodPositionUs; playbackInfo = playbackInfo.fromNewPosition(playbackInfo.periodId, periodPositionUs,
playbackInfo.contentPositionUs);
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, Player.DISCONTINUITY_REASON_INTERNAL,
0, playbackInfo).sendToTarget();
resetRendererPosition(periodPositionUs); resetRendererPosition(periodPositionUs);
} }
...@@ -1280,7 +1287,8 @@ import java.io.IOException; ...@@ -1280,7 +1287,8 @@ import java.io.IOException;
playbackInfo = playbackInfo.fromNewPosition(playingPeriodHolder.info.id, playbackInfo = playbackInfo.fromNewPosition(playingPeriodHolder.info.id,
playingPeriodHolder.info.startPositionUs, playingPeriodHolder.info.contentPositionUs); playingPeriodHolder.info.startPositionUs, playingPeriodHolder.info.contentPositionUs);
updatePlaybackPositions(); updatePlaybackPositions();
eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY, playbackInfo).sendToTarget(); eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY,
Player.DISCONTINUITY_REASON_PERIOD_TRANSITION, 0, playbackInfo).sendToTarget();
} }
if (readingPeriodHolder.info.isFinal) { if (readingPeriodHolder.info.isFinal) {
......
...@@ -243,7 +243,7 @@ public interface Player { ...@@ -243,7 +243,7 @@ public interface Player {
*/ */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({DISCONTINUITY_REASON_PERIOD_TRANSITION, DISCONTINUITY_REASON_SEEK, @IntDef({DISCONTINUITY_REASON_PERIOD_TRANSITION, DISCONTINUITY_REASON_SEEK,
DISCONTINUITY_REASON_INTERNAL}) DISCONTINUITY_REASON_SEEK_ADJUSTMENT, DISCONTINUITY_REASON_INTERNAL})
public @interface DiscontinuityReason {} public @interface DiscontinuityReason {}
/** /**
* Automatic playback transition from one period in the timeline to the next. The period index may * Automatic playback transition from one period in the timeline to the next. The period index may
...@@ -255,9 +255,14 @@ public interface Player { ...@@ -255,9 +255,14 @@ public interface Player {
*/ */
int DISCONTINUITY_REASON_SEEK = 1; int DISCONTINUITY_REASON_SEEK = 1;
/** /**
* Seek adjustment due to being unable to seek to the requested position or because the seek was
* permitted to be inexact.
*/
int DISCONTINUITY_REASON_SEEK_ADJUSTMENT = 2;
/**
* Discontinuity introduced internally by the source. * Discontinuity introduced internally by the source.
*/ */
int DISCONTINUITY_REASON_INTERNAL = 2; int DISCONTINUITY_REASON_INTERNAL = 3;
/** /**
* Register a listener to receive events from the player. The listener's methods will be called on * Register a listener to receive events from the player. The listener's methods will be called on
......
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