1use crate::cabac_codec::{decode_difference, encode_difference};
8
9#[derive(Copy, Clone, Debug, Eq, PartialEq)]
11pub enum CodecCorrection {
12 TokenCount,
13 BlockTypeCorrection,
14 LenCorrection,
15 DistOnlyCorrection,
16 DistAfterLenCorrection,
17 TreeCodeBitLengthCorrection,
18 LDTypeCorrection,
19 RepeatCountCorrection,
20 LDBitLengthCorrection,
21
22 TreeCodeCountCorrection,
23 LiteralCountCorrection,
24 DistanceCountCorrection,
25 UncompressBlockLenCorrection,
26
27 Last,
28 EndOfChunk,
29 LiteralPredictionWrong,
30 ReferencePredictionWrong,
31 MAX,
32}
33
34pub trait PredictionEncoder {
35 fn encode_correction(&mut self, action: CodecCorrection, value: u32);
36
37 fn encode_verify_state(&mut self, message: &'static str, checksum: u64);
38
39 fn finish(&mut self);
40
41 fn encode_correction_diff(
42 &mut self,
43 action: CodecCorrection,
44 actual_value: u32,
45 predicted_value: u32,
46 ) {
47 self.encode_correction(action, encode_difference(predicted_value, actual_value));
48 }
49
50 fn encode_misprediction(&mut self, action: CodecCorrection, actual_value: bool) {
51 self.encode_correction(action, actual_value as u32);
52 }
53
54 fn encode_correction_bool(
56 &mut self,
57 action: CodecCorrection,
58 actual_value: bool,
59 predicted_value: bool,
60 ) {
61 self.encode_correction(action, (actual_value != predicted_value) as u32)
62 }
63}
64
65pub trait PredictionDecoder {
66 fn decode_correction(&mut self, correction: CodecCorrection) -> u32;
67 fn decode_verify_state(&mut self, message: &'static str, checksum: u64);
68
69 #[inline]
70 fn decode_correction_diff(&mut self, correction: CodecCorrection, predicted_value: u32) -> u32 {
71 let actual_value = self.decode_correction(correction);
72 decode_difference(predicted_value, actual_value)
73 }
74
75 #[inline]
76 fn decode_misprediction(&mut self, correction: CodecCorrection) -> bool {
77 self.decode_correction(correction) != 0
78 }
79
80 fn decode_correction_bool(
82 &mut self,
83 correction: CodecCorrection,
84 predicted_value: bool,
85 ) -> bool {
86 predicted_value ^ (self.decode_correction(correction) != 0)
87 }
88}
89
90#[derive(Copy, Clone, Debug, Eq, PartialEq)]
91pub enum CodecAction {
92 Correction(CodecCorrection, u32),
93 VerifyState(&'static str, u64),
94}
95
96#[derive(Default)]
97pub struct CountNonDefaultActions {
98 pub total_non_default: u32,
99
100 pub corrections_count: [u32; CodecCorrection::MAX as usize],
101}
102
103impl CountNonDefaultActions {
104 pub fn record_correction(&mut self, correction: CodecCorrection, value: u32) {
105 if value != 0 {
106 self.corrections_count[correction as usize] += 1;
107 self.total_non_default += 1;
108 }
109 }
110
111 pub fn print(&self) {
112 use CodecCorrection::*;
113
114 let corr = [
115 TokenCount,
116 BlockTypeCorrection,
117 LenCorrection,
118 DistOnlyCorrection,
119 DistAfterLenCorrection,
120 TreeCodeBitLengthCorrection,
121 LDTypeCorrection,
122 RepeatCountCorrection,
123 LDBitLengthCorrection,
124 TreeCodeCountCorrection,
125 LiteralCountCorrection,
126 DistanceCountCorrection,
127 UncompressBlockLenCorrection,
128 Last,
129 EndOfChunk,
130 LiteralPredictionWrong,
131 ReferencePredictionWrong,
132 ];
133
134 assert_eq!(
135 corr.len(),
136 CodecCorrection::MAX as usize,
137 "need to update array if you add an enum"
138 );
139
140 for i in corr {
141 if self.corrections_count[i as usize] != 0 {
142 println!("{:?}: {}", i, self.corrections_count[i as usize]);
143 }
144 }
145 }
146}
147
148pub struct VerifyPredictionDecoder {
149 actions: Vec<CodecAction>,
150 index: usize,
151}
152
153#[derive(Default)]
154pub struct VerifyPredictionEncoder {
155 actions: Vec<CodecAction>,
156 count: CountNonDefaultActions,
157}
158
159#[allow(dead_code)]
161impl VerifyPredictionEncoder {
162 pub fn new() -> Self {
163 Self {
164 actions: Vec::new(),
165 count: CountNonDefaultActions::default(),
166 }
167 }
168
169 pub fn actions(&self) -> Vec<CodecAction> {
170 self.actions.clone()
171 }
172
173 pub fn print(&self) {
174 self.count.print();
175 }
176
177 pub fn count_nondefault_actions(&self) -> usize {
178 self.count.total_non_default as usize
179 }
180}
181
182impl PredictionEncoder for VerifyPredictionEncoder {
183 fn encode_verify_state(&mut self, message: &'static str, checksum: u64) {
184 self.actions
185 .push(CodecAction::VerifyState(message, checksum));
186 }
187
188 fn encode_correction(&mut self, action: CodecCorrection, value: u32) {
189 self.actions.push(CodecAction::Correction(action, value));
190 self.count.record_correction(action, value);
191 }
192 fn finish(&mut self) {}
193}
194
195#[allow(dead_code)]
197impl VerifyPredictionDecoder {
198 pub fn new(actions: Vec<CodecAction>) -> Self {
199 Self { actions, index: 0 }
200 }
201
202 fn pop(&mut self) -> Option<CodecAction> {
203 if self.index >= self.actions.len() {
204 None
205 } else {
206 self.index += 1;
207 Some(self.actions[self.index - 1])
208 }
209 }
210}
211
212impl PredictionDecoder for VerifyPredictionDecoder {
213 fn decode_verify_state(&mut self, message: &'static str, checksum: u64) {
214 let x = self.pop().unwrap();
215 assert_eq!(
216 x,
217 CodecAction::VerifyState(message, checksum),
218 "mismatch {} (left encode, right decode)",
219 self.index
220 );
221 }
222
223 fn decode_correction(&mut self, correction: CodecCorrection) -> u32 {
224 let x = self.pop().unwrap();
225 match x {
226 CodecAction::Correction(c, value) => {
227 assert_eq!(correction, c);
228 return value;
229 }
230 CodecAction::VerifyState(s, _h) => {
231 panic!("found VerifyState {}, expected {:?}", s, correction);
232 }
233 }
234 }
235}
236
237#[cfg(test)]
238pub fn drive_encoder<T: PredictionEncoder>(encoder: &mut T, actions: &[CodecAction]) {
239 for action in actions {
240 match action {
241 &CodecAction::Correction(correction, value) => {
242 encoder.encode_correction(correction, value);
243 }
244 &CodecAction::VerifyState(message, checksum) => {
245 encoder.encode_verify_state(message, checksum);
246 }
247 }
248 }
249}
250
251#[cfg(test)]
252pub fn verify_decoder<T: PredictionDecoder>(decoder: &mut T, actions: &[CodecAction]) {
253 for action in actions {
254 match action {
255 &CodecAction::Correction(correction, value) => {
256 let x = decoder.decode_correction(correction);
257 assert_eq!(x, value);
258 }
259 &CodecAction::VerifyState(message, checksum) => {
260 decoder.decode_verify_state(message, checksum);
261 }
262 }
263 }
264}
265
266#[cfg(test)]
269#[derive(Default)]
270pub struct AssertDefaultOnlyEncoder {}
271
272#[cfg(test)]
273impl PredictionEncoder for AssertDefaultOnlyEncoder {
274 fn encode_correction(&mut self, action: CodecCorrection, value: u32) {
275 assert_eq!(0, value, "unexpected correction {:?}", action);
276 }
277
278 fn encode_verify_state(&mut self, _message: &'static str, _checksum: u64) {}
279
280 fn finish(&mut self) {}
281}
282
283#[cfg(test)]
284#[derive(Default)]
285pub struct AssertDefaultOnlyDecoder {}
286
287#[cfg(test)]
288impl PredictionDecoder for AssertDefaultOnlyDecoder {
289 fn decode_correction(&mut self, _correction: CodecCorrection) -> u32 {
290 0
291 }
292
293 fn decode_verify_state(&mut self, _message: &'static str, _checksum: u64) {}
294}
295
296impl<A, B> PredictionEncoder for (A, B)
299where
300 A: PredictionEncoder,
301 B: PredictionEncoder,
302{
303 fn encode_verify_state(&mut self, message: &'static str, checksum: u64) {
304 self.0.encode_verify_state(message, checksum);
305 self.1.encode_verify_state(message, checksum);
306 }
307
308 fn encode_correction(&mut self, action: CodecCorrection, value: u32) {
309 self.0.encode_correction(action, value);
310 self.1.encode_correction(action, value);
311 }
312
313 fn finish(&mut self) {
314 self.0.finish();
315 self.1.finish();
316 }
317}
318
319impl<A, B> PredictionDecoder for (A, B)
322where
323 A: PredictionDecoder,
324 B: PredictionDecoder,
325{
326 fn decode_correction(&mut self, correction: CodecCorrection) -> u32 {
327 let a = self.0.decode_correction(correction);
328 let b = self.1.decode_correction(correction);
329 assert_eq!(a, b);
330 a
331 }
332
333 fn decode_verify_state(&mut self, message: &'static str, checksum: u64) {
334 self.0.decode_verify_state(message, checksum);
335 self.1.decode_verify_state(message, checksum);
336 }
337}