Commit 8c89c9c6 by olly Committed by Ian Baker

Require playback to be stuck for a minimum period before failing

PiperOrigin-RevId: 420738165
parent 15dc8638
......@@ -167,6 +167,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
* this does not matter for now.
*/
private static final long MIN_RENDERER_SLEEP_DURATION_MS = 2000;
/**
* Duration for which the player needs to appear stuck before the playback is failed on the
* assumption that no further progress will be made. To appear stuck, the player's renderers must
* not be ready, there must be more media available to load, and the LoadControl must be refusing
* to load it.
*/
private static final long PLAYBACK_STUCK_AFTER_MS = 4000;
private final Renderer[] renderers;
private final Set<Renderer> renderersToReset;
......@@ -206,15 +213,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
private boolean foregroundMode;
private boolean requestForRendererSleep;
private boolean offloadSchedulingEnabled;
private int enabledRendererCount;
@Nullable private SeekPosition pendingInitialSeekPosition;
private long rendererPositionUs;
private int nextPendingMessageIndexHint;
private boolean deliverPendingMessageAtStartPositionRequired;
@Nullable private ExoPlaybackException pendingRecoverableRendererError;
private long setForegroundModeTimeoutMs;
private long playbackMaybeBecameStuckAtMs;
public ExoPlayerImplInternal(
Renderer[] renderers,
......@@ -248,6 +254,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
this.pauseAtEndOfWindow = pauseAtEndOfWindow;
this.clock = clock;
playbackMaybeBecameStuckAtMs = C.TIME_UNSET;
backBufferDurationUs = loadControl.getBackBufferDurationUs();
retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe();
......@@ -668,6 +675,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void setState(int state) {
if (playbackInfo.playbackState != state) {
if (state != Player.STATE_BUFFERING) {
playbackMaybeBecameStuckAtMs = C.TIME_UNSET;
}
playbackInfo = playbackInfo.copyWithPlaybackState(state);
}
}
......@@ -1038,6 +1048,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
stopRenderers();
}
boolean playbackMaybeStuck = false;
if (playbackInfo.playbackState == Player.STATE_BUFFERING) {
for (int i = 0; i < renderers.length; i++) {
if (isRendererEnabled(renderers[i])
......@@ -1048,12 +1059,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
if (!playbackInfo.isLoading
&& playbackInfo.totalBufferedDurationUs < 500_000
&& isLoadingPossible()) {
// Throw if the LoadControl prevents loading even if the buffer is empty or almost empty. We
// can't compare against 0 to account for small differences between the renderer position
// and buffered position in the media at the point where playback gets stuck.
throw new IllegalStateException("Playback stuck buffering and not loading");
// The renderers are not ready, there is more media available to load, and the LoadControl
// is refusing to load it (indicated by !playbackInfo.isLoading). This could be because the
// renderers are still transitioning to their ready states, but it could also indicate a
// stuck playback. The playbackInfo.totalBufferedDurationUs check further isolates the
// cause to a lack of media for the renderers to consume, to avoid classifying playbacks as
// stuck when they're waiting for other reasons (in particular, loading DRM keys).
playbackMaybeStuck = true;
}
}
if (!playbackMaybeStuck) {
playbackMaybeBecameStuckAtMs = C.TIME_UNSET;
} else if (playbackMaybeBecameStuckAtMs == C.TIME_UNSET) {
playbackMaybeBecameStuckAtMs = clock.elapsedRealtime();
} else if (clock.elapsedRealtime() - playbackMaybeBecameStuckAtMs >= PLAYBACK_STUCK_AFTER_MS) {
throw new IllegalStateException("Playback stuck buffering and not loading");
}
if (offloadSchedulingEnabled != playbackInfo.offloadSchedulingEnabled) {
playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(offloadSchedulingEnabled);
}
......
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