private void handlePeriodPrepared(MediaPeriod mediaPeriod) throws ExoPlaybackException { if (!queue.isLoading(mediaPeriod)) { // Stale event. return; } MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); loadingPeriodHolder.handlePrepared(mediaClock.getPlaybackParameters().speed); updateLoadControlTrackSelection( loadingPeriodHolder.trackGroups, loadingPeriodHolder.trackSelectorResult); if (!queue.hasPlayingPeriod()) { // This is the first prepared period, so start playing it. MediaPeriodHolder playingPeriodHolder = queue.advancePlayingPeriod(); resetRendererPosition(playingPeriodHolder.info.startPositionUs); updatePlayingPeriodRenderers(/* oldPlayingPeriodHolder= */ null); } maybeContinueLoading(); }
MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { if (previousPeriodHolder == null) { periodHolder.info = getUpdatedMediaPeriodInfo(periodHolder.info); } else { || !periodHolder.uid.equals(timeline.getUidOfPeriod(periodIndex))) { return !removeAfter(previousPeriodHolder); getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (periodInfo == null) { return !removeAfter(previousPeriodHolder); periodHolder.info = getUpdatedMediaPeriodInfo(periodHolder.info); if (!canKeepMediaPeriodHolder(periodHolder, periodInfo)) { return !removeAfter(previousPeriodHolder);
private void maybeUpdateLoadingPeriod() throws IOException { queue.reevaluateBuffer(rendererPositionUs); if (queue.shouldLoadNextMediaPeriod()) { MediaPeriodInfo info = queue.getNextMediaPeriodInfo(rendererPositionUs, playbackInfo); if (info == null) { maybeThrowSourceInfoRefreshError(); } else { MediaPeriod mediaPeriod = queue.enqueueNextMediaPeriod( rendererCapabilities, trackSelector, loadControl.getAllocator(), mediaSource, info); mediaPeriod.prepare(this, info.startPositionUs); setIsLoading(true); handleLoadingMediaPeriodChanged(/* loadingTrackSelectionChanged= */ false); } } }
/** * Returns the {@link MediaPeriodInfo} for the next media period to load. * * @param rendererPositionUs The current renderer position. * @param playbackInfo The current playback information. * @return The {@link MediaPeriodInfo} for the next media period to load, or {@code null} if not * yet known. */ public @Nullable MediaPeriodInfo getNextMediaPeriodInfo( long rendererPositionUs, PlaybackInfo playbackInfo) { return loading == null ? getFirstMediaPeriodInfo(playbackInfo) : getFollowingMediaPeriodInfo(loading, rendererPositionUs); }
/** * Clears the queue. * * @param keepFrontPeriodUid Whether the queue should keep the id of the media period in the front * of queue (typically the playing one) for later reuse. */ public void clear(boolean keepFrontPeriodUid) { MediaPeriodHolder front = getFrontPeriod(); if (front != null) { oldFrontPeriodUid = keepFrontPeriodUid ? front.uid : null; oldFrontPeriodWindowSequenceNumber = front.info.id.windowSequenceNumber; front.release(); removeAfter(front); } else if (!keepFrontPeriodUid) { oldFrontPeriodUid = null; } playing = null; loading = null; reading = null; length = 0; }
private void maybeThrowPeriodPrepareError() throws IOException { MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod(); if (loadingPeriodHolder != null && !loadingPeriodHolder.prepared && (readingPeriodHolder == null || readingPeriodHolder.next == loadingPeriodHolder)) { for (Renderer renderer : enabledRenderers) { if (!renderer.hasReadStreamToEnd()) { return; } } loadingPeriodHolder.mediaPeriod.maybeThrowPrepareError(); } }
MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); if (loadingPeriodHolder == null || loadingPeriodHolder.isFullyBuffered()) { setIsLoading(false); if (!queue.hasPlayingPeriod()) { MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod(); MediaPeriodHolder readingPeriodHolder = queue.getReadingPeriod(); boolean advancedPlayingPeriod = false; while (playWhenReady : Player.DISCONTINUITY_REASON_AD_INSERTION; MediaPeriodHolder oldPlayingPeriodHolder = playingPeriodHolder; playingPeriodHolder = queue.advancePlayingPeriod(); updatePlayingPeriodRenderers(oldPlayingPeriodHolder); playbackInfo = readingPeriodHolder = queue.advanceReadingPeriod(); TrackSelectorResult newTrackSelectorResult = readingPeriodHolder.trackSelectorResult;
Timeline timeline = sourceRefreshInfo.timeline; Object manifest = sourceRefreshInfo.manifest; queue.setTimeline(timeline); playbackInfo = playbackInfo.copyWithTimeline(timeline, manifest); resolvePendingMessagePositions(); Object periodUid = periodPosition.first; long positionUs = periodPosition.second; MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, positionUs); playbackInfo = playbackInfo.resetToNewPosition( Object periodUid = defaultPosition.first; long startPositionUs = defaultPosition.second; MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, startPositionUs); playbackInfo = playbackInfo.resetToNewPosition( Object periodUid = defaultPosition.first; long startPositionUs = defaultPosition.second; MediaPeriodId periodId = queue.resolveMediaPeriodIdForAds(periodUid, startPositionUs); playbackInfo = playbackInfo.resetToNewPosition( MediaPeriodHolder periodHolder = queue.getFrontPeriod(); long contentPositionUs = playbackInfo.contentPositionUs; Object playingPeriodUid = newPeriodUid = defaultPosition.first;
MediaPeriodHolder lastValidPeriodHolder = getFrontPeriod(); if (lastValidPeriodHolder == null) { return true; boolean readingPeriodRemoved = removeAfter(lastValidPeriodHolder); lastValidPeriodHolder.info = getUpdatedMediaPeriodInfo(lastValidPeriodHolder.info); return !readingPeriodRemoved || !hasPlayingPeriod();
MediaPeriodHolder oldPlayingPeriodHolder = queue.getPlayingPeriod(); MediaPeriodHolder newPlayingPeriodHolder = oldPlayingPeriodHolder; while (newPlayingPeriodHolder != null) { if (periodId.equals(newPlayingPeriodHolder.info.id) && newPlayingPeriodHolder.prepared) { queue.removeAfter(newPlayingPeriodHolder); break; newPlayingPeriodHolder = queue.advancePlayingPeriod(); maybeContinueLoading(); } else { queue.clear(/* keepFrontPeriodUid= */ true);
private void updatePlaybackPositions() throws ExoPlaybackException { if (!queue.hasPlayingPeriod()) { return; MediaPeriodHolder playingPeriodHolder = queue.getPlayingPeriod(); long periodPositionUs = playingPeriodHolder.mediaPeriod.readDiscontinuity(); if (periodPositionUs != C.TIME_UNSET) { MediaPeriodHolder loadingPeriod = queue.getLoadingPeriod(); playbackInfo.bufferedPositionUs = loadingPeriod.getBufferedPositionUs(); playbackInfo.totalBufferedDurationUs = getTotalBufferedDurationUs();
private long getTotalBufferedDurationUs(long bufferedPositionInLoadingPeriodUs) { MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); return loadingPeriodHolder == null ? 0 : bufferedPositionInLoadingPeriodUs - loadingPeriodHolder.toPeriodTime(rendererPositionUs); }
queue.clear(/* keepFrontPeriodUid= */ !resetPosition); setIsLoading(false); if (resetPosition) { queue.setTimeline(Timeline.EMPTY); for (PendingMessageInfo pendingMessageInfo : pendingMessages) { pendingMessageInfo.message.markAsProcessed(/* isDelivered= */ false);
private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) { MediaPeriodHolder periodHolder = queue.getFrontPeriod(); while (periodHolder != null) { if (periodHolder.trackSelectorResult != null) { TrackSelection[] trackSelections = periodHolder.trackSelectorResult.selections.getAll(); for (TrackSelection trackSelection : trackSelections) { if (trackSelection != null) { trackSelection.onPlaybackSpeed(playbackSpeed); } } } periodHolder = periodHolder.next; } }
this.player = player; this.clock = clock; this.queue = new MediaPeriodQueue();
private void maybeThrowSourceInfoRefreshError() throws IOException { MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); if (loadingPeriodHolder != null) { // Defer throwing until we read all available media periods. for (Renderer renderer : enabledRenderers) { if (!renderer.hasReadStreamToEnd()) { return; } } } mediaSource.maybeThrowSourceInfoRefreshError(); }
MediaPeriodHolder mediaPeriodHolder = getFrontPeriod(); while (mediaPeriodHolder != null) { if (mediaPeriodHolder.uid.equals(periodUid)) { mediaPeriodHolder = getFrontPeriod(); while (mediaPeriodHolder != null) { int indexOfHolderInTimeline = timeline.getIndexOfPeriod(mediaPeriodHolder.uid);
private boolean shouldTransitionToReadyState(boolean renderersReadyOrEnded) { if (enabledRenderers.length == 0) { // If there are no enabled renderers, determine whether we're ready based on the timeline. return isTimelineReady(); } if (!renderersReadyOrEnded) { return false; } if (!playbackInfo.isLoading) { // Renderers are ready and we're not loading. Transition to ready, since the alternative is // getting stuck waiting for additional media that's not being loaded. return true; } // Renderers are ready and we're loading. Ask the LoadControl whether to transition. MediaPeriodHolder loadingHolder = queue.getLoadingPeriod(); boolean bufferedToEnd = loadingHolder.isFullyBuffered() && loadingHolder.info.isFinal; return bufferedToEnd || loadControl.shouldStartPlayback( getTotalBufferedDurationUs(), mediaClock.getPlaybackParameters().speed, rebuffering); }
private void handleLoadingMediaPeriodChanged(boolean loadingTrackSelectionChanged) { MediaPeriodHolder loadingMediaPeriodHolder = queue.getLoadingPeriod(); MediaPeriodId loadingMediaPeriodId = loadingMediaPeriodHolder == null ? playbackInfo.periodId : loadingMediaPeriodHolder.info.id; boolean loadingMediaPeriodChanged = !playbackInfo.loadingMediaPeriodId.equals(loadingMediaPeriodId); if (loadingMediaPeriodChanged) { playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(loadingMediaPeriodId); } playbackInfo.bufferedPositionUs = loadingMediaPeriodHolder == null ? playbackInfo.positionUs : loadingMediaPeriodHolder.getBufferedPositionUs(); playbackInfo.totalBufferedDurationUs = getTotalBufferedDurationUs(); if ((loadingMediaPeriodChanged || loadingTrackSelectionChanged) && loadingMediaPeriodHolder != null && loadingMediaPeriodHolder.prepared) { updateLoadControlTrackSelection( loadingMediaPeriodHolder.trackGroups, loadingMediaPeriodHolder.trackSelectorResult); } }
private void maybeContinueLoading() { MediaPeriodHolder loadingPeriodHolder = queue.getLoadingPeriod(); long nextLoadPositionUs = loadingPeriodHolder.getNextLoadPositionUs(); if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) { setIsLoading(false); return; } long bufferedDurationUs = getTotalBufferedDurationUs(/* bufferedPositionInLoadingPeriodUs= */ nextLoadPositionUs); boolean continueLoading = loadControl.shouldContinueLoading( bufferedDurationUs, mediaClock.getPlaybackParameters().speed); setIsLoading(continueLoading); if (continueLoading) { loadingPeriodHolder.continueLoading(rendererPositionUs); } }