X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fcodecs%2Fclearvideo.rs;h=47357311668dcfb1d7a59efe4ebaffddd626be36;hp=d485bdb6b00cb572f7bb91cdce916c7284ff9ebc;hb=e64739f87a35f29be0bbbce366876180ba3eb57e;hpb=2422d9699cd56cbb86ac32b3e8dd026e20a89db5 diff --git a/nihav-commonfmt/src/codecs/clearvideo.rs b/nihav-commonfmt/src/codecs/clearvideo.rs index d485bdb..4735731 100644 --- a/nihav-commonfmt/src/codecs/clearvideo.rs +++ b/nihav-commonfmt/src/codecs/clearvideo.rs @@ -3,8 +3,6 @@ use nihav_core::io::bitreader::*; use nihav_core::io::codebook::*; use nihav_core::formats; use nihav_core::codecs::*; -use std::fmt; -use std::ops::{Add, Sub}; struct CLVDCCodeReader { } struct CLVACCodeReader { } @@ -13,28 +11,28 @@ struct CLVSym16CodeReader { codes: &'static [u16], bits: &'static [u8], syms: &' impl CodebookDescReader for CLVDCCodeReader { fn bits(&mut self, idx: usize) -> u8 { CLV_DC_BITS[idx] } - fn code(&mut self, idx: usize) -> u32 { CLV_DC_CODES[idx] as u32 } + fn code(&mut self, idx: usize) -> u32 { u32::from(CLV_DC_CODES[idx]) } fn sym (&mut self, idx: usize) -> i8 { (idx as i8) - 63 } fn len(&mut self) -> usize { CLV_DC_BITS.len() } } impl CodebookDescReader for CLVACCodeReader { fn bits(&mut self, idx: usize) -> u8 { CLV_AC_BITS[idx] } - fn code(&mut self, idx: usize) -> u32 { CLV_AC_CODES[idx] as u32 } + fn code(&mut self, idx: usize) -> u32 { u32::from(CLV_AC_CODES[idx]) } fn sym (&mut self, idx: usize) -> u16 { CLV_AC_SYMS[idx] } fn len(&mut self) -> usize { CLV_AC_BITS.len() } } impl CodebookDescReader for CLVFlagsCodeReader { fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] } - fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 } + fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) } fn sym (&mut self, idx: usize) -> u8 { idx as u8 } fn len(&mut self) -> usize { self.bits.len() } } impl CodebookDescReader for CLVSym16CodeReader { fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] } - fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 } + fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) } fn sym (&mut self, idx: usize) -> u16 { self.syms[idx] } fn len(&mut self) -> usize { self.bits.len() } } @@ -53,83 +51,24 @@ impl LevelCodes { mvd: Option<(&'static [u8], &'static [u16], &'static [u16])>, mv_esc: u16, bias: Option<(&'static [u8], &'static [u16], &'static [u16])>, bias_esc: u16) -> Self { let flags_cb = if let Some((bits, codes)) = flgd { - let mut coderead = CLVFlagsCodeReader { bits: bits, codes: codes }; + let mut coderead = CLVFlagsCodeReader { bits, codes }; Some(Codebook::new(&mut coderead, CodebookMode::MSB).unwrap()) } else { None }; let mv_cb = if let Some((bits, codes, syms)) = mvd { - let mut coderead = CLVSym16CodeReader { bits: bits, codes: codes, syms: syms }; + let mut coderead = CLVSym16CodeReader { bits, codes, syms }; Some(Codebook::new(&mut coderead, CodebookMode::MSB).unwrap()) } else { None }; let bias_cb = if let Some((bits, codes, syms)) = bias { - let mut coderead = CLVSym16CodeReader { bits: bits, codes: codes, syms: syms }; + let mut coderead = CLVSym16CodeReader { bits, codes, syms }; Some(Codebook::new(&mut coderead, CodebookMode::MSB).unwrap()) } else { None }; - LevelCodes { flags_cb: flags_cb, mv_cb: mv_cb, mv_esc: mv_esc, bias_cb: bias_cb, bias_esc: bias_esc } - } -} - -#[derive(Debug,Clone,Copy)] -pub struct MV { - x: i16, - y: i16, -} - -impl MV { - pub fn new(x: i16, y: i16) -> Self { MV{ x: x, y: y } } - pub fn pred(a: MV, b: MV, c: MV) -> Self { - let x; - if a.x < b.x { - if b.x < c.x { - x = b.x; - } else { - if a.x < c.x { x = c.x; } else { x = a.x; } - } - } else { - if b.x < c.x { - if a.x < c.x { x = a.x; } else { x = c.x; } - } else { - x = b.x; - } - } - let y; - if a.y < b.y { - if b.y < c.y { - y = b.y; - } else { - if a.y < c.y { y = c.y; } else { y = a.y; } - } - } else { - if b.y < c.y { - if a.y < c.y { y = a.y; } else { y = c.y; } - } else { - y = b.y; - } - } - MV { x: x, y: y } - } -} - -pub const ZERO_MV: MV = MV { x: 0, y: 0 }; - -impl Add for MV { - type Output = MV; - fn add(self, other: MV) -> MV { MV { x: self.x + other.x, y: self.y + other.y } } -} - -impl Sub for MV { - type Output = MV; - fn sub(self, other: MV) -> MV { MV { x: self.x - other.x, y: self.y - other.y } } -} - -impl fmt::Display for MV { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{},{}", self.x, self.y) + LevelCodes { flags_cb, mv_cb, mv_esc, bias_cb, bias_esc } } } @@ -208,8 +147,8 @@ fn dct_row(blk: &mut [i32]) { let t7 = ((blk[0] - blk[4]) << dshift) + (1 << (shift - 1)); let t8 = t0 + t2; let t9 = t0 - t2; - let tA = 181 * (t9 + (t1 - t3)) + 0x80 >> 8; - let tB = 181 * (t9 - (t1 - t3)) + 0x80 >> 8; + let tA = (181 * (t9 + (t1 - t3)) + 0x80) >> 8; + let tB = (181 * (t9 - (t1 - t3)) + 0x80) >> 8; let tC = t1 + t3; blk[0] = (t6 + t5 + t8) >> shift; @@ -223,6 +162,8 @@ fn dct_row(blk: &mut [i32]) { } #[allow(non_snake_case)] +#[allow(clippy::erasing_op)] +#[allow(clippy::identity_op)] fn dct_col(blk: &mut [i32; 64], col: usize) { let dshift = 8; let shift = 14; @@ -236,8 +177,8 @@ fn dct_col(blk: &mut [i32; 64], col: usize) { let t7 = ((blk[0*8 + col] - blk[4*8 + col]) << dshift) + (1 << (shift - 1)); let t8 = t0 + t2; let t9 = t0 - t2; - let tA = 181 * (t9 + (t1 - t3)) + 0x80 >> 8; - let tB = 181 * (t9 - (t1 - t3)) + 0x80 >> 8; + let tA = (181 * (t9 + (t1 - t3)) + 0x80) >> 8; + let tB = (181 * (t9 - (t1 - t3)) + 0x80) >> 8; let tC = t1 + t3; blk[0*8 + col] = (t6 + t5 + t8) >> shift; @@ -257,7 +198,7 @@ fn clv_dct(blk: &mut [i32; 64]) { fn clv_dct_dc(blk: &mut [i32; 64]) { let dval = blk[0] >> 3; - for i in 0..64 { blk[i] = dval; } + for el in blk.iter_mut() { *el = dval; } } fn put_blocks(buf: &mut NAVideoBuffer, xpos: usize, ypos: usize, blk: &[[i32;64]; 6]) { @@ -274,12 +215,12 @@ fn put_blocks(buf: &mut NAVideoBuffer, xpos: usize, ypos: usize, blk: &[[i32 for j in 0..8 { for k in 0..8 { let mut v = blk[0][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxy + k] = v as u8; } for k in 0..8 { let mut v = blk[1][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxy + k + 8] = v as u8; } idxy += stridey; @@ -287,12 +228,12 @@ fn put_blocks(buf: &mut NAVideoBuffer, xpos: usize, ypos: usize, blk: &[[i32 for j in 0..8 { for k in 0..8 { let mut v = blk[2][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxy + k] = v as u8; } for k in 0..8 { let mut v = blk[3][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxy + k + 8] = v as u8; } idxy += stridey; @@ -301,12 +242,12 @@ fn put_blocks(buf: &mut NAVideoBuffer, xpos: usize, ypos: usize, blk: &[[i32 for j in 0..8 { for k in 0..8 { let mut v = blk[4][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxu + k] = v as u8; } for k in 0..8 { let mut v = blk[5][k + j * 8] + 128; - if v < 0 { v = 0; } if v > 255 { v = 255; } + if v < 0 { v = 0; } else if v > 255 { v = 255; } framebuf[idxv + k] = v as u8; } idxu += strideu; @@ -355,7 +296,7 @@ fn copyadd_block(dst: &mut NAVideoBuffer, src: &NAVideoBuffer, let dst = &mut dbuf[doff..][..size]; let src = &sbuf[soff..][..size]; for i in 0..size { - let val = (src[i] as i16) + bias; + let val = i16::from(src[i]) + bias; if val < 0x00 { dst[i] = 0x00; } else if val > 0xFF { dst[i] = 0xFF; } else { dst[i] = val as u8; } @@ -444,7 +385,7 @@ fn decode_dct_block(br: &mut BitReader, blk: &mut [i32; 64], ac_quant: i32, has_ let mut idx = 1; let mut eob = false; - blk[0] = br.read_cb(dc_cb)? as i32; + blk[0] = i32::from(br.read_cb(dc_cb)?); if !has_ac { return Ok(()); } @@ -453,7 +394,7 @@ fn decode_dct_block(br: &mut BitReader, blk: &mut [i32; 64], ac_quant: i32, has_ let (level, skip) = if val != CLV_AC_ESCAPE { eob = ((val >> 12) & 1) != 0; let run = ((val >> 4) & 0xFF) as usize; - let lev = (val & 0xF) as i32; + let lev = i32::from(val & 0xF); if br.read_bool()? { (-lev, run) } else { @@ -495,7 +436,7 @@ fn decode_tile_info(br: &mut BitReader, lc: &[LevelCodes], level: usize) -> Deco let mv = if let Some(ref cb) = lc[level].mv_cb { let mv_code = br.read_cb(cb)?; if mv_code != lc[level].mv_esc { - MV::new(((mv_code & 0xFF) as i8) as i16, (mv_code as i16) >> 8) + MV::new(i16::from((mv_code & 0xFF) as i8), (mv_code as i16) >> 8) } else { let x = br.read_s(8)? as i16; let y = br.read_s(8)? as i16; @@ -514,7 +455,7 @@ fn decode_tile_info(br: &mut BitReader, lc: &[LevelCodes], level: usize) -> Deco } else { 0 }; - let mut ti = TileInfo { flags: flags, mv: mv, bias: bias, child: [None, None, None, None] }; + let mut ti = TileInfo { flags, mv, bias, child: [None, None, None, None] }; if ti.flags != 0 { for i in 0..4 { if (ti.flags & (1 << i)) != 0 { @@ -536,9 +477,9 @@ impl ClearVideoDecoder { ClearVideoDecoder { info: dummy_info, - dc_cb: dc_cb, ac_cb: ac_cb, + dc_cb, ac_cb, frmmgr: HAMShuffler::new(), - is_rm: is_rm, + is_rm, ylev: [ LevelCodes::new(Some((CLV_FLAGSY_0_BITS, CLV_FLAGSY_0_CODES)), Some((CLV_MVY_0_BITS, CLV_MVY_0_CODES, CLV_MVY_0_SYMS)), CLV_MVY_0_ESCAPE, @@ -593,7 +534,7 @@ impl ClearVideoDecoder { let mut blks: [[i32; 64]; 6] = [[0; 64]; 6]; let mut has_ac: [bool; 6] = [false; 6]; - for i in 0..6 { has_ac[i] = br.read_bool()? } + for flag in has_ac.iter_mut() { *flag = br.read_bool()?; } for i in 0..4 { decode_dct_block(br, &mut blks[i], ac_quant, has_ac[i], &self.dc_cb, &self.ac_cb)?; @@ -681,7 +622,7 @@ impl ClearVideoDecoder { } impl NADecoder for ClearVideoDecoder { - fn init(&mut self, info: NACodecInfoRef) -> DecoderResult<()> { + fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { if info.get_extradata().is_none() { return Err(DecoderError::InvalidData); } if let NACodecTypeInfo::Video(vinfo) = info.get_properties() { let w = vinfo.get_width(); @@ -711,7 +652,7 @@ impl NADecoder for ClearVideoDecoder { Err(DecoderError::InvalidData) } } - fn decode(&mut self, pkt: &NAPacket) -> DecoderResult { + fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult { let src = pkt.get_buffer(); if src.len() <= 1 { return Err(DecoderError::ShortData); } let off = if self.is_rm { @@ -726,16 +667,14 @@ impl NADecoder for ClearVideoDecoder { let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None); frm.set_keyframe(false); frm.set_frame_type(FrameType::Skip); - return Ok(Rc::new(RefCell::new(frm))); + return Ok(frm.into_ref()); } let is_intra = (src[off] & 2) == 2; - let mut br = BitReader::new(&src[(off + 1)..], src.len() - (off + 1), BitReaderMode::BE); + let mut br = BitReader::new(&src[(off + 1)..], BitReaderMode::BE); let vinfo = self.info.get_properties().get_video_info().unwrap(); - let bufret = alloc_video_buffer(vinfo, self.tsize); - if let Err(_) = bufret { return Err(DecoderError::InvalidData); } - let bufinfo = bufret.unwrap(); + let bufinfo = alloc_video_buffer(vinfo, self.tsize)?; let mut buf = bufinfo.get_vbuf().unwrap(); if is_intra { @@ -744,7 +683,9 @@ impl NADecoder for ClearVideoDecoder { self.decode_frame_intra(&mut br, &mut buf, vinfo.get_width(), vinfo.get_height())?; extend_edges(&mut buf, 1 << self.tsize); } else { - let mut prev = self.frmmgr.clone_ref().unwrap(); + let pref = self.frmmgr.clone_ref(); + if pref.is_none() { return Err(DecoderError::MissingReference); } + let mut prev = pref.unwrap(); extend_edges(&mut prev, 1 << self.tsize); self.decode_frame_inter(&mut br, &mut buf, &mut prev, vinfo.get_width(), vinfo.get_height())?; extend_edges(&mut buf, 1 << self.tsize); @@ -757,15 +698,18 @@ impl NADecoder for ClearVideoDecoder { } else { frm.set_frame_type(FrameType::P); } - Ok(Rc::new(RefCell::new(frm))) + Ok(frm.into_ref()) + } + fn flush(&mut self) { + self.frmmgr.clear(); } } -pub fn get_decoder() -> Box { +pub fn get_decoder() -> Box { Box::new(ClearVideoDecoder::new(false)) } -pub fn get_decoder_rm() -> Box { +pub fn get_decoder_rm() -> Box { Box::new(ClearVideoDecoder::new(true)) } @@ -773,18 +717,28 @@ pub fn get_decoder_rm() -> Box { mod test { use nihav_core::codecs::RegisteredDecoders; use nihav_core::demuxers::RegisteredDemuxers; - use nihav_core::test::dec_video::test_file_decoding; - use crate::codecs::generic_register_all_codecs; - use crate::demuxers::generic_register_all_demuxers; + use nihav_core::test::dec_video::*; + use crate::generic_register_all_codecs; + use crate::generic_register_all_demuxers; #[test] fn test_clv() { let mut dmx_reg = RegisteredDemuxers::new(); generic_register_all_demuxers(&mut dmx_reg); let mut dec_reg = RegisteredDecoders::new(); generic_register_all_codecs(&mut dec_reg); - test_file_decoding("avi", "assets/Misc/TalkingHead_352x288.avi", Some(10), true, false, None/*Some("clv")*/, &dmx_reg, &dec_reg); -// test_file_decoding("avi", "assets/Misc/basketball.avi", None/*Some(10)*/, true, false, Some("clv1")); -//panic!("debug"); + test_decoding("avi", "clearvideo", "assets/Misc/TalkingHead_352x288.avi", Some(10), &dmx_reg, + &dec_reg, ExpectedTestResult::MD5Frames(vec![ + [0xb432376c, 0xf1dce57b, 0x8e79c7ee, 0xdd51850d], + [0x76eb9726, 0x7ca1aabd, 0xf3f0740c, 0xf804dd0e], + [0xc639b32c, 0x1f53f1f4, 0x50c34651, 0xc49cd2ac], + [0x55408f2a, 0x37b01de0, 0xcc6aeadd, 0x09768735], + [0xea219c51, 0xed72710c, 0x6c4b2bb0, 0xbfab0cb7], + [0xfbf56708, 0x7f6597c7, 0x08ce894d, 0x9c4c7f60], + [0x3dbf8b57, 0x9e1513ef, 0x209309a6, 0x56f0aca7], + [0xc5fb6cb7, 0x1b9b092f, 0xe11127be, 0xe4fe8f45], + [0x81a4a122, 0xb2b84bcf, 0xa478bd80, 0x12c78fb6], + [0xb5b43c22, 0xd9c457fa, 0xcc5390d8, 0x1201ef22], + [0x27a206e9, 0x88085556, 0x1114fb62, 0x77f1ebed]])); } } @@ -876,17 +830,6 @@ const CLV_AC_BITS: &[u8] = &[ const CLV_AC_ESCAPE: u16 = 0x1BFF; -const ZIGZAG: &[usize] = &[ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -]; - const CLV_BIAS_ESCAPE: u16 = 0x100; const CLV_MVY_0_BITS: &[u8] = &[