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