aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2023-03-13 12:00:09 +0100
committerKostya Shishkov <kostya.shishkov@gmail.com>2023-03-13 12:00:09 +0100
commite36af1571ce5619b333843ef9e10ad36843c9178 (patch)
tree29edca7e48249449372fee286112c78ad4ceac9b
parentf5c7ce011fd64da390862e4a12c0b74d94018adf (diff)
downloadnihav-e36af1571ce5619b333843ef9e10ad36843c9178.tar.gz
aacsbr: fix off-by-one situation with envelope borders
-rw-r--r--nihav-mpeg/src/codecs/aac/sbr/bs.rs51
-rw-r--r--nihav-mpeg/src/codecs/aac/sbr/synth.rs37
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]);