X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fcodecs%2Faac.rs;h=09a5b6b1dd582e90600e1b6ae16715ccfbf7f9f3;hp=8232e07f1f7caa689b8da38f40de3e714b4bdbb5;hb=d4547e6a80fe0dcc76b7453c8b85664738a0e466;hpb=1a967e6bad5f17943b4de0607078eb940ad5adfe diff --git a/nihav-commonfmt/src/codecs/aac.rs b/nihav-commonfmt/src/codecs/aac.rs index 8232e07..09a5b6b 100644 --- a/nihav-commonfmt/src/codecs/aac.rs +++ b/nihav-commonfmt/src/codecs/aac.rs @@ -1,12 +1,10 @@ -use std::rc::Rc; -use std::cell::RefCell; use nihav_core::formats::*; use nihav_core::frame::*; use nihav_core::codecs::*; -use nihav_core::dsp::fft::FFTMode; -use nihav_core::dsp::mdct::IMDCT; -use nihav_core::dsp::window::*; +use nihav_codec_support::dsp::mdct::IMDCT; +use nihav_codec_support::dsp::window::*; use nihav_core::io::bitreader::*; +use nihav_core::io::byteio::*; use nihav_core::io::codebook::*; use std::fmt; use nihav_core::io::intcode::*; @@ -150,7 +148,7 @@ impl M4AInfo { } } fn read(&mut self, src: &[u8]) -> DecoderResult<()> { - let mut br = BitReader::new(src, src.len(), BitReaderMode::BE); + let mut br = BitReader::new(src, BitReaderMode::BE); self.otype = Self::read_object_type(&mut br)?; self.srate = Self::read_sampling_frequency(&mut br)?; validate!(self.srate > 0); @@ -327,12 +325,16 @@ impl ICSInfo { self.window_sequence = br.read(2)? as u8; match self.prev_window_sequence { ONLY_LONG_SEQUENCE | LONG_STOP_SEQUENCE => { - validate!((self.window_sequence == ONLY_LONG_SEQUENCE) || - (self.window_sequence == LONG_START_SEQUENCE)); + if (self.window_sequence != ONLY_LONG_SEQUENCE) && + (self.window_sequence != LONG_START_SEQUENCE) { + println!("incorrect previous window"); + } }, LONG_START_SEQUENCE | EIGHT_SHORT_SEQUENCE => { - validate!((self.window_sequence == EIGHT_SHORT_SEQUENCE) || - (self.window_sequence == LONG_STOP_SEQUENCE)); + if (self.window_sequence != EIGHT_SHORT_SEQUENCE) && + (self.window_sequence != LONG_STOP_SEQUENCE) { + println!("incorrect previous window"); + } }, _ => {}, }; @@ -465,14 +467,14 @@ impl TNSCoeffs { let iqfac = (fac_base - 0.5) / (consts::PI / 2.0); let iqfac_m = (fac_base + 0.5) / (consts::PI / 2.0); let mut tmp: [f32; TNS_MAX_ORDER] = [0.0; TNS_MAX_ORDER]; - for i in 0..self.order { + for el in tmp.iter_mut().take(self.order) { let val = br.read(coef_bits)? as i8; - let c = if (val & sign_mask) != 0 { val | neg_mask } else { val } as f32; - tmp[i] = (if c >= 0.0 { c / iqfac } else { c / iqfac_m }).sin(); + let c = f32::from(if (val & sign_mask) != 0 { val | neg_mask } else { val }); + *el = (if c >= 0.0 { c / iqfac } else { c / iqfac_m }).sin(); } // convert to LPC coefficients let mut b: [f32; TNS_MAX_ORDER + 1] = [0.0; TNS_MAX_ORDER + 1]; - for m in 1..(self.order + 1) { + for m in 1..=self.order { for i in 1..m { b[i] = self.coef[i - 1] + tmp[m - 1] * self.coef[m - i - 1]; } @@ -641,32 +643,30 @@ impl ICS { } fn decode_scale_factor_data(&mut self, br: &mut BitReader, codebooks: &Codebooks) -> DecoderResult<()> { let mut noise_pcm_flag = true; - let mut scf_normal = self.global_gain as i16; + let mut scf_normal = i16::from(self.global_gain); let mut scf_intensity = 0i16; let mut scf_noise = 0i16; for g in 0..self.info.window_groups { for sfb in 0..self.info.max_sfb { if self.sfb_cb[g][sfb] != ZERO_HCB { if self.is_intensity(g, sfb) { - let diff = br.read_cb(&codebooks.scale_cb)? as i16; + let diff = i16::from(br.read_cb(&codebooks.scale_cb)?); scf_intensity += diff; validate!((scf_intensity >= INTENSITY_SCALE_MIN) && (scf_intensity < INTENSITY_SCALE_MIN + 256)); self.scales[g][sfb] = (scf_intensity - INTENSITY_SCALE_MIN) as u8; - } else { - if self.sfb_cb[g][sfb] == NOISE_HCB { - if noise_pcm_flag { - noise_pcm_flag = false; - scf_noise = (br.read(9)? as i16) - 256 + (self.global_gain as i16) - 90; - } else { - scf_noise += br.read_cb(&codebooks.scale_cb)? as i16; - } - validate!((scf_noise >= NOISE_SCALE_MIN) && (scf_noise < NOISE_SCALE_MIN + 256)); - self.scales[g][sfb] = (scf_noise - NOISE_SCALE_MIN) as u8; + } else if self.sfb_cb[g][sfb] == NOISE_HCB { + if noise_pcm_flag { + noise_pcm_flag = false; + scf_noise = (br.read(9)? as i16) - 256 + i16::from(self.global_gain) - 90; } else { - scf_normal += br.read_cb(&codebooks.scale_cb)? as i16; - validate!((scf_normal >= 0) && (scf_normal < 255)); - self.scales[g][sfb] = scf_normal as u8; + scf_noise += i16::from(br.read_cb(&codebooks.scale_cb)?); } + validate!((scf_noise >= NOISE_SCALE_MIN) && (scf_noise < NOISE_SCALE_MIN + 256)); + self.scales[g][sfb] = (scf_noise - NOISE_SCALE_MIN) as u8; + } else { + scf_normal += i16::from(br.read_cb(&codebooks.scale_cb)?); + validate!((scf_normal >= 0) && (scf_normal < 255)); + self.scales[g][sfb] = scf_normal as u8; } } } @@ -734,9 +734,9 @@ impl ICS { base = requant(self.coeffs[k], scale); } if base > 0.0 { - base += pdata.pulse_amp[pno] as f32; + base += f32::from(pdata.pulse_amp[pno]); } else { - base -= pdata.pulse_amp[pno] as f32; + base -= f32::from(pdata.pulse_amp[pno]); } self.coeffs[k] = iquant(base) * scale; } @@ -787,17 +787,23 @@ impl ICS { let start = w * 128 + self.get_band_start(tns_max_bands.min(bottom)); let end = w * 128 + self.get_band_start(tns_max_bands.min(top)); let lpc = &tns_data.coeffs[w][f].coef; + let mut state = [0.0f32; 64]; + let mut sidx = 32; if !tns_data.coeffs[w][f].direction { for m in start..end { - for i in 0..order.min(m) { - self.coeffs[m] -= self.coeffs[m - i - 1] * lpc[i]; + for i in 0..order { + self.coeffs[m] -= state[(sidx + i) & 63] * lpc[i]; } + sidx = (sidx + 63) & 63; + state[sidx] = self.coeffs[m]; } } else { for m in (start..end).rev() { - for i in 0..order.min(m) { - self.coeffs[m] -= self.coeffs[m + i - 1] * lpc[i]; + for i in 0..order { + self.coeffs[m] -= state[(sidx + i) & 63] * lpc[i]; } + sidx = (sidx + 63) & 63; + state[sidx] = self.coeffs[m]; } } } @@ -808,7 +814,7 @@ impl ICS { } fn get_scale(scale: u8) -> f32 { - 2.0f32.powf(0.25 * ((scale as f32) - 100.0 - 56.0)) + 2.0f32.powf(0.25 * (f32::from(scale) - 100.0 - 56.0)) } fn iquant(val: f32) -> f32 { if val < 0.0 { @@ -834,15 +840,15 @@ fn decode_quads(br: &mut BitReader, cb: &Codebook, unsigned: bool, scale: f let val = AAC_QUADS[cw][i]; if val != 0 { if br.read_bool()? { - out[i] = iquant(-val as f32) * scale; + out[i] = iquant(-f32::from(val)) * scale; } else { - out[i] = iquant( val as f32) * scale; + out[i] = iquant( f32::from(val)) * scale; } } } } else { for i in 0..4 { - out[i] = iquant((AAC_QUADS[cw][i] - 1) as f32) * scale; + out[i] = iquant(f32::from(AAC_QUADS[cw][i] - 1)) * scale; } } } @@ -872,8 +878,8 @@ fn decode_pairs(br: &mut BitReader, cb: &Codebook, unsigned: bool, escape: y += read_escape(br, y > 0)?; } } - out[0] = iquant(x as f32) * scale; - out[1] = iquant(y as f32) * scale; + out[0] = iquant(f32::from(x)) * scale; + out[1] = iquant(f32::from(y)) * scale; } Ok(()) } @@ -881,6 +887,7 @@ fn read_escape(br: &mut BitReader, sign: bool) -> DecoderResult { let prefix = br.read_code(UintCodeType::UnaryOnes)? as u8; validate!(prefix < 9); let bits = br.read(prefix + 4)? as i16; + let bits = bits | (1 << (prefix + 4)); if sign { Ok(bits) } else { @@ -929,11 +936,11 @@ impl ChannelPair { self.ics[1].info = self.ics[0].info; } self.ics[0].decode_ics(br, codebooks, m4atype, common_window, true)?; - self.ics[1].decode_ics(br, codebooks, m4atype, common_window, false)?; + self.ics[1].decode_ics(br, codebooks, m4atype, common_window, true)?; if common_window && self.ms_mask_present != 0 { let mut g = 0; for w in 0..self.ics[0].info.num_windows { - if w > 0 && self.ics[0].info.scale_factor_grouping[w - 1] { + if w > 0 && !self.ics[0].info.scale_factor_grouping[w - 1] { g += 1; } for sfb in 0..self.ics[0].info.max_sfb { @@ -942,7 +949,7 @@ impl ChannelPair { if self.ics[0].is_intensity(g, sfb) { let invert = (self.ms_mask_present == 1) && self.ms_used[g][sfb]; let dir = self.ics[0].get_intensity_dir(g, sfb) ^ invert; - let scale = 0.5f32.powf(0.25 * ((self.ics[0].scales[g][sfb] as f32) + (INTENSITY_SCALE_MIN as f32))); + let scale = 0.5f32.powf(0.25 * (f32::from(self.ics[0].scales[g][sfb]) + f32::from(INTENSITY_SCALE_MIN))); if !dir { for i in start..end { self.ics[1].coeffs[i] = scale * self.ics[0].coeffs[i]; @@ -1003,11 +1010,12 @@ impl DSP { Self { kbd_long_win, kbd_short_win, sine_long_win, sine_short_win, - imdct_long: IMDCT::new(FFTMode::SplitRadix, 1024 * 2, true), - imdct_short: IMDCT::new(FFTMode::SplitRadix, 128 * 2, true), + imdct_long: IMDCT::new(1024 * 2, true), + imdct_short: IMDCT::new(128 * 2, true), tmp: [0.0; 2048], ew_buf: [0.0; 1152], } } + #[allow(clippy::cyclomatic_complexity)] fn synth(&mut self, coeffs: &[f32; 1024], delay: &mut [f32; 1024], seq: u8, window_shape: bool, prev_window_shape: bool, dst: &mut [f32]) { let long_win = if window_shape { &self.kbd_long_win } else { &self.sine_long_win }; let short_win = if window_shape { &self.kbd_short_win } else { &self.sine_short_win }; @@ -1107,7 +1115,7 @@ impl DSP { } struct AACDecoder { - info: Rc, + info: NACodecInfoRef, chmap: NAChannelMap, m4ainfo: M4AInfo, pairs: Vec, @@ -1205,13 +1213,66 @@ impl AACDecoder { } impl NADecoder for AACDecoder { - fn init(&mut self, info: Rc) -> DecoderResult<()> { + fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { if let NACodecTypeInfo::Audio(_) = info.get_properties() { let edata = info.get_extradata().unwrap(); validate!(edata.len() >= 2); //print!("edata:"); for s in edata.iter() { print!(" {:02X}", *s);}println!(""); - self.m4ainfo.read(&edata)?; + if (edata.len() > 12) && (&edata[4..8] == b"esds") { + let mut mr = MemoryReader::new_read(edata.as_slice()); + let mut br = ByteReader::new(&mut mr); + let esds_size = br.read_u32be()? as usize; + validate!(esds_size <= edata.len()); + br.read_skip(8)?; + let mut info_start = 0; + let mut info_size = 0; + while br.tell() < (esds_size as u64) { + let tag = br.read_byte()?; + let mut size = 0; + loop { + let b = br.read_byte()?; + size = (size << 7) | u64::from(b & 0x7F); + validate!(br.tell() + size <= (esds_size as u64)); + if (b & 0x80) == 0 { + break; + } + } + match tag { + 3 => { + br.read_u16be()?; + let flags = br.read_byte()?; + if (flags & 0x80) != 0 { + br.read_u16be()?; + } + if (flags & 0x40) != 0 { + let len = br.read_byte()?; + br.read_skip(len as usize)?; + } + if (flags & 0x20) != 0 { + br.read_u16be()?; + } + }, + 4 => { + let _otype = br.read_byte()?; + let _stype = br.read_byte()?; + let _flags = br.read_u24be()?; + let _max_br = br.read_u32be()?; + let _min_br = br.read_u32be()?; + }, + 5 => { + info_start = br.tell() as usize; + info_size = size as usize; + break; + }, + _ => br.read_skip(size as usize)?, + } + } + validate!(info_start > 0 && info_size > 0); + self.m4ainfo.read(&edata[info_start..][..info_size])?; + } else { + self.m4ainfo.read(&edata)?; + } //println!("{}", self.m4ainfo); if (self.m4ainfo.otype != M4AType::LC) || (self.m4ainfo.channels > 2) || (self.m4ainfo.samples != 1024) { @@ -1227,7 +1288,7 @@ impl NADecoder for AACDecoder { return Err(DecoderError::NotImplemented); } let chmap_str = DEFAULT_CHANNEL_MAP[self.m4ainfo.channels]; - if chmap_str.len() == 0 { return Err(DecoderError::NotImplemented); } + if chmap_str.is_empty() { return Err(DecoderError::NotImplemented); } self.chmap = NAChannelMap::from_str(chmap_str).unwrap(); Ok(()) @@ -1235,7 +1296,7 @@ impl NADecoder for AACDecoder { Err(DecoderError::InvalidData) } } - fn decode(&mut self, pkt: &NAPacket) -> DecoderResult { + fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult { let info = pkt.get_stream().get_info(); validate!(info.get_properties().is_audio()); let pktbuf = pkt.get_buffer(); @@ -1243,7 +1304,7 @@ impl NADecoder for AACDecoder { let ainfo = self.info.get_properties().get_audio_info().unwrap(); let mut abuf = alloc_audio_buffer(ainfo, self.m4ainfo.samples, self.chmap.clone())?; - let mut br = BitReader::new(&pktbuf, pktbuf.len(), BitReaderMode::BE); + let mut br = BitReader::new(&pktbuf, BitReaderMode::BE); match self.m4ainfo.otype { M4AType::LC => { self.decode_ga(&mut br, &mut abuf)?; @@ -1253,11 +1314,23 @@ impl NADecoder for AACDecoder { let mut frm = NAFrame::new_from_pkt(pkt, self.info.replace_info(NACodecTypeInfo::Audio(ainfo)), abuf); frm.set_keyframe(true); - Ok(Rc::new(RefCell::new(frm))) + Ok(frm.into_ref()) } + fn flush(&mut self) { + for pair in self.pairs.iter_mut() { + pair.ics[0].delay = [0.0; 1024]; + pair.ics[1].delay = [0.0; 1024]; + } + } +} + +impl NAOptionHandler for AACDecoder { + 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() -> Box { +pub fn get_decoder() -> Box { Box::new(AACDecoder::new()) } @@ -1265,19 +1338,19 @@ pub fn get_decoder() -> Box { mod test { use nihav_core::codecs::RegisteredDecoders; use nihav_core::demuxers::RegisteredDemuxers; - use nihav_core::test::dec_video::test_decode_audio; - use crate::codecs::generic_register_all_codecs; - use nihav_realmedia::demuxers::realmedia_register_all_demuxers; + use nihav_codec_support::test::dec_video::test_decode_audio; + use crate::generic_register_all_decoders; + use nihav_realmedia::realmedia_register_all_demuxers; #[test] fn test_aac() { let mut dmx_reg = RegisteredDemuxers::new(); realmedia_register_all_demuxers(&mut dmx_reg); let mut dec_reg = RegisteredDecoders::new(); - generic_register_all_codecs(&mut dec_reg); + generic_register_all_decoders(&mut dec_reg); // let file = "assets/RV/rv40_weighted_mc.rmvb"; let file = "assets/RV/rv40_weighted_mc_2.rmvb"; - test_decode_audio("realmedia", file, Some(12000), "aac", &dmx_reg, &dec_reg); + test_decode_audio("realmedia", file, Some(12000), None/*Some("aac")*/, &dmx_reg, &dec_reg); } } @@ -1746,16 +1819,16 @@ struct GASubbandInfo { impl GASubbandInfo { fn find(srate: u32) -> GASubbandInfo { - for i in 0..AAC_SUBBAND_INFO.len() { - if srate >= AAC_SUBBAND_INFO[i].min_srate { - return AAC_SUBBAND_INFO[i]; + for sbi in AAC_SUBBAND_INFO.iter() { + if srate >= sbi.min_srate { + return *sbi; } } unreachable!("") } fn find_idx(srate: u32) -> usize { - for i in 0..AAC_SUBBAND_INFO.len() { - if srate >= AAC_SUBBAND_INFO[i].min_srate { + for (i, sbi) in AAC_SUBBAND_INFO.iter().enumerate() { + if srate >= sbi.min_srate { return i; } }