async fetch_(mediaState, reference, streamDataCallback) {
    const segmentData = reference.getSegmentData();
    if (segmentData) {
      return segmentData;
    }
    let op = null;
    if (mediaState.segmentPrefetch) {
      op = mediaState.segmentPrefetch.getPrefetchedSegment(
          reference, streamDataCallback);
    }
    if (!op) {
      op = this.dispatchFetch_(
          reference, mediaState.stream, streamDataCallback);
    }

    let position = 0;
    if (mediaState.segmentIterator) {
      position = mediaState.segmentIterator.currentPosition();
    }

    mediaState.operation = op;
    const response = await op.promise;
    mediaState.operation = null;
    let result = response.data;
    if (reference.aesKey) {
      result = await shaka.media.SegmentUtils.aesDecrypt(
          result, reference.aesKey, position);
    }
    return result;
  }
Fetches the given segment.

@param {!shaka.media.StreamingEngine.MediaState_} mediaState
@param {(!shaka.media.InitSegmentReference|
         !shaka.media.SegmentReference)} reference
@param {?function(BufferSource):!Promise=} streamDataCallback

@return {!Promise<BufferSource>}
@private