///|
/// Incremental WebM/Matroska demux state. The outer container stream owns the
/// input buffer; this state only retains validated initialization OBUs and
/// packets that have already been materialized from a laced block.
priv enum WebmStreamStage {
  WebmNeedEbml
  WebmNeedSegment
  WebmInSegment
  WebmInCluster
  WebmAfterSegment
  WebmDone
}

///|
priv enum WebmStreamProbe {
  WebmProbeWait
  WebmProbeReady(WebmElement)
}

///|
priv struct Av1WebmStreamState {
  limits : DecodeLimits
  requested_track : Int64?
  mut track : Av1DemuxedTrack?
  mut selected : WebmTrack?
  mut track_numbers : Array[Int64]
  mut timestamp_scale : Int64
  mut stage : WebmStreamStage
  mut saw_segment : Bool
  mut saw_info : Bool
  mut saw_tracks : Bool
  mut segment_start : Int64?
  mut segment_end : Int64?
  mut segment_unknown : Bool
  mut segment_elements : Int
  mut cluster_start : Int64?
  mut cluster_end : Int64?
  mut cluster_unknown : Bool
  mut cluster_timestamp : Int64?
  mut cluster_elements : Int
  mut queue : Array[Av1Packet]
  mut queue_at : Int
  mut packet_count : Int
}

///|
fn Av1WebmStreamState::new(
  track_id : Int64?,
  limits : DecodeLimits,
) -> Av1WebmStreamState {
  {
    limits,
    requested_track: track_id,
    track: None,
    selected: None,
    track_numbers: [],
    timestamp_scale: WEBM_DEFAULT_TIMESTAMP_SCALE,
    stage: WebmNeedEbml,
    saw_segment: false,
    saw_info: false,
    saw_tracks: false,
    segment_start: None,
    segment_end: None,
    segment_unknown: false,
    segment_elements: 0,
    cluster_start: None,
    cluster_end: None,
    cluster_unknown: false,
    cluster_timestamp: None,
    cluster_elements: 0,
    queue: [],
    queue_at: 0,
    packet_count: 0,
  }
}

///|
fn webm_stream_rebase(
  input : ContainerStreamInput,
  error : DecodeError,
) -> DecodeError {
  { ..error, byte_offset: error.byte_offset.map(at => input.base_offset + at), }
}

///|
fn webm_stream_error(
  input : ContainerStreamInput,
  kind : DecodeErrorKind,
  context : String,
  message : String,
  at : Int,
) -> DecodeError {
  {
    kind,
    context,
    message,
    byte_offset: Some(input.base_offset + at.to_int64()),
  }
}

