mirror of
https://github.com/androidx/media.git
synced 2025-05-06 23:20:42 +08:00
Test setPlaybackParameters before preparation completes
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=176837939
This commit is contained in:
parent
de476ba4e6
commit
36255c42cf
@ -570,4 +570,48 @@ public final class ExoPlayerTest extends TestCase {
|
|||||||
testRunner.assertPlayedPeriodIndices(0, 1, 0);
|
testRunner.assertPlayedPeriodIndices(0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testSetPlaybackParametersBeforePreparationCompletesSucceeds() throws Exception {
|
||||||
|
// Test that no exception is thrown when playback parameters are updated between creating a
|
||||||
|
// period and preparation of the period completing.
|
||||||
|
final CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1);
|
||||||
|
final FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1];
|
||||||
|
MediaSource mediaSource =
|
||||||
|
new FakeMediaSource(new FakeTimeline(/* windowCount= */ 1), null, Builder.VIDEO_FORMAT) {
|
||||||
|
@Override
|
||||||
|
protected FakeMediaPeriod createFakeMediaPeriod(
|
||||||
|
MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator) {
|
||||||
|
// Defer completing preparation of the period until playback parameters have been set.
|
||||||
|
fakeMediaPeriodHolder[0] =
|
||||||
|
new FakeMediaPeriod(trackGroupArray, /* deferOnPrepared= */ true);
|
||||||
|
createPeriodCalledCountDownLatch.countDown();
|
||||||
|
return fakeMediaPeriodHolder[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ActionSchedule actionSchedule =
|
||||||
|
new ActionSchedule.Builder("testSetPlaybackParametersBeforePreparationCompletesSucceeds")
|
||||||
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
|
// Block until createPeriod has been called on the fake media source.
|
||||||
|
.executeRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
createPeriodCalledCountDownLatch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Set playback parameters (while the fake media period is not yet prepared).
|
||||||
|
.setPlaybackParameters(new PlaybackParameters(2f, 2f))
|
||||||
|
// Complete preparation of the fake media period.
|
||||||
|
.executeRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
fakeMediaPeriodHolder[0].setPreparationComplete();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
new ExoPlayerTestRunner.Builder().setMediaSource(mediaSource).setActionSchedule(actionSchedule)
|
||||||
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import android.os.Handler;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
@ -303,6 +304,30 @@ public abstract class Action {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link Player#setPlaybackParameters(PlaybackParameters)}.
|
||||||
|
*/
|
||||||
|
public static final class SetPlaybackParameters extends Action {
|
||||||
|
|
||||||
|
private final PlaybackParameters playbackParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tag A tag to use for logging.
|
||||||
|
* @param playbackParameters The playback parameters.
|
||||||
|
*/
|
||||||
|
public SetPlaybackParameters(String tag, PlaybackParameters playbackParameters) {
|
||||||
|
super(tag, "SetPlaybackParameters:" + playbackParameters);
|
||||||
|
this.playbackParameters = playbackParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doActionImpl(SimpleExoPlayer player, MappingTrackSelector trackSelector,
|
||||||
|
Surface surface) {
|
||||||
|
player.setPlaybackParameters(playbackParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}.
|
* Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}.
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,7 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
@ -28,6 +29,7 @@ import com.google.android.exoplayer2.testutil.Action.ExecuteRunnable;
|
|||||||
import com.google.android.exoplayer2.testutil.Action.PrepareSource;
|
import com.google.android.exoplayer2.testutil.Action.PrepareSource;
|
||||||
import com.google.android.exoplayer2.testutil.Action.Seek;
|
import com.google.android.exoplayer2.testutil.Action.Seek;
|
||||||
import com.google.android.exoplayer2.testutil.Action.SetPlayWhenReady;
|
import com.google.android.exoplayer2.testutil.Action.SetPlayWhenReady;
|
||||||
|
import com.google.android.exoplayer2.testutil.Action.SetPlaybackParameters;
|
||||||
import com.google.android.exoplayer2.testutil.Action.SetRendererDisabled;
|
import com.google.android.exoplayer2.testutil.Action.SetRendererDisabled;
|
||||||
import com.google.android.exoplayer2.testutil.Action.SetRepeatMode;
|
import com.google.android.exoplayer2.testutil.Action.SetRepeatMode;
|
||||||
import com.google.android.exoplayer2.testutil.Action.SetShuffleModeEnabled;
|
import com.google.android.exoplayer2.testutil.Action.SetShuffleModeEnabled;
|
||||||
@ -151,6 +153,17 @@ public final class ActionSchedule {
|
|||||||
.apply(new WaitForPlaybackState(tag, Player.STATE_READY));
|
.apply(new WaitForPlaybackState(tag, Player.STATE_READY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a playback parameters setting action to be executed.
|
||||||
|
*
|
||||||
|
* @param playbackParameters The playback parameters to set.
|
||||||
|
* @return The builder, for convenience.
|
||||||
|
* @see Player#setPlaybackParameters(PlaybackParameters)
|
||||||
|
*/
|
||||||
|
public Builder setPlaybackParameters(PlaybackParameters playbackParameters) {
|
||||||
|
return apply(new SetPlaybackParameters(tag, playbackParameters));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a stop action to be executed.
|
* Schedules a stop action to be executed.
|
||||||
*
|
*
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||||
import com.google.android.exoplayer2.source.SampleStream;
|
import com.google.android.exoplayer2.source.SampleStream;
|
||||||
@ -32,12 +34,30 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||||||
|
|
||||||
private final TrackGroupArray trackGroupArray;
|
private final TrackGroupArray trackGroupArray;
|
||||||
|
|
||||||
private boolean preparedPeriod;
|
@Nullable private Handler playerHandler;
|
||||||
|
@Nullable private Callback prepareCallback;
|
||||||
|
|
||||||
|
private boolean deferOnPrepared;
|
||||||
|
private boolean prepared;
|
||||||
private long seekOffsetUs;
|
private long seekOffsetUs;
|
||||||
private long discontinuityPositionUs;
|
private long discontinuityPositionUs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param trackGroupArray The track group array.
|
||||||
|
*/
|
||||||
public FakeMediaPeriod(TrackGroupArray trackGroupArray) {
|
public FakeMediaPeriod(TrackGroupArray trackGroupArray) {
|
||||||
|
this(trackGroupArray, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param trackGroupArray The track group array.
|
||||||
|
* @param deferOnPrepared Whether {@link MediaPeriod.Callback#onPrepared(MediaPeriod)} should be
|
||||||
|
* called only after {@link #setPreparationComplete()} has been called. If {@code false}
|
||||||
|
* preparation completes immediately.
|
||||||
|
*/
|
||||||
|
public FakeMediaPeriod(TrackGroupArray trackGroupArray, boolean deferOnPrepared) {
|
||||||
this.trackGroupArray = trackGroupArray;
|
this.trackGroupArray = trackGroupArray;
|
||||||
|
this.deferOnPrepared = deferOnPrepared;
|
||||||
discontinuityPositionUs = C.TIME_UNSET;
|
discontinuityPositionUs = C.TIME_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +71,22 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||||||
this.discontinuityPositionUs = discontinuityPositionUs;
|
this.discontinuityPositionUs = discontinuityPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the fake media period to complete preparation. May be called on any thread.
|
||||||
|
*/
|
||||||
|
public synchronized void setPreparationComplete() {
|
||||||
|
deferOnPrepared = false;
|
||||||
|
if (playerHandler != null && prepareCallback != null) {
|
||||||
|
playerHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
prepared = true;
|
||||||
|
prepareCallback.onPrepared(FakeMediaPeriod.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an offset to be applied to positions returned by {@link #seekToUs(long)}.
|
* Sets an offset to be applied to positions returned by {@link #seekToUs(long)}.
|
||||||
*
|
*
|
||||||
@ -61,31 +97,35 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void release() {
|
public void release() {
|
||||||
preparedPeriod = false;
|
prepared = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepare(Callback callback, long positionUs) {
|
public synchronized void prepare(Callback callback, long positionUs) {
|
||||||
Assert.assertFalse(preparedPeriod);
|
if (deferOnPrepared) {
|
||||||
preparedPeriod = true;
|
playerHandler = new Handler();
|
||||||
callback.onPrepared(this);
|
prepareCallback = callback;
|
||||||
|
} else {
|
||||||
|
prepared = true;
|
||||||
|
callback.onPrepared(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void maybeThrowPrepareError() throws IOException {
|
public void maybeThrowPrepareError() throws IOException {
|
||||||
Assert.assertTrue(preparedPeriod);
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TrackGroupArray getTrackGroups() {
|
public TrackGroupArray getTrackGroups() {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
return trackGroupArray;
|
return trackGroupArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
int rendererCount = selections.length;
|
int rendererCount = selections.length;
|
||||||
for (int i = 0; i < rendererCount; i++) {
|
for (int i = 0; i < rendererCount; i++) {
|
||||||
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
||||||
@ -113,7 +153,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long readDiscontinuity() {
|
public long readDiscontinuity() {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
long positionDiscontinuityUs = this.discontinuityPositionUs;
|
long positionDiscontinuityUs = this.discontinuityPositionUs;
|
||||||
this.discontinuityPositionUs = C.TIME_UNSET;
|
this.discontinuityPositionUs = C.TIME_UNSET;
|
||||||
return positionDiscontinuityUs;
|
return positionDiscontinuityUs;
|
||||||
@ -121,25 +161,25 @@ public class FakeMediaPeriod implements MediaPeriod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBufferedPositionUs() {
|
public long getBufferedPositionUs() {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
return C.TIME_END_OF_SOURCE;
|
return C.TIME_END_OF_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long seekToUs(long positionUs) {
|
public long seekToUs(long positionUs) {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
return positionUs + seekOffsetUs;
|
return positionUs + seekOffsetUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNextLoadPositionUs() {
|
public long getNextLoadPositionUs() {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
return C.TIME_END_OF_SOURCE;
|
return C.TIME_END_OF_SOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean continueLoading(long positionUs) {
|
public boolean continueLoading(long positionUs) {
|
||||||
Assert.assertTrue(preparedPeriod);
|
Assert.assertTrue(prepared);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user