xref: /xiu/library/codec/h264/src/utils.rs (revision ccd9a1fa)
1 use super::errors::H264Error;
2 use bytesio::bits_reader::BitsReader;
3 
4 // ue(v) in 9.1 Parsing process for Exp-Golomb codes
5 // ISO_IEC_14496-10-AVC-2012.pdf, page 227.
6 // Syntax elements coded as ue(v), me(v), or se(v) are Exp-Golomb-coded.
7 //      leadingZeroBits = -1;
8 //      for( b = 0; !b; leadingZeroBits++ )
9 //          b = read_bits( 1 )
10 // The variable codeNum is then assigned as follows:
11 //      codeNum = (2<<leadingZeroBits) - 1 + read_bits( leadingZeroBits )
read_uev(bit_reader: &mut BitsReader) -> Result<u32, H264Error>12 pub fn read_uev(bit_reader: &mut BitsReader) -> Result<u32, H264Error> {
13     let mut leading_zeros_bits: usize = 0;
14 
15     loop {
16         if bit_reader.read_bit()? != 0 {
17             break;
18         }
19         leading_zeros_bits += 1;
20     }
21     let code_num = (1 << leading_zeros_bits) - 1 + bit_reader.read_n_bits(leading_zeros_bits)?;
22     Ok(code_num as u32)
23 }
24 
25 // ISO_IEC_14496-10-AVC-2012.pdf, page 229.
read_sev(bit_reader: &mut BitsReader) -> Result<i32, H264Error>26 pub fn read_sev(bit_reader: &mut BitsReader) -> Result<i32, H264Error> {
27     let code_num = read_uev(bit_reader)?;
28 
29     let negative: i64 = if code_num % 2 == 0 { -1 } else { 1 };
30     let se_value = (code_num as i64 + 1) / 2 * negative;
31     Ok(se_value as i32)
32 }
33 
34 #[cfg(test)]
35 mod tests {
36 
37     use super::read_uev;
38     use bytes::BytesMut;
39     use bytesio::bits_reader::BitsReader;
40     use bytesio::bytes_reader::BytesReader;
41 
42     #[test]
test_read_uev()43     fn test_read_uev() {
44         // 0 => 1 => 1
45         // 1 => 10 => 010
46         // 2 => 11 => 011
47         // 3 => 100 => 00100
48         // 4 => 101 => 00101
49         // 5 => 110 => 00110
50         // 6 => 111 => 00111
51         // 7 => 1000 => 0001000
52         // 8 => 1001 => 0001001
53 
54         let mut bytes_reader = BytesReader::new(BytesMut::new());
55         bytes_reader.extend_from_slice(&[0b00000001]);
56         bytes_reader.extend_from_slice(&[0b00000010]);
57         bytes_reader.extend_from_slice(&[0b00000011]);
58         bytes_reader.extend_from_slice(&[0b00000100]);
59         bytes_reader.extend_from_slice(&[0b00000101]);
60         bytes_reader.extend_from_slice(&[0b00000110]);
61         bytes_reader.extend_from_slice(&[0b00000111]);
62         bytes_reader.extend_from_slice(&[0b00001000]);
63         bytes_reader.extend_from_slice(&[0b00001001]);
64 
65         let mut bits_reader = BitsReader::new(bytes_reader);
66 
67         bits_reader.read_n_bits(7).unwrap();
68         let v1 = read_uev(&mut bits_reader).unwrap();
69         println!("=={v1}==");
70         assert!(v1 == 0);
71 
72         bits_reader.read_n_bits(5).unwrap();
73         let v2 = read_uev(&mut bits_reader).unwrap();
74         println!("=={v2}==");
75         assert!(v2 == 1);
76 
77         bits_reader.read_n_bits(5).unwrap();
78         let v3 = read_uev(&mut bits_reader).unwrap();
79         println!("=={v3}==");
80         assert!(v3 == 2);
81 
82         bits_reader.read_n_bits(3).unwrap();
83         let v4 = read_uev(&mut bits_reader).unwrap();
84         println!("=={v4}==");
85         assert!(v4 == 3);
86 
87         bits_reader.read_n_bits(3).unwrap();
88         let v5 = read_uev(&mut bits_reader).unwrap();
89         println!("=={v5}==");
90         assert!(v5 == 4);
91 
92         bits_reader.read_n_bits(3).unwrap();
93         let v6 = read_uev(&mut bits_reader).unwrap();
94         println!("=={v6}==");
95         assert!(v6 == 5);
96 
97         bits_reader.read_n_bits(3).unwrap();
98         let v7 = read_uev(&mut bits_reader).unwrap();
99         println!("=={v7}==");
100         assert!(v7 == 6);
101 
102         bits_reader.read_n_bits(1).unwrap();
103         let v8 = read_uev(&mut bits_reader).unwrap();
104         println!("=={v8}==");
105         assert!(v8 == 7);
106 
107         bits_reader.read_n_bits(1).unwrap();
108         let v9 = read_uev(&mut bits_reader).unwrap();
109         println!("=={v9}==");
110         assert!(v9 == 8);
111     }
112 }
113