]> git.nihav.org Git - nihav.git/blame_incremental - nihav-duck/src/codecs/truemotion1.rs
h264: cache data before use in fill_deblock()
[nihav.git] / nihav-duck / src / codecs / truemotion1.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use super::truemotion1data::*;
4
5struct MaskState<'a> {
6 is_intra: bool,
7 pos: usize,
8 row_pos: usize,
9 row_size: usize,
10 mask: u8,
11 src: &'a [u8],
12}
13
14impl<'a> MaskState<'a> {
15 fn new(is_intra: bool, src: &'a [u8], row_size: usize) -> Self {
16 Self { is_intra, src, pos: 0, row_pos: 0, row_size, mask: 0x01 }
17 }
18 fn get_next(&mut self) -> bool {
19 if self.is_intra {
20 true
21 } else {
22 let res = (self.src[self.pos] & self.mask) == 0;
23 self.mask <<= 1;
24 if self.mask == 0 {
25 self.pos += 1;
26 self.mask = 0x01;
27 }
28 res
29 }
30 }
31 fn reset_row(&mut self) {
32 self.pos = self.row_pos;
33 self.mask = 0x01;
34 }
35 fn next_row(&mut self) {
36 self.row_pos += self.row_size;
37 self.reset_row();
38 }
39}
40
41struct IndexState<'a> {
42 src: &'a [u8],
43 pos: usize,
44 vec_idx: usize,
45 vec_subidx: usize,
46}
47
48impl<'a> IndexState<'a> {
49 fn new(src: &'a [u8]) -> Self {
50 Self { src, pos: 0, vec_idx: 0, vec_subidx: 0 }
51 }
52 fn get_next(&mut self) -> DecoderResult<()> {
53 validate!(self.pos < self.src.len());
54 self.vec_idx = self.src[self.pos] as usize;
55 self.vec_subidx = 0;
56 self.pos += 1;
57 Ok(())
58 }
59 fn get_pred(&self, dtab: &[[u32; 4]; 256]) -> u32 { dtab[self.vec_idx][self.vec_subidx] }
60 fn get_diff16(&mut self, dtab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
61 let pred1 = self.get_pred(dtab);
62 let mut pred = pred1 >> 1;
63 if (pred1 & 1) != 0 {
64 self.get_next()?;
65 if self.vec_idx == 0 {
66 self.get_next()?;
67 let pred2 = self.get_pred(dtab);
68 pred = pred.wrapping_add((pred2 >> 1).wrapping_mul(5));
69 if (pred2 & 1) != 0 {
70 self.get_next()?;
71 } else {
72 self.vec_subidx += 1;
73 }
74 }
75 } else {
76 self.vec_subidx += 1;
77 }
78 Ok(pred)
79 }
80 fn get_diff16_noesc(&mut self, dtab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
81 let pred1 = self.get_pred(dtab);
82 let pred = pred1 >> 1;
83 if (pred1 & 1) != 0 {
84 self.get_next()?;
85 } else {
86 self.vec_subidx += 1;
87 }
88 Ok(pred)
89 }
90 fn get_diff24(&mut self, dtab: &[[u32; 4]; 256], esctab: &[[u32; 4]; 256]) -> DecoderResult<u32> {
91 let pred1 = self.get_pred(dtab);
92 let mut pred = pred1 >> 1;
93 if (pred1 & 1) != 0 {
94 self.get_next()?;
95 if self.vec_idx == 0 {
96 self.get_next()?;
97 let pred2 = self.get_pred(esctab);
98 pred = pred.wrapping_add(pred2 >> 1);
99 if (pred2 & 1) != 0 {
100 self.get_next()?;
101 } else {
102 self.vec_subidx += 1;
103 }
104 }
105 } else {
106 self.vec_subidx += 1;
107 }
108 Ok(pred)
109 }
110}
111
112struct DeltaTables {
113 ydt: [[u32; 4]; 256],
114 cdt: [[u32; 4]; 256],
115 fat_ydt: [[u32; 4]; 256],
116 fat_cdt: [[u32; 4]; 256],
117 adt: [[u32; 4]; 256],
118}
119
120impl Default for DeltaTables {
121 fn default() -> Self {
122 Self {
123 ydt: [[0; 4]; 256],
124 cdt: [[0; 4]; 256],
125 fat_ydt: [[0; 4]; 256],
126 fat_cdt: [[0; 4]; 256],
127 adt: [[0; 4]; 256],
128 }
129 }
130}
131
132#[derive(Default)]
133struct FrameBuf {
134 last16: Option<NAVideoBufferRef<u16>>,
135 last24: Option<NAVideoBufferRef<u8>>,
136}
137
138impl FrameBuf {
139 fn set16(&mut self, buf: NAVideoBufferRef<u16>) { self.last16 = Some(buf); }
140 fn set24(&mut self, buf: NAVideoBufferRef<u8>) { self.last24 = Some(buf); }
141 fn get16(&mut self) -> Option<NAVideoBufferRef<u16>> {
142 if let Some(ref mut frm) = self.last16 {
143 let newfrm = frm.copy_buffer();
144 *frm = newfrm.clone().into_ref();
145 Some(newfrm.into_ref())
146 } else {
147 None
148 }
149 }
150 fn get24(&mut self) -> Option<NAVideoBufferRef<u8>> {
151 if let Some(ref mut frm) = self.last24 {
152 let newfrm = frm.copy_buffer();
153 *frm = newfrm.clone().into_ref();
154 Some(newfrm.into_ref())
155 } else {
156 None
157 }
158 }
159 fn reset(&mut self) {
160 self.last16 = None;
161 self.last24 = None;
162 }
163}
164
165#[derive(Default)]
166struct TM1Decoder {
167 info: NACodecInfoRef,
168 last_delta_set: usize,
169 last_table_idx: usize,
170 delta_tables: DeltaTables,
171 blk_w: usize,
172 blk_h: usize,
173 vert_pred: Vec<u32>,
174 lastframe: FrameBuf,
175}
176
177impl TM1Decoder {
178 fn new() -> Self { Self::default() }
179 fn set_delta_tables(&mut self, delta_set: usize, table_idx: usize, is_24bit: bool) {
180 if (self.last_delta_set == delta_set) && (self.last_table_idx == table_idx) { return; }
181 let ydt = &DUCK_Y_DELTAS[delta_set];
182 let yfdt = DUCK_Y_FAT_DELTAS[delta_set];
183 let cdt = &DUCK_C_DELTAS[delta_set];
184 let cfdt = DUCK_C_FAT_DELTAS[delta_set];
185 let vec = DUCK_VECTABLES[table_idx - 1];
186
187 let mut vec_iter = vec.iter();
188 for i in 0..256 {
189 let len = (*vec_iter.next().unwrap() as usize) >> 1;
190 for j in 0..len {
191 let pair = vec_iter.next().unwrap();
192 let lo = (pair >> 4) as usize;
193 let hi = (pair & 0xF) as usize;
194 if !is_24bit {
195 let d_lo = ydt[lo] + (ydt[lo] << 5) + (ydt[lo] << 10);
196 let d_hi = ydt[hi] + (ydt[hi] << 5) + (ydt[hi] << 10);
197 self.delta_tables.ydt[i][j] = ((d_lo + (d_hi << 16)) << 1) as u32;
198 let d_c = cdt[hi] + (cdt[lo] << 10);
199 self.delta_tables.cdt[i][j] = ((d_c + (d_c << 16)) << 1) as u32;
200 let d_a = lo + hi * 5;
201 self.delta_tables.adt[i][j] = ((d_a << 16) << 1) as u32;
202 } else {
203 self.delta_tables.ydt[i][j] = ((ydt [lo] + (ydt [hi] << 8) + (ydt [hi] << 16)) << 1) as u32;
204 self.delta_tables.fat_ydt[i][j] = ((yfdt[lo] + (yfdt[hi] << 8) + (yfdt[hi] << 16)) << 1) as u32;
205 self.delta_tables.cdt[i][j] = ((cdt [hi] + (cdt [lo] << 16)) << 1) as u32;
206 self.delta_tables.fat_cdt[i][j] = ((cfdt[hi] + (cfdt[lo] << 16)) << 1) as u32;
207 }
208 }
209 self.delta_tables.ydt[i][len - 1] |= 1;
210 self.delta_tables.cdt[i][len - 1] |= 1;
211 self.delta_tables.adt[i][len - 1] |= 1;
212 self.delta_tables.fat_ydt[i][len - 1] |= 1;
213 self.delta_tables.fat_cdt[i][len - 1] |= 1;
214 }
215
216 self.last_delta_set = delta_set;
217 self.last_table_idx = table_idx;
218 }
219 fn decode_16bit(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
220 let mut off = 0;
221 index.get_next()?;
222 for y in 0..height {
223 let mut hor_pred: u32 = 0;
224 for x in (0..width).step_by(4) {
225 if mask.get_next() {
226 match y & 3 {
227 0 => {
228 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
229 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
230 hor_pred = hor_pred.wrapping_add(dc0);
231 hor_pred = hor_pred.wrapping_add(dy0);
232 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
233 self.vert_pred[(x >> 1) + 0] = cur;
234 dst[off + x + 0] = cur as u16;
235 dst[off + x + 1] = (cur >> 16) as u16;
236 if self.blk_w == 2 {
237 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
238 hor_pred = hor_pred.wrapping_add(dc1);
239 }
240 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
241 hor_pred = hor_pred.wrapping_add(dy1);
242 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
243 self.vert_pred[(x >> 1) + 1] = cur;
244 dst[off + x + 2] = cur as u16;
245 dst[off + x + 3] = (cur >> 16) as u16;
246 },
247 1 | 3 => {
248 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
249 hor_pred = hor_pred.wrapping_add(dy0);
250 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
251 self.vert_pred[(x >> 1) + 0] = cur;
252 dst[off + x + 0] = cur as u16;
253 dst[off + x + 1] = (cur >> 16) as u16;
254 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
255 hor_pred = hor_pred.wrapping_add(dy1);
256 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
257 self.vert_pred[(x >> 1) + 1] = cur;
258 dst[off + x + 2] = cur as u16;
259 dst[off + x + 3] = (cur >> 16) as u16;
260 },
261 2 => {
262 if self.blk_h == 2 {
263 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
264 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
265 hor_pred = hor_pred.wrapping_add(dc0);
266 hor_pred = hor_pred.wrapping_add(dy0);
267 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
268 self.vert_pred[(x >> 1) + 0] = cur;
269 dst[off + x + 0] = cur as u16;
270 dst[off + x + 1] = (cur >> 16) as u16;
271 if self.blk_w == 2 {
272 let dc1 = index.get_diff16(&self.delta_tables.cdt)?;
273 hor_pred = hor_pred.wrapping_add(dc1);
274 }
275 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
276 hor_pred = hor_pred.wrapping_add(dy1);
277 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
278 self.vert_pred[(x >> 1) + 1] = cur;
279 dst[off + x + 2] = cur as u16;
280 dst[off + x + 3] = (cur >> 16) as u16;
281 } else {
282 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
283 hor_pred = hor_pred.wrapping_add(dy0);
284 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
285 self.vert_pred[(x >> 1) + 0] = cur;
286 dst[off + x + 0] = cur as u16;
287 dst[off + x + 1] = (cur >> 16) as u16;
288 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
289 hor_pred = hor_pred.wrapping_add(dy1);
290 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
291 self.vert_pred[(x >> 1) + 1] = cur;
292 dst[off + x + 2] = cur as u16;
293 dst[off + x + 3] = (cur >> 16) as u16;
294 }
295 },
296 _ => unreachable!(),
297 };
298 } else {
299 let cur = u32::from(dst[off + x + 0]) | (u32::from(dst[off + x + 1]) << 16);
300 self.vert_pred[(x >> 1) + 0] = cur;
301 let cur = u32::from(dst[off + x + 2]) | (u32::from(dst[off + x + 3]) << 16);
302 hor_pred = cur.wrapping_sub(self.vert_pred[(x >> 1) + 1]);
303 self.vert_pred[(x >> 1) + 1] = cur;
304 }
305 }
306 if (y & 3) != 3 {
307 mask.reset_row();
308 } else {
309 mask.next_row();
310 }
311 off += stride;
312 }
313 Ok(())
314 }
315 fn decode_sprite(&mut self, dst: &mut [u16], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
316 let mut off = 0;
317 let _ = index.get_next();
318 for y in 0..height {
319 let mut hor_pred: u32 = 0;
320 for x in (0..width).step_by(4) {
321 let is_tm = !mask.get_next();
322 let is_sprite = !mask.get_next();
323 if is_tm {
324 if (y & 3) == 0 {
325 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
326 hor_pred = hor_pred.wrapping_add(dc0);
327 }
328 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
329 hor_pred = hor_pred.wrapping_add(dy0);
330 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
331 self.vert_pred[(x >> 1) + 0] = cur;
332 dst[off + x + 0] = cur as u16;
333 dst[off + x + 1] = (cur >> 16) as u16;
334 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
335 hor_pred = hor_pred.wrapping_add(dy1);
336 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
337 self.vert_pred[(x >> 1) + 1] = cur;
338 dst[off + x + 2] = cur as u16;
339 dst[off + x + 3] = (cur >> 16) as u16;
340 } else if is_sprite {
341 if (y & 3) == 0 {
342 let dc0 = index.get_diff16(&self.delta_tables.cdt)?;
343 hor_pred = hor_pred.wrapping_add(dc0);
344 }
345 let dy0 = index.get_diff16(&self.delta_tables.ydt)?;
346 hor_pred = hor_pred.wrapping_add(dy0);
347 let _da0 = index.get_diff16_noesc(&self.delta_tables.adt)?;
348 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 0]);
349 self.vert_pred[(x >> 1) + 0] = cur;
350 dst[off + x + 0] = cur as u16;
351 dst[off + x + 1] = (cur >> 16) as u16;
352 let dy1 = index.get_diff16(&self.delta_tables.ydt)?;
353 hor_pred = hor_pred.wrapping_add(dy1);
354 let _da1 = index.get_diff16_noesc(&self.delta_tables.adt)?;
355 let cur = hor_pred.wrapping_add(self.vert_pred[(x >> 1) + 1]);
356 self.vert_pred[(x >> 1) + 1] = cur;
357 dst[off + x + 2] = cur as u16;
358 dst[off + x + 3] = (cur >> 16) as u16;
359 } else {
360 hor_pred = 0;
361 dst[off + x + 0] = 0;
362 dst[off + x + 1] = 0;
363 dst[off + x + 2] = 0;
364 dst[off + x + 3] = 0;
365 self.vert_pred[(x >> 1) + 0] = 0;
366 self.vert_pred[(x >> 1) + 1] = 0;
367 }
368 }
369 if (y & 3) != 3 {
370 mask.reset_row();
371 } else {
372 mask.next_row();
373 }
374 off += stride;
375 }
376 Ok(())
377 }
378 fn decode_24bit(&mut self, dst: &mut [u8], stride: usize, width: usize, height: usize, mask: &mut MaskState<'_>, index: &mut IndexState<'_>) -> DecoderResult<()> {
379 let mut off = 0;
380 index.get_next()?;
381 for y in 0..height {
382 let mut hor_pred: u32 = 0;
383 for x in (0..width).step_by(2) {
384 if mask.get_next() {
385 match y & 3 {
386 0 => {
387 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
388 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
389 hor_pred = hor_pred.wrapping_add(dc0);
390 hor_pred = hor_pred.wrapping_add(dy0);
391 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
392 self.vert_pred[x + 0] = cur;
393 dst[off + x*4 + 0] = cur as u8;
394 dst[off + x*4 + 1] = (cur >> 8) as u8;
395 dst[off + x*4 + 2] = (cur >> 16) as u8;
396 dst[off + x*4 + 3] = 0;
397 if self.blk_w == 2 {
398 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
399 hor_pred = hor_pred.wrapping_add(dc1);
400 }
401 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
402 hor_pred = hor_pred.wrapping_add(dy1);
403 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
404 self.vert_pred[x + 1] = cur;
405 dst[off + x*4 + 4] = cur as u8;
406 dst[off + x*4 + 5] = (cur >> 8) as u8;
407 dst[off + x*4 + 6] = (cur >> 16) as u8;
408 dst[off + x*4 + 7] = 0;
409 },
410 1 | 3 => {
411 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
412 hor_pred = hor_pred.wrapping_add(dy0);
413 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
414 self.vert_pred[x + 0] = cur;
415 dst[off + x*4 + 0] = cur as u8;
416 dst[off + x*4 + 1] = (cur >> 8) as u8;
417 dst[off + x*4 + 2] = (cur >> 16) as u8;
418 dst[off + x*4 + 3] = 0;
419 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
420 hor_pred = hor_pred.wrapping_add(dy1);
421 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
422 self.vert_pred[x + 1] = cur;
423 dst[off + x*4 + 4] = cur as u8;
424 dst[off + x*4 + 5] = (cur >> 8) as u8;
425 dst[off + x*4 + 6] = (cur >> 16) as u8;
426 dst[off + x*4 + 7] = 0;
427 },
428 2 => {
429 if self.blk_h == 2 {
430 let dc0 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
431 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
432 hor_pred = hor_pred.wrapping_add(dc0);
433 hor_pred = hor_pred.wrapping_add(dy0);
434 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
435 self.vert_pred[x + 0] = cur;
436 dst[off + x*4 + 0] = cur as u8;
437 dst[off + x*4 + 1] = (cur >> 8) as u8;
438 dst[off + x*4 + 2] = (cur >> 16) as u8;
439 dst[off + x*4 + 3] = 0;
440 if self.blk_w == 2 {
441 let dc1 = index.get_diff24(&self.delta_tables.cdt, &self.delta_tables.fat_cdt)?;
442 hor_pred = hor_pred.wrapping_add(dc1);
443 }
444 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
445 hor_pred = hor_pred.wrapping_add(dy1);
446 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
447 self.vert_pred[x + 1] = cur;
448 dst[off + x*4 + 4] = cur as u8;
449 dst[off + x*4 + 5] = (cur >> 8) as u8;
450 dst[off + x*4 + 6] = (cur >> 16) as u8;
451 dst[off + x*4 + 7] = 0;
452 } else {
453 let dy0 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
454 hor_pred = hor_pred.wrapping_add(dy0);
455 let cur = hor_pred.wrapping_add(self.vert_pred[x + 0]);
456 self.vert_pred[x + 0] = cur;
457 dst[off + x*4 + 0] = cur as u8;
458 dst[off + x*4 + 1] = (cur >> 8) as u8;
459 dst[off + x*4 + 2] = (cur >> 16) as u8;
460 dst[off + x*4 + 3] = 0;
461 let dy1 = index.get_diff24(&self.delta_tables.ydt, &self.delta_tables.fat_ydt)?;
462 hor_pred = hor_pred.wrapping_add(dy1);
463 let cur = hor_pred.wrapping_add(self.vert_pred[x + 1]);
464 self.vert_pred[x + 1] = cur;
465 dst[off + x*4 + 4] = cur as u8;
466 dst[off + x*4 + 5] = (cur >> 8) as u8;
467 dst[off + x*4 + 6] = (cur >> 16) as u8;
468 dst[off + x*4 + 7] = 0;
469 }
470 },
471 _ => unreachable!(),
472 };
473 } else {
474 let cur = u32::from(dst[off + x*4 + 0])
475 | (u32::from(dst[off + x*4 + 1]) << 8)
476 | (u32::from(dst[off + x*4 + 2]) << 16)
477 | (u32::from(dst[off + x*4 + 3]) << 24);
478 self.vert_pred[x + 0] = cur;
479 let cur = u32::from(dst[off + x*4 + 4])
480 | (u32::from(dst[off + x*4 + 5]) << 8)
481 | (u32::from(dst[off + x*4 + 6]) << 16)
482 | (u32::from(dst[off + x*4 + 7]) << 24);
483 hor_pred = cur.wrapping_sub(self.vert_pred[x + 1]);
484 self.vert_pred[x + 1] = cur;
485 }
486 }
487 if (y & 3) != 3 {
488 mask.reset_row();
489 } else {
490 mask.next_row();
491 }
492 off += stride;
493 }
494 Ok(())
495 }
496}
497
498impl NADecoder for TM1Decoder {
499 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
500 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
501 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, YUV410_FORMAT));
502 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
503 Ok(())
504 } else {
505 Err(DecoderError::InvalidData)
506 }
507 }
508 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
509 let src = pkt.get_buffer();
510 validate!(src.len() > 10);
511 let hdr_size = (src[0].rotate_left(3) & 0x7F) as usize;
512 validate!(hdr_size >= 12 && hdr_size < src.len());
513 let mut hdr: [u8; 127] = [0; 127];
514 for i in 1..hdr_size {
515 hdr[i - 1] = src[i] ^ src[i + 1];
516 }
517 let mut mr = MemoryReader::new_read(&hdr[0..hdr_size-1]);
518 let mut br = ByteReader::new(&mut mr);
519
520 let tm1type = br.read_byte()? as usize;
521 let delta_set = br.read_byte()? as usize;
522 let table_idx = br.read_byte()? as usize;
523 let height = br.read_u16le()? as usize;
524 let width = br.read_u16le()? as usize;
525 let _frameno = br.read_u16le()? as usize;
526 let version = br.read_byte()?;
527 let meta_type = br.read_byte()?;
528 validate!(width > 0 && height > 0);
529 let is_intra;
530 let mut is_sprite = false;
531 let mut spr_xoff = 0;
532 let mut spr_yoff = 0;
533 let mut spr_width = 0;
534 let mut spr_height = 0;
535 if version >= 2 {
536 validate!(meta_type <= 3);
537 if meta_type >= 2 {
538 let frameinfo = br.read_byte()?;
539 let _control = br.read_byte()?;
540
541 is_intra = ((frameinfo & 0x10) != 0) || ((frameinfo & 0x08) == 0);
542 } else {
543 is_intra = true;
544 }
545 if meta_type == 3 {
546 spr_xoff = br.read_u16le()? as usize;
547 spr_yoff = br.read_u16le()? as usize;
548 spr_width = br.read_u16le()? as usize;
549 spr_height = br.read_u16le()? as usize;
550 is_sprite = true;
551 }
552 } else {
553 is_intra = true;
554 }
555 validate!(tm1type < TM1_COMPR_TYPES.len());
556 let cinfo = TM1_COMPR_TYPES[tm1type];
557 if cinfo.is_none() {
558//check for missing ref
559 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
560 frm.set_keyframe(false);
561 frm.set_frame_type(FrameType::Skip);
562 return Ok(frm.into_ref());
563 }
564 let compr_info = cinfo.unwrap();
565 let is_24bit = !is_sprite && compr_info.is_24bit;
566
567 let vec_idx = if ((tm1type & 1) != 0) && (meta_type > 0) { 1 } else { table_idx };
568 validate!((delta_set < DUCK_Y_DELTAS.len()) && (vec_idx > 0) && (vec_idx <= DUCK_VECTABLES.len()));
569 self.set_delta_tables(delta_set, vec_idx, is_24bit);
570
571 let out_width = if is_24bit { width >> 1 } else { width };
572 let mask_row_size = if is_sprite {
573 ((spr_width >> 2) + 3) >> 2
574 } else if is_intra {
575 0
576 } else {
577 ((width >> 2) + 7) >> 3
578 };
579 let mask_size = mask_row_size * (if is_sprite { spr_height >> 2 } else { height >> 2 });
580 let mask_bits = &src[hdr_size..][..mask_size];
581 let index_bytes = &src[hdr_size+mask_size..];
582 validate!(src.len() >= hdr_size + mask_size);
583 self.vert_pred.clear();
584 self.vert_pred.resize(out_width, 0);
585
586 if is_intra || is_sprite {
587 let fmt = if is_24bit { BGR0_FORMAT } else { RGB555_FORMAT };
588 let myinfo = NAVideoInfo::new(out_width, height, false, fmt);
589 let bufinfo = alloc_video_buffer(myinfo, 2)?;
590 self.lastframe.reset();
591 if !is_24bit {
592 self.lastframe.set16(bufinfo.get_vbuf16().unwrap());
593 } else {
594 self.lastframe.set24(bufinfo.get_vbuf().unwrap());
595 }
596 }
597
598 self.blk_w = compr_info.block_w;
599 self.blk_h = compr_info.block_h;
600 let mut mask = MaskState::new(is_intra && !is_sprite, mask_bits, mask_row_size);
601 let mut index = IndexState::new(index_bytes);
602 let bufinfo;
603 if !is_24bit {
604 if let Some(mut buf) = self.lastframe.get16() {
605 let stride = buf.get_stride(0);
606 {
607 let data = buf.get_data_mut().unwrap();
608 if !is_sprite {
609 self.decode_16bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
610 } else {
611 validate!(spr_xoff + spr_width <= out_width);
612 validate!(spr_yoff + spr_height <= height);
613 for el in data.iter_mut() { *el = 0; }
614 let dst = &mut data[spr_xoff + spr_yoff * stride..];
615 self.decode_sprite(dst, stride, spr_width, spr_height, &mut mask, &mut index)?;
616 }
617 }
618 bufinfo = NABufferType::Video16(buf);
619 } else {
620 return Err(DecoderError::MissingReference);
621 }
622 } else if let Some(mut buf) = self.lastframe.get24() {
623 let stride = buf.get_stride(0);
624 {
625 let data = buf.get_data_mut().unwrap();
626 self.decode_24bit(data.as_mut_slice(), stride, out_width, height, &mut mask, &mut index)?;
627 }
628 bufinfo = NABufferType::VideoPacked(buf);
629 } else {
630 return Err(DecoderError::MissingReference);
631 }
632
633 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
634 frm.set_keyframe(is_intra || is_sprite);
635 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
636 Ok(frm.into_ref())
637 }
638 fn flush(&mut self) {
639 self.lastframe.reset();
640 }
641}
642
643impl NAOptionHandler for TM1Decoder {
644 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
645 fn set_options(&mut self, _options: &[NAOption]) { }
646 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
647}
648
649pub fn get_decoder() -> Box<dyn NADecoder + Send> {
650 Box::new(TM1Decoder::new())
651}
652
653#[cfg(test)]
654mod test {
655 use nihav_core::codecs::RegisteredDecoders;
656 use nihav_core::demuxers::RegisteredDemuxers;
657 use nihav_codec_support::test::dec_video::*;
658 use crate::duck_register_all_decoders;
659 use nihav_commonfmt::generic_register_all_demuxers;
660 #[test]
661 fn test_tm1() {
662 let mut dmx_reg = RegisteredDemuxers::new();
663 generic_register_all_demuxers(&mut dmx_reg);
664 let mut dec_reg = RegisteredDecoders::new();
665 duck_register_all_decoders(&mut dec_reg);
666
667 // sample: https://samples.mplayerhq.hu/V-codecs/DUCK/phant2-940.duk
668 test_decoding("avi", "truemotion1", "assets/Duck/phant2-940.duk", Some(12), &dmx_reg, &dec_reg,
669 ExpectedTestResult::MD5Frames(vec![
670 [0x989e62b8, 0x5d85c23c, 0x1cffba6d, 0xe599f1c4],
671 [0xc4231321, 0x25561487, 0x9db11f57, 0x4faeb9a5],
672 [0x36e3a831, 0xdbd21f89, 0x0a446071, 0xf6d31ee7],
673 [0x0af640af, 0x64bc2bac, 0x0e95dd72, 0x9e55360b],
674 [0xbc9c5f8b, 0x6c06f2bc, 0x216f4129, 0x3a421337],
675 [0xd8ea7297, 0xce5f79fc, 0x46071f4c, 0xaed7fb7a],
676 [0x87617060, 0x72ce8df8, 0xde42eaa6, 0x804a6f45],
677 [0xfd8c45b3, 0xf424b683, 0xb4d6a9bd, 0xc622d0b9],
678 [0x6c233746, 0xba8ed68e, 0xc0ed0e85, 0xc99e1dc0],
679 [0x5842aac0, 0xd3d78242, 0x5da21218, 0xea1ed0ad],
680 [0xdea0db20, 0xe2ce3586, 0xf7386649, 0xecc374f9],
681 [0xb80ae9cb, 0x04eb938e, 0xd8a337ee, 0x0054b5ed],
682 [0xf8b80e1d, 0xd8eb3d6c, 0xa99b23ff, 0x562851a1]]));
683 test_decoding("avi", "truemotion1", "assets/Duck/SPRITES.AVI", Some(2), &dmx_reg, &dec_reg,
684 ExpectedTestResult::MD5([0xb89a4275, 0xf9797f5f, 0xe53c1ccd, 0xfa163e02]));
685 //let file = "assets/Duck/AVI-DUCK-dk3.duk";
686 //let file = "assets/Duck/phant2-940.duk";
687 //let file = "assets/Duck/bugsampler-m01-16bit.avi";
688 //let file = "assets/Duck/sonic3dblast_intro.avi";
689 //let file = "assets/Duck/BUTTONS.AVI";
690 //let file = "assets/Duck/SPRITES.AVI";
691 //let file = "assets/Duck/TRICORD.AVI";
692 //test_file_decoding("avi", file, Some(42), true, false, None/*Some("tm1-")*/, &dmx_reg, &dec_reg);
693 }
694}