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);
|
||||
}
|
||||
|
||||
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.view.Surface;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
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)}.
|
||||
*/
|
||||
|
@ -19,6 +19,7 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Surface;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
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.Seek;
|
||||
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.SetRepeatMode;
|
||||
import com.google.android.exoplayer2.testutil.Action.SetShuffleModeEnabled;
|
||||
@ -151,6 +153,17 @@ public final class ActionSchedule {
|
||||
.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.
|
||||
*
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
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.source.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
@ -32,12 +34,30 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
|
||||
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 discontinuityPositionUs;
|
||||
|
||||
/**
|
||||
* @param trackGroupArray The track group array.
|
||||
*/
|
||||
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.deferOnPrepared = deferOnPrepared;
|
||||
discontinuityPositionUs = C.TIME_UNSET;
|
||||
}
|
||||
|
||||
@ -51,6 +71,22 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
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)}.
|
||||
*
|
||||
@ -61,31 +97,35 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
}
|
||||
|
||||
public void release() {
|
||||
preparedPeriod = false;
|
||||
prepared = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(Callback callback, long positionUs) {
|
||||
Assert.assertFalse(preparedPeriod);
|
||||
preparedPeriod = true;
|
||||
public synchronized void prepare(Callback callback, long positionUs) {
|
||||
if (deferOnPrepared) {
|
||||
playerHandler = new Handler();
|
||||
prepareCallback = callback;
|
||||
} else {
|
||||
prepared = true;
|
||||
callback.onPrepared(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowPrepareError() throws IOException {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackGroupArray getTrackGroups() {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
return trackGroupArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
|
||||
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
int rendererCount = selections.length;
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
||||
@ -113,7 +153,7 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
|
||||
@Override
|
||||
public long readDiscontinuity() {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
long positionDiscontinuityUs = this.discontinuityPositionUs;
|
||||
this.discontinuityPositionUs = C.TIME_UNSET;
|
||||
return positionDiscontinuityUs;
|
||||
@ -121,25 +161,25 @@ public class FakeMediaPeriod implements MediaPeriod {
|
||||
|
||||
@Override
|
||||
public long getBufferedPositionUs() {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
return C.TIME_END_OF_SOURCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long seekToUs(long positionUs) {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
return positionUs + seekOffsetUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextLoadPositionUs() {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
return C.TIME_END_OF_SOURCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean continueLoading(long positionUs) {
|
||||
Assert.assertTrue(preparedPeriod);
|
||||
Assert.assertTrue(prepared);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user