///|
/// Probe an EBML element. `complete` controls whether the payload must already
/// be present. Container masters are probed from their header and consumed a
/// header at a time; metadata and block payloads require a complete element.
fn webm_stream_probe_element(
  input : ContainerStreamInput,
  parent_end : Int64?,
  complete : Bool,
) -> Result[WebmStreamProbe, DecodeError] {
  let data = input.bytes
  let p = input.start
  let physical_end = p + input.available()
  if p >= physical_end {
    return Ok(WebmProbeWait)
  }
  let parent_local : Int? = match parent_end {
    None => None
    Some(value) => {
      if value < input.base_offset {
        return Err(
          webm_stream_error(
            input,
            InvalidState,
            "webm.stream",
            "Logical parent precedes input offset",
            p,
          ),
        )
      }
      let delta = value - input.base_offset
      if delta > 2147483647L {
        return Err(
          webm_stream_error(
            input,
            LimitExceeded,
            "webm.stream",
            "Logical element boundary exceeds Int",
            p,
          ),
        )
      }
      Some(delta.to_int())
    }
  }
  let id_width = webm_vint_width(data[p].to_int())
  if id_width == 0 {
    return Err(
      webm_stream_error(input, InvalidData, "ebml/id", "Invalid EBML ID", p),
    )
  }
  if id_width > physical_end - p {
    return Ok(WebmProbeWait)
  }
  let id = match webm_read_vint(data, p, physical_end, id=true) {
    Ok(value) => value
    Err(error) => return Err(webm_stream_rebase(input, error))
  }
  let size_at = p + id.width
  if size_at >= physical_end {
    return Ok(WebmProbeWait)
  }
  let size_width = webm_vint_width(data[size_at].to_int())
  if size_width == 0 {
    return Err(
      webm_stream_error(
        input,
        InvalidData,
        "ebml/vint",
        "Invalid EBML size",
        size_at,
      ),
    )
  }
  if size_width > physical_end - size_at {
    return Ok(WebmProbeWait)
  }
  let size = match webm_read_vint(data, size_at, physical_end, size_mode=true) {
    Ok(value) => value
    Err(error) => return Err(webm_stream_rebase(input, error))
  }
  let payload = size_at + size.width
  let end = if size.unknown {
    match parent_local {
      Some(value) => value
      None => physical_end
    }
  } else {
    if size.value > (2147483647 - payload).to_int64() {
      return Err(
        webm_stream_error(
          input,
          LimitExceeded,
          "ebml/element",
          "Element exceeds the addressable input bound",
          p,
        ),
      )
    }
    let value = payload + size.value.to_int()
    match parent_local {
      Some(bound) if value > bound =>
        return Err(
          webm_stream_error(
            input,
            TruncatedInput,
            "ebml/element",
            "Element exceeds its logical parent",
            p,
          ),
        )
      _ => value
    }
  }
  if end < payload {
    return Err(
      webm_stream_error(
        input,
        InvalidData,
        "ebml/element",
        "Element end precedes payload",
        p,
      ),
    )
  }
  if complete && end > physical_end {
    return Ok(WebmProbeWait)
  }
  if !complete {
    return Ok(
      WebmProbeReady({
        id: id.value,
        start: p,
        payload,
        end,
        unknown: size.unknown,
      }),
    )
  }
  match webm_read_element(data, p, physical_end) {
    Ok(value) => Ok(WebmProbeReady(value))
    Err(error) => Err(webm_stream_rebase(input, error))
  }
}

///|
fn Av1WebmStreamState::retained_bytes(self : Av1WebmStreamState) -> Int {
  let mut out = match self.track {
    Some(value) => value.codec_initialization.length()
    None => 0
  }
  for i in self.queue_at.. 2147483647 - length {
      return 2147483647
    }
    out += length
  }
  out
}

///|
fn Av1WebmStreamState::webm_stream_take_packet(
  self : Av1WebmStreamState,
) -> Av1Packet? {
  if self.queue_at >= self.queue.length() {
    return None
  }
  let packet = self.queue[self.queue_at]
  self.queue_at += 1
  if self.queue_at == self.queue.length() {
    self.queue = []
    self.queue_at = 0
  }
  Some(packet)
}

///|
fn Av1WebmStreamState::webm_stream_track_is_known(
  self : Av1WebmStreamState,
  number : Int64,
) -> Bool {
  for value in self.track_numbers {
    if value == number {
      return true
    }
  }
  false
}

///|
/// Locate the copied CodecPrivate payload so AV1C diagnostics can be rebased
/// from the standalone configuration array back to the stream input.
fn webm_stream_codec_private_offset(
  data : Array[Byte],
  tracks_element : WebmElement,
  number : Int64,
) -> Int {
  let entries : Array[WebmElement] = []
  match webm_element_children(data, tracks_element, entries, 1) {
    Err(_) => return tracks_element.start
    Ok(_) => ()
  }
  for entry in entries {
    if entry.id != WEBM_TRACK_ENTRY {
      continue
    }
    let children : Array[WebmElement] = []
    match webm_element_children(data, entry, children, 2) {
      Err(_) => continue
      Ok(_) => ()
    }
    let mut track_number : Int64? = None
    let mut codec_offset : Int? = None
    for child in children {
      if child.id == WEBM_TRACK_NUMBER {
        track_number = match webm_uint(data, child.payload, child.end) {
          Ok(value) => Some(value)
          Err(_) => None
        }
      } else if child.id == WEBM_CODEC_PRIVATE {
        codec_offset = Some(child.payload)
      }
    }
    if track_number == Some(number) {
      match codec_offset {
        Some(value) => return value
        None => return tracks_element.start
      }
    }
  }
  tracks_element.start
}

