Commit 460449ce by tonihei Committed by Oliver Woodman

Make seek in FakeMediaPeriod more realistic.

Currently seeks are basically ignored. However, it's more realistic to re-queue the
single sample if the seek is to position 0.

PiperOrigin-RevId: 290273564
parent 3e41c0a1
......@@ -435,9 +435,8 @@ public final class AnalyticsCollectorTest {
assertThat(listener.getEvents(EVENT_AUDIO_SESSION_ID)).containsExactly(period1Seq2);
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES))
.containsExactly(period0, period1Seq2, period1Seq2);
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(period0, period1Seq2);
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME))
.containsExactly(period0, period1Seq2);
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(period0, period0);
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(period0, period0);
listener.assertNoMoreEvents();
}
......
......@@ -120,14 +120,6 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
}
@Override
public long seekToUs(long positionUs) {
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
sampleStream.seekToUs(positionUs);
}
return super.seekToUs(positionUs);
}
@Override
public long getNextLoadPositionUs() {
super.getNextLoadPositionUs();
return sequenceableLoader.getNextLoadPositionUs();
......@@ -145,7 +137,8 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
}
@Override
protected SampleStream createSampleStream(TrackSelection trackSelection) {
protected SampleStream createSampleStream(
TrackSelection trackSelection, EventDispatcher eventDispatcher) {
FakeChunkSource chunkSource =
chunkSourceFactory.createChunkSource(trackSelection, durationUs, transferListener);
return new ChunkSampleStream<>(
......@@ -162,6 +155,12 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
}
@Override
@SuppressWarnings("unchecked")
protected void seekSampleStream(SampleStream sampleStream, long positionUs) {
((ChunkSampleStream<FakeChunkSource>) sampleStream).seekToUs(positionUs);
}
@Override
public void onContinueLoadingRequested(ChunkSampleStream<FakeChunkSource> source) {
callback.onContinueLoadingRequested(this);
}
......
......@@ -28,11 +28,14 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispat
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting
......@@ -44,7 +47,8 @@ public class FakeMediaPeriod implements MediaPeriod {
public static final DataSpec FAKE_DATA_SPEC = new DataSpec(Uri.parse("http://fake.uri"));
private final TrackGroupArray trackGroupArray;
protected final EventDispatcher eventDispatcher;
private final List<SampleStream> sampleStreams;
private final EventDispatcher eventDispatcher;
@Nullable private Handler playerHandler;
@Nullable private Callback prepareCallback;
......@@ -76,6 +80,7 @@ public class FakeMediaPeriod implements MediaPeriod {
this.eventDispatcher = eventDispatcher;
this.deferOnPrepared = deferOnPrepared;
discontinuityPositionUs = C.TIME_UNSET;
sampleStreams = new ArrayList<>();
eventDispatcher.mediaPeriodCreated();
}
......@@ -148,6 +153,7 @@ public class FakeMediaPeriod implements MediaPeriod {
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags,
SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
assertThat(prepared).isTrue();
sampleStreams.clear();
int rendererCount = selections.length;
for (int i = 0; i < rendererCount; i++) {
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
......@@ -161,7 +167,8 @@ public class FakeMediaPeriod implements MediaPeriod {
int indexInTrackGroup = selection.getIndexInTrackGroup(selection.getSelectedIndex());
assertThat(indexInTrackGroup).isAtLeast(0);
assertThat(indexInTrackGroup).isLessThan(trackGroup.length);
streams[i] = createSampleStream(selection);
streams[i] = createSampleStream(selection, eventDispatcher);
sampleStreams.add(streams[i]);
streamResetFlags[i] = true;
}
}
......@@ -199,12 +206,16 @@ public class FakeMediaPeriod implements MediaPeriod {
@Override
public long seekToUs(long positionUs) {
assertThat(prepared).isTrue();
return positionUs + seekOffsetUs;
long seekPositionUs = positionUs + seekOffsetUs;
for (SampleStream sampleStream : sampleStreams) {
seekSampleStream(sampleStream, seekPositionUs);
}
return seekPositionUs;
}
@Override
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
return positionUs;
return positionUs + seekOffsetUs;
}
@Override
......@@ -223,11 +234,35 @@ public class FakeMediaPeriod implements MediaPeriod {
return false;
}
protected SampleStream createSampleStream(TrackSelection selection) {
/**
* Creates a sample stream for the provided selection.
*
* @param selection A selection of tracks.
* @param eventDispatcher A dispatcher for events that should be used by the sample stream.
* @return A {@link SampleStream} for this selection.
*/
protected SampleStream createSampleStream(
TrackSelection selection, EventDispatcher eventDispatcher) {
return new FakeSampleStream(
selection.getSelectedFormat(), eventDispatcher, /* shouldOutputSample= */ true);
}
/**
* Seeks inside the given sample stream.
*
* @param sampleStream A sample stream that was created by a call to {@link
* #createSampleStream(TrackSelection, EventDispatcher)}.
* @param positionUs The position to seek to, in microseconds.
*/
protected void seekSampleStream(SampleStream sampleStream, long positionUs) {
if (positionUs == 0) {
// When seeking back to 0, queue our single sample at time 0 again.
((FakeSampleStream) sampleStream)
.resetSampleStreamItems(
Collections.singletonList(new FakeSampleStreamItem(new byte[] {0})), /* timeUs= */ 0);
}
}
private void finishPreparation() {
prepared = true;
prepareCallback.onPrepared(this);
......
......@@ -24,7 +24,6 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispat
import com.google.android.exoplayer2.source.SampleStream;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
......@@ -96,7 +95,7 @@ public final class FakeSampleStream implements SampleStream {
format,
eventDispatcher,
shouldOutputSample
? Arrays.asList(new FakeSampleStreamItem(new byte[] {0}))
? Collections.singletonList(new FakeSampleStreamItem(new byte[] {0}))
: Collections.emptyList(),
/* timeUsIncrement= */ 0);
}
......@@ -122,6 +121,18 @@ public final class FakeSampleStream implements SampleStream {
this.timeUsIncrement = timeUsIncrement;
}
/**
* Resets the samples provided by this sample stream to the provided list.
*
* @param fakeSampleStreamItems The list of {@link FakeSampleStreamItem items} to provide.
* @param timeUs The time at which samples will start being output, in microseconds.
*/
public void resetSampleStreamItems(List<FakeSampleStreamItem> fakeSampleStreamItems, int timeUs) {
this.fakeSampleStreamItems.clear();
this.fakeSampleStreamItems.addAll(fakeSampleStreamItems);
this.timeUs = timeUs;
}
@Override
public boolean isReady() {
return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment