@Test public void updateQueuedPeriods_withDurationChangeInReadingPeriodAfterReadingPosition_handlesChangeAndRemovesPeriodsAfterChangedPeriod() { setupTimeline( 0, FIRST_AD_START_TIME_US, SECOND_AD_START_TIME_US); setAdGroupLoaded( 0); setAdGroupLoaded( 1); enqueueNext(); advancePlaying(); enqueueNext(); enqueueNext(); enqueueNext(); advanceReading(); advanceReading(); setupTimeline( 0, FIRST_AD_START_TIME_US, SECOND_AD_START_TIME_US - 1000); setAdGroupLoaded( 0); setAdGroupLoaded( 1); long readingPositionAtStartOfContentBetweenAds = FIRST_AD_START_TIME_US + AD_DURATION_US; boolean changeHandled = mediaPeriodQueue.updateQueuedPeriods( 0, readingPositionAtStartOfContentBetweenAds); assertThat(changeHandled).isTrue(); assertThat(getQueueLength()).isEqualTo(3); }
public boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs) { MediaPeriodHolder previousPeriodHolder = null; MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { MediaPeriodInfo oldPeriodInfo = periodHolder.info; MediaPeriodInfo newPeriodInfo; if (previousPeriodHolder == null) { newPeriodInfo = getUpdatedMediaPeriodInfo(oldPeriodInfo); } else { newPeriodInfo = getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (newPeriodInfo == null) { return !removeAfter(previousPeriodHolder); } if (!canKeepMediaPeriodHolder(oldPeriodInfo, newPeriodInfo)) { return !removeAfter(previousPeriodHolder); } } periodHolder.info = newPeriodInfo.copyWithContentPositionUs(oldPeriodInfo.contentPositionUs); if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { long newDurationInRendererTime = newPeriodInfo.durationUs == C.TIME_UNSET ? Long.MAX_VALUE : periodHolder.toRendererTime(newPeriodInfo.durationUs); boolean isReadingAndReadBeyondNewDuration = periodHolder == reading && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE || maxRendererReadPositionUs >= newDurationInRendererTime); boolean readingPeriodRemoved = removeAfter(periodHolder); return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; } previousPeriodHolder = periodHolder; periodHolder = periodHolder.getNext(); } return true; }
MediaPeriodQueue { public boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs) { MediaPeriodHolder previousPeriodHolder = null; MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { MediaPeriodInfo oldPeriodInfo = periodHolder.info; MediaPeriodInfo newPeriodInfo; if (previousPeriodHolder == null) { newPeriodInfo = getUpdatedMediaPeriodInfo(oldPeriodInfo); } else { newPeriodInfo = getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (newPeriodInfo == null) { return !removeAfter(previousPeriodHolder); } if (!canKeepMediaPeriodHolder(oldPeriodInfo, newPeriodInfo)) { return !removeAfter(previousPeriodHolder); } } periodHolder.info = newPeriodInfo.copyWithContentPositionUs(oldPeriodInfo.contentPositionUs); if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { long newDurationInRendererTime = newPeriodInfo.durationUs == C.TIME_UNSET ? Long.MAX_VALUE : periodHolder.toRendererTime(newPeriodInfo.durationUs); boolean isReadingAndReadBeyondNewDuration = periodHolder == reading && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE || maxRendererReadPositionUs >= newDurationInRendererTime); boolean readingPeriodRemoved = removeAfter(periodHolder); return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; } previousPeriodHolder = periodHolder; periodHolder = periodHolder.getNext(); } return true; } }
MediaPeriodQueue { public boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs) { MediaPeriodHolder previousPeriodHolder = null; MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { MediaPeriodInfo oldPeriodInfo = periodHolder.info; MediaPeriodInfo newPeriodInfo; if (previousPeriodHolder == null) { newPeriodInfo = getUpdatedMediaPeriodInfo(oldPeriodInfo); } else { newPeriodInfo = getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (newPeriodInfo == null) { return !removeAfter(previousPeriodHolder); } if (!canKeepMediaPeriodHolder(oldPeriodInfo, newPeriodInfo)) { return !removeAfter(previousPeriodHolder); } } periodHolder.info = newPeriodInfo.copyWithContentPositionUs(oldPeriodInfo.contentPositionUs); if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { long newDurationInRendererTime = newPeriodInfo.durationUs == C.TIME_UNSET ? Long.MAX_VALUE : periodHolder.toRendererTime(newPeriodInfo.durationUs); boolean isReadingAndReadBeyondNewDuration = periodHolder == reading && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE || maxRendererReadPositionUs >= newDurationInRendererTime); boolean readingPeriodRemoved = removeAfter(periodHolder); return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; } previousPeriodHolder = periodHolder; periodHolder = periodHolder.getNext(); } return true; } MediaPeriodQueue(); }
MediaPeriodQueue { public boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs) { MediaPeriodHolder previousPeriodHolder = null; MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { MediaPeriodInfo oldPeriodInfo = periodHolder.info; MediaPeriodInfo newPeriodInfo; if (previousPeriodHolder == null) { newPeriodInfo = getUpdatedMediaPeriodInfo(oldPeriodInfo); } else { newPeriodInfo = getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (newPeriodInfo == null) { return !removeAfter(previousPeriodHolder); } if (!canKeepMediaPeriodHolder(oldPeriodInfo, newPeriodInfo)) { return !removeAfter(previousPeriodHolder); } } periodHolder.info = newPeriodInfo.copyWithContentPositionUs(oldPeriodInfo.contentPositionUs); if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { long newDurationInRendererTime = newPeriodInfo.durationUs == C.TIME_UNSET ? Long.MAX_VALUE : periodHolder.toRendererTime(newPeriodInfo.durationUs); boolean isReadingAndReadBeyondNewDuration = periodHolder == reading && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE || maxRendererReadPositionUs >= newDurationInRendererTime); boolean readingPeriodRemoved = removeAfter(periodHolder); return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; } previousPeriodHolder = periodHolder; periodHolder = periodHolder.getNext(); } return true; } MediaPeriodQueue(); void setTimeline(Timeline timeline); boolean updateRepeatMode(@RepeatMode int repeatMode); boolean updateShuffleModeEnabled(boolean shuffleModeEnabled); boolean isLoading(MediaPeriod mediaPeriod); void reevaluateBuffer(long rendererPositionUs); boolean shouldLoadNextMediaPeriod(); @Nullable MediaPeriodInfo getNextMediaPeriodInfo(
      long rendererPositionUs, PlaybackInfo playbackInfo); MediaPeriod enqueueNextMediaPeriod(
      RendererCapabilities[] rendererCapabilities,
      TrackSelector trackSelector,
      Allocator allocator,
      MediaSource mediaSource,
      MediaPeriodInfo info); MediaPeriodHolder getLoadingPeriod(); MediaPeriodHolder getPlayingPeriod(); MediaPeriodHolder getReadingPeriod(); MediaPeriodHolder getFrontPeriod(); boolean hasPlayingPeriod(); MediaPeriodHolder advanceReadingPeriod(); MediaPeriodHolder advancePlayingPeriod(); boolean removeAfter(MediaPeriodHolder mediaPeriodHolder); void clear(boolean keepFrontPeriodUid); boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs); MediaPeriodInfo getUpdatedMediaPeriodInfo(MediaPeriodInfo info); MediaPeriodId resolveMediaPeriodIdForAds(Object periodUid, long positionUs); }