///|
fn Av1WebmStreamState::webm_stream_parse_tracks(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  element : WebmElement,
) -> Result[Unit, DecodeError] {
  let tracks = match webm_parse_tracks(input.bytes, element) {
    Ok(value) => value
    Err(error) => return Err(webm_stream_rebase(input, error))
  }
  let selected = match self.requested_track {
    Some(number) =>
      match webm_find_track(tracks, number) {
        Some(value) => value
        None =>
          return Err(
            webm_stream_error(
              input,
              InvalidData,
              "tracks",
              "Requested TrackNumber was not found",
              element.start,
            ),
          )
      }
    None => {
      let mut found : WebmTrack? = None
      for value in tracks {
        if value.track_type == 1 && value.codec_av1 {
          found = Some(value)
          break
        }
      }
      match found {
        Some(value) => value
        None =>
          return Err(
            webm_stream_error(
              input,
              Unsupported,
              "tracks",
              "No AV1 video TrackEntry",
              element.start,
            ),
          )
      }
    }
  }
  if selected.track_type != 1 || !selected.codec_av1 {
    return Err(
      webm_stream_error(
        input,
        Unsupported,
        "tracks",
        "Selected track is not V_AV1 video",
        element.start,
      ),
    )
  }
  if selected.content_encoded {
    return Err(
      webm_stream_error(
        input,
        Unsupported,
        "tracks",
        "Compressed or encrypted TrackEntry is unsupported",
        element.start,
      ),
    )
  }
  if !selected.track_timestamp_scale_one {
    return Err(
      webm_stream_error(
        input,
        Unsupported,
        "tracks",
        "Non-unit TrackTimestampScale is unsupported",
        element.start,
      ),
    )
  }
  if selected.width <= 0 || selected.height <= 0 {
    return Err(
      webm_stream_error(
        input,
        InvalidData,
        "tracks/video",
        "V_AV1 track has no PixelWidth/PixelHeight",
        element.start,
      ),
    )
  }
  if selected.width > self.limits.max_frame_pixels / selected.height {
    return Err(
      webm_stream_error(
        input,
        LimitExceeded,
        "tracks/video",
        "Track dimensions exceed max_frame_pixels",
        element.start,
      ),
    )
  }
  let codec_private = match selected.codec_private {
    Some(value) => value
    None =>
      return Err(
        webm_stream_error(
          input,
          InvalidData,
          "tracks",
          "V_AV1 track has no CodecPrivate",
          element.start,
        ),
      )
  }
  let codec_private_start = webm_stream_codec_private_offset(
    input.bytes,
    element,
    selected.number,
  )
  let codec_initialization = match av1_demux_av1c(codec_private) {
    Ok(value) => value
    Err(error) => {
      let mapped = {
        ..error,
        byte_offset: match error.byte_offset {
          Some(at) =>
            Some(input.base_offset + codec_private_start.to_int64() + at)
          None => Some(input.base_offset + element.start.to_int64())
        },
      }
      return Err(mapped)
    }
  }
  let sequence = match av1_sequence_info(codec_initialization) {
    Some(value) => value
    None =>
      return Err(
        webm_stream_error(
          input,
          InvalidData,
          "tracks/video",
          "CodecPrivate has no usable sequence header",
          element.start,
        ),
      )
  }
  if selected.width != sequence.width || selected.height != sequence.height {
    return Err(
      webm_stream_error(
        input,
        InvalidData,
        "tracks/video",
        "Pixel dimensions do not match AV1 sequence maxima",
        element.start,
      ),
    )
  }
  self.track_numbers = []
  for value in tracks {
    self.track_numbers.push(value.number)
  }
  self.selected = Some({ ..selected, codec_private: None, })
  self.track = Some({
    format: WebM,
    track_id: selected.number,
    width: selected.width,
    height: selected.height,
    timescale: WEBM_NANOS,
    movie_timescale: None,
    edits: [],
    codec_initialization,
    packets: [],
  })
  Ok(())
}

