cros_codecs/codec/av1/
reader.rs

1// Copyright 2023 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::anyhow;
6use bitreader::BitReader;
7
8use crate::codec::av1::helpers;
9
10use super::parser::AnnexBState;
11
12pub struct Reader<'a>(BitReader<'a>);
13
14impl<'a> Reader<'a> {
15    pub fn new(data: &'a [u8]) -> Self {
16        Self(BitReader::new(data))
17    }
18
19    /// Read a single bit from the spec. Implements f(1) to return a bool for
20    /// convenience.
21    pub fn read_bit(&mut self) -> anyhow::Result<bool> {
22        self.0.read_bool().map_err(|e| anyhow!(e))
23    }
24
25    /// Implements f(n): Unsigned n-bit number appearing directly in the
26    /// bitstream. The bits are read from high to low order. See 4.10.2
27    pub fn read_bits(&mut self, num_bits: u8) -> anyhow::Result<u32> {
28        self.0.read_u32(num_bits).map_err(|e| anyhow!(e))
29    }
30
31    /// Implements uvlc(): Variable length unsigned n-bit number appearing
32    /// directly in the bitstream. See 4.10.3
33    pub fn read_uvlc(&mut self) -> anyhow::Result<u32> {
34        let mut leading_zeroes = 0;
35        loop {
36            let done = self.read_bit()?;
37
38            if done {
39                break;
40            }
41
42            leading_zeroes += 1;
43        }
44
45        if leading_zeroes >= 32 {
46            return Ok(u32::MAX);
47        }
48
49        let value = self.read_bits(leading_zeroes)?;
50        Ok(value + (1 << leading_zeroes) - 1)
51    }
52
53    /// Implements le(n): Unsigned little-endian n-byte number appearing
54    /// directly in the bitstream. See 4.10.4
55    pub fn read_le(&mut self, num_bits: u8) -> anyhow::Result<u32> {
56        assert!(self.0.is_aligned(1));
57        let mut t = 0;
58
59        for i in 0..num_bits {
60            let byte = self.read_bits(8)?;
61            t += byte << (i * 8)
62        }
63
64        Ok(t)
65    }
66
67    /// Implements leb128(): Unsigned integer represented by a variable number
68    /// of little-endian bytes. See 4.10.5
69    pub fn read_leb128(&mut self) -> anyhow::Result<u32> {
70        assert!(self.0.is_aligned(1));
71
72        let mut value = 0u64;
73        let mut leb128bytes = 0;
74
75        for i in 0..8 {
76            let byte = u64::from(self.read_bits(8)?);
77            value |= (byte & 0x7f) << (i * 7);
78
79            leb128bytes += 1;
80
81            if byte & 0x80 == 0 {
82                break;
83            }
84        }
85
86        assert!(leb128bytes < 8);
87        assert!(value <= u32::MAX.into());
88        Ok(value as u32)
89    }
90
91    /// Implements su(n): Signed integer converted from an n bits unsigned
92    /// integer in the bitstream. (The unsigned integer corresponds to the
93    /// bottom n bits of the signed integer.). See 4.10.6
94    pub fn read_su(&mut self, num_bits: u8) -> anyhow::Result<i32> {
95        let mut value = self.read_bits(num_bits)? as i32;
96        let sign_mask = 1 << (num_bits - 1);
97
98        if (value & sign_mask) != 0 {
99            value -= 2 * sign_mask;
100        }
101
102        Ok(value)
103    }
104
105    /// Implements ns(n): Unsigned encoded integer with maximum number of values
106    /// n (i.e. output in range 0..n-1). See 4.10.7
107    pub fn read_ns(&mut self, num_bits: u8) -> anyhow::Result<u32> {
108        let w = helpers::floor_log2(u32::from(num_bits)) + 1;
109        let m = (1 << w) - num_bits;
110        let v = self.read_bits(u8::try_from(w)? - 1)?;
111
112        if v < m.into() {
113            return Ok(v);
114        }
115
116        let extra_bit = self.read_bit()?;
117        Ok((v << 1) - u32::from(m) + u32::from(extra_bit))
118    }
119
120    /// Implements 5.9.13: Delta quantizer syntax.
121    pub fn read_delta_q(&mut self) -> anyhow::Result<i32> {
122        let delta_coded = self.read_bit()?;
123
124        if delta_coded {
125            self.read_su(7)
126        } else {
127            Ok(0)
128        }
129    }
130
131    pub fn more_data_in_bitstream(&self) -> bool {
132        self.0.remaining() != 0
133    }
134
135    pub(crate) fn consumed(&self, start_pos: u32) -> u32 {
136        assert!(self.position() % 8 == 0);
137        (self.position() / 8) as u32 - start_pos
138    }
139
140    /// Get the length of the current OBU in AnnexB format.
141    pub fn current_annexb_obu_length(
142        &mut self,
143        annexb_state: &mut AnnexBState,
144    ) -> anyhow::Result<Option<usize>> {
145        if !self.more_data_in_bitstream() {
146            return Ok(None);
147        }
148
149        #[allow(clippy::comparison_chain)]
150        if annexb_state.temporal_unit_consumed == annexb_state.temporal_unit_size {
151            annexb_state.temporal_unit_size = 0;
152        } else if annexb_state.temporal_unit_consumed > annexb_state.temporal_unit_size {
153            return Err(anyhow!(
154                "temporal_unit_size is {} but we consumed {} bytes",
155                annexb_state.temporal_unit_size,
156                annexb_state.temporal_unit_consumed,
157            ));
158        }
159
160        if annexb_state.temporal_unit_size == 0 {
161            annexb_state.temporal_unit_size = self.read_leb128()?;
162            if annexb_state.temporal_unit_size == 0 {
163                return Ok(None);
164            }
165        }
166
167        let start_pos = self.consumed(0);
168
169        #[allow(clippy::comparison_chain)]
170        if annexb_state.frame_unit_consumed == annexb_state.frame_unit_size {
171            annexb_state.frame_unit_size = 0;
172        } else if annexb_state.frame_unit_consumed > annexb_state.frame_unit_size {
173            return Err(anyhow!(
174                "frame_unit_size is {} but we consumed {} bytes",
175                annexb_state.frame_unit_size,
176                annexb_state.frame_unit_consumed,
177            ));
178        }
179
180        if annexb_state.frame_unit_size == 0 {
181            annexb_state.frame_unit_size = self.read_leb128()?;
182            if annexb_state.frame_unit_size == 0 {
183                return Ok(None);
184            }
185            annexb_state.temporal_unit_consumed += self.consumed(start_pos);
186        }
187
188        let start_pos = self.consumed(0);
189        let obu_length = self.read_leb128()?;
190        let consumed = self.consumed(start_pos);
191
192        annexb_state.temporal_unit_consumed += consumed;
193        annexb_state.frame_unit_consumed += consumed;
194
195        Ok(Some(obu_length.try_into().unwrap()))
196    }
197
198    /// Skips `num_bits` bits.
199    pub fn skip(&mut self, num_bits: u64) -> anyhow::Result<()> {
200        self.0.skip(num_bits).map_err(|e| anyhow!(e))
201    }
202
203    pub fn position(&self) -> u64 {
204        self.0.position()
205    }
206
207    /// Implements 5.3.4.
208    pub fn read_trailing_bits(&mut self, mut num_bits: u64) -> anyhow::Result<()> {
209        let trailing_one_bit = self.read_bit()?;
210        num_bits -= 1;
211
212        if !trailing_one_bit {
213            return Err(anyhow!("bad padding: trailing_one_bit is not set"));
214        }
215
216        while num_bits > 0 {
217            let trailing_zero_bit = self.read_bit()?;
218            if trailing_zero_bit {
219                return Err(anyhow!("bad padding: trailing_zero_bit is set"));
220            }
221            num_bits -= 1;
222        }
223
224        Ok(())
225    }
226
227    fn decode_subexp(&mut self, num_syms: i32) -> anyhow::Result<u32> {
228        let mut i = 0;
229        let mut mk = 0;
230        let k = 3;
231
232        loop {
233            let b2 = if i != 0 { k + i - 1 } else { k };
234            let a = 1 << b2;
235            if num_syms <= mk + 3 * a {
236                let num_bits = u8::try_from(num_syms - mk).unwrap();
237                let subexp_final_bits = self.read_ns(num_bits)?;
238                return Ok(subexp_final_bits);
239            } else {
240                let subexp_more_bits = self.read_bit()?;
241                if subexp_more_bits {
242                    i += 1;
243                    mk += a;
244                } else {
245                    let num_bits = u8::try_from(b2).unwrap();
246                    let subexp_bits = self.read_bits(num_bits)?;
247                    return Ok(subexp_bits + mk as u32);
248                }
249            }
250        }
251    }
252
253    /// Implements 5.9.27.
254    pub fn decode_unsigned_subexp_with_ref(&mut self, mx: i32, r: i32) -> anyhow::Result<u32> {
255        let v = self.decode_subexp(mx)?;
256        if (r << 1) <= mx {
257            Ok(helpers::inverse_recenter(r, v.try_into().unwrap())
258                .try_into()
259                .unwrap())
260        } else {
261            let res = mx - 1 - helpers::inverse_recenter(mx - 1 - r, v.try_into().unwrap());
262            Ok(res.try_into().unwrap())
263        }
264    }
265
266    /// Implements 5.9.26.
267    pub fn decode_signed_subexp_with_ref(
268        &mut self,
269        low: i32,
270        high: i32,
271        r: i32,
272    ) -> anyhow::Result<i32> {
273        let x = self.decode_unsigned_subexp_with_ref(high - low, r - low)?;
274        Ok(i32::try_from(x).unwrap() + low)
275    }
276
277    /// Implements 5.3.5 Byte alignment syntax
278    pub fn byte_alignment(&mut self) -> anyhow::Result<()> {
279        while (self.position() & 7) != 0 {
280            self.read_bit()?;
281        }
282
283        Ok(())
284    }
285
286    pub fn remaining_bits(&self) -> u64 {
287        self.0.remaining()
288    }
289}
290
291impl<'a> Clone for Reader<'a> {
292    fn clone(&self) -> Self {
293        Self(self.0.relative_reader())
294    }
295}