Merge playback speed into PlaybackInfo and update EPI and EPII

PiperOrigin-RevId: 322539001
This commit is contained in:
ibaker 2020-07-22 11:05:19 +01:00 committed by Oliver Woodman
parent 78260e2021
commit 1c6aaac958
5 changed files with 98 additions and 91 deletions

View File

@ -22,7 +22,6 @@ import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.PlayerMessage.Target; import com.google.android.exoplayer2.PlayerMessage.Target;
@ -67,7 +66,8 @@ import java.util.concurrent.TimeoutException;
private final Renderer[] renderers; private final Renderer[] renderers;
private final TrackSelector trackSelector; private final TrackSelector trackSelector;
private final PlaybackUpdateListenerImpl playbackUpdateListener; private final Handler playbackInfoUpdateHandler;
private final ExoPlayerImplInternal.PlaybackInfoUpdateListener playbackInfoUpdateListener;
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;
@ -87,8 +87,6 @@ import java.util.concurrent.TimeoutException;
@DiscontinuityReason private int pendingDiscontinuityReason; @DiscontinuityReason private int pendingDiscontinuityReason;
@PlayWhenReadyChangeReason private int pendingPlayWhenReadyChangeReason; @PlayWhenReadyChangeReason private int pendingPlayWhenReadyChangeReason;
private boolean foregroundMode; private boolean foregroundMode;
private int pendingSetPlaybackSpeedAcks;
private float playbackSpeed;
private SeekParameters seekParameters; private SeekParameters seekParameters;
private ShuffleOrder shuffleOrder; private ShuffleOrder shuffleOrder;
private boolean pauseAtEndOfMediaItems; private boolean pauseAtEndOfMediaItems;
@ -155,9 +153,11 @@ import java.util.concurrent.TimeoutException;
new TrackSelection[renderers.length], new TrackSelection[renderers.length],
null); null);
period = new Timeline.Period(); period = new Timeline.Period();
playbackSpeed = Player.DEFAULT_PLAYBACK_SPEED;
maskingWindowIndex = C.INDEX_UNSET; maskingWindowIndex = C.INDEX_UNSET;
playbackUpdateListener = new PlaybackUpdateListenerImpl(applicationLooper); playbackInfoUpdateHandler = new Handler(applicationLooper);
playbackInfoUpdateListener =
playbackInfoUpdate ->
playbackInfoUpdateHandler.post(() -> handlePlaybackInfo(playbackInfoUpdate));
playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult); playbackInfo = PlaybackInfo.createDummy(emptyTrackSelectorResult);
pendingListenerNotifications = new ArrayDeque<>(); pendingListenerNotifications = new ArrayDeque<>();
if (analyticsCollector != null) { if (analyticsCollector != null) {
@ -179,7 +179,7 @@ import java.util.concurrent.TimeoutException;
pauseAtEndOfMediaItems, pauseAtEndOfMediaItems,
applicationLooper, applicationLooper,
clock, clock,
playbackUpdateListener); playbackInfoUpdateListener);
internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper()); internalPlayerHandler = new Handler(internalPlayer.getPlaybackLooper());
} }
@ -595,7 +595,7 @@ 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");
playbackUpdateListener.onPlaybackInfoUpdate( playbackInfoUpdateListener.onPlaybackInfoUpdate(
new ExoPlayerImplInternal.PlaybackInfoUpdate(playbackInfo)); new ExoPlayerImplInternal.PlaybackInfoUpdate(playbackInfo));
return; return;
} }
@ -632,30 +632,30 @@ import java.util.concurrent.TimeoutException;
@Deprecated @Deprecated
@Override @Override
public PlaybackParameters getPlaybackParameters() { public PlaybackParameters getPlaybackParameters() {
return new PlaybackParameters(playbackSpeed); return new PlaybackParameters(playbackInfo.playbackSpeed);
} }
@SuppressWarnings("deprecation")
@Override @Override
public void setPlaybackSpeed(float playbackSpeed) { public void setPlaybackSpeed(float playbackSpeed) {
checkState(playbackSpeed > 0); checkState(playbackSpeed > 0);
if (this.playbackSpeed == playbackSpeed) { if (playbackInfo.playbackSpeed == playbackSpeed) {
return; return;
} }
pendingSetPlaybackSpeedAcks++; PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackSpeed(playbackSpeed);
this.playbackSpeed = playbackSpeed; pendingOperationAcks++;
PlaybackParameters playbackParameters = new PlaybackParameters(playbackSpeed);
internalPlayer.setPlaybackSpeed(playbackSpeed); internalPlayer.setPlaybackSpeed(playbackSpeed);
notifyListeners( updatePlaybackInfo(
listener -> { newPlaybackInfo,
listener.onPlaybackParametersChanged(playbackParameters); /* positionDiscontinuity= */ false,
listener.onPlaybackSpeedChanged(playbackSpeed); /* ignored */ DISCONTINUITY_REASON_INTERNAL,
}); /* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED,
/* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST,
/* seekProcessed= */ false);
} }
@Override @Override
public float getPlaybackSpeed() { public float getPlaybackSpeed() {
return playbackSpeed; return playbackInfo.playbackSpeed;
} }
@Override @Override
@ -726,7 +726,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.")))));
} }
playbackUpdateListener.handler.removeCallbacksAndMessages(null); playbackInfoUpdateHandler.removeCallbacksAndMessages(null);
if (analyticsCollector != null) { if (analyticsCollector != null) {
bandwidthMeter.removeEventListener(analyticsCollector); bandwidthMeter.removeEventListener(analyticsCollector);
} }
@ -896,23 +896,6 @@ import java.util.concurrent.TimeoutException;
return mediaSources; return mediaSources;
} }
@SuppressWarnings("deprecation")
private void handlePlaybackSpeed(float playbackSpeed, boolean operationAck) {
if (operationAck) {
pendingSetPlaybackSpeedAcks--;
}
if (pendingSetPlaybackSpeedAcks == 0) {
if (this.playbackSpeed != playbackSpeed) {
this.playbackSpeed = playbackSpeed;
notifyListeners(
listener -> {
listener.onPlaybackParametersChanged(new PlaybackParameters(playbackSpeed));
listener.onPlaybackSpeedChanged(playbackSpeed);
});
}
}
}
private void handlePlaybackInfo(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfoUpdate) { private void handlePlaybackInfo(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfoUpdate) {
pendingOperationAcks -= playbackInfoUpdate.operationAcks; pendingOperationAcks -= playbackInfoUpdate.operationAcks;
if (playbackInfoUpdate.positionDiscontinuity) { if (playbackInfoUpdate.positionDiscontinuity) {
@ -996,7 +979,7 @@ import java.util.concurrent.TimeoutException;
PlaybackInfo playbackInfo, PlaybackInfo playbackInfo,
PlaybackInfo oldPlaybackInfo, PlaybackInfo oldPlaybackInfo,
boolean positionDiscontinuity, boolean positionDiscontinuity,
int positionDiscontinuityReason, @DiscontinuityReason int positionDiscontinuityReason,
boolean timelineChanged) { boolean timelineChanged) {
Timeline oldTimeline = oldPlaybackInfo.timeline; Timeline oldTimeline = oldPlaybackInfo.timeline;
@ -1360,49 +1343,6 @@ import java.util.concurrent.TimeoutException;
return positionMs; return positionMs;
} }
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;
@ -1424,6 +1364,7 @@ import java.util.concurrent.TimeoutException;
private final boolean playWhenReadyChanged; private final boolean playWhenReadyChanged;
private final boolean playbackSuppressionReasonChanged; private final boolean playbackSuppressionReasonChanged;
private final boolean isPlayingChanged; private final boolean isPlayingChanged;
private final boolean playbackSpeedChanged;
public PlaybackInfoUpdate( public PlaybackInfoUpdate(
PlaybackInfo playbackInfo, PlaybackInfo playbackInfo,
@ -1461,6 +1402,7 @@ import java.util.concurrent.TimeoutException;
playbackSuppressionReasonChanged = playbackSuppressionReasonChanged =
previousPlaybackInfo.playbackSuppressionReason != playbackInfo.playbackSuppressionReason; previousPlaybackInfo.playbackSuppressionReason != playbackInfo.playbackSuppressionReason;
isPlayingChanged = isPlaying(previousPlaybackInfo) != isPlaying(playbackInfo); isPlayingChanged = isPlaying(previousPlaybackInfo) != isPlaying(playbackInfo);
playbackSpeedChanged = previousPlaybackInfo.playbackSpeed != playbackInfo.playbackSpeed;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -1526,6 +1468,15 @@ import java.util.concurrent.TimeoutException;
invokeAll( invokeAll(
listenerSnapshot, listener -> listener.onIsPlayingChanged(isPlaying(playbackInfo))); listenerSnapshot, listener -> listener.onIsPlayingChanged(isPlaying(playbackInfo)));
} }
if (playbackSpeedChanged) {
PlaybackParameters playbackParameters = new PlaybackParameters(playbackInfo.playbackSpeed);
invokeAll(
listenerSnapshot,
listener -> {
listener.onPlaybackSpeedChanged(playbackInfo.playbackSpeed);
listener.onPlaybackParametersChanged(playbackParameters);
});
}
if (seekProcessed) { if (seekProcessed) {
invokeAll(listenerSnapshot, EventListener::onSeekProcessed); invokeAll(listenerSnapshot, EventListener::onSeekProcessed);
} }

View File

@ -109,10 +109,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
} }
public interface PlaybackUpdateListener { public interface PlaybackInfoUpdateListener {
void onPlaybackInfoUpdate(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfo); void onPlaybackInfoUpdate(ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfo);
void onPlaybackSpeedChange(float playbackSpeed, boolean acknowledgeCommand);
} }
// Internal messages // Internal messages
@ -168,7 +166,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 PlaybackInfoUpdateListener playbackInfoUpdateListener;
private final MediaPeriodQueue queue; private final MediaPeriodQueue queue;
private final MediaSourceList mediaSourceList; private final MediaSourceList mediaSourceList;
@ -210,8 +208,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
boolean pauseAtEndOfWindow, boolean pauseAtEndOfWindow,
Looper applicationLooper, Looper applicationLooper,
Clock clock, Clock clock,
PlaybackUpdateListener playbackUpdateListener) { PlaybackInfoUpdateListener playbackInfoUpdateListener) {
this.playbackUpdateListener = playbackUpdateListener; this.playbackInfoUpdateListener = playbackInfoUpdateListener;
this.renderers = renderers; this.renderers = renderers;
this.trackSelector = trackSelector; this.trackSelector = trackSelector;
this.emptyTrackSelectorResult = emptyTrackSelectorResult; this.emptyTrackSelectorResult = emptyTrackSelectorResult;
@ -624,7 +622,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) {
playbackUpdateListener.onPlaybackInfoUpdate(playbackInfoUpdate); playbackInfoUpdateListener.onPlaybackInfoUpdate(playbackInfoUpdate);
playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo); playbackInfoUpdate = new PlaybackInfoUpdate(playbackInfo);
} }
} }
@ -1279,6 +1277,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
mediaPeriodId, mediaPeriodId,
playbackInfo.playWhenReady, playbackInfo.playWhenReady,
playbackInfo.playbackSuppressionReason, playbackInfo.playbackSuppressionReason,
playbackInfo.playbackSpeed,
startPositionUs, startPositionUs,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
startPositionUs); startPositionUs);
@ -1964,7 +1963,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void handlePlaybackSpeed(float playbackSpeed, boolean acknowledgeCommand) private void handlePlaybackSpeed(float playbackSpeed, boolean acknowledgeCommand)
throws ExoPlaybackException { throws ExoPlaybackException {
playbackUpdateListener.onPlaybackSpeedChange(playbackSpeed, acknowledgeCommand); playbackInfoUpdate.incrementPendingOperationAcks(acknowledgeCommand ? 1 : 0);
playbackInfo = playbackInfo.copyWithPlaybackSpeed(playbackSpeed);
updateTrackSelectionPlaybackSpeed(playbackSpeed); updateTrackSelectionPlaybackSpeed(playbackSpeed);
for (Renderer renderer : renderers) { for (Renderer renderer : renderers) {
if (renderer != null) { if (renderer != null) {

View File

@ -63,6 +63,8 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
public final boolean playWhenReady; public final boolean playWhenReady;
/** Reason why playback is suppressed even though {@link #playWhenReady} is {@code true}. */ /** Reason why playback is suppressed even though {@link #playWhenReady} is {@code true}. */
@PlaybackSuppressionReason public final int playbackSuppressionReason; @PlaybackSuppressionReason public final int playbackSuppressionReason;
/** The playback speed. */
public final float playbackSpeed;
/** /**
* Position up to which media is buffered in {@link #loadingMediaPeriodId) relative to the start * Position up to which media is buffered in {@link #loadingMediaPeriodId) relative to the start
@ -101,6 +103,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
PLACEHOLDER_MEDIA_PERIOD_ID, PLACEHOLDER_MEDIA_PERIOD_ID,
/* playWhenReady= */ false, /* playWhenReady= */ false,
Player.PLAYBACK_SUPPRESSION_REASON_NONE, Player.PLAYBACK_SUPPRESSION_REASON_NONE,
Player.DEFAULT_PLAYBACK_SPEED,
/* bufferedPositionUs= */ 0, /* bufferedPositionUs= */ 0,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
/* positionUs= */ 0); /* positionUs= */ 0);
@ -133,6 +136,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
MediaPeriodId loadingMediaPeriodId, MediaPeriodId loadingMediaPeriodId,
boolean playWhenReady, boolean playWhenReady,
@PlaybackSuppressionReason int playbackSuppressionReason, @PlaybackSuppressionReason int playbackSuppressionReason,
float playbackSpeed,
long bufferedPositionUs, long bufferedPositionUs,
long totalBufferedDurationUs, long totalBufferedDurationUs,
long positionUs) { long positionUs) {
@ -147,6 +151,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
this.loadingMediaPeriodId = loadingMediaPeriodId; this.loadingMediaPeriodId = loadingMediaPeriodId;
this.playWhenReady = playWhenReady; this.playWhenReady = playWhenReady;
this.playbackSuppressionReason = playbackSuppressionReason; this.playbackSuppressionReason = playbackSuppressionReason;
this.playbackSpeed = playbackSpeed;
this.bufferedPositionUs = bufferedPositionUs; this.bufferedPositionUs = bufferedPositionUs;
this.totalBufferedDurationUs = totalBufferedDurationUs; this.totalBufferedDurationUs = totalBufferedDurationUs;
this.positionUs = positionUs; this.positionUs = positionUs;
@ -190,6 +195,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -215,6 +221,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -240,6 +247,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -265,6 +273,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -290,6 +299,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -315,6 +325,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);
@ -344,6 +355,33 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
loadingMediaPeriodId, loadingMediaPeriodId,
playWhenReady, playWhenReady,
playbackSuppressionReason, playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs,
totalBufferedDurationUs,
positionUs);
}
/**
* Copies playback info with new playback speed.
*
* @param playbackSpeed New playback speed. See {@link #playbackSpeed}.
* @return Copied playback info with new playback speed.
*/
@CheckResult
public PlaybackInfo copyWithPlaybackSpeed(float playbackSpeed) {
return new PlaybackInfo(
timeline,
periodId,
requestedContentPositionUs,
playbackState,
playbackError,
isLoading,
trackGroups,
trackSelectorResult,
loadingMediaPeriodId,
playWhenReady,
playbackSuppressionReason,
playbackSpeed,
bufferedPositionUs, bufferedPositionUs,
totalBufferedDurationUs, totalBufferedDurationUs,
positionUs); positionUs);

View File

@ -62,6 +62,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdPlaybackState; import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.source.ads.AdsLoader; import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource; import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.testutil.Action;
import com.google.android.exoplayer2.testutil.ActionSchedule; import com.google.android.exoplayer2.testutil.ActionSchedule;
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable; import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable;
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerTarget; import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerTarget;
@ -82,6 +83,7 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
import com.google.android.exoplayer2.testutil.FakeTrackSelection; import com.google.android.exoplayer2.testutil.FakeTrackSelection;
import com.google.android.exoplayer2.testutil.FakeTrackSelector; import com.google.android.exoplayer2.testutil.FakeTrackSelector;
import com.google.android.exoplayer2.testutil.TestExoPlayer; import com.google.android.exoplayer2.testutil.TestExoPlayer;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.Allocation; import com.google.android.exoplayer2.upstream.Allocation;
@ -3333,15 +3335,29 @@ public final class ExoPlayerTest {
} }
@Test @Test
public void setPlaybackParametersConsecutivelyNotifiesListenerForEveryChangeOnce() public void setPlaybackParametersConsecutivelyNotifiesListenerForEveryChangeOnceAndIsMasked()
throws Exception { throws Exception {
List<Float> maskedPlaybackSpeeds = new ArrayList<>();
Action getPlaybackSpeedAction =
new Action("getPlaybackSpeed", /* description= */ null) {
@Override
protected void doActionImpl(
SimpleExoPlayer player,
DefaultTrackSelector trackSelector,
@Nullable Surface surface) {
maskedPlaybackSpeeds.add(player.getPlaybackSpeed());
}
};
ActionSchedule actionSchedule = ActionSchedule actionSchedule =
new ActionSchedule.Builder(TAG) new ActionSchedule.Builder(TAG)
.pause() .pause()
.waitForPlaybackState(Player.STATE_READY) .waitForPlaybackState(Player.STATE_READY)
.setPlaybackSpeed(1.1f) .setPlaybackSpeed(1.1f)
.apply(getPlaybackSpeedAction)
.setPlaybackSpeed(1.2f) .setPlaybackSpeed(1.2f)
.apply(getPlaybackSpeedAction)
.setPlaybackSpeed(1.3f) .setPlaybackSpeed(1.3f)
.apply(getPlaybackSpeedAction)
.play() .play()
.build(); .build();
List<Float> reportedPlaybackSpeeds = new ArrayList<>(); List<Float> reportedPlaybackSpeeds = new ArrayList<>();
@ -3360,6 +3376,7 @@ public final class ExoPlayerTest {
.blockUntilEnded(TIMEOUT_MS); .blockUntilEnded(TIMEOUT_MS);
assertThat(reportedPlaybackSpeeds).containsExactly(1.1f, 1.2f, 1.3f).inOrder(); assertThat(reportedPlaybackSpeeds).containsExactly(1.1f, 1.2f, 1.3f).inOrder();
assertThat(maskedPlaybackSpeeds).isEqualTo(reportedPlaybackSpeeds);
} }
@Test @Test

View File

@ -437,6 +437,7 @@ public final class MediaPeriodQueueTest {
/* loadingMediaPeriodId= */ null, /* loadingMediaPeriodId= */ null,
/* playWhenReady= */ false, /* playWhenReady= */ false,
Player.PLAYBACK_SUPPRESSION_REASON_NONE, Player.PLAYBACK_SUPPRESSION_REASON_NONE,
/* playbackSpeed= */ Player.DEFAULT_PLAYBACK_SPEED,
/* bufferedPositionUs= */ 0, /* bufferedPositionUs= */ 0,
/* totalBufferedDurationUs= */ 0, /* totalBufferedDurationUs= */ 0,
/* positionUs= */ 0); /* positionUs= */ 0);