@Override public int getIndexOfPeriod(Object uid) { return timeline.getIndexOfPeriod(uid); }
@Override public int getIndexOfPeriod(Object uid) { return timeline.getIndexOfPeriod(DUMMY_ID.equals(uid) ? replacedId : uid); }
@Override public int getCurrentPeriodIndex() { if (shouldMaskPosition()) { return maskingPeriodIndex; } else { return playbackInfo.timeline.getIndexOfPeriod(playbackInfo.periodId.periodUid); } }
/** * Populates a {@link Period} with data for the period with the specified unique identifier. * * @param periodUid The unique identifier of the period. * @param period The {@link Period} to populate. Must not be null. * @return The populated {@link Period}, for convenience. */ public Period getPeriodByUid(Object periodUid, Period period) { return getPeriod(getIndexOfPeriod(periodUid), period, /* setIds= */ true); }
/** * Tries to find an existing media period info from the specified window index. Only returns a * non-null media period info if there is a unique, unambiguous match. */ public @Nullable MediaPeriodInfo tryResolveWindowIndex(int windowIndex) { MediaPeriodInfo match = null; for (int i = 0; i < mediaPeriodInfoQueue.size(); i++) { MediaPeriodInfo info = mediaPeriodInfoQueue.get(i); int periodIndex = timeline.getIndexOfPeriod(info.mediaPeriodId.periodUid); if (periodIndex != C.INDEX_UNSET && timeline.getPeriod(periodIndex, period).windowIndex == windowIndex) { if (match != null) { // Ambiguous match. return null; } match = info; } } return match; }
/** Updates the queue with a newly created media period. */ public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) { boolean isInTimeline = timeline.getIndexOfPeriod(mediaPeriodId.periodUid) != C.INDEX_UNSET; MediaPeriodInfo mediaPeriodInfo = new MediaPeriodInfo(mediaPeriodId, isInTimeline ? timeline : Timeline.EMPTY, windowIndex); mediaPeriodInfoQueue.add(mediaPeriodInfo); mediaPeriodIdToInfo.put(mediaPeriodId, mediaPeriodInfo); if (mediaPeriodInfoQueue.size() == 1 && !timeline.isEmpty()) { updateLastReportedPlayingMediaPeriod(); } }
private MediaPeriodInfo updateMediaPeriodInfoToNewTimeline( MediaPeriodInfo info, Timeline newTimeline) { int newPeriodIndex = newTimeline.getIndexOfPeriod(info.mediaPeriodId.periodUid); if (newPeriodIndex == C.INDEX_UNSET) { // Media period is not yet or no longer available in the new timeline. Keep it as it is. return info; } int newWindowIndex = newTimeline.getPeriod(newPeriodIndex, period).windowIndex; return new MediaPeriodInfo(info.mediaPeriodId, newTimeline, newWindowIndex); } }
/** * Given a period index into an old timeline, finds the first subsequent period that also exists * in a new timeline. The uid of this period in the new timeline is returned. * * @param oldPeriodUid The index of the period in the old timeline. * @param oldTimeline The old timeline. * @param newTimeline The new timeline. * @return The uid in the new timeline of the first subsequent period, or null if no such period * was found. */ private @Nullable Object resolveSubsequentPeriod( Object oldPeriodUid, Timeline oldTimeline, Timeline newTimeline) { int oldPeriodIndex = oldTimeline.getIndexOfPeriod(oldPeriodUid); int newPeriodIndex = C.INDEX_UNSET; int maxIterations = oldTimeline.getPeriodCount(); for (int i = 0; i < maxIterations && newPeriodIndex == C.INDEX_UNSET; i++) { oldPeriodIndex = oldTimeline.getNextPeriodIndex(oldPeriodIndex, period, window, repeatMode, shuffleModeEnabled); if (oldPeriodIndex == C.INDEX_UNSET) { // We've reached the end of the old timeline. break; } newPeriodIndex = newTimeline.getIndexOfPeriod(oldTimeline.getUidOfPeriod(oldPeriodIndex)); } return newPeriodIndex == C.INDEX_UNSET ? null : newTimeline.getUidOfPeriod(newPeriodIndex); }
private boolean isLastInTimeline(MediaPeriodId id, boolean isLastMediaPeriodInPeriod) { int periodIndex = timeline.getIndexOfPeriod(id.periodUid); int windowIndex = timeline.getPeriod(periodIndex, period).windowIndex; return !timeline.getWindow(windowIndex, window).isDynamic && timeline.isLastPeriod(periodIndex, period, window, repeatMode, shuffleModeEnabled) && isLastMediaPeriodInPeriod; } }
private String getEventTimeString(EventTime eventTime) { String windowPeriodString = "window=" + eventTime.windowIndex; if (eventTime.mediaPeriodId != null) { windowPeriodString += ", period=" + eventTime.timeline.getIndexOfPeriod(eventTime.mediaPeriodId.periodUid); if (eventTime.mediaPeriodId.isAd()) { windowPeriodString += ", adGroup=" + eventTime.mediaPeriodId.adGroupIndex; windowPeriodString += ", ad=" + eventTime.mediaPeriodId.adIndexInAdGroup; } } return getTimeString(eventTime.realtimeMs - startTimeMs) + ", " + getTimeString(eventTime.currentPlaybackPositionMs) + ", " + windowPeriodString; }
/** * Asserts that the media source reported completed loads via {@link * MediaSourceEventListener#onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} for * each specified media period id, and asserts that the associated window index matches the one in * the last known timeline returned from {@link #prepareSource()}, {@link #assertTimelineChange()} * or {@link #assertTimelineChangeBlocking()}. */ public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) { Timeline.Period period = new Timeline.Period(); HashSet<MediaPeriodId> expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds)); for (Pair<Integer, MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) { int windowIndex = windowIndexAndMediaPeriodId.first; MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second; if (expectedLoads.remove(mediaPeriodId)) { int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid); assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex); } } assertWithMessage("Not all expected media source loads have been completed.") .that(expectedLoads) .isEmpty(); }
@Override public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { assertThat(preparedSource).isTrue(); assertThat(releasedSource).isFalse(); int periodIndex = timeline.getIndexOfPeriod(id.periodUid); Assertions.checkArgument(periodIndex != C.INDEX_UNSET); Period period = timeline.getPeriod(periodIndex, new Period()); EventDispatcher eventDispatcher = createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs()); FakeMediaPeriod mediaPeriod = createFakeMediaPeriod(id, trackGroupArray, allocator, eventDispatcher, transferListener); activeMediaPeriods.add(mediaPeriod); createdMediaPeriods.add(id); return mediaPeriod; }
@Override public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { MediaPeriod[] periods = new MediaPeriod[mediaSources.length]; int periodIndex = timelines[0].getIndexOfPeriod(id.periodUid); for (int i = 0; i < periods.length; i++) { MediaPeriodId childMediaPeriodId = id.copyWithPeriodUid(timelines[i].getUidOfPeriod(periodIndex)); periods[i] = mediaSources[i].createPeriod(childMediaPeriodId, allocator, startPositionUs); } return new MergingMediaPeriod(compositeSequenceableLoaderFactory, periods); }
int windowIndex = timeline.getPeriodByUid(periodUid, period).windowIndex; if (oldFrontPeriodUid != null) { int oldFrontPeriodIndex = timeline.getIndexOfPeriod(oldFrontPeriodUid); if (oldFrontPeriodIndex != C.INDEX_UNSET) { int oldFrontWindowIndex = timeline.getPeriod(oldFrontPeriodIndex, period).windowIndex; int indexOfHolderInTimeline = timeline.getIndexOfPeriod(mediaPeriodHolder.uid); if (indexOfHolderInTimeline != C.INDEX_UNSET) { int holderWindowIndex = timeline.getPeriod(indexOfHolderInTimeline, period).windowIndex;
return true; int currentPeriodIndex = timeline.getIndexOfPeriod(lastValidPeriodHolder.uid); while (true) { int nextPeriodIndex = break; int nextPeriodHolderPeriodIndex = timeline.getIndexOfPeriod(lastValidPeriodHolder.next.uid); if (nextPeriodHolderPeriodIndex != nextPeriodIndex) { break;
private boolean resolvePendingMessagePosition(PendingMessageInfo pendingMessageInfo) { if (pendingMessageInfo.resolvedPeriodUid == null) { // Position is still unresolved. Try to find window in current timeline. Pair<Object, Long> periodPosition = resolveSeekPosition( new SeekPosition( pendingMessageInfo.message.getTimeline(), pendingMessageInfo.message.getWindowIndex(), C.msToUs(pendingMessageInfo.message.getPositionMs())), /* trySubsequentPeriods= */ false); if (periodPosition == null) { return false; } pendingMessageInfo.setResolvedPosition( playbackInfo.timeline.getIndexOfPeriod(periodPosition.first), periodPosition.second, periodPosition.first); } else { // Position has been resolved for a previous timeline. Try to find the updated period index. int index = playbackInfo.timeline.getIndexOfPeriod(pendingMessageInfo.resolvedPeriodUid); if (index == C.INDEX_UNSET) { return false; } pendingMessageInfo.resolvedPeriodIndex = index; } return true; }
@Override public final int getIndexOfPeriod(Object uid) { if (!(uid instanceof Pair)) { return C.INDEX_UNSET; } Object childUid = getChildTimelineUidFromConcatenatedUid(uid); Object periodUid = getChildPeriodUidFromConcatenatedUid(uid); int childIndex = getChildIndexByChildUid(childUid); if (childIndex == C.INDEX_UNSET) { return C.INDEX_UNSET; } int periodIndexInChild = getTimelineByChildIndex(childIndex).getIndexOfPeriod(periodUid); return periodIndexInChild == C.INDEX_UNSET ? C.INDEX_UNSET : getFirstPeriodIndexByChildIndex(childIndex) + periodIndexInChild; }
/** * Asserts that the media source reported completed loads via {@link * MediaSourceEventListener#onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} for * each specified media period id, and asserts that the associated window index matches the one in * the last known timeline returned from {@link #prepareSource()}, {@link #assertTimelineChange()} * or {@link #assertTimelineChangeBlocking()}. */ public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) { Timeline.Period period = new Timeline.Period(); HashSet<MediaPeriodId> expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds)); for (Pair<Integer, MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) { int windowIndex = windowIndexAndMediaPeriodId.first; MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second; if (expectedLoads.remove(mediaPeriodId)) { int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid); assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex); } } assertWithMessage("Not all expected media source loads have been completed.") .that(expectedLoads) .isEmpty(); }
@Override public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { assertThat(preparedSource).isTrue(); assertThat(releasedSource).isFalse(); int periodIndex = timeline.getIndexOfPeriod(id.periodUid); Assertions.checkArgument(periodIndex != C.INDEX_UNSET); Period period = timeline.getPeriod(periodIndex, new Period()); EventDispatcher eventDispatcher = createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs()); FakeMediaPeriod mediaPeriod = createFakeMediaPeriod(id, trackGroupArray, allocator, eventDispatcher, transferListener); activeMediaPeriods.add(mediaPeriod); createdMediaPeriods.add(id); return mediaPeriod; }
timeline.getPeriodPosition(window, period, windowIndex, windowPositionUs); maskingWindowPositionMs = C.usToMs(windowPositionUs); maskingPeriodIndex = timeline.getIndexOfPeriod(periodUidAndPosition.first);