dec_video: allow YUV444 output
[nihav.git] / nihav-duck / src / codecs / truemotion2x.rs
CommitLineData
2994c841
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3
4#[derive(Default)]
5struct Decryptor {
6 key: [u8; 4],
7}
8
9impl Decryptor {
10 fn decrypt(&mut self, buf: &mut [u8]) {
11 let mut pos: u8 = 0;
12 for el in buf.iter_mut() {
13 *el ^= self.key[(pos & 3) as usize];
14 pos = pos.wrapping_add(1);
15 }
16 }
17 fn set_state(&mut self, mut key: u32) {
18 for _ in 0..3 {
19 let bit31 = (key >> 31) & 1;
20 let bit21 = (key >> 21) & 1;
21 let bit01 = (key >> 1) & 1;
22 let nbit0 = !key & 1;
23 key = (key << 1) | (bit31 ^ bit21 ^ bit01 ^ nbit0);
24 }
25 for i in 0..4 {
26 self.key[i] = (key >> (8 * (i ^ 3))) as u8;
27 }
28 }
29}
30
31struct Deltas {
32 tabs: [[i16; 256]; 2],
33 codebook: [[u8; 8]; 256],
34 num_elems: [usize; 256],
35 num_vq: usize,
36 vq_idx: usize,
37 vq_pos: usize,
38}
39
40impl Deltas {
41 fn reset(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
42 let b = br.read_byte()? as usize;
43 self.vq_idx = b;
44 self.vq_pos = 0;
45 Ok(())
46 }
47 fn get_val(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
48 if self.vq_idx > self.codebook.len() { return Err(DecoderError::ShortData); }
49 let ret = self.codebook[self.vq_idx][self.vq_pos];
50 self.vq_pos += 1;
51 if self.vq_pos == self.num_elems[self.vq_idx] {
52 if br.left() > 0 {
53 self.reset(br)?;
54 } else {
55 self.vq_idx = self.codebook.len() + 1;
56 }
57 }
58 Ok(ret)
59 }
60 fn get_int(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
61 let b = self.get_val(br)?;
62 if b > 0 { unimplemented!(); }
63 Ok(b as i16)
64 }
65 fn get_dy(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
66 let b = self.get_val(br)?;
67 Ok(self.tabs[1][b as usize])
68 }
69 fn get_dc(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
70 let b = self.get_val(br)?;
71 Ok(self.tabs[0][b as usize])
72 }
73}
74
75impl Default for Deltas {
76 fn default() -> Self {
77 Self {
78 tabs: [[0; 256]; 2],
79 codebook: [[0; 8]; 256],
80 num_elems: [0; 256],
81 num_vq: 0,
82 vq_idx: 0,
83 vq_pos: 0,
84 }
85 }
86}
87
88#[derive(Clone,Copy, Default)]
89struct BlkInfo {
90 btype: u8,
91 mode: u8,
92 mv_x: i16,
93 mv_y: i16,
94}
95
96const NUM_CPARAMS: usize = 25;
97const CPARAM_NONE: u8 = 42;
98const CPARAM_MISSING: u8 = 42 * 2;
99
100macro_rules! apply_delta {
101 ($buf:expr, $off:expr, $stride:expr, $hpred: expr, $delta:expr) => {
102 $hpred = $hpred.wrapping_add($delta);
103 $buf[$off] = $buf[$off - $stride].wrapping_add($hpred);
104 };
105}
106macro_rules! copy_line {
107 ($buf:expr, $off:expr, $stride:expr) => {
108 for i in 0..8 {
109 $buf[$off + i] = $buf[$off + i - $stride];
110 }
111 };
112}
113
114#[derive(Default)]
115struct TM2XDecoder {
116 info: Rc<NACodecInfo>,
117 width: usize,
118 height: usize,
119 dec_buf: Vec<u8>,
120 version: u8,
121 deltas: Deltas,
122 blk_info: Vec<BlkInfo>,
123 tile_size: usize,
124 cparams: [[u8; 8]; NUM_CPARAMS],
125 ydata: Vec<i16>,
126 udata: Vec<i16>,
127 vdata: Vec<i16>,
128 ystride: usize,
129 cstride: usize,
130}
131
132impl TM2XDecoder {
133 fn new() -> Self { Self::default() }
134 fn output_frame(&mut self, buf: &mut NAVideoBuffer<u8>) {
135 let fmt = buf.get_info().get_format();
136 let offs = [fmt.get_chromaton(0).unwrap().get_offset() as usize,
137 fmt.get_chromaton(1).unwrap().get_offset() as usize,
138 fmt.get_chromaton(2).unwrap().get_offset() as usize];
139 let stride = buf.get_stride(0);
140 let mut data = buf.get_data_mut();
141 let dst = data.as_mut_slice();
142
143 let mut off = 0;
144 let mut ysrc = self.ystride;
145 let mut csrc = self.cstride;
146 for _y in 0..self.height {
147 let out = &mut dst[off..];
148 for (x, pic) in out.chunks_exact_mut(3).take(self.width).enumerate() {
149 let y = self.ydata[ysrc + x];
150 let u = self.udata[csrc + x] - 128;
151 let v = self.vdata[csrc + x] - 128;
152 pic[offs[0]] = (y + v).max(0).min(255) as u8;
153 pic[offs[1]] = y.max(0).min(255) as u8;
154 pic[offs[2]] = (y + u).max(0).min(255) as u8;
155 }
156 off += stride;
157 ysrc += self.ystride;
158 csrc += self.cstride;
159 }
160 }
161 fn parse_init(&mut self, version: u8) -> DecoderResult<()> {
162 self.version = version;
163
164 let mut mr = MemoryReader::new_read(&self.dec_buf);
165 let mut br = ByteReader::new(&mut mr);
166 if version > 4 {
167 let _smth = br.read_u32be()?;
168 }
169 let height = br.read_u16be()? as usize;
170 let width = br.read_u16be()? as usize;
171 validate!(width == self.width && height == self.height);
172 if version > 4 {
173 let _smth = br.read_u32be()?;
174 }
175 let _smth = br.read_byte()?;
176 let _nfuncs = br.read_byte()? as usize;
177 let _smth = br.read_u16be()? as usize;
178 let has_mv = br.read_byte()?;
179 if has_mv != 0 {
180 unimplemented!();
181 }
182 if version >= 4 {
183 let _flags = br.read_u16be()?;
184 let id_len = br.read_byte()? as usize;
185 br.read_skip(id_len)?;
186 let _smth1 = br.read_byte()?;
187 let len = br.read_byte()? as usize;
188 br.read_skip(len)?;
189 let _smth = br.read_u32be()?;
190 }
191
192 Ok(())
193 }
194 fn parse_tabs(&mut self) -> DecoderResult<()> {
195 let mut mr = MemoryReader::new_read(&self.dec_buf);
196 let mut br = ByteReader::new(&mut mr);
197
198 let idx = br.read_byte()? as usize;
199 validate!(idx < self.deltas.tabs.len());
200 let len = br.read_byte()? as usize;
201 validate!(((len * 2) as i64) == br.left());
202 for i in 0..len {
203 self.deltas.tabs[idx][i] = br.read_u16be()? as i16;
204 }
205
206 Ok(())
207 }
208 fn parse_cb_desc(&mut self, version: u8) -> DecoderResult<()> {
209 let mut mr = MemoryReader::new_read(&self.dec_buf);
210 let mut br = ByteReader::new(&mut mr);
211
212 if version == 0x0A {
213 let _esc_val = br.read_byte()?;
214 let _tag = br.read_u16be()?;
215 }
216 let len = br.read_u16be()? as usize;
217 validate!(len + 3 == (br.left() as usize));
218 let num_entries = br.read_u16be()?;
219 validate!(num_entries == 256);
220 let max_elems = br.read_byte()?;
221 validate!(max_elems > 0 && max_elems <= 8);
222 let mut idx = 0;
223 while br.left() > 0 {
224 validate!(idx < self.deltas.codebook.len());
225 let num_elems = br.read_byte()? as usize;
226 validate!(num_elems <= 8);
227 self.deltas.num_elems[idx] = num_elems;
228 for i in 0..num_elems {
229 self.deltas.codebook[idx][i] = br.read_byte()?;
230 }
231 idx += 1;
232 }
233 validate!(idx == 256);
234 self.deltas.num_vq = idx;
235 Ok(())
236 }
237
238 fn decode_frame(&mut self, src: &[u8]) -> DecoderResult<()> {
239 let mut mr = MemoryReader::new_read(src);
240 let mut br = ByteReader::new(&mut mr);
241
242 self.deltas.reset(&mut br)?;
243 let bw = self.width / 8;
244 let bh = self.height / 8;
245 let ntiles = (bw + self.tile_size - 1) / self.tile_size;
246 let mut ypos = self.ystride;
247 let mut cpos = self.cstride;
248 for _by in 0..bh {
249 for tile in 0..ntiles {
250 let xpos = tile * self.tile_size;
251 let len = self.tile_size.min(bw - xpos);
252 for el in self.blk_info.iter_mut().take(len) {
253 let t1 = self.deltas.get_val(&mut br)?;
254 let t2 = self.deltas.get_val(&mut br)?;
255 if t2 > 1 { unimplemented!(); }
256 validate!((t1 as usize) < NUM_CPARAMS);
257 validate!(self.cparams[t1 as usize][0] != CPARAM_MISSING);
258 el.btype = t1;
259 el.mode = t2;
260 if t2 > 0 {
261 el.mv_x = self.deltas.get_int(&mut br)?;
262 el.mv_y = self.deltas.get_int(&mut br)?;
263 } else {
264 el.mv_x = 0;
265 el.mv_y = 0;
266 }
267 }
268 for line in 0..8 {
269 let mut ypred = 0i16;
270 let mut upred = 0i16;
271 let mut vpred = 0i16;
272 for x in 0..len {
273 let bx = xpos + x;
274 let op = self.cparams[self.blk_info[x].btype as usize][line];
275 let cur_yoff = ypos + bx * 8 + line * self.ystride;
276 let cur_coff = cpos + bx * 8 + line * self.cstride;
277 match op {
278 0 => { // y4|y4
279 for i in 0..8 {
280 let delta = self.deltas.get_dy(&mut br)?;
281 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
282 }
283 copy_line!(self.udata, cur_coff, self.cstride);
284 copy_line!(self.vdata, cur_coff, self.cstride);
285 upred = 0;
286 vpred = 0;
287 },
288 1 => { // y2|y2
289 for i in 0..8 {
290 if (i & 1) == 0 {
291 let delta = self.deltas.get_dy(&mut br)?;
292 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
293 } else {
294 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
295 }
296 }
297 copy_line!(self.udata, cur_coff, self.cstride);
298 copy_line!(self.vdata, cur_coff, self.cstride);
299 upred = 0;
300 vpred = 0;
301 },
302 2 => { // y1|y1
303 for i in 0..8 {
304 if (i & 3) == 0 {
305 let delta = self.deltas.get_dy(&mut br)?;
306 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
307 } else {
308 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
309 }
310 }
311 copy_line!(self.udata, cur_coff, self.cstride);
312 copy_line!(self.vdata, cur_coff, self.cstride);
313 upred = 0;
314 vpred = 0;
315 },
316 3 => { // y1|0
317 let delta = self.deltas.get_dy(&mut br)?;
318 apply_delta!(self.ydata, cur_yoff, self.ystride, ypred, delta);
319 for i in 1..8 {
320 self.ydata[cur_yoff + i] = self.ydata[cur_yoff];
321 }
322 copy_line!(self.udata, cur_coff, self.cstride);
323 copy_line!(self.vdata, cur_coff, self.cstride);
324 upred = 0;
325 vpred = 0;
326 },
327 4 => { // c2y2c2y2|c2y2c2y2
328 for i in (0..8).step_by(2) {
329 let delta = self.deltas.get_dc(&mut br)?;
330 apply_delta!(self.udata, cur_coff + i + 0, self.cstride, upred, delta);
331 self.udata[cur_coff + i + 1] = self.udata[cur_coff + i];
332 let delta = self.deltas.get_dc(&mut br)?;
333 apply_delta!(self.vdata, cur_coff + i + 0, self.cstride, vpred, delta);
334 self.vdata[cur_coff + i + 1] = self.vdata[cur_coff + i];
335 let delta = self.deltas.get_dy(&mut br)?;
336 apply_delta!(self.ydata, cur_yoff + i + 0, self.ystride, ypred, delta);
337 let delta = self.deltas.get_dy(&mut br)?;
338 apply_delta!(self.ydata, cur_yoff + i + 1, self.ystride, ypred, delta);
339 }
340 },
341 5 => { // c2y1|c2y1
342 for i in 0..8 {
343 if (i & 3) == 0 {
344 let delta = self.deltas.get_dc(&mut br)?;
345 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
346 let delta = self.deltas.get_dc(&mut br)?;
347 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
348 let delta = self.deltas.get_dy(&mut br)?;
349 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
350 } else {
351 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
352 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
353 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
354 }
355 }
356 },
357 6 | 7 => unreachable!(),
358 8 => { // c2y4|c2y4
359 for i in 0..8 {
360 if (i & 3) == 0 {
361 let delta = self.deltas.get_dc(&mut br)?;
362 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
363 let delta = self.deltas.get_dc(&mut br)?;
364 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
365 } else {
366 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
367 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
368 }
369 let delta = self.deltas.get_dy(&mut br)?;
370 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
371 }
372 },
373 9 => { // c2y2|c2y2
374 for i in 0..8 {
375 if (i & 3) == 0 {
376 let delta = self.deltas.get_dc(&mut br)?;
377 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
378 let delta = self.deltas.get_dc(&mut br)?;
379 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
380 } else {
381 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
382 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
383 }
384 if (i & 1) == 0 {
385 let delta = self.deltas.get_dy(&mut br)?;
386 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
387 } else {
388 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
389 }
390 }
391 },
392 10 => { // c2y1|c2y1
393 for i in 0..8 {
394 if (i & 3) == 0 {
395 let delta = self.deltas.get_dc(&mut br)?;
396 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
397 let delta = self.deltas.get_dc(&mut br)?;
398 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
399 let delta = self.deltas.get_dy(&mut br)?;
400 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
401 } else {
402 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
403 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
404 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
405 }
406 }
407 },
408 11 => unreachable!(),
409 12 => { // c2y8
410 for i in 0..8 {
411 if i == 0 {
412 let delta = self.deltas.get_dc(&mut br)?;
413 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
414 let delta = self.deltas.get_dc(&mut br)?;
415 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
416 } else {
417 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
418 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
419 }
420 let delta = self.deltas.get_dy(&mut br)?;
421 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
422 }
423 },
424 13 => { // c2y4
425 for i in 0..8 {
426 if i == 0 {
427 let delta = self.deltas.get_dc(&mut br)?;
428 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
429 let delta = self.deltas.get_dc(&mut br)?;
430 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
431 } else {
432 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
433 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
434 }
435 if (i & 1) == 0 {
436 let delta = self.deltas.get_dy(&mut br)?;
437 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
438 } else {
439 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
440 }
441 }
442 },
443 14 => { // c2y2
444 for i in 0..8 {
445 if i == 0 {
446 let delta = self.deltas.get_dc(&mut br)?;
447 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
448 let delta = self.deltas.get_dc(&mut br)?;
449 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
450 } else {
451 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
452 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
453 }
454 if (i & 3) == 0 {
455 let delta = self.deltas.get_dy(&mut br)?;
456 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
457 } else {
458 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
459 }
460 }
461 },
462 15 => { // c2y1
463 for i in 0..8 {
464 if i == 0 {
465 let delta = self.deltas.get_dc(&mut br)?;
466 apply_delta!(self.udata, cur_coff + i, self.cstride, upred, delta);
467 let delta = self.deltas.get_dc(&mut br)?;
468 apply_delta!(self.vdata, cur_coff + i, self.cstride, vpred, delta);
469 let delta = self.deltas.get_dy(&mut br)?;
470 apply_delta!(self.ydata, cur_yoff + i, self.ystride, ypred, delta);
471 } else {
472 self.udata[cur_coff + i] = self.udata[cur_coff + i - 1];
473 self.vdata[cur_coff + i] = self.vdata[cur_coff + i - 1];
474 self.ydata[cur_yoff + i] = self.ydata[cur_yoff + i - 1];
475 }
476 }
477 },
478 CPARAM_NONE => {
479 copy_line!(self.ydata, cur_yoff, self.ystride);
480 copy_line!(self.udata, cur_coff, self.cstride);
481 copy_line!(self.vdata, cur_coff, self.cstride);
482 ypred = 0;
483 upred = 0;
484 vpred = 0;
485 },
486 _ => unreachable!(),
487 }
488 }
489 }
490 }
491 ypos += 8 * self.ystride;
492 cpos += 8 * self.cstride;
493 }
494
495 Ok(())
496 }
497}
498
499impl NADecoder for TM2XDecoder {
500 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
501 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
502 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, RGB24_FORMAT));
503 self.width = vinfo.get_width();
504 self.height = vinfo.get_height();
505 self.ystride = self.width;
506 self.cstride = self.width;
507 self.ydata.resize(self.ystride * (self.height + 1), 0x80);
508 self.udata.resize(self.cstride * (self.height + 1), 0x80);
509 self.vdata.resize(self.cstride * (self.height + 1), 0x80);
510 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
511 Ok(())
512 } else {
513 Err(DecoderError::InvalidData)
514 }
515 }
516 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
517 let src = pkt.get_buffer();
518 validate!(src.len() > 8);
519 let mut mr = MemoryReader::new_read(&src);
520 let mut br = ByteReader::new(&mut mr);
521 let mut dec = Decryptor::default();
522
523 let mut initialised = false;
524 let mut got_key = false;
525 let mut data_size = 0;
526 self.cparams = [[CPARAM_MISSING; 8]; NUM_CPARAMS];
527 while br.left() >= 8 {
528 let magic = br.read_u24be()?;
529 let ctype = br.read_byte()?;
530 let size = br.read_u32be()? as usize;
531 validate!(magic == 0xA00001 && br.left() >= (size as i64));
532 if ctype == 0x06 {
533 validate!(size >= 4);
534 let key = br.read_u32be()?;
535 validate!((key as usize) == size - 4);
536 dec.set_state(key);
537 data_size = size - 4;
538 br.read_skip(size - 4)?;
539 got_key = true;
540 continue;
541 }
542 self.dec_buf.resize(size, 0);
543 br.read_buf(&mut self.dec_buf)?;
544 if ctype != 0x0A {
545 dec.decrypt(&mut self.dec_buf);
546 }
547 match ctype {
548 0x08 | 0x0C | 0x10 | 0x11 | 0x15 | 0x16 => {
549 if ctype < 0x15 { // old versions are not encrypted, roll back and zero key
550 dec.decrypt(&mut self.dec_buf);
551 dec.set_state(0);
552 got_key = true;
553 }
554 validate!(got_key && !initialised);
555 match ctype {
556 0x08 => self.parse_init(0)?,
557 0x0C => self.parse_init(1)?,
558 0x10 => self.parse_init(2)?,
559 0x11 => self.parse_init(3)?,
560 0x15 => self.parse_init(4)?,
561 0x16 => self.parse_init(5)?,
562 _ => unreachable!(),
563 };
564 initialised = true;
565 },
566 0x09 => {
567 validate!(initialised);
568 validate!(self.dec_buf.len() == 3);
569 validate!(self.dec_buf[0] == 8);
570 validate!(self.dec_buf[1] > 0);
571 validate!(self.dec_buf[2] == 1);
572 self.tile_size = self.dec_buf[1] as usize;
573 self.blk_info.resize(self.tile_size, BlkInfo::default());
574 },
575 0x0B => {
576 validate!(initialised);
577 validate!(self.dec_buf.len() == 4);
578 let idx = self.dec_buf[3] as usize;
579 validate!(idx < NUM_CPARAMS);
580 validate!(self.dec_buf[0] != 0);
581 validate!((self.dec_buf[0] as usize) < TM2X_CODING_PARAMS.len());
582 let tab = &TM2X_CODING_PARAMS[self.dec_buf[0] as usize];
583 let m0 = tab[0] as usize;
584 let m1 = tab[1] as usize;
585 let m2 = tab[2] as usize;
586 let m3 = tab[3] as usize;
587 let full_mode = (m2 * 4 + m0) as u8;
588 let lores_mode = m0 as u8;
589 for i in 0..8 {
590 if (i % m1) == 0 && (i % m3) == 0 {
591 self.cparams[idx][i] = full_mode;
592 } else if (i % m1) == 0 {
593 self.cparams[idx][i] = lores_mode;
594 } else {
595 self.cparams[idx][i] = CPARAM_NONE;
596 }
597 }
598 },
599 0x02 => {
600 validate!(initialised);
601 self.parse_tabs()?;
602 },
603 0x0A => {
604 validate!(initialised);
605 self.parse_cb_desc(0xA)?;
606 },
607 _ => { unimplemented!(); },
608 };
609 }
610 self.decode_frame(&src[12..][..data_size])?;
611
612 let myinfo = NAVideoInfo::new(self.width, self.height, false, RGB24_FORMAT);
613 let bufret = alloc_video_buffer(myinfo, 2);
614 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
615 let bufinfo = bufret.unwrap();
616 let mut buf = bufinfo.get_vbuf().unwrap();
617
618 let is_intra = true;
619 self.output_frame(&mut buf);
620
621 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
622 frm.set_keyframe(is_intra);
623 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
624 Ok(Rc::new(RefCell::new(frm)))
625 }
626}
627
628pub fn get_decoder() -> Box<NADecoder> {
629 Box::new(TM2XDecoder::new())
630}
631
632#[cfg(test)]
633mod test {
634 use nihav_core::codecs::RegisteredDecoders;
635 use nihav_core::demuxers::RegisteredDemuxers;
636 use nihav_core::test::dec_video::*;
637 use crate::codecs::duck_register_all_codecs;
638 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
639 #[test]
640 fn test_tm2x() {
641 let mut dmx_reg = RegisteredDemuxers::new();
642 generic_register_all_demuxers(&mut dmx_reg);
643 let mut dec_reg = RegisteredDecoders::new();
644 duck_register_all_codecs(&mut dec_reg);
645
646 test_file_decoding("avi", "assets/Duck/TM2x.avi", Some(16), true, false, None/*Some("tm2x")*/, &dmx_reg, &dec_reg);
647 }
648}
649
650const TM2X_CODING_PARAMS: [[u8; 4]; 25] = [
651 [ 0, 0, 0, 0 ], [ 0, 1, 1, 1 ], [ 0, 1, 1, 2 ], [ 0, 1, 2, 4 ], [ 1, 1, 2, 4 ],
652 [ 0, 2, 2, 4 ], [ 1, 2, 2, 4 ], [ 2, 2, 2, 4 ], [ 1, 4, 2, 4 ], [ 2, 4, 2, 4 ],
653 [ 2, 8, 3, 8 ], [ 3, 4, 3, 8 ], [ 3, 8, 3, 8 ], [ 0, 1, 1, 4 ], [ 0, 1, 2, 2 ],
654 [ 0, 2, 1, 4 ], [ 1, 1, 2, 2 ], [ 1, 4, 2, 8 ], [ 2, 2, 3, 4 ], [ 2, 4, 3, 8 ],
655 [ 0, 1, 3, 8 ], [ 1, 2, 3, 8 ], [ 2, 4, 2, 4 ], [ 2, 4, 3, 8 ], [ 3, 8, 3, 8 ]
656];