]>
Commit | Line | Data |
---|---|---|
0cc75664 KS |
1 | use nihav_codec_support::data::GenericCache; |
2 | use super::vpcommon::*; | |
3 | ||
4 | pub enum VPTreeDef<T: Copy> { | |
5 | Index(u8), | |
6 | Value(T), | |
7 | } | |
8 | ||
9 | pub trait VPTreeReader { | |
10 | fn read_tree<T:Copy>(&mut self, tree_def: &[VPTreeDef<T>], tree_prob: &[u8]) -> T; | |
11 | } | |
12 | ||
13 | impl<'a> VPTreeReader for BoolCoder<'a> { | |
14 | fn read_tree<T:Copy>(&mut self, tree_def: &[VPTreeDef<T>], tree_prob: &[u8]) -> T { | |
15 | let mut idx = 0; | |
16 | ||
17 | loop { | |
18 | let bit = self.read_prob(tree_prob[idx >> 1]); | |
19 | match tree_def[idx + (bit as usize)] { | |
20 | VPTreeDef::Value(v) => return v, | |
21 | VPTreeDef::Index(ix) => { idx = ix as usize; }, | |
22 | }; | |
23 | } | |
24 | } | |
25 | } | |
26 | ||
27 | #[repr(u8)] | |
e6aaad5c | 28 | #[derive(Clone,Copy,PartialEq,Debug,Default)] |
0cc75664 | 29 | pub enum PredMode { |
e6aaad5c | 30 | #[default] |
0cc75664 KS |
31 | DCPred, |
32 | HPred, | |
33 | VPred, | |
34 | TMPred, | |
35 | BPred, | |
36 | ||
37 | //sub-block prediction modes | |
38 | LDPred, | |
39 | RDPred, | |
40 | VRPred, | |
41 | VLPred, | |
42 | HDPred, | |
43 | HUPred, | |
44 | ||
45 | Inter, | |
46 | } | |
47 | ||
0cc75664 KS |
48 | impl PredMode { |
49 | pub fn to_b_mode(self) -> Self { | |
50 | if self == PredMode::DCPred { | |
51 | self | |
52 | } else { | |
53 | PredMode::TMPred | |
54 | } | |
55 | } | |
56 | pub fn to_b_index(self) -> usize { | |
57 | match self { | |
58 | PredMode::DCPred => 0, | |
59 | PredMode::TMPred => 1, | |
60 | PredMode::VPred => 2, | |
61 | PredMode::HPred => 3, | |
62 | PredMode::LDPred => 4, | |
63 | PredMode::RDPred => 5, | |
64 | PredMode::VRPred => 6, | |
65 | PredMode::VLPred => 7, | |
66 | PredMode::HDPred => 8, | |
67 | PredMode::HUPred => 9, | |
68 | _ => unreachable!(), | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
73 | #[derive(Clone,Copy,PartialEq)] | |
74 | pub enum DCTToken { | |
75 | Zero, | |
76 | One, | |
77 | Two, | |
78 | Three, | |
79 | Four, | |
80 | Cat1, | |
81 | Cat2, | |
82 | Cat3, | |
83 | Cat4, | |
84 | Cat5, | |
85 | Cat6, | |
86 | EOB, | |
87 | } | |
88 | ||
89 | pub fn expand_token(bc: &mut BoolCoder, token: DCTToken) -> i16 { | |
90 | let cat; | |
91 | match token { | |
92 | DCTToken::Zero => return 0, | |
93 | DCTToken::One => return if bc.read_bool() { -1 } else { 1 }, | |
94 | DCTToken::Two => return if bc.read_bool() { -2 } else { 2 }, | |
95 | DCTToken::Three => return if bc.read_bool() { -3 } else { 3 }, | |
96 | DCTToken::Four => return if bc.read_bool() { -4 } else { 4 }, | |
97 | DCTToken::Cat1 => cat = 0, | |
98 | DCTToken::Cat2 => cat = 1, | |
99 | DCTToken::Cat3 => cat = 2, | |
100 | DCTToken::Cat4 => cat = 3, | |
101 | DCTToken::Cat5 => cat = 4, | |
102 | DCTToken::Cat6 => cat = 5, | |
103 | _ => unreachable!(), | |
104 | }; | |
105 | let mut add = 0i16; | |
106 | let add_probs = &VP56_COEF_ADD_PROBS[cat]; | |
107 | for prob in add_probs.iter() { | |
108 | if *prob == 128 { break; } | |
109 | add = (add << 1) | (bc.read_prob(*prob) as i16); | |
110 | } | |
111 | let sign = bc.read_bool(); | |
112 | let level = VP56_COEF_BASE[cat] + add; | |
113 | if !sign { | |
114 | level | |
115 | } else { | |
116 | -level | |
117 | } | |
118 | } | |
119 | ||
120 | #[derive(Clone,Copy,Debug,PartialEq)] | |
121 | pub enum MVSplitMode { | |
122 | TopBottom, | |
123 | LeftRight, | |
124 | Quarters, | |
125 | Sixteenths, | |
126 | } | |
127 | ||
128 | #[derive(Clone,Copy,Debug,PartialEq)] | |
129 | pub enum SubMVRef { | |
130 | Left, | |
131 | Above, | |
132 | New, | |
133 | Zero, | |
134 | } | |
135 | ||
136 | pub struct PredCache { | |
137 | pub y_pred: GenericCache<u8>, | |
138 | pub u_pred: GenericCache<u8>, | |
139 | pub v_pred: GenericCache<u8>, | |
140 | pub y2_pred: GenericCache<u8>, | |
141 | pub y_pred_left: [u8; 4], | |
142 | pub u_pred_left: [u8; 2], | |
143 | pub v_pred_left: [u8; 2], | |
144 | pub y2_pred_left: u8, | |
145 | } | |
146 | ||
147 | impl PredCache { | |
148 | pub fn new() -> Self { | |
149 | Self { | |
150 | y_pred: GenericCache::new(1, 1, 0), | |
151 | u_pred: GenericCache::new(1, 1, 0), | |
152 | v_pred: GenericCache::new(1, 1, 0), | |
153 | y2_pred: GenericCache::new(1, 1, 0), | |
154 | y_pred_left: [0; 4], | |
155 | u_pred_left: [0; 2], | |
156 | v_pred_left: [0; 2], | |
157 | y2_pred_left: 0, | |
158 | } | |
159 | } | |
160 | pub fn resize(&mut self, mb_w: usize) { | |
161 | self.y_pred = GenericCache::new(4, mb_w * 4 + 1, 0); | |
162 | self.u_pred = GenericCache::new(2, mb_w * 2 + 1, 0); | |
163 | self.v_pred = GenericCache::new(2, mb_w * 2 + 1, 0); | |
164 | self.y2_pred = GenericCache::new(1, mb_w + 1, 0); | |
165 | } | |
166 | pub fn reset(&mut self) { | |
167 | self.y_pred.reset(); | |
168 | self.u_pred.reset(); | |
169 | self.v_pred.reset(); | |
170 | self.y2_pred.reset(); | |
171 | self.y_pred_left = [0; 4]; | |
172 | self.u_pred_left = [0; 2]; | |
173 | self.v_pred_left = [0; 2]; | |
174 | self.y2_pred_left = 0; | |
175 | } | |
176 | pub fn update_row(&mut self) { | |
177 | self.y_pred.update_row(); | |
178 | self.u_pred.update_row(); | |
179 | self.v_pred.update_row(); | |
180 | self.y2_pred.update_row(); | |
181 | } | |
d0d21988 KS |
182 | pub fn reset_left(&mut self) { |
183 | self.y_pred_left = [0; 4]; | |
184 | self.u_pred_left = [0; 2]; | |
185 | self.v_pred_left = [0; 2]; | |
186 | self.y2_pred_left = 0; | |
187 | } | |
0cc75664 KS |
188 | } |
189 | ||
190 | pub const Y_MODE_TREE: &[VPTreeDef<PredMode>] = &[ | |
191 | VPTreeDef::Value(PredMode::DCPred), VPTreeDef::Index(2), | |
192 | VPTreeDef::Index(4), VPTreeDef::Index(6), | |
193 | VPTreeDef::Value(PredMode::VPred), VPTreeDef::Value(PredMode::HPred), | |
194 | VPTreeDef::Value(PredMode::TMPred), VPTreeDef::Value(PredMode::BPred), | |
195 | ]; | |
196 | pub const KF_Y_MODE_TREE: &[VPTreeDef<PredMode>] = &[ | |
197 | VPTreeDef::Value(PredMode::BPred), VPTreeDef::Index(2), | |
198 | VPTreeDef::Index(4), VPTreeDef::Index(6), | |
199 | VPTreeDef::Value(PredMode::DCPred), VPTreeDef::Value(PredMode::VPred), | |
200 | VPTreeDef::Value(PredMode::HPred), VPTreeDef::Value(PredMode::TMPred), | |
201 | ]; | |
202 | pub const UV_MODE_TREE: &[VPTreeDef<PredMode>] = &[ | |
203 | VPTreeDef::Value(PredMode::DCPred), VPTreeDef::Index(2), | |
204 | VPTreeDef::Value(PredMode::VPred), VPTreeDef::Index(4), | |
205 | VPTreeDef::Value(PredMode::HPred), VPTreeDef::Value(PredMode::TMPred) | |
206 | ]; | |
207 | pub const B_MODE_TREE: &[VPTreeDef<PredMode>] = &[ | |
208 | VPTreeDef::Value(PredMode::DCPred), VPTreeDef::Index(2), | |
209 | VPTreeDef::Value(PredMode::TMPred), VPTreeDef::Index(4), | |
210 | VPTreeDef::Value(PredMode::VPred), VPTreeDef::Index(6), | |
211 | VPTreeDef::Index(8), VPTreeDef::Index(12), | |
212 | VPTreeDef::Value(PredMode::HPred), VPTreeDef::Index(10), | |
213 | VPTreeDef::Value(PredMode::RDPred), VPTreeDef::Value(PredMode::VRPred), | |
214 | VPTreeDef::Value(PredMode::LDPred), VPTreeDef::Index(14), | |
215 | VPTreeDef::Value(PredMode::VLPred), VPTreeDef::Index(16), | |
216 | VPTreeDef::Value(PredMode::HDPred), VPTreeDef::Value(PredMode::HUPred) | |
217 | ]; | |
218 | ||
219 | pub const FEATURE_TREE: &[VPTreeDef<usize>] = &[ | |
220 | VPTreeDef::Index(2), VPTreeDef::Index(4), | |
221 | VPTreeDef::Value(0), VPTreeDef::Value(1), | |
222 | VPTreeDef::Value(2), VPTreeDef::Value(3) | |
223 | ]; | |
224 | ||
225 | pub const COEF_TREE: &[VPTreeDef<DCTToken>] = &[ | |
226 | VPTreeDef::Value(DCTToken::EOB), VPTreeDef::Index(2), | |
227 | VPTreeDef::Value(DCTToken::Zero), VPTreeDef::Index(4), | |
228 | VPTreeDef::Value(DCTToken::One), VPTreeDef::Index(6), | |
229 | VPTreeDef::Index(8), VPTreeDef::Index(12), | |
230 | VPTreeDef::Value(DCTToken::Two), VPTreeDef::Index(10), | |
231 | VPTreeDef::Value(DCTToken::Three), VPTreeDef::Value(DCTToken::Four), | |
232 | VPTreeDef::Index(14), VPTreeDef::Index(16), | |
233 | VPTreeDef::Value(DCTToken::Cat1), VPTreeDef::Value(DCTToken::Cat2), | |
234 | VPTreeDef::Index(18), VPTreeDef::Index(20), | |
235 | VPTreeDef::Value(DCTToken::Cat3), VPTreeDef::Value(DCTToken::Cat4), | |
236 | VPTreeDef::Value(DCTToken::Cat5), VPTreeDef::Value(DCTToken::Cat6) | |
237 | ]; | |
238 | ||
239 | pub const MV_REF_TREE: &[VPTreeDef<VPMBType>] = &[ | |
240 | VPTreeDef::Value(VPMBType::InterNoMV), VPTreeDef::Index(2), | |
241 | VPTreeDef::Value(VPMBType::InterNearest), VPTreeDef::Index(4), | |
242 | VPTreeDef::Value(VPMBType::InterNear), VPTreeDef::Index(6), | |
243 | VPTreeDef::Value(VPMBType::InterMV), VPTreeDef::Value(VPMBType::InterFourMV) | |
244 | ]; | |
245 | pub const SMALL_MV_TREE: &[VPTreeDef<i16>] = &[ | |
246 | VPTreeDef::Index(2), VPTreeDef::Index(8), | |
247 | VPTreeDef::Index(4), VPTreeDef::Index(6), | |
248 | VPTreeDef::Value(0), VPTreeDef::Value(1), | |
249 | VPTreeDef::Value(2), VPTreeDef::Value(3), | |
250 | VPTreeDef::Index(10), VPTreeDef::Index(12), | |
251 | VPTreeDef::Value(4), VPTreeDef::Value(5), | |
252 | VPTreeDef::Value(6), VPTreeDef::Value(7) | |
253 | ]; | |
254 | pub const MV_SPLIT_MODE_TREE: &[VPTreeDef<MVSplitMode>] = &[ | |
255 | VPTreeDef::Value(MVSplitMode::Sixteenths), VPTreeDef::Index(2), | |
256 | VPTreeDef::Value(MVSplitMode::Quarters), VPTreeDef::Index(4), | |
257 | VPTreeDef::Value(MVSplitMode::TopBottom), VPTreeDef::Value(MVSplitMode::LeftRight) | |
258 | ]; | |
259 | pub const SUB_MV_REF_TREE: &[VPTreeDef<SubMVRef>] = &[ | |
260 | VPTreeDef::Value(SubMVRef::Left), VPTreeDef::Index(2), | |
261 | VPTreeDef::Value(SubMVRef::Above), VPTreeDef::Index(4), | |
262 | VPTreeDef::Value(SubMVRef::Zero), VPTreeDef::Value(SubMVRef::New) | |
263 | ]; | |
264 |