-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::*;
}
}
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);
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];
}
}
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;
}
}
}
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;
}
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];
}
}
}
}
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 {
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;
}
}
}
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(())
}
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 {
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 {
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];
}
fn synth_audio(&mut self, dsp: &mut DSP, abuf: &mut NABufferType, srate_idx: usize) {
let mut adata = abuf.get_abuf_f32().unwrap();
- let mut output = adata.get_data_mut();
+ let output = adata.get_data_mut().unwrap();
let off0 = abuf.get_offset(self.channel);
let off1 = abuf.get_offset(self.channel + 1);
self.ics[0].synth_channel(dsp, &mut output[off0..], srate_idx);
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 };
}
struct AACDecoder {
- info: Rc<NACodecInfo>,
+ info: NACodecInfoRef,
chmap: NAChannelMap,
m4ainfo: M4AInfo,
pairs: Vec<ChannelPair>,
}
impl NADecoder for AACDecoder {
- fn init(&mut self, info: Rc<NACodecInfo>) -> 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) {
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(())
Err(DecoderError::InvalidData)
}
}
- fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
+ fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
let info = pkt.get_stream().get_info();
validate!(info.get_properties().is_audio());
let pktbuf = pkt.get_buffer();
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)?;
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<NAValue> { None }
}
-pub fn get_decoder() -> Box<NADecoder> {
+pub fn get_decoder() -> Box<dyn NADecoder + Send> {
Box::new(AACDecoder::new())
}
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);
}
}
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;
}
}