///|
fn webm_stream_parse_group(
  data : Array[Byte],
  child : WebmElement,
  tracks : Array[Int64],
  selected : WebmTrack,
) -> Result[(WebmBlock?, Int64?, Bool), DecodeError] {
  if child.unknown {
    return Err(
      webm_error(
        Unsupported,
        "cluster/blockgroup",
        "Unknown-sized BlockGroup",
        child.start,
      ),
    )
  }
  let group_children : Array[WebmElement] = []
  match webm_element_children(data, child, group_children, 3) {
    Err(error) => return Err(error)
    Ok(_) => ()
  }
  let mut block : WebmBlock? = None
  let mut saw_block = false
  let mut duration : Int64? = None
  let mut reference = false
  let mut reference_zero = false
  let mut unsupported_extra = false
  for item in group_children {
    if item.id == WEBM_BLOCK {
      if saw_block {
        return Err(
          webm_error(
            InvalidData,
            "cluster/blockgroup",
            "Duplicate Block",
            item.start,
          ),
        )
      }
      saw_block = true
      let block_track = match
        webm_block_track_number(data, item.payload, item.end) {
        Ok(value) => value
        Err(error) => return Err(error)
      }
      if !tracks.contains(block_track) {
        return Err(
          webm_error(
            InvalidData,
            "block",
            "Block references an unknown track",
            item.start,
          ),
        )
      }
      if block_track == selected.number {
        block = Some(
          match
            webm_block_track(
              data,
              item.payload,
              item.end,
              [selected],
              block_group=true,
            ) {
            Ok(value) => value
            Err(error) => return Err(error)
          },
        )
      }
    } else if item.id == WEBM_BLOCK_DURATION {
      if duration is Some(_) {
        return Err(
          webm_error(
            InvalidData,
            "cluster/blockgroup",
            "Duplicate BlockDuration",
            item.start,
          ),
        )
      }
      duration = Some(
        match webm_uint(data, item.payload, item.end) {
          Ok(value) => value
          Err(error) => return Err(error)
        },
      )
    } else if item.id == WEBM_REFERENCE_BLOCK {
      if item.end <= item.payload || item.end - item.payload > 8 {
        return Err(
          webm_error(
            InvalidData,
            "cluster/blockgroup",
            "Invalid ReferenceBlock integer",
            item.start,
          ),
        )
      }
      let mut zero = true
      for position in item.payload.. value
    None => return Ok((None, duration, reference))
  }
  if unsupported_extra {
    return Err(
      webm_error(
        Unsupported,
        "cluster/blockgroup",
        "Unsupported BlockGroup payload",
        child.start,
      ),
    )
  }
  Ok((Some(value), duration, reference))
}

///|
fn Av1WebmStreamState::enqueue_block(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  block : WebmBlock,
  duration_ticks : Int64?,
  reference : Bool,
  is_block_group : Bool,
) -> Result[Unit, DecodeError] {
  let selected = match self.selected {
    Some(value) => value
    None =>
      return Err(
        webm_stream_error(
          input,
          InvalidState,
          "webm.stream",
          "Selected track is unavailable while parsing a block",
          block.frames[0].start,
        ),
      )
  }
  let cluster_time = match self.cluster_timestamp {
    Some(value) => value
    None =>
      return Err(
        webm_stream_error(
          input,
          Unsupported,
          "cluster",
          "Streaming requires Cluster Timestamp before selected blocks",
          block.frames[0].start,
        ),
      )
  }
  let frame_count = block.frames.length()
  if frame_count > self.limits.max_frames - self.packet_count {
    return Err(
      webm_stream_error(
        input,
        LimitExceeded,
        "webm",
        "Packet count exceeds max_frames",
        block.frames[0].start,
      ),
    )
  }
  let base_ticks = match
    webm_i64_add(cluster_time, block.timecode, block.frames[0].start) {
    Ok(value) => value
    Err(error) => return Err(webm_stream_rebase(input, error))
  }
  for i in 0.. value
      Err(error) => return Err(webm_stream_rebase(input, error))
    }
    let timestamp_base = match
      webm_scale_ticks(base_ticks, self.timestamp_scale, frame.start) {
      Ok(value) => value
      Err(error) => return Err(webm_stream_rebase(input, error))
    }
    let timestamp_unshifted : Int64? = match timing.1 {
      Some(offset) =>
        Some(
          match webm_i64_add(timestamp_base, offset, frame.start) {
            Ok(value) => value
            Err(error) => return Err(webm_stream_rebase(input, error))
          },
        )
      None => None
    }
    let timestamp = match timestamp_unshifted {
      Some(value) =>
        match selected.codec_delay {
          Some(delay) =>
            Some(
              match webm_i64_sub(value, delay, frame.start) {
                Ok(result) => result
                Err(error) => return Err(webm_stream_rebase(input, error))
              },
            )
          None => Some(value)
        }
      None => None
    }
    self.queue.push({
      data: webm_copy(input.bytes, frame.start, frame.end),
      presentation_timestamp: timestamp,
      decode_timestamp: None,
      duration: timing.0,
      sync_sample: Some(
        if reference {
          false
        } else if is_block_group {
          true
        } else {
          block.keyframe
        },
      ),
    })
    self.packet_count += 1
  }
  Ok(())
}

