mirror of
https://github.com/androidx/media.git
synced 2025-05-05 22:50:57 +08:00
Make FakeMediaPeriod and FakeAdaptiveMediaPeriod independent.
The adaptive period currently extends the base (non-adaptive) period to share common MediaPeriod boilerplate code. However, once we start using the real SampleQueue in FakeMediaPeriod the common code becomes even less and the overhead to support multiple stream implementation from the base class is no longer worth it. Thus, this change removes the class hierarchy and copies the common parts to FakeAdaptiveMediaPeriod. PiperOrigin-RevId: 347990468
This commit is contained in:
parent
8a560429e9
commit
43886491f6
@ -652,7 +652,7 @@ public final class ExoPlayerTest {
|
|||||||
FakeMediaSource mediaSource =
|
FakeMediaSource mediaSource =
|
||||||
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -696,7 +696,7 @@ public final class ExoPlayerTest {
|
|||||||
FakeMediaSource mediaSource =
|
FakeMediaSource mediaSource =
|
||||||
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -728,7 +728,7 @@ public final class ExoPlayerTest {
|
|||||||
FakeMediaSource mediaSource =
|
FakeMediaSource mediaSource =
|
||||||
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -974,7 +974,7 @@ public final class ExoPlayerTest {
|
|||||||
MediaSource mediaSource =
|
MediaSource mediaSource =
|
||||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -1027,7 +1027,7 @@ public final class ExoPlayerTest {
|
|||||||
FakeMediaSource mediaSource =
|
FakeMediaSource mediaSource =
|
||||||
new FakeMediaSource(/* timeline= */ null, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(/* timeline= */ null, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -4284,7 +4284,7 @@ public final class ExoPlayerTest {
|
|||||||
AdPlaybackState.NONE));
|
AdPlaybackState.NONE));
|
||||||
return new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
return new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -4659,7 +4659,7 @@ public final class ExoPlayerTest {
|
|||||||
MediaSource mediaSourceWithLoadInProgress =
|
MediaSource mediaSourceWithLoadInProgress =
|
||||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -7210,7 +7210,7 @@ public final class ExoPlayerTest {
|
|||||||
MediaSource continuouslyAllocatingMediaSource =
|
MediaSource continuouslyAllocatingMediaSource =
|
||||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -7287,7 +7287,7 @@ public final class ExoPlayerTest {
|
|||||||
MediaSource largeBufferAllocatingMediaSource =
|
MediaSource largeBufferAllocatingMediaSource =
|
||||||
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -8023,7 +8023,7 @@ public final class ExoPlayerTest {
|
|||||||
player.addMediaSource(
|
player.addMediaSource(
|
||||||
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -8068,7 +8068,7 @@ public final class ExoPlayerTest {
|
|||||||
player.addMediaSource(
|
player.addMediaSource(
|
||||||
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
|
@ -32,7 +32,6 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|||||||
import com.google.android.exoplayer2.source.ClippingMediaSource.IllegalClippingException;
|
import com.google.android.exoplayer2.source.ClippingMediaSource.IllegalClippingException;
|
||||||
import com.google.android.exoplayer2.source.MaskingMediaSource.PlaceholderTimeline;
|
import com.google.android.exoplayer2.source.MaskingMediaSource.PlaceholderTimeline;
|
||||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||||
import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
|
|
||||||
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
||||||
@ -562,7 +561,7 @@ public final class ClippingMediaSourceTest {
|
|||||||
FakeMediaSource fakeMediaSource =
|
FakeMediaSource fakeMediaSource =
|
||||||
new FakeMediaSource(timeline) {
|
new FakeMediaSource(timeline) {
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -579,7 +578,7 @@ public final class ClippingMediaSourceTest {
|
|||||||
/* trackSelectionData= */ null,
|
/* trackSelectionData= */ null,
|
||||||
C.usToMs(eventStartUs),
|
C.usToMs(eventStartUs),
|
||||||
C.usToMs(eventEndUs)));
|
C.usToMs(eventEndUs)));
|
||||||
return super.createFakeMediaPeriod(
|
return super.createMediaPeriod(
|
||||||
id,
|
id,
|
||||||
trackGroupArray,
|
trackGroupArray,
|
||||||
allocator,
|
allocator,
|
||||||
|
@ -15,42 +15,58 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.SystemClock;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.SeekParameters;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
import com.google.android.exoplayer2.source.CompositeSequenceableLoader;
|
import com.google.android.exoplayer2.source.CompositeSequenceableLoader;
|
||||||
|
import com.google.android.exoplayer2.source.LoadEventInfo;
|
||||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||||
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
||||||
import com.google.android.exoplayer2.source.SampleStream;
|
import com.google.android.exoplayer2.source.SampleStream;
|
||||||
import com.google.android.exoplayer2.source.SequenceableLoader;
|
import com.google.android.exoplayer2.source.SequenceableLoader;
|
||||||
|
import com.google.android.exoplayer2.source.TrackGroup;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
|
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.upstream.Allocator;
|
import com.google.android.exoplayer2.upstream.Allocator;
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
||||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.util.ArrayList;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.util.List;
|
import com.google.common.collect.Sets;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting a
|
* Fake {@link MediaPeriod} that provides tracks from the given {@link TrackGroupArray}. Selecting a
|
||||||
* track will give the player a {@link ChunkSampleStream}.
|
* track will give the player a {@link ChunkSampleStream}.
|
||||||
*/
|
*/
|
||||||
public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
public class FakeAdaptiveMediaPeriod
|
||||||
implements SequenceableLoader.Callback<ChunkSampleStream<FakeChunkSource>> {
|
implements MediaPeriod, SequenceableLoader.Callback<ChunkSampleStream<FakeChunkSource>> {
|
||||||
|
|
||||||
private final Allocator allocator;
|
private static final DataSpec FAKE_DATA_SPEC = new DataSpec(Uri.parse("http://fake.test"));
|
||||||
|
|
||||||
|
private final TrackGroupArray trackGroupArray;
|
||||||
|
private final MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher;
|
||||||
|
private final long fakePreparationLoadTaskId;
|
||||||
private final FakeChunkSource.Factory chunkSourceFactory;
|
private final FakeChunkSource.Factory chunkSourceFactory;
|
||||||
@Nullable private final TransferListener transferListener;
|
private final Allocator allocator;
|
||||||
private final long durationUs;
|
private final long durationUs;
|
||||||
|
@Nullable private final TransferListener transferListener;
|
||||||
|
private final Set<ChunkSampleStream<FakeChunkSource>> sampleStreams;
|
||||||
|
|
||||||
private @MonotonicNonNull Callback callback;
|
@Nullable private Callback callback;
|
||||||
private ChunkSampleStream<FakeChunkSource>[] sampleStreams;
|
private boolean prepared;
|
||||||
private SequenceableLoader sequenceableLoader;
|
private SequenceableLoader sequenceableLoader;
|
||||||
|
|
||||||
public FakeAdaptiveMediaPeriod(
|
public FakeAdaptiveMediaPeriod(
|
||||||
@ -60,54 +76,121 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||||||
FakeChunkSource.Factory chunkSourceFactory,
|
FakeChunkSource.Factory chunkSourceFactory,
|
||||||
long durationUs,
|
long durationUs,
|
||||||
@Nullable TransferListener transferListener) {
|
@Nullable TransferListener transferListener) {
|
||||||
super(
|
this.trackGroupArray = trackGroupArray;
|
||||||
trackGroupArray,
|
this.mediaSourceEventDispatcher = mediaSourceEventDispatcher;
|
||||||
/* trackDataFactory= */ (unusedFormat, unusedMediaPeriodId) -> {
|
|
||||||
throw new RuntimeException("unused track data");
|
|
||||||
},
|
|
||||||
mediaSourceEventDispatcher,
|
|
||||||
DrmSessionManager.DUMMY,
|
|
||||||
new DrmSessionEventListener.EventDispatcher(),
|
|
||||||
/* deferOnPrepared= */ false);
|
|
||||||
this.allocator = allocator;
|
|
||||||
this.chunkSourceFactory = chunkSourceFactory;
|
this.chunkSourceFactory = chunkSourceFactory;
|
||||||
this.transferListener = transferListener;
|
this.allocator = allocator;
|
||||||
this.durationUs = durationUs;
|
this.durationUs = durationUs;
|
||||||
this.sampleStreams = newSampleStreamArray(0);
|
this.transferListener = transferListener;
|
||||||
this.sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
sampleStreams = Sets.newIdentityHashSet();
|
||||||
|
sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
||||||
|
fakePreparationLoadTaskId = LoadEventInfo.getNewId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Releases the media period. */
|
||||||
|
public void release() {
|
||||||
|
prepared = false;
|
||||||
|
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
|
||||||
|
sampleStream.release();
|
||||||
|
}
|
||||||
|
sampleStreams.clear();
|
||||||
|
sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void prepare(Callback callback, long positionUs) {
|
public void prepare(Callback callback, long positionUs) {
|
||||||
super.prepare(callback, positionUs);
|
mediaSourceEventDispatcher.loadStarted(
|
||||||
|
new LoadEventInfo(fakePreparationLoadTaskId, FAKE_DATA_SPEC, SystemClock.elapsedRealtime()),
|
||||||
|
C.DATA_TYPE_MEDIA,
|
||||||
|
C.TRACK_TYPE_UNKNOWN,
|
||||||
|
/* trackFormat= */ null,
|
||||||
|
C.SELECTION_REASON_UNKNOWN,
|
||||||
|
/* trackSelectionData= */ null,
|
||||||
|
/* mediaStartTimeUs= */ 0,
|
||||||
|
/* mediaEndTimeUs = */ C.TIME_UNSET);
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
prepared = true;
|
||||||
|
Util.castNonNull(this.callback).onPrepared(this);
|
||||||
|
mediaSourceEventDispatcher.loadCompleted(
|
||||||
|
new LoadEventInfo(
|
||||||
|
fakePreparationLoadTaskId,
|
||||||
|
FAKE_DATA_SPEC,
|
||||||
|
FAKE_DATA_SPEC.uri,
|
||||||
|
/* responseHeaders= */ ImmutableMap.of(),
|
||||||
|
SystemClock.elapsedRealtime(),
|
||||||
|
/* loadDurationMs= */ 0,
|
||||||
|
/* bytesLoaded= */ 100),
|
||||||
|
C.DATA_TYPE_MEDIA,
|
||||||
|
C.TRACK_TYPE_UNKNOWN,
|
||||||
|
/* trackFormat= */ null,
|
||||||
|
C.SELECTION_REASON_UNKNOWN,
|
||||||
|
/* trackSelectionData= */ null,
|
||||||
|
/* mediaStartTimeUs= */ 0,
|
||||||
|
/* mediaEndTimeUs = */ C.TIME_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
public void maybeThrowPrepareError() throws IOException {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrackGroupArray getTrackGroups() {
|
||||||
|
assertThat(prepared).isTrue();
|
||||||
|
return trackGroupArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"}) // Casting sample streams created by this class.
|
||||||
|
@Override
|
||||||
public long selectTracks(
|
public long selectTracks(
|
||||||
@NullableType TrackSelection[] selections,
|
@NullableType TrackSelection[] selections,
|
||||||
boolean[] mayRetainStreamFlags,
|
boolean[] mayRetainStreamFlags,
|
||||||
@NullableType SampleStream[] streams,
|
@NullableType SampleStream[] streams,
|
||||||
boolean[] streamResetFlags,
|
boolean[] streamResetFlags,
|
||||||
long positionUs) {
|
long positionUs) {
|
||||||
long returnPositionUs = super.selectTracks(selections, mayRetainStreamFlags, streams,
|
assertThat(prepared).isTrue();
|
||||||
streamResetFlags, positionUs);
|
int rendererCount = selections.length;
|
||||||
List<ChunkSampleStream<FakeChunkSource>> validStreams = new ArrayList<>();
|
for (int i = 0; i < rendererCount; i++) {
|
||||||
for (SampleStream stream : streams) {
|
if (streams[i] != null && (selections[i] == null || !mayRetainStreamFlags[i])) {
|
||||||
if (stream != null) {
|
((ChunkSampleStream<FakeChunkSource>) streams[i]).release();
|
||||||
validStreams.add((ChunkSampleStream<FakeChunkSource>) stream);
|
sampleStreams.remove(streams[i]);
|
||||||
|
streams[i] = null;
|
||||||
|
}
|
||||||
|
if (streams[i] == null && selections[i] != null) {
|
||||||
|
TrackSelection selection = selections[i];
|
||||||
|
assertThat(selection.length()).isAtLeast(1);
|
||||||
|
TrackGroup trackGroup = selection.getTrackGroup();
|
||||||
|
assertThat(trackGroupArray.indexOf(trackGroup)).isNotEqualTo(C.INDEX_UNSET);
|
||||||
|
int indexInTrackGroup = selection.getIndexInTrackGroup(selection.getSelectedIndex());
|
||||||
|
assertThat(indexInTrackGroup).isAtLeast(0);
|
||||||
|
assertThat(indexInTrackGroup).isLessThan(trackGroup.length);
|
||||||
|
FakeChunkSource chunkSource =
|
||||||
|
chunkSourceFactory.createChunkSource(selection, durationUs, transferListener);
|
||||||
|
ChunkSampleStream<FakeChunkSource> sampleStream =
|
||||||
|
new ChunkSampleStream<>(
|
||||||
|
MimeTypes.getTrackType(selection.getSelectedFormat().sampleMimeType),
|
||||||
|
/* embeddedTrackTypes= */ null,
|
||||||
|
/* embeddedTrackFormats= */ null,
|
||||||
|
chunkSource,
|
||||||
|
/* callback= */ this,
|
||||||
|
allocator,
|
||||||
|
positionUs,
|
||||||
|
DrmSessionManager.DUMMY,
|
||||||
|
new DrmSessionEventListener.EventDispatcher(),
|
||||||
|
new DefaultLoadErrorHandlingPolicy(/* minimumLoadableRetryCount= */ 3),
|
||||||
|
mediaSourceEventDispatcher);
|
||||||
|
streams[i] = sampleStream;
|
||||||
|
sampleStreams.add(sampleStream);
|
||||||
|
streamResetFlags[i] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sampleStreams = newSampleStreamArray(validStreams.size());
|
sequenceableLoader =
|
||||||
Util.nullSafeListToArray(validStreams, sampleStreams);
|
new CompositeSequenceableLoader(sampleStreams.toArray(new ChunkSampleStream[0]));
|
||||||
this.sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
return seekToUs(positionUs);
|
||||||
return returnPositionUs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void discardBuffer(long positionUs, boolean toKeyframe) {
|
public void discardBuffer(long positionUs, boolean toKeyframe) {
|
||||||
super.discardBuffer(positionUs, toKeyframe);
|
|
||||||
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
|
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
|
||||||
sampleStream.discardBuffer(positionUs, toKeyframe);
|
sampleStream.discardBuffer(positionUs, toKeyframe);
|
||||||
}
|
}
|
||||||
@ -115,26 +198,45 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reevaluateBuffer(long positionUs) {
|
public void reevaluateBuffer(long positionUs) {
|
||||||
super.reevaluateBuffer(positionUs);
|
|
||||||
sequenceableLoader.reevaluateBuffer(positionUs);
|
sequenceableLoader.reevaluateBuffer(positionUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long readDiscontinuity() {
|
||||||
|
assertThat(prepared).isTrue();
|
||||||
|
return C.TIME_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBufferedPositionUs() {
|
public long getBufferedPositionUs() {
|
||||||
super.getBufferedPositionUs();
|
assertThat(prepared).isTrue();
|
||||||
return sequenceableLoader.getBufferedPositionUs();
|
return sequenceableLoader.getBufferedPositionUs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long seekToUs(long positionUs) {
|
||||||
|
assertThat(prepared).isTrue();
|
||||||
|
for (ChunkSampleStream<FakeChunkSource> sampleStream : sampleStreams) {
|
||||||
|
sampleStream.seekToUs(positionUs);
|
||||||
|
}
|
||||||
|
return positionUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getAdjustedSeekPositionUs(long positionUs, SeekParameters seekParameters) {
|
||||||
|
return positionUs;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNextLoadPositionUs() {
|
public long getNextLoadPositionUs() {
|
||||||
super.getNextLoadPositionUs();
|
assertThat(prepared).isTrue();
|
||||||
return sequenceableLoader.getNextLoadPositionUs();
|
return sequenceableLoader.getNextLoadPositionUs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean continueLoading(long positionUs) {
|
public boolean continueLoading(long positionUs) {
|
||||||
super.continueLoading(positionUs);
|
sequenceableLoader.continueLoading(positionUs);
|
||||||
return sequenceableLoader.continueLoading(positionUs);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -142,51 +244,8 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod
|
|||||||
return sequenceableLoader.isLoading();
|
return sequenceableLoader.isLoading();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final SampleStream createSampleStream(
|
|
||||||
long positionUs,
|
|
||||||
TrackSelection trackSelection,
|
|
||||||
MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher,
|
|
||||||
DrmSessionManager drmSessionManager,
|
|
||||||
DrmSessionEventListener.EventDispatcher drmEventDispatcher) {
|
|
||||||
FakeChunkSource chunkSource =
|
|
||||||
chunkSourceFactory.createChunkSource(trackSelection, durationUs, transferListener);
|
|
||||||
return new ChunkSampleStream<>(
|
|
||||||
MimeTypes.getTrackType(trackSelection.getSelectedFormat().sampleMimeType),
|
|
||||||
/* embeddedTrackTypes= */ null,
|
|
||||||
/* embeddedTrackFormats= */ null,
|
|
||||||
chunkSource,
|
|
||||||
/* callback= */ this,
|
|
||||||
allocator,
|
|
||||||
positionUs,
|
|
||||||
/* drmSessionManager= */ DrmSessionManager.getDummyDrmSessionManager(),
|
|
||||||
drmEventDispatcher,
|
|
||||||
new DefaultLoadErrorHandlingPolicy(/* minimumLoadableRetryCount= */ 3),
|
|
||||||
mediaSourceEventDispatcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
// sampleStream is created by createSampleStream() above.
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected void seekSampleStream(SampleStream sampleStream, long positionUs) {
|
|
||||||
((ChunkSampleStream<FakeChunkSource>) sampleStream).seekToUs(positionUs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
// sampleStream is created by createSampleStream() above.
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
protected void releaseSampleStream(SampleStream sampleStream) {
|
|
||||||
((ChunkSampleStream<FakeChunkSource>) sampleStream).release();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onContinueLoadingRequested(ChunkSampleStream<FakeChunkSource> source) {
|
public void onContinueLoadingRequested(ChunkSampleStream<FakeChunkSource> source) {
|
||||||
Assertions.checkStateNotNull(callback).onContinueLoadingRequested(this);
|
Assertions.checkStateNotNull(callback).onContinueLoadingRequested(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We won't assign the array to a variable that erases the generic type, and then write into it.
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
private static ChunkSampleStream<FakeChunkSource>[] newSampleStreamArray(int length) {
|
|
||||||
return new ChunkSampleStream[length];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import com.google.android.exoplayer2.Timeline;
|
|||||||
import com.google.android.exoplayer2.Timeline.Period;
|
import com.google.android.exoplayer2.Timeline.Period;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
import com.google.android.exoplayer2.source.MediaSourceEventListener;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
@ -50,7 +51,7 @@ public class FakeAdaptiveMediaSource extends FakeMediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -68,4 +69,8 @@ public class FakeAdaptiveMediaSource extends FakeMediaSource {
|
|||||||
transferListener);
|
transferListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseMediaPeriod(MediaPeriod mediaPeriod) {
|
||||||
|
((FakeAdaptiveMediaPeriod) mediaPeriod).release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
|
|
||||||
private final TrackGroupArray trackGroupArray;
|
private final TrackGroupArray trackGroupArray;
|
||||||
@Nullable private final FakeMediaPeriod.TrackDataFactory trackDataFactory;
|
@Nullable private final FakeMediaPeriod.TrackDataFactory trackDataFactory;
|
||||||
private final ArrayList<FakeMediaPeriod> activeMediaPeriods;
|
private final ArrayList<MediaPeriod> activeMediaPeriods;
|
||||||
private final ArrayList<MediaPeriodId> createdMediaPeriods;
|
private final ArrayList<MediaPeriodId> createdMediaPeriods;
|
||||||
private final DrmSessionManager drmSessionManager;
|
private final DrmSessionManager drmSessionManager;
|
||||||
|
|
||||||
@ -225,8 +225,8 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs());
|
createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs());
|
||||||
DrmSessionEventListener.EventDispatcher drmEventDispatcher =
|
DrmSessionEventListener.EventDispatcher drmEventDispatcher =
|
||||||
createDrmEventDispatcher(period.windowIndex, id);
|
createDrmEventDispatcher(period.windowIndex, id);
|
||||||
FakeMediaPeriod mediaPeriod =
|
MediaPeriod mediaPeriod =
|
||||||
createFakeMediaPeriod(
|
createMediaPeriod(
|
||||||
id,
|
id,
|
||||||
trackGroupArray,
|
trackGroupArray,
|
||||||
allocator,
|
allocator,
|
||||||
@ -243,9 +243,8 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
public void releasePeriod(MediaPeriod mediaPeriod) {
|
public void releasePeriod(MediaPeriod mediaPeriod) {
|
||||||
assertThat(preparedSource).isTrue();
|
assertThat(preparedSource).isTrue();
|
||||||
assertThat(releasedSource).isFalse();
|
assertThat(releasedSource).isFalse();
|
||||||
FakeMediaPeriod fakeMediaPeriod = (FakeMediaPeriod) mediaPeriod;
|
assertThat(activeMediaPeriods.remove(mediaPeriod)).isTrue();
|
||||||
assertThat(activeMediaPeriods.remove(fakeMediaPeriod)).isTrue();
|
releaseMediaPeriod(mediaPeriod);
|
||||||
fakeMediaPeriod.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -317,7 +316,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link FakeMediaPeriod} for this media source.
|
* Creates a {@link MediaPeriod} for this media source.
|
||||||
*
|
*
|
||||||
* @param id The identifier of the period.
|
* @param id The identifier of the period.
|
||||||
* @param trackGroupArray The {@link TrackGroupArray} supported by the media period.
|
* @param trackGroupArray The {@link TrackGroupArray} supported by the media period.
|
||||||
@ -331,7 +330,7 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
* @return A new {@link FakeMediaPeriod}.
|
* @return A new {@link FakeMediaPeriod}.
|
||||||
*/
|
*/
|
||||||
@RequiresNonNull("this.timeline")
|
@RequiresNonNull("this.timeline")
|
||||||
protected FakeMediaPeriod createFakeMediaPeriod(
|
protected MediaPeriod createMediaPeriod(
|
||||||
MediaPeriodId id,
|
MediaPeriodId id,
|
||||||
TrackGroupArray trackGroupArray,
|
TrackGroupArray trackGroupArray,
|
||||||
Allocator allocator,
|
Allocator allocator,
|
||||||
@ -353,6 +352,15 @@ public class FakeMediaSource extends BaseMediaSource {
|
|||||||
/* deferOnPrepared= */ false);
|
/* deferOnPrepared= */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a media period created by {@link #createMediaPeriod(MediaPeriodId, TrackGroupArray,
|
||||||
|
* Allocator, MediaSourceEventListener.EventDispatcher, DrmSessionManager,
|
||||||
|
* DrmSessionEventListener.EventDispatcher, TransferListener)}.
|
||||||
|
*/
|
||||||
|
protected void releaseMediaPeriod(MediaPeriod mediaPeriod) {
|
||||||
|
((FakeMediaPeriod) mediaPeriod).release();
|
||||||
|
}
|
||||||
|
|
||||||
private void finishSourcePreparation(boolean sendManifestLoadEvents) {
|
private void finishSourcePreparation(boolean sendManifestLoadEvents) {
|
||||||
refreshSourceInfo(Assertions.checkStateNotNull(timeline));
|
refreshSourceInfo(Assertions.checkStateNotNull(timeline));
|
||||||
if (!timeline.isEmpty() && sendManifestLoadEvents) {
|
if (!timeline.isEmpty() && sendManifestLoadEvents) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user