pixelflux/encoders/
bits.rs1#[derive(Default)]
13pub struct BitWriter {
14 bytes: Vec<u8>,
15 bits: usize,
16}
17
18impl BitWriter {
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 pub fn len(&self) -> usize {
25 self.bits
26 }
27
28 pub fn is_empty(&self) -> bool {
29 self.bits == 0
30 }
31
32 pub fn aligned(&self) -> bool {
34 self.bits.is_multiple_of(8)
35 }
36
37 pub fn u(&mut self, count: u32, value: u64) {
39 for shift in (0..count).rev() {
40 if self.bits.is_multiple_of(8) {
41 self.bytes.push(0);
42 }
43 if (value >> shift) & 1 != 0 {
44 let index = self.bits >> 3;
45 self.bytes[index] |= 1 << (7 - (self.bits & 7));
46 }
47 self.bits += 1;
48 }
49 }
50
51 pub fn flag(&mut self, value: bool) {
53 self.u(1, value as u64);
54 }
55
56 pub fn ue(&mut self, value: u32) {
58 let v = value as u64 + 1;
59 let zeros = 63 - v.leading_zeros();
60 self.u(zeros, 0);
61 self.u(zeros + 1, v);
62 }
63
64 pub fn se(&mut self, value: i32) {
66 let mapped = if value > 0 {
67 2 * value as u32 - 1
68 } else {
69 (-2 * value) as u32
70 };
71 self.ue(mapped);
72 }
73
74 pub fn trailing_bits(&mut self) {
76 self.flag(true);
77 self.align();
78 }
79
80 pub fn align(&mut self) {
82 while !self.bits.is_multiple_of(8) {
83 self.flag(false);
84 }
85 }
86
87 pub fn bytes(&mut self, bytes: &[u8]) {
89 debug_assert!(self.aligned());
90 self.bytes.extend_from_slice(bytes);
91 self.bits += 8 * bytes.len();
92 }
93
94 pub fn into_bytes(self) -> Vec<u8> {
96 self.bytes
97 }
98
99 pub fn as_bytes(&self) -> &[u8] {
100 &self.bytes
101 }
102}
103
104pub fn escape(rbsp: &[u8]) -> Vec<u8> {
107 let mut out = Vec::with_capacity(rbsp.len() + rbsp.len() / 64 + 4);
108 let mut zeros = 0;
109 for &byte in rbsp {
110 if zeros >= 2 && byte <= 3 {
111 out.push(3);
112 zeros = 0;
113 }
114 out.push(byte);
115 zeros = if byte == 0 { zeros + 1 } else { 0 };
116 }
117 out
118}
119
120pub fn nal_unit(header: &[u8], rbsp: &[u8]) -> Vec<u8> {
122 let mut out = vec![0, 0, 0, 1];
123 out.extend_from_slice(header);
124 out.extend(escape(rbsp));
125 out
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn exp_golomb_and_fixed_fields_pack_as_the_standards_read_them() {
134 let mut w = BitWriter::new();
135 w.ue(0);
136 w.ue(1);
137 w.ue(2);
138 w.ue(3);
139 w.se(1);
140 w.se(-1);
141 w.u(3, 0b101);
142 w.trailing_bits();
143 assert_eq!(w.as_bytes(), &[0b1010_0110, 0b0100_0100, 0b1110_1100]);
144 assert_eq!(w.len(), 24);
145 }
146
147 #[test]
148 fn emulation_prevention_guards_every_start_code() {
149 assert_eq!(
150 escape(&[0, 0, 1, 0, 0, 0, 5, 0, 0, 3]),
151 vec![0, 0, 3, 1, 0, 0, 3, 0, 5, 0, 0, 3, 3]
152 );
153 assert_eq!(
154 nal_unit(&[0x67], &[0, 0, 2]),
155 vec![0, 0, 0, 1, 0x67, 0, 0, 3, 2]
156 );
157 }
158}