///|
fn Av1WebmStreamState::finish_cluster(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
) -> Result[Unit, DecodeError] {
  if self.cluster_timestamp is None {
    let at = match self.cluster_start {
      Some(value) => value
      None => input.offset()
    }
    return Err({
      kind: InvalidData,
      context: "cluster",
      message: "Cluster has no Timestamp",
      byte_offset: Some(at),
    })
  }
  self.cluster_end = None
  self.cluster_unknown = false
  self.cluster_start = None
  self.cluster_timestamp = None
  self.stage = WebmInSegment
  Ok(())
}

///|
fn Av1WebmStreamState::finish_segment(
  self : Av1WebmStreamState,
) -> Result[Unit, DecodeError] {
  if !self.saw_info || !self.saw_tracks {
    let at = match self.segment_start {
      Some(value) => value
      None => 0L
    }
    return Err({
      kind: InvalidData,
      context: "segment",
      message: "Segment lacks Info or Tracks",
      byte_offset: Some(at),
    })
  }
  self.stage = if self.segment_unknown { WebmDone } else { WebmAfterSegment }
  Ok(())
}

///|
fn Av1WebmStreamState::step_ebml(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  match webm_stream_probe_element(input, None, true) {
    Err(error) => Err(error)
    Ok(WebmProbeWait) =>
      if eof {
        Err(
          webm_stream_error(
            input,
            TruncatedInput,
            "ebml",
            "Incomplete EBML header",
            input.start,
          ),
        )
      } else {
        Ok(Wait)
      }
    Ok(WebmProbeReady(element)) => {
      if element.id != WEBM_EBML {
        return Err(
          webm_stream_error(
            input,
            InvalidData,
            "webm",
            "Input does not start with EBML",
            element.start,
          ),
        )
      }
      if element.unknown {
        return Err(
          webm_stream_error(
            input,
            InvalidData,
            "ebml",
            "EBML header cannot be unknown-sized",
            element.start,
          ),
        )
      }
      match webm_parse_ebml_header(input.bytes, element) {
        Err(error) => Err(webm_stream_rebase(input, error))
        Ok(_) => {
          input.consume(element.end - element.start)
          self.stage = WebmNeedSegment
          Ok(Progress)
        }
      }
    }
  }
}

///|
fn Av1WebmStreamState::step_segment_header(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  match webm_stream_probe_element(input, None, false) {
    Err(error) => Err(error)
    Ok(WebmProbeWait) =>
      if eof {
        Err(
          webm_stream_error(
            input,
            TruncatedInput,
            "webm",
            "Missing Segment element",
            input.start,
          ),
        )
      } else {
        Ok(Wait)
      }
    Ok(WebmProbeReady(element)) =>
      if element.id == WEBM_SEGMENT {
        if self.saw_segment {
          return Err(
            webm_stream_error(
              input,
              InvalidData,
              "webm",
              "Duplicate Segment element",
              element.start,
            ),
          )
        }
        self.saw_segment = true
        self.segment_start = Some(input.base_offset + element.start.to_int64())
        self.segment_unknown = element.unknown
        self.segment_elements = 0
        self.segment_end = if element.unknown {
          None
        } else {
          Some(input.base_offset + element.end.to_int64())
        }
        input.consume(element.payload - element.start)
        self.stage = WebmInSegment
        Ok(Progress)
      } else if element.id == WEBM_VOID || element.id == WEBM_CRC32 {
        if element.unknown {
          Err(
            webm_stream_error(
              input,
              Unsupported,
              "webm",
              "Unknown-sized root Void/CRC",
              element.start,
            ),
          )
        } else {
          // Root globals may occur before Segment, but require their complete
          // finite payload before consumption.
          let full = match webm_stream_probe_element(input, None, true) {
            Err(error) => return Err(error)
            Ok(WebmProbeWait) =>
              return if eof {
                Err(
                  webm_stream_error(
                    input,
                    TruncatedInput,
                    "webm",
                    "Truncated root Void/CRC",
                    element.start,
                  ),
                )
              } else {
                Ok(Wait)
              }
            Ok(WebmProbeReady(value)) => value
          }
          input.consume(full.end - full.start)
          Ok(Progress)
        }
      } else {
        Err(
          webm_stream_error(
            input,
            InvalidData,
            "webm",
            "Missing Segment element",
            element.start,
          ),
        )
      }
  }
}

///|
fn Av1WebmStreamState::step_segment(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  let current = input.offset()
  match self.segment_end {
    Some(end) if current > end =>
      return Err(
        webm_stream_error(
          input,
          InvalidData,
          "segment",
          "Input passed Segment boundary",
          input.start,
        ),
      )
    Some(end) if current == end =>
      return match self.finish_segment() {
        Err(error) => return Err(error)
        Ok(_) => return self.step(input, eof)
      }
    _ => ()
  }
  if input.available() == 0 {
    if eof {
      match self.segment_end {
        Some(end) if current < end =>
          Err(
            webm_stream_error(
              input,
              TruncatedInput,
              "segment",
              "Truncated finite Segment",
              input.start,
            ),
          )
        _ =>
          match self.finish_segment() {
            Err(error) => Err(error)
            Ok(_) => self.step(input, eof)
          }
      }
    } else {
      Ok(Wait)
    }
  } else {
    let header = match
      webm_stream_probe_element(input, self.segment_end, false) {
      Err(error) => return Err(error)
      Ok(WebmProbeWait) =>
        return if eof {
          Err(
            webm_stream_error(
              input,
              TruncatedInput,
              "segment",
              "Truncated Segment child header",
              input.start,
            ),
          )
        } else {
          Ok(Wait)
        }
      Ok(WebmProbeReady(value)) => value
    }
    let element = if header.id == WEBM_CLUSTER {
      header
    } else {
      match webm_stream_probe_element(input, self.segment_end, true) {
        Err(error) => return Err(error)
        Ok(WebmProbeWait) =>
          return if eof {
            Err(
              webm_stream_error(
                input,
                TruncatedInput,
                "segment",
                "Truncated Segment child",
                header.start,
              ),
            )
          } else {
            Ok(Wait)
          }
        Ok(WebmProbeReady(value)) => value
      }
    }
    if element.unknown && element.id != WEBM_CLUSTER {
      return Err(
        webm_stream_error(
          input,
          Unsupported,
          "segment",
          "Unknown-sized non-Cluster element",
          element.start,
        ),
      )
    }
    if self.segment_elements >= WEBM_MAX_ELEMENTS {
      return Err(
        webm_stream_error(
          input,
          LimitExceeded,
          "segment",
          "Segment element count exceeds parser bound",
          element.start,
        ),
      )
    }
    self.segment_elements += 1
    if element.id == WEBM_INFO {
      if self.saw_info {
        return Err(
          webm_stream_error(
            input,
            InvalidData,
            "segment",
            "Duplicate Info element",
            element.start,
          ),
        )
      }
      if element.unknown {
        return Err(
          webm_stream_error(
            input,
            Unsupported,
            "info",
            "Unknown-sized Info element",
            element.start,
          ),
        )
      }
      self.timestamp_scale = match webm_parse_info(input.bytes, element) {
        Ok(value) => value
        Err(error) => return Err(webm_stream_rebase(input, error))
      }
      self.saw_info = true
      input.consume(element.end - element.start)
      Ok(Progress)
    } else if element.id == WEBM_TRACKS {
      if self.saw_tracks {
        return Err(
          webm_stream_error(
            input,
            InvalidData,
            "segment",
            "Duplicate Tracks element",
            element.start,
          ),
        )
      }
      if element.unknown {
        return Err(
          webm_stream_error(
            input,
            Unsupported,
            "tracks",
            "Unknown-sized Tracks element",
            element.start,
          ),
        )
      }
      match self.webm_stream_parse_tracks(input, element) {
        Err(error) => Err(error)
        Ok(_) => {
          self.saw_tracks = true
          input.consume(element.end - element.start)
          Ok(Progress)
        }
      }
    } else if element.id == WEBM_CLUSTER {
      if self.track is None || !self.saw_info || !self.saw_tracks {
        return Err(
          webm_stream_error(
            input,
            Unsupported,
            "segment",
            "Streaming requires Info and Tracks before Cluster data",
            element.start,
          ),
        )
      }
      self.cluster_start = Some(input.base_offset + element.start.to_int64())
      self.cluster_unknown = element.unknown
      self.cluster_elements = 0
      self.cluster_end = if element.unknown {
        None
      } else {
        Some(input.base_offset + element.end.to_int64())
      }
      self.cluster_timestamp = None
      input.consume(element.payload - element.start)
      self.stage = WebmInCluster
      Ok(Progress)
    } else if element.id == WEBM_SEGMENT {
      Err(
        webm_stream_error(
          input,
          Unsupported,
          "segment",
          "Nested Segment element is unsupported",
          element.start,
        ),
      )
    } else {
      input.consume(element.end - element.start)
      Ok(Progress)
    }
  }
}

