mirror of
https://github.com/androidx/media.git
synced 2025-05-05 06:30:24 +08:00
Stop sharing a Handler between EPI and EPII
Sharing the Handler has led to it being accidentally used for purposes beyond the original intention. Instead for EPII -> EPI communication: Call methods directly on ExoPlayerImpl that then post from the playback thread to the application thread. And for the MediaSourceList and Queue initialization, create a dedicated Handler based on the same applicationLooper. PiperOrigin-RevId: 320590527
This commit is contained in:
parent
09e97cf279
commit
9290b468d0
@ -66,7 +66,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
|
|
||||||
private final Renderer[] renderers;
|
private final Renderer[] renderers;
|
||||||
private final TrackSelector trackSelector;
|
private final TrackSelector trackSelector;
|
||||||
private final Handler applicationHandler;
|
private final PlaybackUpdateListenerImpl playbackUpdateListener;
|
||||||
private final ExoPlayerImplInternal internalPlayer;
|
private final ExoPlayerImplInternal internalPlayer;
|
||||||
private final Handler internalPlayerHandler;
|
private final Handler internalPlayerHandler;
|
||||||
private final CopyOnWriteArrayList<ListenerHolder> listeners;
|
private final CopyOnWriteArrayList<ListenerHolder> listeners;
|
||||||
@ -76,6 +76,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
private final boolean useLazyPreparation;
|
private final boolean useLazyPreparation;
|
||||||
private final MediaSourceFactory mediaSourceFactory;
|
private final MediaSourceFactory mediaSourceFactory;
|
||||||
@Nullable private final AnalyticsCollector analyticsCollector;
|
@Nullable private final AnalyticsCollector analyticsCollector;
|
||||||
|
private final Looper applicationLooper;
|
||||||
private final BandwidthMeter bandwidthMeter;
|
private final BandwidthMeter bandwidthMeter;
|
||||||
|
|
||||||
@RepeatMode private int repeatMode;
|
@RepeatMode private int repeatMode;
|
||||||
@ -142,6 +143,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
this.useLazyPreparation = useLazyPreparation;
|
this.useLazyPreparation = useLazyPreparation;
|
||||||
this.seekParameters = seekParameters;
|
this.seekParameters = seekParameters;
|
||||||
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
|
this.pauseAtEndOfMediaItems = pauseAtEndOfMediaItems;
|
||||||
|
this.applicationLooper = applicationLooper;
|
||||||
repeatMode = Player.REPEAT_MODE_OFF;
|
repeatMode = Player.REPEAT_MODE_OFF;
|
||||||
listeners = new CopyOnWriteArrayList<>();
|
listeners = new CopyOnWriteArrayList<>();
|
||||||
mediaSourceHolderSnapshots = new ArrayList<>();
|
mediaSourceHolderSnapshots = new ArrayList<>();
|
||||||
@ -154,19 +156,13 @@ import java.util.concurrent.TimeoutException;
|
|||||||
period = new Timeline.Period();
|
period = new Timeline.Period();
|
||||||
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
|
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
|
||||||
maskingWindowIndex = C.INDEX_UNSET;
|
maskingWindowIndex = C.INDEX_UNSET;
|
||||||
applicationHandler =
|
playbackUpdateListener = new PlaybackUpdateListenerImpl(applicationLooper);
|
||||||
new Handler(applicationLooper) {
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
ExoPlayerImpl.this.handleEvent(msg);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
|
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
|
||||||
pendingListenerNotifications = new ArrayDeque<>();
|
pendingListenerNotifications = new ArrayDeque<>();
|
||||||
if (analyticsCollector != null) {
|
if (analyticsCollector != null) {
|
||||||
analyticsCollector.setPlayer(this);
|
analyticsCollector.setPlayer(this);
|
||||||
addListener(analyticsCollector);
|
addListener(analyticsCollector);
|
||||||
bandwidthMeter.addEventListener(applicationHandler, analyticsCollector);
|
bandwidthMeter.addEventListener(new Handler(applicationLooper), analyticsCollector);
|
||||||
}
|
}
|
||||||
internalPlayer =
|
internalPlayer =
|
||||||
new ExoPlayerImplInternal(
|
new ExoPlayerImplInternal(
|
||||||
@ -180,8 +176,9 @@ import java.util.concurrent.TimeoutException;
|
|||||||
analyticsCollector,
|
analyticsCollector,
|
||||||
seekParameters,
|
seekParameters,
|
||||||
pauseAtEndOfMediaItems,
|
pauseAtEndOfMediaItems,
|
||||||
applicationHandler,
|
applicationLooper,
|
||||||
clock);
|
clock,
|
||||||
|
playbackUpdateListener);
|
||||||
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
|
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +248,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Looper getApplicationLooper() {
|
public Looper getApplicationLooper() {
|
||||||
return applicationHandler.getLooper();
|
return applicationLooper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -588,11 +585,8 @@ import java.util.concurrent.TimeoutException;
|
|||||||
// general because the midroll ad preceding the seek destination must be played before the
|
// general because the midroll ad preceding the seek destination must be played before the
|
||||||
// content position can be played, if a different ad is playing at the moment.
|
// content position can be played, if a different ad is playing at the moment.
|
||||||
Log.w(TAG, "seekTo ignored because an ad is playing");
|
Log.w(TAG, "seekTo ignored because an ad is playing");
|
||||||
applicationHandler
|
playbackUpdateListener.onPlaybackInfoUpdate(
|
||||||
.obtainMessage(
|
new ExoPlayerImplInternal.PlaybackInfoUpdate(playbackInfo));
|
||||||
ExoPlayerImplInternal.MSG_PLAYBACK_INFO_CHANGED,
|
|
||||||
new ExoPlayerImplInternal.PlaybackInfoUpdate(playbackInfo))
|
|
||||||
.sendToTarget();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
maskWindowIndexAndPositionForSeek(timeline, windowIndex, positionMs);
|
maskWindowIndexAndPositionForSeek(timeline, windowIndex, positionMs);
|
||||||
@ -715,7 +709,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
ExoPlaybackException.createForUnexpected(
|
ExoPlaybackException.createForUnexpected(
|
||||||
new RuntimeException(new TimeoutException("Player release timed out.")))));
|
new RuntimeException(new TimeoutException("Player release timed out.")))));
|
||||||
}
|
}
|
||||||
applicationHandler.removeCallbacksAndMessages(null);
|
playbackUpdateListener.handler.removeCallbacksAndMessages(null);
|
||||||
if (analyticsCollector != null) {
|
if (analyticsCollector != null) {
|
||||||
bandwidthMeter.removeEventListener(analyticsCollector);
|
bandwidthMeter.removeEventListener(analyticsCollector);
|
||||||
}
|
}
|
||||||
@ -869,20 +863,6 @@ import java.util.concurrent.TimeoutException;
|
|||||||
return playbackInfo.timeline;
|
return playbackInfo.timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not private so it can be called from an inner class without going through a thunk method.
|
|
||||||
/* package */ void handleEvent(Message msg) {
|
|
||||||
switch (msg.what) {
|
|
||||||
case ExoPlayerImplInternal.MSG_PLAYBACK_INFO_CHANGED:
|
|
||||||
handlePlaybackInfo((ExoPlayerImplInternal.PlaybackInfoUpdate) msg.obj);
|
|
||||||
break;
|
|
||||||
case ExoPlayerImplInternal.MSG_PLAYBACK_SPEED_CHANGED:
|
|
||||||
handlePlaybackSpeed((Float) msg.obj, /* operationAck= */ msg.arg1 != 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getCurrentWindowIndexInternal() {
|
private int getCurrentWindowIndexInternal() {
|
||||||
if (shouldMaskPosition()) {
|
if (shouldMaskPosition()) {
|
||||||
return maskingWindowIndex;
|
return maskingWindowIndex;
|
||||||
@ -1282,6 +1262,49 @@ import java.util.concurrent.TimeoutException;
|
|||||||
return playbackInfo.timeline.isEmpty() || pendingOperationAcks > 0;
|
return playbackInfo.timeline.isEmpty() || pendingOperationAcks > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class PlaybackUpdateListenerImpl
|
||||||
|
implements ExoPlayerImplInternal.PlaybackUpdateListener, Handler.Callback {
|
||||||
|
private static final int MSG_PLAYBACK_INFO_CHANGED = 0;
|
||||||
|
private static final int MSG_PLAYBACK_SPEED_CHANGED = 1;
|
||||||
|
|
||||||
|
private final Handler handler;
|
||||||
|
|
||||||
|
private PlaybackUpdateListenerImpl(Looper applicationLooper) {
|
||||||
|
handler = Util.createHandler(applicationLooper, /* callback= */ this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlaybackInfoUpdate(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfo) {
|
||||||
|
handler.obtainMessage(MSG_PLAYBACK_INFO_CHANGED, playbackInfo).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlaybackSpeedChange(float playbackSpeed, boolean acknowledgeCommand) {
|
||||||
|
handler
|
||||||
|
.obtainMessage(
|
||||||
|
MSG_PLAYBACK_SPEED_CHANGED,
|
||||||
|
/* arg1= */ acknowledgeCommand ? 1 : 0,
|
||||||
|
/* arg2= */ 0,
|
||||||
|
/* obj= */ playbackSpeed)
|
||||||
|
.sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_PLAYBACK_INFO_CHANGED:
|
||||||
|
handlePlaybackInfo((ExoPlayerImplInternal.PlaybackInfoUpdate) msg.obj);
|
||||||
|
break;
|
||||||
|
case MSG_PLAYBACK_SPEED_CHANGED:
|
||||||
|
handlePlaybackSpeed((Float) msg.obj, /* operationAck= */ msg.arg1 != 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class PlaybackInfoUpdate implements Runnable {
|
private static final class PlaybackInfoUpdate implements Runnable {
|
||||||
|
|
||||||
private final PlaybackInfo playbackInfo;
|
private final PlaybackInfo playbackInfo;
|
||||||
|
@ -63,9 +63,57 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
private static final String TAG = "ExoPlayerImplInternal";
|
private static final String TAG = "ExoPlayerImplInternal";
|
||||||
|
|
||||||
// External messages
|
public static final class PlaybackInfoUpdate {
|
||||||
public static final int MSG_PLAYBACK_INFO_CHANGED = 0;
|
|
||||||
public static final int MSG_PLAYBACK_SPEED_CHANGED = 1;
|
private boolean hasPendingChange;
|
||||||
|
|
||||||
|
public PlaybackInfo playbackInfo;
|
||||||
|
public int operationAcks;
|
||||||
|
public boolean positionDiscontinuity;
|
||||||
|
@DiscontinuityReason public int discontinuityReason;
|
||||||
|
public boolean hasPlayWhenReadyChangeReason;
|
||||||
|
@PlayWhenReadyChangeReason public int playWhenReadyChangeReason;
|
||||||
|
|
||||||
|
public PlaybackInfoUpdate(PlaybackInfo playbackInfo) {
|
||||||
|
this.playbackInfo = playbackInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementPendingOperationAcks(int operationAcks) {
|
||||||
|
hasPendingChange |= operationAcks > 0;
|
||||||
|
this.operationAcks += operationAcks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaybackInfo(PlaybackInfo playbackInfo) {
|
||||||
|
hasPendingChange |= this.playbackInfo != playbackInfo;
|
||||||
|
this.playbackInfo = playbackInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPositionDiscontinuity(@DiscontinuityReason int discontinuityReason) {
|
||||||
|
if (positionDiscontinuity
|
||||||
|
&& this.discontinuityReason != Player.DISCONTINUITY_REASON_INTERNAL) {
|
||||||
|
// We always prefer non-internal discontinuity reasons. We also assume that we won't report
|
||||||
|
// more than one non-internal discontinuity per message iteration.
|
||||||
|
Assertions.checkArgument(discontinuityReason == Player.DISCONTINUITY_REASON_INTERNAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hasPendingChange = true;
|
||||||
|
positionDiscontinuity = true;
|
||||||
|
this.discontinuityReason = discontinuityReason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayWhenReadyChangeReason(
|
||||||
|
@PlayWhenReadyChangeReason int playWhenReadyChangeReason) {
|
||||||
|
hasPendingChange = true;
|
||||||
|
this.hasPlayWhenReadyChangeReason = true;
|
||||||
|
this.playWhenReadyChangeReason = playWhenReadyChangeReason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PlaybackUpdateListener {
|
||||||
|
void onPlaybackInfoUpdate(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfo);
|
||||||
|
|
||||||
|
void onPlaybackSpeedChange(float playbackSpeed, boolean acknowledgeCommand);
|
||||||
|
}
|
||||||
|
|
||||||
// Internal messages
|
// Internal messages
|
||||||
private static final int MSG_PREPARE = 0;
|
private static final int MSG_PREPARE = 0;
|
||||||
@ -113,7 +161,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private final BandwidthMeter bandwidthMeter;
|
private final BandwidthMeter bandwidthMeter;
|
||||||
private final HandlerWrapper handler;
|
private final HandlerWrapper handler;
|
||||||
private final HandlerThread internalPlaybackThread;
|
private final HandlerThread internalPlaybackThread;
|
||||||
private final Handler eventHandler;
|
|
||||||
private final Timeline.Window window;
|
private final Timeline.Window window;
|
||||||
private final Timeline.Period period;
|
private final Timeline.Period period;
|
||||||
private final long backBufferDurationUs;
|
private final long backBufferDurationUs;
|
||||||
@ -121,6 +168,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private final DefaultMediaClock mediaClock;
|
private final DefaultMediaClock mediaClock;
|
||||||
private final ArrayList<PendingMessageInfo> pendingMessages;
|
private final ArrayList<PendingMessageInfo> pendingMessages;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
private final PlaybackUpdateListener playbackUpdateListener;
|
||||||
private final MediaPeriodQueue queue;
|
private final MediaPeriodQueue queue;
|
||||||
private final MediaSourceList mediaSourceList;
|
private final MediaSourceList mediaSourceList;
|
||||||
|
|
||||||
@ -160,8 +208,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
@Nullable AnalyticsCollector analyticsCollector,
|
@Nullable AnalyticsCollector analyticsCollector,
|
||||||
SeekParameters seekParameters,
|
SeekParameters seekParameters,
|
||||||
boolean pauseAtEndOfWindow,
|
boolean pauseAtEndOfWindow,
|
||||||
Handler eventHandler,
|
Looper applicationLooper,
|
||||||
Clock clock) {
|
Clock clock,
|
||||||
|
PlaybackUpdateListener playbackUpdateListener) {
|
||||||
|
this.playbackUpdateListener = playbackUpdateListener;
|
||||||
this.renderers = renderers;
|
this.renderers = renderers;
|
||||||
this.trackSelector = trackSelector;
|
this.trackSelector = trackSelector;
|
||||||
this.emptyTrackSelectorResult = emptyTrackSelectorResult;
|
this.emptyTrackSelectorResult = emptyTrackSelectorResult;
|
||||||
@ -171,9 +221,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
this.shuffleModeEnabled = shuffleModeEnabled;
|
this.shuffleModeEnabled = shuffleModeEnabled;
|
||||||
this.seekParameters = seekParameters;
|
this.seekParameters = seekParameters;
|
||||||
this.pauseAtEndOfWindow = pauseAtEndOfWindow;
|
this.pauseAtEndOfWindow = pauseAtEndOfWindow;
|
||||||
this.eventHandler = eventHandler;
|
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.queue = new MediaPeriodQueue(analyticsCollector, eventHandler);
|
|
||||||
|
|
||||||
backBufferDurationUs = loadControl.getBackBufferDurationUs();
|
backBufferDurationUs = loadControl.getBackBufferDurationUs();
|
||||||
retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe();
|
retainBackBufferFromKeyframe = loadControl.retainBackBufferFromKeyframe();
|
||||||
@ -191,13 +239,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
period = new Timeline.Period();
|
period = new Timeline.Period();
|
||||||
trackSelector.init(/* listener= */ this, bandwidthMeter);
|
trackSelector.init(/* listener= */ this, bandwidthMeter);
|
||||||
|
|
||||||
|
deliverPendingMessageAtStartPositionRequired = true;
|
||||||
|
|
||||||
|
Handler eventHandler = new Handler(applicationLooper);
|
||||||
|
queue = new MediaPeriodQueue(analyticsCollector, eventHandler);
|
||||||
|
mediaSourceList = new MediaSourceList(/* listener= */ this, analyticsCollector, eventHandler);
|
||||||
|
|
||||||
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
||||||
// not normally change to this priority" is incorrect.
|
// not normally change to this priority" is incorrect.
|
||||||
internalPlaybackThread = new HandlerThread("ExoPlayer:Playback", Process.THREAD_PRIORITY_AUDIO);
|
internalPlaybackThread = new HandlerThread("ExoPlayer:Playback", Process.THREAD_PRIORITY_AUDIO);
|
||||||
internalPlaybackThread.start();
|
internalPlaybackThread.start();
|
||||||
handler = clock.createHandler(internalPlaybackThread.getLooper(), this);
|
handler = clock.createHandler(internalPlaybackThread.getLooper(), this);
|
||||||
deliverPendingMessageAtStartPositionRequired = true;
|
|
||||||
mediaSourceList = new MediaSourceList(/* listener= */ this, analyticsCollector, eventHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void experimental_setReleaseTimeoutMs(long releaseTimeoutMs) {
|
public void experimental_setReleaseTimeoutMs(long releaseTimeoutMs) {
|
||||||
@ -571,7 +623,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private void maybeNotifyPlaybackInfoChanged() {
|
private void maybeNotifyPlaybackInfoChanged() {
|
||||||
playbackInfoUpdate.setPlaybackInfo(playbackInfo);
|
playbackInfoUpdate.setPlaybackInfo(playbackInfo);
|
||||||
if (playbackInfoUpdate.hasPendingChange) {
|
if (playbackInfoUpdate.hasPendingChange) {
|
||||||
eventHandler.obtainMessage(MSG_PLAYBACK_INFO_CHANGED, playbackInfoUpdate).sendToTarget();
|
playbackUpdateListener.onPlaybackInfoUpdate(playbackInfoUpdate);
|
||||||
playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo);
|
playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1938,9 +1990,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
private void handlePlaybackSpeed(float playbackSpeed, boolean acknowledgeCommand)
|
private void handlePlaybackSpeed(float playbackSpeed, boolean acknowledgeCommand)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
eventHandler
|
playbackUpdateListener.onPlaybackSpeedChange(playbackSpeed, acknowledgeCommand);
|
||||||
.obtainMessage(MSG_PLAYBACK_SPEED_CHANGED, acknowledgeCommand ? 1 : 0, 0, playbackSpeed)
|
|
||||||
.sendToTarget();
|
|
||||||
updateTrackSelectionPlaybackSpeed(playbackSpeed);
|
updateTrackSelectionPlaybackSpeed(playbackSpeed);
|
||||||
for (Renderer renderer : renderers) {
|
for (Renderer renderer : renderers) {
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
@ -2650,50 +2700,4 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
this.shuffleOrder = shuffleOrder;
|
this.shuffleOrder = shuffleOrder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ static final class PlaybackInfoUpdate {
|
|
||||||
|
|
||||||
private boolean hasPendingChange;
|
|
||||||
|
|
||||||
public PlaybackInfo playbackInfo;
|
|
||||||
public int operationAcks;
|
|
||||||
public boolean positionDiscontinuity;
|
|
||||||
@DiscontinuityReason public int discontinuityReason;
|
|
||||||
public boolean hasPlayWhenReadyChangeReason;
|
|
||||||
@PlayWhenReadyChangeReason public int playWhenReadyChangeReason;
|
|
||||||
|
|
||||||
public PlaybackInfoUpdate(PlaybackInfo playbackInfo) {
|
|
||||||
this.playbackInfo = playbackInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementPendingOperationAcks(int operationAcks) {
|
|
||||||
hasPendingChange |= operationAcks > 0;
|
|
||||||
this.operationAcks += operationAcks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaybackInfo(PlaybackInfo playbackInfo) {
|
|
||||||
hasPendingChange |= this.playbackInfo != playbackInfo;
|
|
||||||
this.playbackInfo = playbackInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPositionDiscontinuity(@DiscontinuityReason int discontinuityReason) {
|
|
||||||
if (positionDiscontinuity
|
|
||||||
&& this.discontinuityReason != Player.DISCONTINUITY_REASON_INTERNAL) {
|
|
||||||
// We always prefer non-internal discontinuity reasons. We also assume that we won't report
|
|
||||||
// more than one non-internal discontinuity per message iteration.
|
|
||||||
Assertions.checkArgument(discontinuityReason == Player.DISCONTINUITY_REASON_INTERNAL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hasPendingChange = true;
|
|
||||||
positionDiscontinuity = true;
|
|
||||||
this.discontinuityReason = discontinuityReason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayWhenReadyChangeReason(
|
|
||||||
@PlayWhenReadyChangeReason int playWhenReadyChangeReason) {
|
|
||||||
hasPendingChange = true;
|
|
||||||
this.hasPlayWhenReadyChangeReason = true;
|
|
||||||
this.playWhenReadyChangeReason = playWhenReadyChangeReason;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user