mirror of
https://github.com/samsonjs/media.git
synced 2026-04-25 14:47:40 +00:00
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
This commit is contained in:
parent
3e41c0a1d2
commit
460449ce1e
4 changed files with 63 additions and 19 deletions
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,14 +119,6 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||
return sequenceableLoader.getBufferedPositionUs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long seekToUs(long positionUs) {
|
||||
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
|
||||
sampleStream.seekToUs(positionUs);
|
||||
}
|
||||
return super.seekToUs(positionUs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNextLoadPositionUs() {
|
||||
super.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<>(
|
||||
|
|
@ -161,6 +154,12 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||
eventDispatcher);
|
||||
}
|
||||
|
||||
@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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue