diff --git a/crates/av1/src/decoder.rs b/crates/av1/src/decoder.rs index 43abce22b..d463493a1 100644 --- a/crates/av1/src/decoder.rs +++ b/crates/av1/src/decoder.rs @@ -425,6 +425,8 @@ impl Decoder { fn parse_obus(&mut self, data: &[u8], out: &mut Vec<(Output, usize, u32)>) -> Result<()> { let mut tu = 0usize; + // Repeated-frame outputs in `out`, counted as they are added rather than recounted per OBU. + let mut existing = out.iter().filter(|(o, _, _)| matches!(o, Output::Existing { .. })).count(); let mut pos = 0; while pos < data.len() { let obu = parse_obu_unit(data, pos)?; @@ -444,9 +446,10 @@ impl Decoder { } OBU_FRAME_HEADER_T | OBU_REDUNDANT_FRAME_HEADER_T | OBU_FRAME_T => { if let Some(o) = self.frame_obu(&obu)? { - if out.iter().filter(|(o, _, _)| matches!(o, Output::Existing { .. })).count() >= 32 { + if existing >= 32 { return Err(Error::Invalid("too many frame outputs in chunk")); } + existing += usize::from(matches!(o, Output::Existing { .. })); out.push((o, tu, spatial_id)); } } diff --git a/crates/hevc/src/slice.rs b/crates/hevc/src/slice.rs index aadf6159f..3d6233fb6 100644 --- a/crates/hevc/src/slice.rs +++ b/crates/hevc/src/slice.rs @@ -326,7 +326,9 @@ impl SliceHeader { /// entry_point_offset list (tiles / wavefront substreams). fn parse_entry_points(&mut self, r: &mut BitReader, pps: &Pps, sps: &Sps) -> Result<()> { - self.entry_points.clear(); + // A fresh list, not `clear()`: a dependent segment starts as a copy of its independent + // segment's header, and clearing would keep that copy's allocation for every segment. + self.entry_points = Vec::new(); if pps.tiles_enabled || pps.entropy_coding_sync { let n = r.read_ue()?; ensure!(n <= sps.pic_width_in_ctbs() * sps.pic_height_in_ctbs(), "num_entry_point_offsets out of range");