static parseSIDX_(
      sidxOffset, initSegmentReference, timestampOffset, appendWindowStart,
      appendWindowEnd, uris, box) {
    goog.asserts.assert(
        box.version != null,
        'SIDX is a full box and should have a valid version.');

    const references = [];

    // Parse the SIDX structure.
    // Skip reference_ID (32 bits).
    box.reader.skip(4);

    const timescale = box.reader.readUint32();

    if (timescale == 0) {
      shaka.log.error('Invalid timescale.');
      throw new shaka.util.Error(
          shaka.util.Error.Severity.CRITICAL,
          shaka.util.Error.Category.MEDIA,
          shaka.util.Error.Code.MP4_SIDX_INVALID_TIMESCALE);
    }

    let earliestPresentationTime;
    let firstOffset;

    if (box.version == 0) {
      earliestPresentationTime = box.reader.readUint32();
      firstOffset = box.reader.readUint32();
    } else {
      earliestPresentationTime = box.reader.readUint64();
      firstOffset = box.reader.readUint64();
    }

    // Skip reserved (16 bits).
    box.reader.skip(2);

    // Add references.
    const referenceCount = box.reader.readUint16();

    // Subtract the presentation time offset
    let unscaledStartTime = earliestPresentationTime;
    let startByte = sidxOffset + box.size + firstOffset;

    for (let i = 0; i < referenceCount; i++) {
      // |chunk| is 1 bit for |referenceType|, and 31 bits for |referenceSize|.
      const chunk = box.reader.readUint32();
      const referenceType = (chunk & 0x80000000) >>> 31;
      const referenceSize = chunk & 0x7FFFFFFF;

      const subsegmentDuration = box.reader.readUint32();

      // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits
      // for |sapDelta|.
      box.reader.skip(4);

      // If |referenceType| is 1 then the reference is to another SIDX.
      // We do not support this.
      if (referenceType == 1) {
        shaka.log.error('Hierarchical SIDXs are not supported.');
        throw new shaka.util.Error(
            shaka.util.Error.Severity.CRITICAL,
            shaka.util.Error.Category.MEDIA,
            shaka.util.Error.Code.MP4_SIDX_TYPE_NOT_SUPPORTED);
      }

      // The media timestamps inside the container.
      const nativeStartTime = unscaledStartTime / timescale;
      const nativeEndTime =
          (unscaledStartTime + subsegmentDuration) / timescale;

      references.push(
          new shaka.media.SegmentReference(
              nativeStartTime + timestampOffset,
              nativeEndTime + timestampOffset,
              (() => { return uris; }),
              startByte,
              startByte + referenceSize - 1,
              initSegmentReference,
              timestampOffset,
              appendWindowStart,
              appendWindowEnd));

      unscaledStartTime += subsegmentDuration;
      startByte += referenceSize;
    }

    box.parser.stop();
    return references;
  }
Parse a SIDX box from the given reader.

@param {number} sidxOffset
@param {shaka.media.InitSegmentReference} initSegmentReference
@param {number} timestampOffset
@param {number} appendWindowStart
@param {number} appendWindowEnd
@param {!Array<string>} uris The possible locations of the MP4 file that
  contains the segments.
@param {!shaka.extern.ParsedBox} box
@return {!Array<!shaka.media.SegmentReference>}
@private