///|
fn Av1WebmStreamState::step_cluster(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  let current = input.offset()
  let logical_end = match self.cluster_end {
    Some(value) => Some(value)
    None => self.segment_end
  }
  match logical_end {
    Some(end) if current > end =>
      return Err(
        webm_stream_error(
          input,
          InvalidData,
          "cluster",
          "Input passed Cluster boundary",
          input.start,
        ),
      )
    Some(end) if current == end =>
      return match self.finish_cluster(input) {
        Err(error) => Err(error)
        Ok(_) => self.step(input, eof)
      }
    _ => ()
  }
  if input.available() == 0 {
    if eof && self.cluster_unknown {
      match self.finish_cluster(input) {
        Err(error) => Err(error)
        Ok(_) => self.step(input, eof)
      }
    } else if eof {
      Err(
        webm_stream_error(
          input,
          TruncatedInput,
          "cluster",
          "Truncated Cluster",
          input.start,
        ),
      )
    } else {
      Ok(Wait)
    }
  } else {
    // The header-only probe lets an unknown-sized Cluster stop immediately at
    // the next Segment-level sibling, without buffering that sibling payload.
    let header = match webm_stream_probe_element(input, logical_end, false) {
      Err(error) => return Err(error)
      Ok(WebmProbeWait) =>
        return if eof {
          Err(
            webm_stream_error(
              input,
              TruncatedInput,
              "cluster",
              "Truncated Cluster child header",
              input.start,
            ),
          )
        } else {
          Ok(Wait)
        }
      Ok(WebmProbeReady(value)) => value
    }
    if self.cluster_unknown &&
      webm_segment_child_id(header.id) &&
      header.id != WEBM_VOID &&
      header.id != WEBM_CRC32 {
      match self.finish_cluster(input) {
        Err(error) => Err(error)
        Ok(_) => self.step(input, eof)
      }
    } else {
      if self.cluster_elements >= WEBM_MAX_ELEMENTS {
        return Err(
          webm_stream_error(
            input,
            LimitExceeded,
            "cluster",
            "Cluster element count exceeds parser bound",
            header.start,
          ),
        )
      }
      if header.unknown {
        return Err(
          webm_stream_error(
            input,
            Unsupported,
            "cluster",
            "Unknown-sized nested element",
            header.start,
          ),
        )
      }
      let element = match webm_stream_probe_element(input, logical_end, true) {
        Err(error) => return Err(error)
        Ok(WebmProbeWait) =>
          return if eof {
            Err(
              webm_stream_error(
                input,
                TruncatedInput,
                "cluster",
                "Truncated Cluster child",
                header.start,
              ),
            )
          } else {
            Ok(Wait)
          }
        Ok(WebmProbeReady(value)) => value
      }
      self.cluster_elements += 1
      if element.id == WEBM_CLUSTER_TIMESTAMP {
        if self.cluster_timestamp is Some(_) {
          return Err(
            webm_stream_error(
              input,
              InvalidData,
              "cluster",
              "Duplicate Cluster Timestamp",
              element.start,
            ),
          )
        }
        self.cluster_timestamp = Some(
          match webm_uint(input.bytes, element.payload, element.end) {
            Ok(value) => value
            Err(error) => return Err(webm_stream_rebase(input, error))
          },
        )
      } else if element.id == WEBM_SIMPLE_BLOCK {
        let block_track = match
          webm_block_track_number(input.bytes, element.payload, element.end) {
          Ok(value) => value
          Err(error) => return Err(webm_stream_rebase(input, error))
        }
        if !self.webm_stream_track_is_known(block_track) {
          return Err(
            webm_stream_error(
              input,
              InvalidData,
              "block",
              "Block references an unknown track",
              element.start,
            ),
          )
        }
        if self.selected is Some(selected) && block_track == selected.number {
          let block = match
            webm_block_track(input.bytes, element.payload, element.end, [
              selected,
            ]) {
            Ok(value) => value
            Err(error) => return Err(webm_stream_rebase(input, error))
          }
          match self.enqueue_block(input, block, None, false, false) {
            Err(error) => return Err(error)
            Ok(_) => ()
          }
        }
      } else if element.id == WEBM_BLOCK_GROUP {
        let selected = match self.selected {
          Some(value) => value
          None =>
            return Err(
              webm_stream_error(
                input,
                InvalidState,
                "webm.stream",
                "Missing selected track",
                element.start,
              ),
            )
        }
        let parsed = match
          webm_stream_parse_group(
            input.bytes,
            element,
            self.track_numbers,
            selected,
          ) {
          Ok(value) => value
          Err(error) => return Err(webm_stream_rebase(input, error))
        }
        match parsed.0 {
          Some(block) =>
            match self.enqueue_block(input, block, parsed.1, parsed.2, true) {
              Err(error) => return Err(error)
              Ok(_) => ()
            }
          None => ()
        }
      }
      input.consume(element.end - element.start)
      Ok(Progress)
    }
  }
}

