X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-duck%2Fsrc%2Fcodecs%2Fon2avc.rs;h=9a0e0cd64e74d55c48c5370ebeff5f6f30bdcf23;hb=HEAD;hp=46880fac414b92a2a7adb240a8117dc11169dd11;hpb=80aaa7ef4cf5ce03978f64d07c344e4b18718b1b;p=nihav.git diff --git a/nihav-duck/src/codecs/on2avc.rs b/nihav-duck/src/codecs/on2avc.rs index 46880fa..9a0e0cd 100644 --- a/nihav-duck/src/codecs/on2avc.rs +++ b/nihav-duck/src/codecs/on2avc.rs @@ -4,8 +4,8 @@ use nihav_core::io::byteio::read_u16le; use nihav_core::io::bitreader::*; use nihav_core::io::codebook::*; use nihav_core::io::intcode::*; -use nihav_core::dsp::fft::*; -use nihav_core::dsp::mdct::IMDCT; +use nihav_codec_support::dsp::fft::*; +use nihav_codec_support::dsp::mdct::IMDCT; use std::str::FromStr; @@ -210,21 +210,36 @@ impl AVCDecoder { let mut cur_band = 0; let mut scale = 0; let mut first = true; - for wg in self.win_grp.iter().take(self.windows) { - if *wg { + for wg in 0..self.windows { + if self.win_grp[wg] { for _ in 0..bands { if self.cbs[cur_band] == 0 { - self.scales[cur_band] = 0; - } else { - if first { - scale = br.read(7)? as i16; - first = false - } else { - scale += br.read_cb(&self.codebooks.scale_cb)? as i16; - validate!((scale >= 0) && (scale < 128)); + let mut all_zero = true; + let mut band2 = cur_band; + for wg2 in wg + 1..self.windows { + if self.win_grp[wg2] { + break; + } + band2 += bands; + if self.cbs[band2] != 0 { + all_zero = false; + break; + } + } + if all_zero { + self.scales[cur_band] = 0; + cur_band += 1; + continue; } - self.scales[cur_band] = scale as u8; } + if first { + scale = br.read(7)? as i16; + first = false; + } else { + scale += i16::from(br.read_cb(&self.codebooks.scale_cb)?); + validate!((0..128).contains(&scale)); + } + self.scales[cur_band] = scale as u8; cur_band += 1; } } else { @@ -331,6 +346,7 @@ impl AVCDecoder { } Ok(()) } + #[allow(clippy::cognitive_complexity)] fn synth_channel(&mut self, chno: usize, dst: &mut [f32]) { let coeffs = &mut self.coeffs[chno]; let delay = &mut self.delay[chno]; @@ -339,23 +355,13 @@ impl AVCDecoder { 0 | 1 => { self.imdct_long.imdct_half(coeffs, &mut self.tmp); overlap_half(dst, &self.tmp, delay, self.win_long); - (&mut delay[0..COEFFS/2]).copy_from_slice(&self.tmp[COEFFS/2..COEFFS]); + delay[0..COEFFS/2].copy_from_slice(&self.tmp[COEFFS/2..COEFFS]); for i in COEFFS/2..COEFFS { delay[i] = delay[COEFFS - 1 - i]; } }, 2 | 7 => { - self.imdct_long.imdct(coeffs, &mut self.tmp); - for i in 0..SHORT_WIN_POINT0 { - dst[i] = delay[i]; - } - overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &self.tmp[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT); - for i in SHORT_WIN_POINT1..COEFFS { - dst[i] = self.tmp[i - SHORT_WIN_POINT1 + 128]; - } - delay.copy_from_slice(&self.tmp[COEFFS..]); + self.imdct_long.imdct_half(coeffs, &mut self.ew_buf); }, 3 => { for (ain, aout) in coeffs.chunks(128).zip(self.tmp.chunks_mut(256)) { @@ -386,76 +392,52 @@ impl AVCDecoder { for i in 0..SHORT_WIN_POINT1 { delay[i] = self.ew_buf[SHORT_WIN_POINT1 + i]; } - for i in SHORT_WIN_POINT1..COEFFS { - delay[i] = 0.0; + for i in COEFFS/2..COEFFS { + delay[i] = delay[COEFFS - 1 - i]; } }, 4 => { - for i in 0..SHORT_WIN_POINT0 { - dst[i] = delay[i]; - } if !self.use_generic { synth1024(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz); } else { synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 1024); } - overlap_half(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &self.ew_buf[0..64], - &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT); - for i in SHORT_WIN_POINT1..COEFFS { - dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 64]; - } - for i in 0..COEFFS/2 { - delay[i] = self.ew_buf[COEFFS/2 + i]; - } - for i in COEFFS/2..COEFFS { - delay[i] = delay[COEFFS - 1 - i]; - } - }, + }, 5 => { - for i in 0..SHORT_WIN_POINT0 { - dst[i] = delay[i]; - } if !self.use_generic { synth512(&mut self.dsp, coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz); } else { synth_generic(coeffs, &mut self.ew_buf, &mut self.tmp, self.is_40khz, 512); } - self.imdct_mid.imdct(&coeffs[512..], &mut self.ew_buf[512..]); - overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &self.ew_buf[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT); - for i in SHORT_WIN_POINT1..COEFFS { - dst[i] = self.ew_buf[i]; - } - *delay = [0.0; COEFFS]; - for i in 0..SHORT_WIN_POINT1 { - delay[i] = self.ew_buf[i]; - } + self.imdct_mid.imdct_half(&coeffs[512..], &mut self.ew_buf[512..]); }, 6 => { - for i in 0..SHORT_WIN_POINT0 { - dst[i] = delay[i]; - } - self.imdct_mid.imdct(coeffs, &mut self.ew_buf); + self.imdct_mid.imdct_half(coeffs, &mut self.ew_buf); if !self.use_generic { synth512(&mut self.dsp, &coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz); } else { synth_generic(&coeffs[512..], &mut self.ew_buf[512..], &mut self.tmp, self.is_40khz, 512); } - overlap(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &self.ew_buf[SHORT_WIN_POINT0..SHORT_WIN_POINT1], - &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT); - for i in SHORT_WIN_POINT1..COEFFS { - dst[i] = self.ew_buf[i]; - } - *delay = [0.0; COEFFS]; - for i in 0..SHORT_WIN_POINT1 { - delay[i] = self.ew_buf[i]; - } }, _ => unreachable!(), }; + if (self.cur_win == 2) || (self.cur_win >= 4) { + for i in 0..SHORT_WIN_POINT0 { + dst[i] = delay[i]; + } + overlap_half(&mut dst[SHORT_WIN_POINT0..SHORT_WIN_POINT1], + &self.ew_buf[0..64], + &delay[SHORT_WIN_POINT0..SHORT_WIN_POINT1], AVC_WIN_SHORT); + for i in SHORT_WIN_POINT1..COEFFS { + dst[i] = self.ew_buf[i - SHORT_WIN_POINT1 + 64]; + } + for i in 0..COEFFS/2 { + delay[i] = self.ew_buf[COEFFS/2 + i]; + } + for i in COEFFS/2..COEFFS { + delay[i] = delay[COEFFS - 1 - i]; + } + } } } @@ -490,12 +472,12 @@ macro_rules! synth_step0_template { fn $name(src: &[f32], dst: &mut [f32], step: usize, off: usize, sp: &SynthParams) { for i in 0..step { for j in 0..sp.p0 { - dst[i] += ((src[j] as f64) * $tab[sp.idx][j][i]) as f32; + dst[i] += (f64::from(src[j]) * $tab[sp.idx][j][i]) as f32; } } for i in 0..step { for j in 0..sp.p1 { - dst[$size - step + i] += ((src[sp.p0 + off + j] as f64) * $tab[sp.idx][sp.p0 + j][i]) as f32; + dst[$size - step + i] += (f64::from(src[sp.p0 + off + j]) * $tab[sp.idx][sp.p0 + j][i]) as f32; } } } @@ -511,7 +493,7 @@ fn synth_step1(src: &[f32], dst: &mut [f32], size: usize, stride: usize, step: u { let mut pos = step - 1; for _ in 0..off { - let scale = src[p0] as f64; + let scale = f64::from(src[p0]); p0 += 1; pos &= size - 1; for i in 0..pos.min(step) { @@ -675,15 +657,15 @@ fn synth_recursive(dst: &mut [f32], tmp: &mut [f32], size: usize, order: &[u8], let idx = if !dir { i } else { bands - 1 - i }; synth_filter(src, tmp, size, step, bands, idx); } - (&mut dst[..size]).copy_from_slice(&tmp[..size]); + dst[..size].copy_from_slice(&tmp[..size]); } fn synth_generic(src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool, size: usize) { let order = if is_40khz { MERGE_ORDER_40K } else { MERGE_ORDER_44K }; - (&mut dst[..size]).copy_from_slice(&src[..size]); + dst[..size].copy_from_slice(&src[..size]); let mut order_idx = 0; synth_recursive(dst, tmpbuf, size, order, &mut order_idx, false); - for i in 0..COEFFS { dst[i] *= 0.125; } + for el in dst.iter_mut().take(COEFFS) { *el *= 0.125; } } fn synth1024(dsp: &mut SynthDSP, src: &[f32], dst: &mut [f32], tmpbuf: &mut [f32; COEFFS * 2], is_40khz: bool) { @@ -926,7 +908,7 @@ fn dequant(val: i16, qtab: &[f32; QTAB_SIZE], scale: f32) -> f32 { if val >= 0 { qtab[val as usize] * scale } else { - -qtab[val.abs() as usize] * scale + -qtab[val.unsigned_abs() as usize] * scale } } @@ -1012,7 +994,7 @@ impl NADecoder for AVCDecoder { if self.version == 500 { abuf = alloc_audio_buffer(self.ainfo, COEFFS, self.chmap.clone())?; let mut adata = abuf.get_abuf_f32().unwrap(); - let mut br = BitReader::new(src.as_slice(), src.len(), BitReaderMode::BE); + let mut br = BitReader::new(src.as_slice(), BitReaderMode::BE); self.decode_frame(&mut br, &mut adata, 0)?; } else { let mut offsets: Vec = Vec::new(); @@ -1034,7 +1016,7 @@ impl NADecoder for AVCDecoder { let mut adata = abuf.get_abuf_f32().unwrap(); let mut aoffset = 0; for (o, s) in offsets.iter().zip(sizes.iter()) { - let mut br = BitReader::new(&src[*o..], *s, BitReaderMode::BE); + let mut br = BitReader::new(&src[*o..][..*s], BitReaderMode::BE); self.decode_frame(&mut br, &mut adata, aoffset)?; aoffset += COEFFS; } @@ -1044,13 +1026,21 @@ impl NADecoder for AVCDecoder { frm.set_keyframe(true); Ok(frm.into_ref()) } + fn flush(&mut self) { + } +} + +impl NAOptionHandler for AVCDecoder { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } } -pub fn get_decoder_500() -> Box { +pub fn get_decoder_500() -> Box { Box::new(AVCDecoder::new(500)) } -pub fn get_decoder_501() -> Box { +pub fn get_decoder_501() -> Box { Box::new(AVCDecoder::new(501)) } @@ -1058,20 +1048,21 @@ pub fn get_decoder_501() -> Box { mod test { use nihav_core::codecs::RegisteredDecoders; use nihav_core::demuxers::RegisteredDemuxers; - use nihav_core::test::dec_video::*; - use crate::codecs::duck_register_all_codecs; - use nihav_commonfmt::demuxers::generic_register_all_demuxers; + use nihav_codec_support::test::dec_video::*; + use crate::duck_register_all_decoders; + use nihav_commonfmt::generic_register_all_demuxers; #[test] fn test_avc() { let mut dmx_reg = RegisteredDemuxers::new(); generic_register_all_demuxers(&mut dmx_reg); let mut dec_reg = RegisteredDecoders::new(); - duck_register_all_codecs(&mut dec_reg); + duck_register_all_decoders(&mut dec_reg); //let file = "assets/Duck/Cell-140.vp5"; //let file = "assets/Duck/Chocolat-500.vp5"; + // sample: https://samples.mplayerhq.hu/V-codecs/VP7/potter-500.vp7 let file = "assets/Duck/potter-500.vp7"; - test_decode_audio("avi", file, Some(1500), "avc", &dmx_reg, &dec_reg); + test_decode_audio("avi", file, Some(1500), None/*Some("avc")*/, &dmx_reg, &dec_reg); } }