X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-mpeg%2Fsrc%2Fcodecs%2Faac%2Fmod.rs;h=655b45ba5d9823597362d84a304742cbc85fd9a5;hp=7233f52ebbb361b2305c23b14ee2d72267e526fd;hb=HEAD;hpb=999c25f70cce9929567ece9cb285a900f56727f7 diff --git a/nihav-mpeg/src/codecs/aac/mod.rs b/nihav-mpeg/src/codecs/aac/mod.rs index 7233f52..e37e812 100644 --- a/nihav-mpeg/src/codecs/aac/mod.rs +++ b/nihav-mpeg/src/codecs/aac/mod.rs @@ -11,6 +11,9 @@ mod coeff_read; use coeff_read::*; mod info; use info::*; +mod sbr; +use sbr::{SBRHeader, SBRCodebooks, SBRState, SBRChannel, SBRDSP, sbr_read_sce, sbr_read_cpe}; +#[allow(clippy::excessive_precision)] mod tables; use tables::*; mod tools; @@ -61,7 +64,7 @@ impl ICSInfo { let ics_reserved_bit = br.read(1)?; validate!(ics_reserved_bit == 0); self.window_sequence = br.read(2)? as u8; - match self.prev_window_sequence { + /*match self.prev_window_sequence { ONLY_LONG_SEQUENCE | LONG_STOP_SEQUENCE => { if (self.window_sequence != ONLY_LONG_SEQUENCE) && (self.window_sequence != LONG_START_SEQUENCE) { @@ -75,7 +78,7 @@ impl ICSInfo { } }, _ => {}, - }; + };*/ self.window_shape = br.read_bool()?; self.window_groups = 1; if self.window_sequence == EIGHT_SHORT_SEQUENCE { @@ -180,6 +183,9 @@ impl ICS { fn get_intensity_dir(&self, g: usize, sfb: usize) -> bool { self.sfb_cb[g][sfb] == INTENSITY_HCB } + fn is_noise(&self, g: usize, sfb: usize) -> bool { + self.sfb_cb[g][sfb] == NOISE_HCB + } fn decode_scale_factor_data(&mut self, br: &mut BitReader, codebooks: &Codebooks) -> DecoderResult<()> { decode_scale_factor_data(br, &mut self.scales, self.global_gain, &self.info, &self.sfb_cb, codebooks) } @@ -201,6 +207,13 @@ impl ICS { self.coeffs = [0.0; 1024]; decode_spectrum(br, &mut self.coeffs, &self.scales, &self.info, &self.sbinfo, &self.sfb_cb, codebooks) } + fn iquant(val: f32) -> f32 { + if val < 0.0 { + -((-val).powf(4.0 / 3.0)) + } else { + val.powf(4.0 / 3.0) + } + } fn place_pulses(&mut self) { if let Some(ref pdata) = self.pulse_data { if pdata.pulse_start_sfb >= self.sbinfo.long_bands.len() - 1 { return; } @@ -220,7 +233,7 @@ impl ICS { } else { base -= f32::from(pdata.pulse_amp[pno]); } - self.coeffs[k] = iquant(base) * scale; + self.coeffs[k] = Self::iquant(base) * scale; } } } @@ -280,6 +293,10 @@ struct ChannelPair { ms_mask_present: u8, ms_used: [[bool; MAX_SFBS]; MAX_WINDOWS], ics: [ICS; 2], + sbr_hdr: SBRHeader, + sbr_state: SBRState, + sbr_ch: [SBRChannel; 2], + do_sbr: bool, } impl ChannelPair { @@ -290,6 +307,10 @@ impl ChannelPair { ms_mask_present: 0, ms_used: [[false; MAX_SFBS]; MAX_WINDOWS], ics: [ICS::new(sbinfo), ICS::new(sbinfo)], + sbr_hdr: SBRHeader::new(), + sbr_state: SBRState::new(), + sbr_ch: [SBRChannel::new(), SBRChannel::new()], + do_sbr: false, } } fn decode_ga_sce(&mut self, br: &mut BitReader, codebooks: &Codebooks, m4atype: M4AType) -> DecoderResult<()> { @@ -309,12 +330,14 @@ impl ChannelPair { self.ms_used[g][sfb] = br.read_bool()?; } } + } else { + self.ms_used = [[false; MAX_SFBS]; MAX_WINDOWS]; } 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, true)?; - if common_window && self.ms_mask_present != 0 { + if common_window { 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] { @@ -323,11 +346,11 @@ impl ChannelPair { for sfb in 0..self.ics[0].info.max_sfb { let start = w * 128 + self.ics[0].get_band_start(sfb); let end = w * 128 + self.ics[0].get_band_start(sfb + 1); - if self.ics[0].is_intensity(g, sfb) { + if self.ics[1].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 * (f32::from(self.ics[0].scales[g][sfb]) + f32::from(INTENSITY_SCALE_MIN))); - if !dir { + let dir = self.ics[1].get_intensity_dir(g, sfb) ^ invert; + let scale = 0.5f32.powf(0.25 * (f32::from(self.ics[1].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]; } @@ -336,7 +359,7 @@ impl ChannelPair { self.ics[1].coeffs[i] = -scale * self.ics[0].coeffs[i]; } } - } else if (self.ms_mask_present == 2) || self.ms_used[g][sfb] { + } else if ((self.ms_mask_present == 2) || self.ms_used[g][sfb]) && !self.ics[0].is_noise(g, sfb) { for i in start..end { let tmp = self.ics[0].coeffs[i] - self.ics[1].coeffs[i]; self.ics[0].coeffs[i] += self.ics[1].coeffs[i]; @@ -348,14 +371,59 @@ impl ChannelPair { } Ok(()) } - fn synth_audio(&mut self, dsp: &mut DSP, abuf: &mut NABufferType, srate_idx: usize) { + fn decode_sbr(&mut self, buf: &[u8], has_crc: bool, cbs: &SBRCodebooks, srate: u32) -> DecoderResult<()> { + let mut br = BitReader::new(buf, BitReaderMode::BE); + if has_crc { + let _bs_sbr_crc_bits = br.read(10)?; + } + if br.read_bool()? { + if let Ok(hdr) = SBRHeader::read(&mut br) { + if self.sbr_hdr.differs_from(&hdr) { + self.do_sbr = self.sbr_state.init(&hdr, srate).is_ok(); + self.sbr_ch[0].reset(); + self.sbr_ch[1].reset(); + } + self.sbr_hdr = hdr; + } else { + self.do_sbr = false; + } + } + if self.do_sbr { + if !self.pair { + sbr_read_sce(&mut br, self.sbr_hdr.amp_res, &self.sbr_state, cbs, &mut self.sbr_ch[0])?; + } else { + sbr_read_cpe(&mut br, self.sbr_hdr.amp_res, &self.sbr_state, cbs, &mut self.sbr_ch)?; + } + } + + Ok(()) + } + fn synth_audio(&mut self, dsp: &mut DSP, abuf: &mut NABufferType, srate_idx: usize, upsample: bool) { let mut adata = abuf.get_abuf_f32().unwrap(); 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); - if self.pair { - self.ics[1].synth_channel(dsp, &mut output[off1..], srate_idx); + if !upsample { + self.ics[0].synth_channel(dsp, &mut output[off0..], srate_idx); + if self.pair { + self.ics[1].synth_channel(dsp, &mut output[off1..], srate_idx); + } + } else { + let mut tmp = [0.0; 1024]; + let nchannels = if self.pair { 2 } else { 1 }; + for ch in 0..nchannels { + let off = if ch == 0 { off0 } else { off1 }; + self.ics[ch].synth_channel(dsp, &mut tmp, srate_idx); + self.sbr_ch[ch].analysis(&mut dsp.sbr_dsp, &tmp); + if self.do_sbr { + self.sbr_ch[ch].hf_generate(&self.sbr_state); + self.sbr_ch[ch].hf_adjust(&self.sbr_state, &self.sbr_hdr); + } else { + self.sbr_ch[ch].bypass(); + } + self.sbr_ch[ch].synthesis(&mut dsp.sbr_dsp, &mut output[off..][..2048]); + self.sbr_ch[ch].update_frame(); + } } } } @@ -369,6 +437,7 @@ struct DSP { imdct_short: IMDCT, tmp: [f32; 2048], ew_buf: [f32; 1152], + sbr_dsp: SBRDSP, } const SHORT_WIN_POINT0: usize = 512 - 64; @@ -390,6 +459,7 @@ impl DSP { imdct_long: IMDCT::new(1024 * 2, true), imdct_short: IMDCT::new(128 * 2, true), tmp: [0.0; 2048], ew_buf: [0.0; 1152], + sbr_dsp: SBRDSP::new(), } } #[allow(clippy::cognitive_complexity)] @@ -499,6 +569,8 @@ struct AACDecoder { codebooks: Codebooks, dsp: DSP, sbinfo: GASubbandInfo, + sbr_cbs: SBRCodebooks, + upsample: bool, } impl AACDecoder { @@ -511,6 +583,8 @@ impl AACDecoder { codebooks: Codebooks::new(), dsp: DSP::new(), sbinfo: AAC_SUBBAND_INFO[0], + sbr_cbs: SBRCodebooks::new(), + upsample: false, } } fn set_pair(&mut self, pair_no: usize, channel: usize, pair: bool) -> DecoderResult<()> { @@ -556,13 +630,13 @@ impl AACDecoder { 4 => { // ID_DSE let _id = br.read(4)?; let align = br.read_bool()?; - let mut count = br.read(8)? as u32; - if count == 255 { count += br.read(8)? as u32; } + let mut count = br.read(8)?; + if count == 255 { count += br.read(8)?; } if align { br.align(); } br.skip(count * 8)?; // no SBR payload or such }, 5 => { // ID_PCE - unimplemented!("program config"); + skimp_through_program_config_element(br)?; }, 6 => { // ID_FIL let mut count = br.read(4)? as usize; @@ -570,9 +644,28 @@ impl AACDecoder { count += br.read(8)? as usize; count -= 1; } - for _ in 0..count { - // ext payload + if count > 0 { + let extension_type = br.read(4)?; + match extension_type { + 0xD | 0xE => { // SBR data without or with CRC + let has_crc = extension_type == 0xE; + + let mut buf = [0; 256 + 16]; + for el in buf[..count - 1].iter_mut() { + *el = br.read(8)? as u8; + } + buf[count - 1] = br.read(4)? as u8; + if cur_pair > 0 { + self.pairs[cur_pair - 1].decode_sbr(&buf[..count], has_crc, &self.sbr_cbs, self.m4ainfo.srate * 2)?; + } + }, + _ => { + for _ in 0..count-1 { br.skip(8)?; + } + br.skip(4)?; + }, + }; } }, 7 => { // ID_TERM @@ -583,7 +676,7 @@ impl AACDecoder { } let srate_idx = GASubbandInfo::find_idx(self.m4ainfo.srate); for pair in 0..cur_pair { - self.pairs[pair].synth_audio(&mut self.dsp, abuf, srate_idx); + self.pairs[pair].synth_audio(&mut self.dsp, abuf, srate_idx, self.upsample); } Ok(()) } @@ -595,7 +688,6 @@ impl NADecoder for AACDecoder { let edata = info.get_extradata().unwrap(); validate!(edata.len() >= 2); -//print!("edata:"); for s in edata.iter() { print!(" {:02X}", *s);}println!(""); 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); @@ -657,8 +749,15 @@ impl NADecoder for AACDecoder { } self.sbinfo = GASubbandInfo::find(self.m4ainfo.srate); - let ainfo = NAAudioInfo::new(self.m4ainfo.srate, self.m4ainfo.channels as u8, - SND_F32P_FORMAT, self.m4ainfo.samples); + self.upsample = self.m4ainfo.srate < 32000; + let (srate, samples) = if !self.upsample { + (self.m4ainfo.srate, self.m4ainfo.samples) + } else { + (self.m4ainfo.srate * 2, self.m4ainfo.samples * 2) + }; + + let ainfo = NAAudioInfo::new(srate, self.m4ainfo.channels as u8, + SND_F32P_FORMAT, samples); self.info = info.replace_info(NACodecTypeInfo::Audio(ainfo)); if self.m4ainfo.channels >= DEFAULT_CHANNEL_MAP.len() { @@ -679,7 +778,8 @@ impl NADecoder for AACDecoder { 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 samples = if !self.upsample { self.m4ainfo.samples } else { self.m4ainfo.samples * 2 }; + let mut abuf = alloc_audio_buffer(ainfo, samples, self.chmap.clone())?; let mut br = BitReader::new(&pktbuf, BitReaderMode::BE); match self.m4ainfo.otype { @@ -729,6 +829,16 @@ mod test { let file = "assets/RV/rv40_weighted_mc_2.rmvb"; test_decode_audio("realmedia", file, Some(12000), None/*Some("aac")*/, &dmx_reg, &dec_reg); } + #[test] + fn test_aac_sbr() { + let mut dmx_reg = RegisteredDemuxers::new(); + nihav_commonfmt::generic_register_all_demuxers(&mut dmx_reg); + let mut dec_reg = RegisteredDecoders::new(); + mpeg_register_all_decoders(&mut dec_reg); + + let file = "assets/MPEG/SBRtestStereoAot29Sig0.mp4"; + test_decode_audio("mov", file, Some(400), None/*Some("aacsbr")*/, &dmx_reg, &dec_reg); + } } const DEFAULT_CHANNEL_MAP: [&str; 9] = [