1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
10 fn decrypt(&mut self, buf: &mut [u8]) {
12 for el in buf.iter_mut() {
13 *el ^= self.key[(pos & 3) as usize];
14 pos = pos.wrapping_add(1);
17 fn set_state(&mut self, mut key: u32) {
19 let bit31 = (key >> 31) & 1;
20 let bit21 = (key >> 21) & 1;
21 let bit01 = (key >> 1) & 1;
23 key = (key << 1) | (bit31 ^ bit21 ^ bit01 ^ nbit0);
26 self.key[i] = (key >> (8 * (i ^ 3))) as u8;
32 tabs: [[i16; 256]; 2],
33 codebook: [[u8; 8]; 256],
34 num_elems: [usize; 256],
42 fn reset(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
43 let b = br.read_byte()? as usize;
48 fn get_val(&mut self, br: &mut ByteReader) -> DecoderResult<u8> {
49 if self.vq_idx > self.codebook.len() { return Err(DecoderError::ShortData); }
50 let ret = self.codebook[self.vq_idx][self.vq_pos];
52 if self.vq_pos == self.num_elems[self.vq_idx] {
56 self.vq_idx = self.codebook.len() + 1;
61 fn remap(val: u16) -> i16 {
62 let hval = (val >> 1) as i16;
69 fn get_int(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
70 let b = self.get_val(br)?;
71 if b != self.vq_esc - 1 {
72 return Ok(Self::remap(u16::from(b)));
76 let mut pow = u16::from(self.vq_esc);
78 let b = self.get_val(br)?;
80 if b != self.vq_esc - 1 {
81 val = u16::from(b) * pow;
84 pow *= u16::from(self.vq_esc);
88 pow /= u16::from(self.vq_esc);
89 let b = u16::from(self.get_val(br)?);
94 fn get_dy(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
95 let b = self.get_val(br)?;
96 Ok(self.tabs[1][b as usize])
98 fn get_dc(&mut self, br: &mut ByteReader) -> DecoderResult<i16> {
99 let b = self.get_val(br)?;
100 Ok(self.tabs[0][b as usize])
104 impl Default for Deltas {
105 fn default() -> Self {
108 codebook: [[0; 8]; 256],
118 #[derive(Clone,Copy, Default)]
126 const NUM_CPARAMS: usize = 25;
127 const CPARAM_NONE: u8 = 42;
128 const CPARAM_MISSING: u8 = 42 * 2;
129 const CPARAM_MV: u8 = 42 * 3;
131 macro_rules! apply_delta {
132 ($buf:expr, $off:expr, $stride:expr, $hpred: expr, $delta:expr) => {
133 $hpred = $hpred.wrapping_add($delta);
134 $buf[$off] = $buf[$off - $stride].wrapping_add($hpred);
137 macro_rules! copy_line {
138 ($buf:expr, $off:expr, $stride:expr) => {
140 $buf[$off + i] = $buf[$off + i - $stride];
154 fn resize(&mut self, w: usize, h: usize) {
156 self.ydata.resize(self.stride * (h + 1), 0x80);
157 self.udata.resize(self.stride * (h + 1), 0x80);
158 self.vdata.resize(self.stride * (h + 1), 0x80);
164 info: NACodecInfoRef,
171 blk_info: Vec<BlkInfo>,
173 cparams: [[u8; 8]; NUM_CPARAMS],
179 fn new() -> Self { Self::default() }
180 fn output_frame(&mut self, buf: &mut NAVideoBuffer<u8>) {
181 let mut offs = [ buf.get_offset(0), buf.get_offset(1), buf.get_offset(2) ];
182 let strides = [ buf.get_stride(0), buf.get_stride(1), buf.get_stride(2) ];
183 let data = buf.get_data_mut().unwrap();
184 let dst = data.as_mut_slice();
186 let mut pos = self.cur_frame.stride;
187 for _y in 0..self.height {
188 for x in 0..self.width {
189 let y = self.cur_frame.ydata[pos + x];
190 let u = self.cur_frame.udata[pos + x];
191 let v = self.cur_frame.vdata[pos + x];
192 dst[offs[0] + x] = y.max(0).min(255) as u8;
193 dst[offs[1] + x] = u.max(0).min(255) as u8;
194 dst[offs[2] + x] = v.max(0).min(255) as u8;
197 offs[c] += strides[c];
199 pos += self.cur_frame.stride;
202 fn parse_init(&mut self, version: u8) -> DecoderResult<()> {
203 self.version = version;
205 let mut mr = MemoryReader::new_read(&self.dec_buf);
206 let mut br = ByteReader::new(&mut mr);
208 let _smth = br.read_u32be()?;
210 let height = br.read_u16be()? as usize;
211 let width = br.read_u16be()? as usize;
212 validate!(width == self.width && height == self.height);
214 let _smth = br.read_u32be()?;
216 let _smth = br.read_byte()?;
217 let _nfuncs = br.read_byte()? as usize;
218 let _smth = br.read_u16be()? as usize;
219 let has_mv = br.read_byte()?;
220 self.is_intra = has_mv == 0;
222 let _flags = br.read_u16be()?;
223 let id_len = br.read_byte()? as usize;
224 br.read_skip(id_len)?;
225 let _smth1 = br.read_byte()?;
226 let len = br.read_byte()? as usize;
228 let _smth = br.read_u32be()?;
233 fn parse_tabs(&mut self) -> DecoderResult<()> {
234 let mut mr = MemoryReader::new_read(&self.dec_buf);
235 let mut br = ByteReader::new(&mut mr);
237 let idx = br.read_byte()? as usize;
238 validate!(idx < self.deltas.tabs.len());
239 let len = br.read_byte()? as usize;
240 validate!(((len * 2) as i64) == br.left());
242 self.deltas.tabs[idx][i] = br.read_u16be()? as i16;
247 fn parse_cb_desc(&mut self, version: u8) -> DecoderResult<()> {
248 let mut mr = MemoryReader::new_read(&self.dec_buf);
249 let mut br = ByteReader::new(&mut mr);
252 self.deltas.vq_esc = br.read_byte()?;
253 validate!(self.deltas.vq_esc > 1);
254 let _tag = br.read_u16be()?;
256 let len = br.read_u16be()? as usize;
257 validate!(len + 3 == (br.left() as usize));
258 let num_entries = br.read_u16be()?;
259 validate!(num_entries == 256);
260 let max_elems = br.read_byte()?;
261 validate!(max_elems > 0 && max_elems <= 8);
263 while br.left() > 0 {
264 validate!(idx < self.deltas.codebook.len());
265 let num_elems = br.read_byte()? as usize;
266 validate!(num_elems <= 8);
267 self.deltas.num_elems[idx] = num_elems;
268 for i in 0..num_elems {
269 self.deltas.codebook[idx][i] = br.read_byte()?;
273 validate!(idx == 256);
274 self.deltas.num_vq = idx;
278 #[allow(clippy::int_plus_one)]
279 #[allow(clippy::manual_memcpy)]
280 #[allow(clippy::cognitive_complexity)]
281 fn decode_frame(&mut self, src: &[u8]) -> DecoderResult<()> {
282 let mut mr = MemoryReader::new_read(src);
283 let mut br = ByteReader::new(&mut mr);
285 self.deltas.reset(&mut br)?;
286 let bw = self.width / 8;
287 let bh = self.height / 8;
288 let ntiles = (bw + self.tile_size - 1) / self.tile_size;
289 let mut pos = self.cur_frame.stride;
290 let ydata = &mut self.cur_frame.ydata;
291 let udata = &mut self.cur_frame.udata;
292 let vdata = &mut self.cur_frame.vdata;
293 let stride = self.cur_frame.stride;
295 for tile in 0..ntiles {
296 let xpos = tile * self.tile_size;
297 let len = self.tile_size.min(bw - xpos);
300 for el in self.blk_info.iter_mut().take(len) {
301 let t1 = self.deltas.get_val(&mut br)?;
302 let t2 = self.deltas.get_val(&mut br)?;
303 validate!((t1 as usize) < NUM_CPARAMS);
304 validate!(self.cparams[t1 as usize][0] != CPARAM_MISSING);
308 el.mv_x = self.deltas.get_int(&mut br)?;
309 el.mv_y = self.deltas.get_int(&mut br)?;
318 let mut ypred = 0i16;
319 let mut upred = 0i16;
320 let mut vpred = 0i16;
323 let op = self.cparams[self.blk_info[x].btype as usize][line];
324 let cur_off = pos + bx * 8 + line * stride;
328 let delta = self.deltas.get_dy(&mut br)?;
329 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
331 copy_line!(udata, cur_off, stride);
332 copy_line!(vdata, cur_off, stride);
339 let delta = self.deltas.get_dy(&mut br)?;
340 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
342 ydata[cur_off + i] = ydata[cur_off + i - 1];
345 copy_line!(udata, cur_off, stride);
346 copy_line!(vdata, cur_off, stride);
353 let delta = self.deltas.get_dy(&mut br)?;
354 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
356 ydata[cur_off + i] = ydata[cur_off + i - 1];
359 copy_line!(udata, cur_off, stride);
360 copy_line!(vdata, cur_off, stride);
365 let delta = self.deltas.get_dy(&mut br)?;
366 apply_delta!(ydata, cur_off, stride, ypred, delta);
368 ydata[cur_off + i] = ydata[cur_off];
370 copy_line!(udata, cur_off, stride);
371 copy_line!(vdata, cur_off, stride);
375 4 => { // c2y2c2y2|c2y2c2y2
376 for i in (0..8).step_by(2) {
377 let delta = self.deltas.get_dc(&mut br)?;
378 apply_delta!(udata, cur_off + i + 0, stride, upred, delta);
379 udata[cur_off + i + 1] = udata[cur_off + i];
380 let delta = self.deltas.get_dc(&mut br)?;
381 apply_delta!(vdata, cur_off + i + 0, stride, vpred, delta);
382 vdata[cur_off + i + 1] = vdata[cur_off + i];
383 let delta = self.deltas.get_dy(&mut br)?;
384 apply_delta!(ydata, cur_off + i + 0, stride, ypred, delta);
385 let delta = self.deltas.get_dy(&mut br)?;
386 apply_delta!(ydata, cur_off + i + 1, stride, ypred, delta);
392 let delta = self.deltas.get_dc(&mut br)?;
393 apply_delta!(udata, cur_off + i, stride, upred, delta);
394 let delta = self.deltas.get_dc(&mut br)?;
395 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
396 let delta = self.deltas.get_dy(&mut br)?;
397 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
399 udata[cur_off + i] = udata[cur_off + i - 1];
400 vdata[cur_off + i] = vdata[cur_off + i - 1];
401 ydata[cur_off + i] = ydata[cur_off + i - 1];
405 6 | 7 => unreachable!(),
409 let delta = self.deltas.get_dc(&mut br)?;
410 apply_delta!(udata, cur_off + i, stride, upred, delta);
411 let delta = self.deltas.get_dc(&mut br)?;
412 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
414 udata[cur_off + i] = udata[cur_off + i - 1];
415 vdata[cur_off + i] = vdata[cur_off + i - 1];
417 let delta = self.deltas.get_dy(&mut br)?;
418 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
424 let delta = self.deltas.get_dc(&mut br)?;
425 apply_delta!(udata, cur_off + i, stride, upred, delta);
426 let delta = self.deltas.get_dc(&mut br)?;
427 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
429 udata[cur_off + i] = udata[cur_off + i - 1];
430 vdata[cur_off + i] = vdata[cur_off + i - 1];
433 let delta = self.deltas.get_dy(&mut br)?;
434 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
436 ydata[cur_off + i] = ydata[cur_off + i - 1];
443 let delta = self.deltas.get_dc(&mut br)?;
444 apply_delta!(udata, cur_off + i, stride, upred, delta);
445 let delta = self.deltas.get_dc(&mut br)?;
446 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
447 let delta = self.deltas.get_dy(&mut br)?;
448 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
450 udata[cur_off + i] = udata[cur_off + i - 1];
451 vdata[cur_off + i] = vdata[cur_off + i - 1];
452 ydata[cur_off + i] = ydata[cur_off + i - 1];
456 11 => unreachable!(),
460 let delta = self.deltas.get_dc(&mut br)?;
461 apply_delta!(udata, cur_off + i, stride, upred, delta);
462 let delta = self.deltas.get_dc(&mut br)?;
463 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
465 udata[cur_off + i] = udata[cur_off + i - 1];
466 vdata[cur_off + i] = vdata[cur_off + i - 1];
468 let delta = self.deltas.get_dy(&mut br)?;
469 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
475 let delta = self.deltas.get_dc(&mut br)?;
476 apply_delta!(udata, cur_off + i, stride, upred, delta);
477 let delta = self.deltas.get_dc(&mut br)?;
478 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
480 udata[cur_off + i] = udata[cur_off + i - 1];
481 vdata[cur_off + i] = vdata[cur_off + i - 1];
484 let delta = self.deltas.get_dy(&mut br)?;
485 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
487 ydata[cur_off + i] = ydata[cur_off + i - 1];
494 let delta = self.deltas.get_dc(&mut br)?;
495 apply_delta!(udata, cur_off + i, stride, upred, delta);
496 let delta = self.deltas.get_dc(&mut br)?;
497 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
499 udata[cur_off + i] = udata[cur_off + i - 1];
500 vdata[cur_off + i] = vdata[cur_off + i - 1];
503 let delta = self.deltas.get_dy(&mut br)?;
504 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
506 ydata[cur_off + i] = ydata[cur_off + i - 1];
513 let delta = self.deltas.get_dc(&mut br)?;
514 apply_delta!(udata, cur_off + i, stride, upred, delta);
515 let delta = self.deltas.get_dc(&mut br)?;
516 apply_delta!(vdata, cur_off + i, stride, vpred, delta);
517 let delta = self.deltas.get_dy(&mut br)?;
518 apply_delta!(ydata, cur_off + i, stride, ypred, delta);
520 udata[cur_off + i] = udata[cur_off + i - 1];
521 vdata[cur_off + i] = vdata[cur_off + i - 1];
522 ydata[cur_off + i] = ydata[cur_off + i - 1];
527 copy_line!(ydata, cur_off, stride);
528 copy_line!(udata, cur_off, stride);
529 copy_line!(vdata, cur_off, stride);
535 let src_x = (bx as i16) * 8 + self.blk_info[x].mv_x;
536 let src_y = ((by * 8 + line) as i16) + self.blk_info[x].mv_y;
537 validate!(src_x >= 0 && (src_x as usize) + 8 <= self.width);
538 validate!(src_y >= 0 && (src_y as usize) + 1 <= self.height);
539 let ref_off = (src_x as usize) + ((src_y + 1) as usize) * stride;
541 ydata[cur_off + i] = self.ref_frame.ydata[ref_off + i];
542 udata[cur_off + i] = self.ref_frame.udata[ref_off + i];
543 vdata[cur_off + i] = self.ref_frame.vdata[ref_off + i];
545 ypred = ydata[cur_off + 7] - ydata[cur_off + 7 - stride];
546 upred = udata[cur_off + 7] - udata[cur_off + 7 - stride];
547 vpred = vdata[cur_off + 7] - vdata[cur_off + 7 - stride];
561 impl NADecoder for TM2XDecoder {
562 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
563 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
564 let fmt = NAPixelFormaton::new(ColorModel::YUV(YUVSubmodel::YUVJ),
565 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 0, 1)),
566 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 1, 1)),
567 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 2, 1)),
569 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt));
570 self.width = vinfo.get_width();
571 self.height = vinfo.get_height();
572 self.cur_frame.resize(self.width, self.height);
573 self.ref_frame.resize(self.width, self.height);
574 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
577 Err(DecoderError::InvalidData)
580 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
581 let src = pkt.get_buffer();
582 validate!(src.len() > 8);
583 let mut mr = MemoryReader::new_read(&src);
584 let mut br = ByteReader::new(&mut mr);
585 let mut dec = Decryptor::default();
587 let mut initialised = false;
588 let mut got_key = false;
589 let mut data_size = 0;
590 self.cparams = [[CPARAM_MISSING; 8]; NUM_CPARAMS];
591 self.is_intra = false;
592 while br.left() >= 8 {
593 let magic = br.read_u24be()?;
594 let ctype = br.read_byte()?;
595 let size = br.read_u32be()? as usize;
596 validate!(magic == 0xA00001 && br.left() >= (size as i64));
598 validate!(size >= 4);
599 let key = br.read_u32be()?;
600 validate!((key as usize) == size - 4);
602 data_size = size - 4;
603 br.read_skip(size - 4)?;
607 self.dec_buf.resize(size, 0);
608 br.read_buf(&mut self.dec_buf)?;
610 dec.decrypt(&mut self.dec_buf);
613 0x08 | 0x0C | 0x10 | 0x11 | 0x15 | 0x16 => {
614 if ctype < 0x15 { // old versions are not encrypted, roll back and zero key
615 dec.decrypt(&mut self.dec_buf);
619 validate!(got_key && !initialised);
621 0x08 => self.parse_init(0)?,
622 0x0C => self.parse_init(1)?,
623 0x10 => self.parse_init(2)?,
624 0x11 => self.parse_init(3)?,
625 0x15 => self.parse_init(4)?,
626 0x16 => self.parse_init(5)?,
632 validate!(initialised);
633 validate!(self.dec_buf.len() == 3);
634 validate!(self.dec_buf[0] == 8);
635 validate!(self.dec_buf[1] > 0);
636 validate!(self.dec_buf[2] == 1);
637 self.tile_size = self.dec_buf[1] as usize;
638 self.blk_info.resize(self.tile_size, BlkInfo::default());
641 validate!(initialised);
642 validate!(self.dec_buf.len() == 4);
643 let idx = self.dec_buf[3] as usize;
644 validate!(idx < NUM_CPARAMS);
645 validate!((self.dec_buf[0] as usize) < TM2X_CODING_PARAMS.len());
646 if self.dec_buf[0] != 0 {
647 let tab = &TM2X_CODING_PARAMS[self.dec_buf[0] as usize];
648 let m0 = tab[0] as usize;
649 let m1 = tab[1] as usize;
650 let m2 = tab[2] as usize;
651 let m3 = tab[3] as usize;
652 let full_mode = (m2 * 4 + m0) as u8;
653 let lores_mode = m0 as u8;
655 if (i % m1) == 0 && (i % m3) == 0 {
656 self.cparams[idx][i] = full_mode;
657 } else if (i % m1) == 0 {
658 self.cparams[idx][i] = lores_mode;
660 self.cparams[idx][i] = CPARAM_NONE;
664 for i in 0..8 { self.cparams[idx][i] = CPARAM_MV; }
668 validate!(initialised);
672 validate!(initialised);
673 self.parse_cb_desc(0xA)?;
675 _ => { unimplemented!(); },
679 std::mem::swap(&mut self.cur_frame, &mut self.ref_frame);
681 self.decode_frame(&src[12..][..data_size])?;
683 let myinfo = self.info.get_properties().get_video_info().unwrap();
684 let bufinfo = alloc_video_buffer(myinfo, 2)?;
685 let mut buf = bufinfo.get_vbuf().unwrap();
687 self.output_frame(&mut buf);
689 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
690 frm.set_keyframe(self.is_intra);
691 frm.set_frame_type(if self.is_intra { FrameType::I } else { FrameType::P });
694 fn flush(&mut self) {
698 impl NAOptionHandler for TM2XDecoder {
699 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
700 fn set_options(&mut self, _options: &[NAOption]) { }
701 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
704 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
705 Box::new(TM2XDecoder::new())
710 use nihav_core::codecs::RegisteredDecoders;
711 use nihav_core::demuxers::RegisteredDemuxers;
712 use nihav_codec_support::test::dec_video::*;
713 use crate::duck_register_all_decoders;
714 use nihav_commonfmt::generic_register_all_demuxers;
717 let mut dmx_reg = RegisteredDemuxers::new();
718 generic_register_all_demuxers(&mut dmx_reg);
719 let mut dec_reg = RegisteredDecoders::new();
720 duck_register_all_decoders(&mut dec_reg);
722 test_decoding("avi", "truemotion2x", "assets/Duck/TM2x.avi", None,
723 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
724 [0x2854e7f3, 0x41e54fd3, 0xd9a16302, 0x580321b2],
725 [0x8e736f59, 0x57c58dc0, 0xe15bad3a, 0xf96e2c5b],
726 [0x12700e7c, 0xfa2d06e0, 0x05b758ba, 0xe79aabb6],
727 [0x29f935f2, 0x2ad0d6d1, 0x2fde19a2, 0x5aa3823b],
728 [0x7f1a787d, 0x77f3ab61, 0x0e584c66, 0x9d1842ea],
729 [0xb5607334, 0xdb149056, 0xe0e3ddb5, 0x19f8e254],
730 [0xb054e4d0, 0x1d241d4f, 0x75fdfe95, 0x9dde8024]]));
734 const TM2X_CODING_PARAMS: [[u8; 4]; 25] = [
735 [ 0, 0, 0, 0 ], [ 0, 1, 1, 1 ], [ 0, 1, 1, 2 ], [ 0, 1, 2, 4 ], [ 1, 1, 2, 4 ],
736 [ 0, 2, 2, 4 ], [ 1, 2, 2, 4 ], [ 2, 2, 2, 4 ], [ 1, 4, 2, 4 ], [ 2, 4, 2, 4 ],
737 [ 2, 8, 3, 8 ], [ 3, 4, 3, 8 ], [ 3, 8, 3, 8 ], [ 0, 1, 1, 4 ], [ 0, 1, 2, 2 ],
738 [ 0, 2, 1, 4 ], [ 1, 1, 2, 2 ], [ 1, 4, 2, 8 ], [ 2, 2, 3, 4 ], [ 2, 4, 3, 8 ],
739 [ 0, 1, 3, 8 ], [ 1, 2, 3, 8 ], [ 2, 4, 2, 4 ], [ 2, 4, 3, 8 ], [ 3, 8, 3, 8 ]