getSegmentReferenceNeeded_(mediaState, presentationTime, bufferEnd) {
    const logPrefix = shaka.media.StreamingEngine.logPrefix_(mediaState);
    goog.asserts.assert(
        mediaState.stream.segmentIndex,
        'segment index should have been generated already');

    if (mediaState.segmentIterator) {
      // Something is buffered from the same Stream.  Use the current position
      // in the segment index.  This is updated via next() after each segment is
      // appended.
      let ref = mediaState.segmentIterator.current();
      if (ref && mediaState.lastSegmentReference) {
        // In HLS sometimes the segment iterator adds or removes segments very
        // quickly, so we have to be sure that we do not add the last segment
        // again, tolerating a difference of 1ms.
        const isDiffNegligible = (a, b) => Math.abs(a - b) < 0.001;
        const lastStartTime = mediaState.lastSegmentReference.startTime;
        if (isDiffNegligible(lastStartTime, ref.startTime)) {
          ref = mediaState.segmentIterator.next().value;
        }
      }
      return ref;
    } else if (mediaState.lastSegmentReference || bufferEnd) {
      // Something is buffered from another Stream.
      const time = mediaState.lastSegmentReference ?
          mediaState.lastSegmentReference.endTime :
          bufferEnd;
      goog.asserts.assert(time != null, 'Should have a time to search');
      shaka.log.v1(
          logPrefix, 'looking up segment from new stream endTime:', time);

      const reverse = this.playerInterface_.getPlaybackRate() < 0;
      if (mediaState.stream.segmentIndex) {
        mediaState.segmentIterator =
            mediaState.stream.segmentIndex.getIteratorForTime(
                time, /* allowNonIndependent= */ false, reverse);
      }
      const ref = mediaState.segmentIterator &&
          mediaState.segmentIterator.next().value;
      if (ref == null) {
        shaka.log.warning(logPrefix, 'cannot find segment', 'endTime:', time);
      }
      return ref;
    } else {
      // Nothing is buffered.  Start at the playhead time.

      // If there's positive drift then we need to adjust the lookup time, and
      // may wind up requesting the previous segment to be safe.
      // inaccurateManifestTolerance should be 0 for low latency streaming.
      const inaccurateTolerance = this.manifest_.sequenceMode ?
        0 : this.config_.inaccurateManifestTolerance;
      const lookupTime = Math.max(presentationTime - inaccurateTolerance, 0);

      shaka.log.v1(logPrefix, 'looking up segment',
          'lookupTime:', lookupTime,
          'presentationTime:', presentationTime);

      const reverse = this.playerInterface_.getPlaybackRate() < 0;
      let ref = null;
      if (inaccurateTolerance) {
        if (mediaState.stream.segmentIndex) {
          mediaState.segmentIterator =
              mediaState.stream.segmentIndex.getIteratorForTime(
                  lookupTime, /* allowNonIndependent= */ false, reverse);
        }
        ref = mediaState.segmentIterator &&
            mediaState.segmentIterator.next().value;
      }
      if (!ref) {
        // If we can't find a valid segment with the drifted time, look for a
        // segment with the presentation time.
        if (mediaState.stream.segmentIndex) {
          mediaState.segmentIterator =
              mediaState.stream.segmentIndex.getIteratorForTime(
                  presentationTime, /* allowNonIndependent= */ false, reverse);
        }
        ref = mediaState.segmentIterator &&
            mediaState.segmentIterator.next().value;
      }
      if (ref == null) {
        shaka.log.warning(logPrefix, 'cannot find segment',
            'lookupTime:', lookupTime,
            'presentationTime:', presentationTime);
      }
      return ref;
    }
  }
Gets the SegmentReference of the next segment needed.

@param {shaka.media.StreamingEngine.MediaState_} mediaState
@param {number} presentationTime
@param {?number} bufferEnd
@return {shaka.media.SegmentReference} The SegmentReference of the
  next segment needed. Returns null if a segment could not be found, does
  not exist, or is not available.
@private