diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2023-03-13 12:00:09 +0100 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2023-03-13 12:00:09 +0100 |
commit | e36af1571ce5619b333843ef9e10ad36843c9178 (patch) | |
tree | 29edca7e48249449372fee286112c78ad4ceac9b | |
parent | f5c7ce011fd64da390862e4a12c0b74d94018adf (diff) | |
download | nihav-e36af1571ce5619b333843ef9e10ad36843c9178.tar.gz |
aacsbr: fix off-by-one situation with envelope borders
-rw-r--r-- | nihav-mpeg/src/codecs/aac/sbr/bs.rs | 51 | ||||
-rw-r--r-- | nihav-mpeg/src/codecs/aac/sbr/synth.rs | 37 |
2 files changed, 46 insertions, 42 deletions
diff --git a/nihav-mpeg/src/codecs/aac/sbr/bs.rs b/nihav-mpeg/src/codecs/aac/sbr/bs.rs index 02c1108..74e820d 100644 --- a/nihav-mpeg/src/codecs/aac/sbr/bs.rs +++ b/nihav-mpeg/src/codecs/aac/sbr/bs.rs @@ -107,14 +107,14 @@ fn read_grid(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { for el in chan.freq_res[..chan.num_env].iter_mut() { *el = freq_res; } + chan.env_border[0] = 0; if chan.num_env > 1 { let delta = (MAX_SLOTS + chan.num_env / 2) / chan.num_env; - chan.env_border[0] = delta; - for i in 0..chan.num_env - 1 { - chan.env_border[i + 1] = chan.env_border[i] + delta; + for i in 1..chan.num_env { + chan.env_border[i] = chan.env_border[i - 1] + delta; } } - chan.env_border[chan.num_env - 1] = MAX_SLOTS; + chan.env_border[chan.num_env] = MAX_SLOTS; }, FrameClass::FixVar => { let var_bord_1 = br.read(2)? as u8; @@ -129,9 +129,10 @@ fn read_grid(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { *el = br.read_bool()?; } - chan.env_border[chan.num_env - 1] = MAX_SLOTS + usize::from(var_bord_1); + chan.env_border[0] = 0; + chan.env_border[chan.num_env] = MAX_SLOTS + usize::from(var_bord_1); for (i, &delta) in (1..chan.num_env).rev().zip(rel_bord_1.iter()) { - chan.env_border[i - 1] = chan.env_border[i] - usize::from(delta); + chan.env_border[i] = chan.env_border[i + 1] - usize::from(delta); } }, FrameClass::VarFix => { @@ -147,11 +148,11 @@ fn read_grid(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { *el = br.read_bool()?; } - chan.env_border[0] = usize::from(var_bord_0 + rel_bord_0[0]); - for i in 1..chan.num_env { - chan.env_border[i] = chan.env_border[i - 1] + usize::from(rel_bord_0[i]); + chan.env_border[0] = usize::from(var_bord_0); + for i in 0..chan.num_env - 1 { + chan.env_border[i + 1] = chan.env_border[i] + usize::from(rel_bord_0[i]); } - chan.env_border[chan.num_env - 1] = MAX_SLOTS; + chan.env_border[chan.num_env] = MAX_SLOTS; }, FrameClass::VarVar => { let var_bord_0 = br.read(2)? as u8; @@ -173,35 +174,37 @@ fn read_grid(br: &mut BitReader, chan: &mut SBRChannel) -> DecoderResult<()> { *el = br.read_bool()?; } - chan.env_border[0] = usize::from(var_bord_0 + rel_bord_0[0]); - for i in 1..=num_rel_0 { - chan.env_border[i] = chan.env_border[i - 1] + usize::from(rel_bord_0[i]); + chan.env_border[0] = usize::from(var_bord_0); + for i in 0..num_rel_0 { + chan.env_border[i + 1] = chan.env_border[i] + usize::from(rel_bord_0[i]); } - chan.env_border[chan.num_env - 1] = MAX_SLOTS + usize::from(var_bord_1); + chan.env_border[chan.num_env] = MAX_SLOTS + usize::from(var_bord_1); for i in 0..num_rel_1 { - chan.env_border[chan.num_env - 2 - i] = chan.env_border[chan.num_env - 1 - i] - usize::from(rel_bord_1[i]); + chan.env_border[chan.num_env - 1 - i] = chan.env_border[chan.num_env - i] - usize::from(rel_bord_1[i]); } }, }; - for i in 0..chan.num_env - 1 { + for i in 0..chan.num_env { validate!(chan.env_border[i] < chan.env_border[i + 1]); } if chan.num_env > 1 { chan.num_noise = 2; let mid = match (chan.fclass, chan.pointer) { - (FrameClass::FixFix, _) => chan.num_env / 2 - 1, - (FrameClass::VarFix, 0) => 0, - (FrameClass::VarFix, 1) => chan.num_env - 2, - (FrameClass::VarFix, _) => chan.pointer as usize - 2, - (_, 0) | (_, 1) => chan.num_env - 2, - (_, _) => chan.num_env - (chan.pointer as usize), + (FrameClass::FixFix, _) => chan.num_env / 2, + (FrameClass::VarFix, 0) => 1, + (FrameClass::VarFix, 1) => chan.num_env - 1, + (FrameClass::VarFix, _) => chan.pointer as usize - 1, + (_, 0) | (_, 1) => chan.num_env - 1, + (_, _) => chan.num_env + 1 - (chan.pointer as usize), }; - chan.noise_env_border[0] = chan.env_border[mid]; - chan.noise_env_border[1] = chan.env_border[chan.num_env - 1]; + chan.noise_env_border[0] = chan.env_border[0]; + chan.noise_env_border[1] = chan.env_border[mid]; + chan.noise_env_border[2] = chan.env_border[chan.num_env]; } else { chan.num_noise = 1; chan.noise_env_border[0] = chan.env_border[0]; + chan.noise_env_border[1] = chan.env_border[1]; } diff --git a/nihav-mpeg/src/codecs/aac/sbr/synth.rs b/nihav-mpeg/src/codecs/aac/sbr/synth.rs index e06a8c1..75c808e 100644 --- a/nihav-mpeg/src/codecs/aac/sbr/synth.rs +++ b/nihav-mpeg/src/codecs/aac/sbr/synth.rs @@ -41,7 +41,7 @@ pub struct SBRChannel { pub num_env: usize, prev_num_env: usize, pub freq_res: [bool; NUM_ENVELOPES], - pub env_border: [usize; NUM_ENVELOPES], + pub env_border: [usize; NUM_ENVELOPES + 1], pub noise_env_border: [usize; 3], pub pointer: u8, pub num_noise: usize, @@ -93,7 +93,7 @@ impl SBRChannel { num_env: 0, prev_num_env: 0, freq_res: [false; NUM_ENVELOPES], - env_border: [0; NUM_ENVELOPES], + env_border: [0; NUM_ENVELOPES + 1], noise_env_border: [0; 3], pointer: 0, num_noise: 0, @@ -214,7 +214,7 @@ impl SBRChannel { }; } - for (l, x_high) in self.x_high.iter_mut().enumerate().skip(HF_ADJ).take(self.env_border[self.num_env - 1] * 2) { + for (l, x_high) in self.x_high.iter_mut().enumerate().skip(HF_ADJ).take(self.env_border[self.num_env] * 2).skip(self.env_border[0]) { *x_high = [FFTC_ZERO; SBR_BANDS]; let mut dst_k = state.k_x; for (&patch_start, &patch_len) in state.patch_start_subband[..state.num_patches].iter().zip(state.patch_num_subbands.iter()) { @@ -247,7 +247,8 @@ impl SBRChannel { let kx = state.k_x; let km = state.f[state.num_master]; - let envelope_end = self.env_border[self.num_env - 1]; + let envelope_start = self.env_border[0]; + let envelope_end = self.env_border[self.num_env]; let high_start = state.f[..=state.num_master].binary_search(&state.k_x).unwrap(); let f_high = &state.f[..=state.num_master][high_start..]; @@ -342,11 +343,11 @@ impl SBRChannel { } }; let mut q_mapped = [[0.0; SBR_BANDS]; NUM_ENVELOPES]; - let mut start = 0; - let noise_env = [0, self.noise_env_border[0], self.noise_env_border[1]]; + let mut start = self.env_border[0]; + let noise_env = self.noise_env_border; match self.qmode { QuantMode::Single => { - for (env_no, &env_end) in self.env_border[..self.num_env].iter().enumerate() { + for (env_no, &env_end) in self.env_border[1..=self.num_env].iter().enumerate() { let env_end = env_end; let mut noise_env_no = 0; for nenv in 0..self.num_noise { @@ -367,7 +368,7 @@ impl SBRChannel { } }, QuantMode::Left => { - for (env_no, &env_end) in self.env_border[..self.num_env].iter().enumerate() { + for (env_no, &env_end) in self.env_border[1..=self.num_env].iter().enumerate() { let env_end = env_end; let mut noise_env_no = 0; for nenv in 0..self.num_noise { @@ -388,7 +389,7 @@ impl SBRChannel { } }, QuantMode::Right => { - for (env_no, &env_end) in self.env_border[..self.num_env].iter().enumerate() { + for (env_no, &env_end) in self.env_border[1..=self.num_env].iter().enumerate() { let env_end = env_end; let mut noise_env_no = 0; for nenv in 0..self.num_noise { @@ -410,9 +411,9 @@ impl SBRChannel { }, }; - let mut start = 0; + let mut start = self.env_border[0]; let mut e_curr = [[0.0f32; SBR_BANDS]; NUM_ENVELOPES]; - for (e_curr, &env_end) in e_curr.iter_mut().zip(self.env_border[..self.num_env].iter()) { + for (e_curr, &env_end) in e_curr.iter_mut().zip(self.env_border[1..=self.num_env].iter()) { for slot in self.x_high[HF_ADJ..][(start * 2)..(env_end * 2)].iter() { for (dst, x) in e_curr[kx..km].iter_mut().zip(slot[kx..km].iter()) { *dst += x.sq_modulus(); @@ -504,8 +505,8 @@ impl SBRChannel { } let mut env_map = [0; MAX_SLOTS * 2 + QMF_DELAY]; - let mut start = 0; - for (env, &env_end) in self.env_border[..self.num_env].iter().enumerate() { + let mut start = self.env_border[0]; + for (env, &env_end) in self.env_border[1..=self.num_env].iter().enumerate() { for l in (start * 2)..(env_end * 2) { env_map[l] = env; } @@ -517,8 +518,8 @@ impl SBRChannel { if self.last_env_end > 0 { ghead.copy_from_slice(&gcur[self.last_env_end - SMOOTH_DELAY..][..SMOOTH_DELAY]); qhead.copy_from_slice(&qcur[self.last_env_end - SMOOTH_DELAY..][..SMOOTH_DELAY]); - let mut start = 0; - for (&env_end, (g_lim, q_lim)) in self.env_border[..self.num_env].iter().zip(g_lim_boost.iter().zip(q_m_lim_boost.iter())) { + let mut start = self.env_border[0]; + for (&env_end, (g_lim, q_lim)) in self.env_border[1..=self.num_env].iter().zip(g_lim_boost.iter().zip(q_m_lim_boost.iter())) { for slot in (start * 2)..(env_end * 2) { gcur[slot] = *g_lim; qcur[slot] = *q_lim; @@ -533,7 +534,7 @@ impl SBRChannel { *dst = q_m_lim_boost[0]; } let mut start = 0; - for (&env_end, (g_lim, q_lim)) in self.env_border[..self.num_env].iter().zip(g_lim_boost.iter().zip(q_m_lim_boost.iter())) { + for (&env_end, (g_lim, q_lim)) in self.env_border[1..=self.num_env].iter().zip(g_lim_boost.iter().zip(q_m_lim_boost.iter())) { for slot in (start * 2)..(env_end * 2) { gcur[slot] = *g_lim; qcur[slot] = *q_lim; @@ -545,7 +546,7 @@ impl SBRChannel { let mut g_filt = [[0.0; SBR_BANDS]; MAX_SLOTS * 2 + QMF_DELAY]; let mut q_filt = [[0.0; SBR_BANDS]; MAX_SLOTS * 2 + QMF_DELAY]; if !hdr.smoothing_mode { - for slot in 0..(envelope_end * 2) { + for slot in (envelope_start * 2)..(envelope_end * 2) { if (slot as i8) == (la_prev * 2) { g_filt[slot].copy_from_slice(&self.g_temp[slot + SMOOTH_DELAY]); q_filt[slot].copy_from_slice(&self.q_temp[slot + SMOOTH_DELAY]); @@ -568,7 +569,7 @@ impl SBRChannel { } let index_noise = self.index_noise.wrapping_sub(self.env_border[0] * 2) & 511; - for (slot, y) in self.y.iter_mut().skip(HF_ADJ).take(envelope_end * 2).enumerate() { + for (slot, y) in self.y.iter_mut().skip(HF_ADJ).take(envelope_end * 2).skip(envelope_start * 2).enumerate() { for (k, y) in y.iter_mut().enumerate().skip(kx).take(km - kx) { *y = self.x_high[HF_ADJ + slot][k].scale(g_filt[slot][k]); |