use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.
the class ExoPlayerTest method seekDiscontinuityWithAdjustment.
@Test
public void seekDiscontinuityWithAdjustment() throws Exception {
FakeTimeline timeline = new FakeTimeline(1);
FakeMediaSource mediaSource = new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, allocator, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
false);
mediaPeriod.setSeekToUsOffset(10);
return mediaPeriod;
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_READY).seek(10).play().build();
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK, Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT);
}
use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.
the class ExoPlayerTest method internalDiscontinuityAtInitialPosition.
@Test
public void internalDiscontinuityAtInitialPosition() throws Exception {
FakeTimeline timeline = new FakeTimeline();
FakeMediaSource mediaSource = new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
FakeMediaPeriod mediaPeriod = new FakeMediaPeriod(trackGroupArray, allocator, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, mediaSourceEventDispatcher);
// Set a discontinuity at the position this period is supposed to start at anyway.
mediaPeriod.setDiscontinuityPositionUs(timeline.getWindow(/* windowIndex= */
0, new Window()).positionInFirstPeriodUs);
return mediaPeriod;
}
};
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(mediaSource).build().start().blockUntilEnded(TIMEOUT_MS);
// If the position is unchanged we do not expect the discontinuity to be reported externally.
testRunner.assertNoPositionDiscontinuities();
}
use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.
the class ConcatenatingMediaSource method releasePeriod.
@Override
public void releasePeriod(MediaPeriod mediaPeriod) {
MediaSourceHolder holder = Assertions.checkNotNull(mediaSourceByMediaPeriod.remove(mediaPeriod));
holder.mediaSource.releasePeriod(mediaPeriod);
holder.activeMediaPeriodIds.remove(((MaskingMediaPeriod) mediaPeriod).id);
if (!mediaSourceByMediaPeriod.isEmpty()) {
disableUnusedMediaSources();
}
maybeReleaseChildSource(holder);
}
use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.
the class AdsMediaSource method createPeriod.
@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
AdPlaybackState adPlaybackState = checkNotNull(this.adPlaybackState);
if (adPlaybackState.adGroupCount > 0 && id.isAd()) {
int adGroupIndex = id.adGroupIndex;
int adIndexInAdGroup = id.adIndexInAdGroup;
if (adMediaSourceHolders[adGroupIndex].length <= adIndexInAdGroup) {
int adCount = adIndexInAdGroup + 1;
adMediaSourceHolders[adGroupIndex] = Arrays.copyOf(adMediaSourceHolders[adGroupIndex], adCount);
}
@Nullable AdMediaSourceHolder adMediaSourceHolder = adMediaSourceHolders[adGroupIndex][adIndexInAdGroup];
if (adMediaSourceHolder == null) {
adMediaSourceHolder = new AdMediaSourceHolder(id);
adMediaSourceHolders[adGroupIndex][adIndexInAdGroup] = adMediaSourceHolder;
maybeUpdateAdMediaSources();
}
return adMediaSourceHolder.createMediaPeriod(id, allocator, startPositionUs);
} else {
MaskingMediaPeriod mediaPeriod = new MaskingMediaPeriod(id, allocator, startPositionUs);
mediaPeriod.setMediaSource(contentMediaSource);
mediaPeriod.createPeriod(id);
return mediaPeriod;
}
}
use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.
the class MergingMediaPeriod method selectTracks.
@Override
public long selectTracks(@NullableType ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
// Map each selection and stream onto a child period index.
int[] streamChildIndices = new int[selections.length];
int[] selectionChildIndices = new int[selections.length];
for (int i = 0; i < selections.length; i++) {
Integer streamChildIndex = streams[i] == null ? null : streamPeriodIndices.get(streams[i]);
streamChildIndices[i] = streamChildIndex == null ? C.INDEX_UNSET : streamChildIndex;
selectionChildIndices[i] = C.INDEX_UNSET;
if (selections[i] != null) {
TrackGroup mergedTrackGroup = selections[i].getTrackGroup();
TrackGroup childTrackGroup = checkNotNull(childTrackGroupByMergedTrackGroup.get(mergedTrackGroup));
for (int j = 0; j < periods.length; j++) {
if (periods[j].getTrackGroups().indexOf(childTrackGroup) != C.INDEX_UNSET) {
selectionChildIndices[i] = j;
break;
}
}
}
}
streamPeriodIndices.clear();
// Select tracks for each child, copying the resulting streams back into a new streams array.
@NullableType SampleStream[] newStreams = new SampleStream[selections.length];
@NullableType SampleStream[] childStreams = new SampleStream[selections.length];
@NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
ArrayList<MediaPeriod> enabledPeriodsList = new ArrayList<>(periods.length);
for (int i = 0; i < periods.length; i++) {
for (int j = 0; j < selections.length; j++) {
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
if (selectionChildIndices[j] == i) {
ExoTrackSelection mergedTrackSelection = checkNotNull(selections[j]);
TrackGroup mergedTrackGroup = mergedTrackSelection.getTrackGroup();
TrackGroup childTrackGroup = checkNotNull(childTrackGroupByMergedTrackGroup.get(mergedTrackGroup));
childSelections[j] = new ForwardingTrackSelection(mergedTrackSelection, childTrackGroup);
} else {
childSelections[j] = null;
}
}
long selectPositionUs = periods[i].selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, positionUs);
if (i == 0) {
positionUs = selectPositionUs;
} else if (selectPositionUs != positionUs) {
throw new IllegalStateException("Children enabled at different positions.");
}
boolean periodEnabled = false;
for (int j = 0; j < selections.length; j++) {
if (selectionChildIndices[j] == i) {
// Assert that the child provided a stream for the selection.
SampleStream childStream = Assertions.checkNotNull(childStreams[j]);
newStreams[j] = childStreams[j];
periodEnabled = true;
streamPeriodIndices.put(childStream, i);
} else if (streamChildIndices[j] == i) {
// Assert that the child cleared any previous stream.
Assertions.checkState(childStreams[j] == null);
}
}
if (periodEnabled) {
enabledPeriodsList.add(periods[i]);
}
}
// Copy the new streams back into the streams array.
System.arraycopy(newStreams, 0, streams, 0, newStreams.length);
// Update the local state.
enabledPeriods = enabledPeriodsList.toArray(new MediaPeriod[0]);
compositeSequenceableLoader = compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(enabledPeriods);
return positionUs;
}
Aggregations