]> git.nihav.org Git - nihav.git/blame - nihav-duck/src/codecs/vp78.rs
add MPEG-4 ASP decoder
[nihav.git] / nihav-duck / src / codecs / vp78.rs
CommitLineData
0cc75664
KS
1use nihav_codec_support::data::GenericCache;
2use super::vpcommon::*;
3
4pub enum VPTreeDef<T: Copy> {
5 Index(u8),
6 Value(T),
7}
8
9pub trait VPTreeReader {
10 fn read_tree<T:Copy>(&mut self, tree_def: &[VPTreeDef<T>], tree_prob: &[u8]) -> T;
11}
12
13impl<'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 29pub 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
48impl 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)]
74pub 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
89pub 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)]
121pub enum MVSplitMode {
122 TopBottom,
123 LeftRight,
124 Quarters,
125 Sixteenths,
126}
127
128#[derive(Clone,Copy,Debug,PartialEq)]
129pub enum SubMVRef {
130 Left,
131 Above,
132 New,
133 Zero,
134}
135
136pub 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
147impl 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
190pub 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];
196pub 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];
202pub 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];
207pub 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
219pub 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
225pub 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
239pub 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];
245pub 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];
254pub 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];
259pub 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