Use message to set offload scheduling

The code was mutating boolean across threads.

PiperOrigin-RevId: 325826214
This commit is contained in:
krocard 2020-08-10 17:58:54 +01:00 committed by kim-vde
parent 192c1e5dee
commit 19db6feddb
2 changed files with 29 additions and 9 deletions

View File

@ -141,6 +141,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_SET_SHUFFLE_ORDER = 21; private static final int MSG_SET_SHUFFLE_ORDER = 21;
private static final int MSG_PLAYLIST_UPDATE_REQUESTED = 22; private static final int MSG_PLAYLIST_UPDATE_REQUESTED = 22;
private static final int MSG_SET_PAUSE_AT_END_OF_WINDOW = 23; private static final int MSG_SET_PAUSE_AT_END_OF_WINDOW = 23;
private static final int MSG_SET_OFFLOAD_SCHEDULING = 24;
private static final int ACTIVE_INTERVAL_MS = 10; private static final int ACTIVE_INTERVAL_MS = 10;
private static final int IDLE_INTERVAL_MS = 1000; private static final int IDLE_INTERVAL_MS = 1000;
@ -187,7 +188,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private boolean shuffleModeEnabled; private boolean shuffleModeEnabled;
private boolean foregroundMode; private boolean foregroundMode;
private boolean requestForRendererSleep; private boolean requestForRendererSleep;
private boolean offloadSchedulingEnabled; private boolean enableOffloadScheduling;
private int enabledRendererCount; private int enabledRendererCount;
@Nullable private SeekPosition pendingInitialSeekPosition; @Nullable private SeekPosition pendingInitialSeekPosition;
@ -263,10 +264,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
public void experimentalEnableOffloadScheduling(boolean enableOffloadScheduling) { public void experimentalEnableOffloadScheduling(boolean enableOffloadScheduling) {
offloadSchedulingEnabled = enableOffloadScheduling; handler
if (!enableOffloadScheduling) { .obtainMessage(MSG_SET_OFFLOAD_SCHEDULING, enableOffloadScheduling ? 1 : 0, /* unused */ 0)
handler.sendEmptyMessage(MSG_DO_SOME_WORK); .sendToTarget();
}
} }
public void prepare() { public void prepare() {
@ -518,6 +518,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
case MSG_SET_PAUSE_AT_END_OF_WINDOW: case MSG_SET_PAUSE_AT_END_OF_WINDOW:
setPauseAtEndOfWindowInternal(msg.arg1 != 0); setPauseAtEndOfWindowInternal(msg.arg1 != 0);
break; break;
case MSG_SET_OFFLOAD_SCHEDULING:
setOffloadSchedulingEnabledInternal(msg.arg1 == 1);
break;
case MSG_RELEASE: case MSG_RELEASE:
releaseInternal(); releaseInternal();
// Return immediately to not send playback info updates after release. // Return immediately to not send playback info updates after release.
@ -736,6 +739,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false); handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false);
} }
private void setOffloadSchedulingEnabledInternal(boolean enableOffloadScheduling) {
if (enableOffloadScheduling == this.enableOffloadScheduling) {
return;
}
this.enableOffloadScheduling = enableOffloadScheduling;
@Player.State int state = playbackInfo.playbackState;
if (enableOffloadScheduling || state == Player.STATE_ENDED || state == Player.STATE_IDLE) {
playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(enableOffloadScheduling);
} else {
handler.sendEmptyMessage(MSG_DO_SOME_WORK);
}
}
private void setRepeatModeInternal(@Player.RepeatMode int repeatMode) private void setRepeatModeInternal(@Player.RepeatMode int repeatMode)
throws ExoPlaybackException { throws ExoPlaybackException {
this.repeatMode = repeatMode; this.repeatMode = repeatMode;
@ -937,8 +953,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
throw new IllegalStateException("Playback stuck buffering and not loading"); throw new IllegalStateException("Playback stuck buffering and not loading");
} }
} }
if (offloadSchedulingEnabled != playbackInfo.offloadSchedulingEnabled) { if (enableOffloadScheduling != playbackInfo.offloadSchedulingEnabled) {
playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(offloadSchedulingEnabled); playbackInfo = playbackInfo.copyWithOffloadSchedulingEnabled(enableOffloadScheduling);
} }
if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY) if ((shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY)
@ -960,7 +976,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private void maybeScheduleWakeup(long operationStartTimeMs, long intervalMs) { private void maybeScheduleWakeup(long operationStartTimeMs, long intervalMs) {
if (offloadSchedulingEnabled && requestForRendererSleep) { if (enableOffloadScheduling && requestForRendererSleep) {
return; return;
} }
@ -1288,7 +1304,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
startPositionUs, startPositionUs,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
startPositionUs, startPositionUs,
offloadSchedulingEnabled); enableOffloadScheduling);
if (releaseMediaSourceList) { if (releaseMediaSourceList) {
mediaSourceList.release(); mediaSourceList.release();
} }

View File

@ -58,6 +58,8 @@ public interface Renderer extends PlayerMessage.Target {
/** /**
* The renderer no longer needs to render until the next wakeup. * The renderer no longer needs to render until the next wakeup.
* *
* <p>Must be called from the thread ExoPlayer invokes the renderer from.
*
* @param wakeupDeadlineMs Maximum time in milliseconds until {@link #onWakeup()} will be * @param wakeupDeadlineMs Maximum time in milliseconds until {@link #onWakeup()} will be
* called. * called.
*/ */
@ -66,6 +68,8 @@ public interface Renderer extends PlayerMessage.Target {
/** /**
* The renderer needs to render some frames. The client should call {@link #render(long, long)} * The renderer needs to render some frames. The client should call {@link #render(long, long)}
* at its earliest convenience. * at its earliest convenience.
*
* <p>Can be called from any thread.
*/ */
void onWakeup(); void onWakeup();
} }