MediaPeriodQueue { public boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs) { MediaPeriodHolder previousPeriodHolder = null; MediaPeriodHolder periodHolder = getFrontPeriod(); while (periodHolder != null) { MediaPeriodInfo oldPeriodInfo = periodHolder.info; MediaPeriodInfo newPeriodInfo; if (previousPeriodHolder == null) { newPeriodInfo = getUpdatedMediaPeriodInfo(oldPeriodInfo); } else { newPeriodInfo = getFollowingMediaPeriodInfo(previousPeriodHolder, rendererPositionUs); if (newPeriodInfo == null) { return !removeAfter(previousPeriodHolder); } if (!canKeepMediaPeriodHolder(oldPeriodInfo, newPeriodInfo)) { return !removeAfter(previousPeriodHolder); } } periodHolder.info = newPeriodInfo.copyWithContentPositionUs(oldPeriodInfo.contentPositionUs); if (!areDurationsCompatible(oldPeriodInfo.durationUs, newPeriodInfo.durationUs)) { long newDurationInRendererTime = newPeriodInfo.durationUs == C.TIME_UNSET ? Long.MAX_VALUE : periodHolder.toRendererTime(newPeriodInfo.durationUs); boolean isReadingAndReadBeyondNewDuration = periodHolder == reading && (maxRendererReadPositionUs == C.TIME_END_OF_SOURCE || maxRendererReadPositionUs >= newDurationInRendererTime); boolean readingPeriodRemoved = removeAfter(periodHolder); return !readingPeriodRemoved && !isReadingAndReadBeyondNewDuration; } previousPeriodHolder = periodHolder; periodHolder = periodHolder.getNext(); } return true; } MediaPeriodQueue(); void setTimeline(Timeline timeline); boolean updateRepeatMode(@RepeatMode int repeatMode); boolean updateShuffleModeEnabled(boolean shuffleModeEnabled); boolean isLoading(MediaPeriod mediaPeriod); void reevaluateBuffer(long rendererPositionUs); boolean shouldLoadNextMediaPeriod(); @Nullable MediaPeriodInfo getNextMediaPeriodInfo(
      long rendererPositionUs, PlaybackInfo playbackInfo); MediaPeriod enqueueNextMediaPeriod(
      RendererCapabilities[] rendererCapabilities,
      TrackSelector trackSelector,
      Allocator allocator,
      MediaSource mediaSource,
      MediaPeriodInfo info); MediaPeriodHolder getLoadingPeriod(); MediaPeriodHolder getPlayingPeriod(); MediaPeriodHolder getReadingPeriod(); MediaPeriodHolder getFrontPeriod(); boolean hasPlayingPeriod(); MediaPeriodHolder advanceReadingPeriod(); MediaPeriodHolder advancePlayingPeriod(); boolean removeAfter(MediaPeriodHolder mediaPeriodHolder); void clear(boolean keepFrontPeriodUid); boolean updateQueuedPeriods(long rendererPositionUs, long maxRendererReadPositionUs); MediaPeriodInfo getUpdatedMediaPeriodInfo(MediaPeriodInfo info); MediaPeriodId resolveMediaPeriodIdForAds(Object periodUid, long positionUs);  }