///|
fn Av1WebmStreamState::step_after_segment(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  if input.available() == 0 {
    if eof {
      self.stage = WebmDone
      return Ok(End)
    }
    return Ok(Wait)
  }
  match webm_stream_probe_element(input, None, true) {
    Err(error) => Err(error)
    Ok(WebmProbeWait) =>
      if eof {
        Err(
          webm_stream_error(
            input,
            TruncatedInput,
            "webm",
            "Truncated trailing global element",
            input.start,
          ),
        )
      } else {
        Ok(Wait)
      }
    Ok(WebmProbeReady(element)) => {
      if element.unknown {
        return Err(
          webm_stream_error(
            input,
            Unsupported,
            "webm",
            "Unknown-sized root Void/CRC",
            element.start,
          ),
        )
      }
      if element.id == WEBM_VOID || element.id == WEBM_CRC32 {
        input.consume(element.end - element.start)
        Ok(Progress)
      } else if element.id == WEBM_SEGMENT {
        Err(
          webm_stream_error(
            input,
            Unsupported,
            "webm",
            "Multiple Segment elements are unsupported",
            element.start,
          ),
        )
      } else {
        Err(
          webm_stream_error(
            input,
            InvalidData,
            "webm",
            "Unexpected non-global data after Segment",
            element.start,
          ),
        )
      }
    }
  }
}

///|
fn Av1WebmStreamState::step(
  self : Av1WebmStreamState,
  input : ContainerStreamInput,
  eof : Bool,
) -> Result[ContainerStreamStep, DecodeError] {
  match self.webm_stream_take_packet() {
    Some(packet) => return Ok(Packet(packet))
    None => ()
  }
  match self.stage {
    WebmNeedEbml => self.step_ebml(input, eof)
    WebmNeedSegment => self.step_segment_header(input, eof)
    WebmInSegment => self.step_segment(input, eof)
    WebmInCluster => self.step_cluster(input, eof)
    WebmAfterSegment => self.step_after_segment(input, eof)
    WebmDone => Ok(End)
  }
}