Snap for 5180536 from d3e72584588ad0fafc726bcfdea4aec54b364584 to pi-platform-release
Change-Id: Ida7dfb98393b178426963300990b2227047e2b82
diff --git a/decoder/drc_src/impd_drc_bitbuffer.c b/decoder/drc_src/impd_drc_bitbuffer.c
index de1f86d..3750f11 100644
--- a/decoder/drc_src/impd_drc_bitbuffer.c
+++ b/decoder/drc_src/impd_drc_bitbuffer.c
@@ -34,7 +34,6 @@
UWORD32 ret_val;
UWORD8* ptr_read_next = it_bit_buff->ptr_read_next;
WORD bit_pos = it_bit_buff->bit_pos;
- it_bit_buff->error = 0;
if (it_bit_buff->cnt_bits <= 0) {
it_bit_buff->error = 1;
@@ -68,6 +67,26 @@
return ret_val;
}
+WORD32 impd_skip_bits_buf(ia_bit_buf_struct* it_bit_buff, WORD no_of_bits) {
+ UWORD8* ptr_read_next = it_bit_buff->ptr_read_next;
+ WORD bit_pos = it_bit_buff->bit_pos;
+
+ if (it_bit_buff->cnt_bits < no_of_bits) {
+ it_bit_buff->error = 1;
+ return -1;
+ }
+
+ it_bit_buff->cnt_bits -= no_of_bits;
+
+ bit_pos -= no_of_bits;
+ while (bit_pos < 0) {
+ bit_pos += 8;
+ ptr_read_next++;
+ }
+ it_bit_buff->ptr_read_next = ptr_read_next;
+ it_bit_buff->bit_pos = (WORD16)bit_pos;
+ return no_of_bits;
+}
ia_bit_buf_struct* impd_create_bit_buf(ia_bit_buf_struct* it_bit_buff,
UWORD8* ptr_bit_buf_base,
WORD32 bit_buf_size) {
@@ -79,6 +98,7 @@
it_bit_buff->cnt_bits = 0;
it_bit_buff->size = bit_buf_size << 3;
+ it_bit_buff->error = 0;
return it_bit_buff;
}
diff --git a/decoder/drc_src/impd_drc_bitbuffer.h b/decoder/drc_src/impd_drc_bitbuffer.h
index f42e24a..9e29825 100644
--- a/decoder/drc_src/impd_drc_bitbuffer.h
+++ b/decoder/drc_src/impd_drc_bitbuffer.h
@@ -44,4 +44,5 @@
WORD32 impd_read_bits_buf(ia_bit_buf_struct *it_bit_buff, WORD no_of_bits);
+WORD32 impd_skip_bits_buf(ia_bit_buf_struct *it_bit_buff, WORD no_of_bits);
#endif
diff --git a/decoder/drc_src/impd_drc_common.h b/decoder/drc_src/impd_drc_common.h
index dd0e621..2da2542 100644
--- a/decoder/drc_src/impd_drc_common.h
+++ b/decoder/drc_src/impd_drc_common.h
@@ -69,7 +69,7 @@
#define UNIQUE_SUBBAND_GAIN_COUNT_MAX 16
#define FILTER_BLOCK_COUNT_MAX 16
#define FILTER_ELEMENT_COUNT_MAX 16
-#define UNIQUE_SUBBAND_GAINS_COUNT_MAX 8
+
#define EQ_CHANNEL_GROUP_COUNT_MAX 4
#define EQ_FILTER_BLOCK_COUNT_MAX 4
#define LOUD_EQ_INSTRUCTIONS_COUNT_MAX 8
@@ -86,6 +86,8 @@
#define SELECTION_CANDIDATE_COUNT_MAX 32
+#define MAX_NUM_COMPRESSION_EQ (16)
+
#define PROC_COMPLETE 1
#define UNEXPECTED_ERROR 2
#define PARAM_ERROR 3
@@ -149,6 +151,8 @@
#define PARAM_DRC_TYPE_LIM_ATTACK_DEFAULT 5
#define PARAM_DRC_TYPE_LIM_RELEASE_DEFAULT 50
+#define MAX_LOUDNESS_INFO_COUNT (16)
+
#define UNIDRCCONFEXT_V1 0x2
#define UNIDRCLOUDEXT_EQ 0x1
#define UNIDRCINTERFACEEXT_EQ 0x1
diff --git a/decoder/drc_src/impd_drc_dynamic_payload.c b/decoder/drc_src/impd_drc_dynamic_payload.c
index 68583b2..35a3c37 100644
--- a/decoder/drc_src/impd_drc_dynamic_payload.c
+++ b/decoder/drc_src/impd_drc_dynamic_payload.c
@@ -28,7 +28,6 @@
#include "impd_drc_parser.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
-
WORD32 impd_parse_loud_eq_instructions(
ia_bit_buf_struct* it_bit_buff,
ia_loud_eq_instructions_struct* loud_eq_instructions);
@@ -343,7 +342,7 @@
WORD32 impd_parse_uni_drc_gain_ext(
ia_bit_buf_struct* it_bit_buff,
ia_uni_drc_gain_ext_struct* uni_drc_gain_ext) {
- WORD32 i, k;
+ WORD32 k;
WORD32 bit_size_len, ext_size_bits, bit_size, other_bit;
k = 0;
@@ -351,6 +350,7 @@
impd_read_bits_buf(it_bit_buff, 4);
if (it_bit_buff->error) return it_bit_buff->error;
while (uni_drc_gain_ext->uni_drc_gain_ext_type[k] != UNIDRCGAINEXT_TERM) {
+ if (k >= (EXT_COUNT_MAX - 1)) return UNEXPECTED_ERROR;
bit_size_len = impd_read_bits_buf(it_bit_buff, 3);
if (it_bit_buff->error) return it_bit_buff->error;
ext_size_bits = bit_size_len + 4;
@@ -359,14 +359,9 @@
if (it_bit_buff->error) return it_bit_buff->error;
uni_drc_gain_ext->ext_bit_size[k] = bit_size + 1;
- switch (uni_drc_gain_ext->uni_drc_gain_ext_type[k]) {
- default:
- for (i = 0; i < uni_drc_gain_ext->ext_bit_size[k]; i++) {
- other_bit = impd_read_bits_buf(it_bit_buff, 1);
- if (it_bit_buff->error) return it_bit_buff->error;
- }
- break;
- }
+ other_bit =
+ impd_skip_bits_buf(it_bit_buff, uni_drc_gain_ext->ext_bit_size[k]);
+ if (it_bit_buff->error) return it_bit_buff->error;
k++;
uni_drc_gain_ext->uni_drc_gain_ext_type[k] =
impd_read_bits_buf(it_bit_buff, 4);
@@ -918,7 +913,7 @@
ia_eq_coeff_struct* str_eq_coeff) {
WORD32 err = 0;
WORD32 eq_gain_cnt, mu, nu, temp;
- WORD32 subband_gain_len_tbl[7] = {0, 32, 39, 64, 71, 128, 135};
+ static const WORD32 subband_gain_len_tbl[7] = {0, 32, 39, 64, 71, 128, 135};
str_eq_coeff->eq_delay_max_present = impd_read_bits_buf(it_bit_buff, 1);
if (it_bit_buff->error) return it_bit_buff->error;
@@ -961,15 +956,22 @@
str_eq_coeff->eq_subband_gain_representation = (temp >> 4) & 0x01;
str_eq_coeff->eq_subband_gain_format = temp & 0x0F;
-
- if (str_eq_coeff->eq_subband_gain_format == GAINFORMAT_UNIFORM) {
+ if ((str_eq_coeff->eq_subband_gain_format > 0) &&
+ (str_eq_coeff->eq_subband_gain_format < GAINFORMAT_UNIFORM)) {
+ str_eq_coeff->eq_subband_gain_count =
+ subband_gain_len_tbl[str_eq_coeff->eq_subband_gain_format];
+ } else {
+ /* Gain format 0 or any value between 7 to 15 is considered as default
+ * case */
eq_gain_cnt = impd_read_bits_buf(it_bit_buff, 8);
+
if (it_bit_buff->error) return it_bit_buff->error;
str_eq_coeff->eq_subband_gain_count = eq_gain_cnt + 1;
- } else
- str_eq_coeff->eq_subband_gain_count =
- subband_gain_len_tbl[str_eq_coeff->eq_subband_gain_format];
+ if (str_eq_coeff->eq_subband_gain_count > EQ_SUBBAND_GAIN_COUNT_MAX)
+ return UNEXPECTED_ERROR;
+
+ }
if (str_eq_coeff->eq_subband_gain_representation == 1) {
err = impd_parse_eq_subband_gain_spline(
@@ -1168,6 +1170,9 @@
}
}
+ if (str_eq_instructions->eq_ch_group_count > EQ_CHANNEL_GROUP_COUNT_MAX)
+ return (UNEXPECTED_ERROR);
+
str_eq_instructions->td_filter_cascade_present =
impd_read_bits_buf(it_bit_buff, 1);
if (it_bit_buff->error) return it_bit_buff->error;
@@ -1307,12 +1312,20 @@
temp = impd_read_bits_buf(it_bit_buff, 8);
if (it_bit_buff->error) return it_bit_buff->error;
+ /* Parsed but unused */
loud_eq_instructions->loudness_after_drc = (temp >> 7) & 0x01;
+ /* Parsed but unused */
loud_eq_instructions->loudness_after_eq = (temp >> 6) & 0x01;
+ /* Parsed but unused */
loud_eq_instructions->loud_eq_gain_sequence_count = temp & 0x3F;
+ if (loud_eq_instructions->loud_eq_gain_sequence_count >
+ LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX)
+ return UNEXPECTED_ERROR;
+
+ /* Section under for loop, Parsed but unused */
for (i = 0; i < loud_eq_instructions->loud_eq_gain_sequence_count; i++) {
temp = impd_read_bits_buf(it_bit_buff, 7);
if (it_bit_buff->error) return it_bit_buff->error;
diff --git a/decoder/drc_src/impd_drc_loudness_control.c b/decoder/drc_src/impd_drc_loudness_control.c
index ec8fcf1..687fc6f 100644
--- a/decoder/drc_src/impd_drc_loudness_control.c
+++ b/decoder/drc_src/impd_drc_loudness_control.c
@@ -28,7 +28,6 @@
#include "impd_drc_selection_process.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
-
WORD32 impd_signal_peak_level_info(
ia_drc_config* pstr_drc_config,
ia_drc_loudness_info_set_struct* pstr_loudness_info,
@@ -717,8 +716,11 @@
loudness_normalization_gain_db[k] = 0.0f;
}
}
+ if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR;
eq_set_id[k] = 0;
+
loudness[k] = UNDEFINED_LOUDNESS_VALUE;
+
loudness_normalization_gain_db[k] = 0.0f;
k++;
diff --git a/decoder/drc_src/impd_drc_selection_process.c b/decoder/drc_src/impd_drc_selection_process.c
index b5b1b7f..53f76b0 100644
--- a/decoder/drc_src/impd_drc_selection_process.c
+++ b/decoder/drc_src/impd_drc_selection_process.c
@@ -640,6 +640,7 @@
for (c = 0; c < str_eq_instructions->drc_set_id_count; c++) {
if ((str_eq_instructions->drc_set_id[c] == ID_FOR_ANY_DRC) ||
(str_eq_instructions->drc_set_id[c] == 0)) {
+ if (k >= MAX_NUM_COMPRESSION_EQ) return UNEXPECTED_ERROR;
num_compression_eq_id[k] = str_eq_instructions->eq_set_id;
k++;
}
diff --git a/decoder/drc_src/impd_drc_selection_process_drcset_selection.c b/decoder/drc_src/impd_drc_selection_process_drcset_selection.c
index 7ca8aec..f05eceb 100644
--- a/decoder/drc_src/impd_drc_selection_process_drcset_selection.c
+++ b/decoder/drc_src/impd_drc_selection_process_drcset_selection.c
@@ -775,6 +775,9 @@
loudness_normalization_gain_db, loudness);
if (err) return (err);
+ if (loudness_info_count > MAX_LOUDNESS_INFO_COUNT)
+ return UNEXPECTED_ERROR;
+
err = impd_signal_peak_level_info(
pstr_drc_config, pstr_loudness_info, str_drc_instruction_str,
requested_dwnmix_id[d],
@@ -787,6 +790,7 @@
for (l = 0; l < loudness_info_count; l++) {
WORD32 match_found_flag = 0;
WORD32 p;
+ if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
selection_candidate_info[k].loudness_norm_db_gain_adjusted =
loudness_normalization_gain_db[l];
@@ -873,7 +877,6 @@
!str_drc_instruction_str
->drc_set_target_loudness_present)) {
k++;
- } else {
}
}
}
@@ -913,6 +916,7 @@
signal_peak_level[p] + loudness_normalization_gain_db[l] -
pstr_drc_sel_proc_params_struct->output_peak_level_max);
adjustment = min(adjustment, max(0.0f, loudness_deviation_max));
+ if (k >= SELECTION_CANDIDATE_COUNT_MAX) return UNEXPECTED_ERROR;
selection_candidate_info[k].loudness_norm_db_gain_adjusted =
loudness_normalization_gain_db[l] - adjustment;
@@ -1410,10 +1414,11 @@
}
while (!selection_candidate_count) {
- impd_drc_set_preselection(
+ err = impd_drc_set_preselection(
pstr_drc_sel_proc_params_struct, pstr_drc_config, pstr_loudness_info,
restrict_to_drc_with_album_loudness, pstr_drc_uni_sel_proc,
&selection_candidate_count, selection_candidate_info);
+ if (err) return err;
if (selection_candidate_count == 0) {
if (restrict_to_drc_with_album_loudness == 1) {
diff --git a/decoder/drc_src/impd_drc_static_payload.c b/decoder/drc_src/impd_drc_static_payload.c
index de4ceec..9639046 100644
--- a/decoder/drc_src/impd_drc_static_payload.c
+++ b/decoder/drc_src/impd_drc_static_payload.c
@@ -896,6 +896,7 @@
impd_read_bits_buf(it_bit_buff, 4);
if (it_bit_buff->error) return it_bit_buff->error;
while (str_drc_config_ext->drc_config_ext_type[k] != UNIDRCCONFEXT_TERM) {
+ if (k >= (EXT_COUNT_MAX - 1)) return UNEXPECTED_ERROR;
bit_size_len = impd_read_bits_buf(it_bit_buff, 4);
if (it_bit_buff->error) return it_bit_buff->error;
ext_size_bits = bit_size_len + 4;
@@ -1590,6 +1591,7 @@
bit_size = impd_read_bits_buf(it_bit_buff, ext_size_bits);
if (it_bit_buff->error) return it_bit_buff->error;
+ if (k >= (EXT_COUNT_MAX - 1)) return UNEXPECTED_ERROR;
loudness_info_set->str_loudness_info_set_ext.ext_bit_size[k] = bit_size + 1;
switch (loudness_info_set->str_loudness_info_set_ext
@@ -2382,7 +2384,9 @@
temp = impd_read_bits_buf(it_bit_buff, 6);
if (it_bit_buff->error) return it_bit_buff->error;
+ /* Parsed but unused */
loudness_info->true_peak_level_measurement_system = (temp >> 2) & 0xf;
+ /* Parsed but unused */
loudness_info->true_peak_level_reliability = temp & 3;
}
diff --git a/decoder/drc_src/impd_drc_struct.h b/decoder/drc_src/impd_drc_struct.h
index a608da9..0ee8fd8 100644
--- a/decoder/drc_src/impd_drc_struct.h
+++ b/decoder/drc_src/impd_drc_struct.h
@@ -441,8 +441,8 @@
FLOAT32 sample_peak_level;
WORD32 true_peak_level_present;
FLOAT32 true_peak_level;
- WORD32 true_peak_level_measurement_system;
- WORD32 true_peak_level_reliability;
+ WORD32 true_peak_level_measurement_system; /* Parsed but unused */
+ WORD32 true_peak_level_reliability; /* Parsed but unused */
WORD32 measurement_count;
ia_loudness_measure_struct loudness_measure[MEASUREMENT_COUNT_MAX];
} ia_loudness_info_struct;
@@ -456,17 +456,24 @@
WORD32 drc_set_id[DRC_SET_ID_COUNT_MAX];
WORD32 eq_set_id_count;
WORD32 eq_set_id[EQ_SET_ID_COUNT_MAX];
- WORD32 loudness_after_drc;
- WORD32 loudness_after_eq;
- WORD32 loud_eq_gain_sequence_count;
- WORD32 gain_seq_idx[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- WORD32 drc_characteristic_format_is_cicp[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- WORD32 drc_characteristic[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- WORD32 drc_characteristic_left_index[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- WORD32 drc_characteristic_right_index[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- WORD32 frequency_range_index[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- FLOAT32 loud_eq_scaling[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
- FLOAT32 loud_eq_offset[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX];
+ WORD32 loudness_after_drc; /* Parsed but unused */
+ WORD32 loudness_after_eq; /* Parsed but unused */
+ WORD32 loud_eq_gain_sequence_count; /* Parsed but unused */
+ WORD32 gain_seq_idx[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
+ WORD32 drc_characteristic_format_is_cicp
+ [LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
+ WORD32 drc_characteristic[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but
+ unused */
+ WORD32 drc_characteristic_left_index
+ [LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
+ WORD32 drc_characteristic_right_index
+ [LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
+ WORD32 frequency_range_index[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but
+ unused */
+ FLOAT32
+ loud_eq_scaling[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
+ FLOAT32
+ loud_eq_offset[LOUD_EQ_GAIN_SEQUENCE_COUNT_MAX]; /* Parsed but unused */
} ia_loud_eq_instructions_struct;
typedef struct {
diff --git a/decoder/ixheaacd_arith_dec.c b/decoder/ixheaacd_arith_dec.c
index af9f4c0..77b516d 100644
--- a/decoder/ixheaacd_arith_dec.c
+++ b/decoder/ixheaacd_arith_dec.c
@@ -599,7 +599,7 @@
static const WORD32 ixheaacd_pow_14_3[8] = {0, 3251, 4096, 5161,
6502, 8192, 10321, 13004};
-const WORD32 ixheaacd_pow_table_Q13[1024] = {0,
+const WORD32 ixheaacd_pow_table_Q13[1025] = {0,
131072 >> 4,
330281 >> 4,
567116 >> 4,
@@ -1622,7 +1622,8 @@
84111783,
84221751,
84331755,
- 84441795};
+ 84441795,
+ 84551870};
static WORD32 ixheaacd_esc_nb_offset[8] = {0, 131072, 262144, 393216,
524288, 655360, 786432, 917504};
@@ -1943,15 +1944,15 @@
}
}
- if (q[i] >= 8192) {
- q[i] = 8191;
- }
-
if (q[i] < 0) {
flag = -1;
q[i] = -q[i];
}
+ if (q[i] >= 8192) {
+ q[i] = 8191;
+ }
+
if (q[i] < 1024) {
coef[i] = flag * ixheaacd_pow_table_Q13[q[i]];
} else {
diff --git a/decoder/ixheaacd_avq_dec.c b/decoder/ixheaacd_avq_dec.c
index fae899d..478edd8 100644
--- a/decoder/ixheaacd_avq_dec.c
+++ b/decoder/ixheaacd_avq_dec.c
@@ -97,7 +97,8 @@
VOID ixheaacd_voronoi_search(WORD32 x[], WORD32 y[], WORD32 count, WORD32 *rem1,
WORD32 *rem2) {
WORD32 i, y0[8], y1[8];
- WORD32 e0, e1, x1[8], tmp;
+ WORD32 x1[8], tmp;
+ WORD64 e0, e1;
ixheaacd_nearest_neighbor_2d(x, y0, count, rem1);
for (i = 0; i < 8; i++) {
@@ -122,9 +123,9 @@
e0 = e1 = 0;
for (i = 0; i < 8; i++) {
tmp = rem1[i];
- e0 += tmp * tmp;
+ e0 += (WORD64)tmp * tmp;
tmp = rem2[i];
- e1 += tmp * tmp;
+ e1 += (WORD64)tmp * tmp;
}
if (e0 < e1) {
diff --git a/decoder/ixheaacd_create.c b/decoder/ixheaacd_create.c
index 9091a95..9f72de1 100644
--- a/decoder/ixheaacd_create.c
+++ b/decoder/ixheaacd_create.c
@@ -324,8 +324,11 @@
.str_usac_element_config[ele_id]
.str_usac_mps212_config);
- ixheaacd_mps_create(&aac_dec_handle->mps_dec_handle, bs_frame_length,
- bs_residual_coding, ptr_usac_mps212_config);
+ if (ixheaacd_mps_create(&aac_dec_handle->mps_dec_handle,
+ bs_frame_length, bs_residual_coding,
+ ptr_usac_mps212_config)) {
+ return -1;
+ }
}
break;
}
@@ -425,7 +428,7 @@
err_code =
ixheaacd_decode_init(handle, pstr_frame_data->str_layer.sample_rate_layer,
usac_data, pstr_stream_config);
- if (err_code == -1) return -1;
+ if (err_code != 0) return err_code;
for (i_ch = 0; i_ch < MAX_NUM_CHANNELS; i_ch++) {
if (usac_data->tw_mdct[0] == 1) {
@@ -556,7 +559,7 @@
handle->aac_config.ui_sbr_mode = 0;
}
- if (err == -1) return -1;
+ if (err != 0) return err;
break;
diff --git a/decoder/ixheaacd_env_dec.c b/decoder/ixheaacd_env_dec.c
index ae39456..7f10188 100644
--- a/decoder/ixheaacd_env_dec.c
+++ b/decoder/ixheaacd_env_dec.c
@@ -238,7 +238,7 @@
}
}
-static PLATFORM_INLINE VOID
+static PLATFORM_INLINE WORD32
ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data,
ia_sbr_prev_frame_data_struct *ptr_prev_data,
@@ -270,6 +270,8 @@
p_frame_info->border_vec[0] = start_pos_est;
p_frame_info->noise_border_vec[0] = start_pos_est;
+ if (start_pos_est < 0) return -1;
+
if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
num_env_sf =
((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);
@@ -279,6 +281,8 @@
add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
}
}
+
+ return 0;
}
WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
@@ -568,19 +572,22 @@
(1 + pow(2, temp_r - pan_offset[1])));
}
}
-VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
- ia_sbr_header_data_struct *ptr_header_data_ch_1,
- ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
- ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
- ixheaacd_misc_tables *ptr_common_tables) {
+WORD32 ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
+ ia_sbr_header_data_struct *ptr_header_data_ch_1,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
+ ixheaacd_misc_tables *ptr_common_tables) {
FLAG error_code;
+ WORD32 err = 0;
WORD32 usac_flag = ptr_header_data_ch_0->usac_flag;
- ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
- ptr_prev_data_ch_0, ptr_prev_data_ch_1,
- ptr_common_tables);
+ err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
+ ptr_prev_data_ch_0, ptr_prev_data_ch_1,
+ ptr_common_tables);
+
+ if (err) return err;
ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
ptr_prev_data_ch_0);
@@ -598,9 +605,11 @@
if (ptr_sbr_data_ch_1 != NULL) {
error_code = ptr_header_data_ch_0->err_flag;
- ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
- ptr_prev_data_ch_1, ptr_prev_data_ch_0,
- ptr_common_tables);
+ err = ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
+ ptr_prev_data_ch_1, ptr_prev_data_ch_0,
+ ptr_common_tables);
+
+ if (err) return err;
ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
ptr_prev_data_ch_1);
@@ -618,9 +627,11 @@
if (!usac_flag) {
if (!error_code && ptr_header_data_ch_0->err_flag) {
- ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
- ptr_prev_data_ch_0, ptr_prev_data_ch_1,
- ptr_common_tables);
+ err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
+ ptr_prev_data_ch_0, ptr_prev_data_ch_1,
+ ptr_common_tables);
+
+ if (err) return err;
}
}
@@ -631,13 +642,16 @@
ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
}
}
+
+ return 0;
}
-VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
- ia_sbr_frame_info_data_struct *ptr_sbr_data,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
- ixheaacd_misc_tables *pstr_common_tables) {
+WORD32 ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
+ ixheaacd_misc_tables *pstr_common_tables) {
FLAG error_code;
+ WORD32 err;
WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
WORD32 usac_flag = ptr_header_data->usac_flag;
WORD32 temp_1 =
@@ -664,8 +678,12 @@
if (ptr_header_data->err_flag_prev && !usac_flag) {
WORD16 *ptr1, *ptr2;
WORD32 i;
- ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
- ptr_prev_data_ch_0, pstr_common_tables);
+
+ err = ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
+ ptr_prev_data_ch_0,
+ pstr_common_tables);
+
+ if (err) return err;
if (ptr_sbr_data->coupling_mode !=
(WORD16)ptr_prev_data_ch_0->coupling_mode) {
@@ -708,14 +726,19 @@
memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
sizeof(WORD16) * MAX_FREQ_COEFFS);
- ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0,
- ptr_prev_data_ch_1, pstr_common_tables);
- return;
+ err = ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data,
+ ptr_prev_data_ch_0, ptr_prev_data_ch_1,
+ pstr_common_tables);
+
+ if (err) return err;
+ return 0;
}
}
}
if (!usac_flag)
ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
+
+ return 0;
}
VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,
diff --git a/decoder/ixheaacd_env_dec.h b/decoder/ixheaacd_env_dec.h
index 3f4556a..3c36486 100644
--- a/decoder/ixheaacd_env_dec.h
+++ b/decoder/ixheaacd_env_dec.h
@@ -20,13 +20,13 @@
#ifndef IXHEAACD_ENV_DEC_H
#define IXHEAACD_ENV_DEC_H
-VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
- ia_sbr_header_data_struct *ptr_header_data_ch_1,
- ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
- ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
- ixheaacd_misc_tables *ptr_common_tables);
+WORD32 ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
+ ia_sbr_header_data_struct *ptr_header_data_ch_1,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
+ ixheaacd_misc_tables *ptr_common_tables);
VOID ixheaacd_dec_sbrdata_for_pvc(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data,
@@ -55,11 +55,11 @@
WORD16 *ptr_sine_level_buf, WORD16 noise_e,
WORD freq_inv_flag, WORD32 harm_index);
-VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
- ia_sbr_frame_info_data_struct *ptr_sbr_data,
- ia_sbr_prev_frame_data_struct *ptr_prev_data,
- ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
- ixheaacd_misc_tables *pstr_common_tables);
+WORD32 ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
+ ia_sbr_frame_info_data_struct *ptr_sbr_data,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data,
+ ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
+ ixheaacd_misc_tables *pstr_common_tables);
VOID ixheaacd_lean_sbrconcealment(ia_sbr_header_data_struct *ptr_header_data,
ia_sbr_frame_info_data_struct *ptr_sbr_data,
diff --git a/decoder/ixheaacd_esbr_envcal.c b/decoder/ixheaacd_esbr_envcal.c
index 53aacef..b90df22 100644
--- a/decoder/ixheaacd_esbr_envcal.c
+++ b/decoder/ixheaacd_esbr_envcal.c
@@ -68,11 +68,12 @@
} while (inc > 1);
}
-VOID ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct *frame_data,
- FLOAT32 input_real[][64], FLOAT32 input_imag[][64],
- FLOAT32 input_real1[][64], FLOAT32 input_imag1[][64],
- WORD32 x_over_qmf[MAX_NUM_PATCHES],
- FLOAT32 *scratch_buff, FLOAT32 *env_out) {
+WORD32 ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct *frame_data,
+ FLOAT32 input_real[][64], FLOAT32 input_imag[][64],
+ FLOAT32 input_real1[][64],
+ FLOAT32 input_imag1[][64],
+ WORD32 x_over_qmf[MAX_NUM_PATCHES],
+ FLOAT32 *scratch_buff, FLOAT32 *env_out) {
WORD8 harmonics[64];
FLOAT32(*env_tmp)[48];
FLOAT32(*noise_level_pvc)[48];
@@ -192,6 +193,7 @@
ui = frame_data->pstr_sbr_header->pstr_freq_band_data
->freq_band_tbl_hi[i + 1];
tmp = ((ui + li) - (sub_band_start << 1)) >> 1;
+ if ((tmp >= 64) || (tmp < 0)) return -1;
harmonics[tmp] = add_harmonics[i];
}
@@ -559,6 +561,7 @@
ui = frame_data->pstr_sbr_header->pstr_freq_band_data
->freq_band_tbl_hi[i + 1];
tmp = ((ui + li) - (sub_band_start << 1)) >> 1;
+ if ((tmp >= 64) || (tmp < 0)) return -1;
harmonics[tmp] = add_harmonics[i];
}
@@ -783,6 +786,7 @@
frame_data->phase_index = phase_index;
frame_data->pstr_sbr_header->esbr_start_up = esbr_start_up;
frame_data->pstr_sbr_header->esbr_start_up_pvc = esbr_start_up_pvc;
+ return 0;
}
VOID ixheaacd_createlimiterbands(WORD32 lim_table[4][12 + 1],
diff --git a/decoder/ixheaacd_ext_ch_ele.c b/decoder/ixheaacd_ext_ch_ele.c
index 5f09ba8..8bc17e7 100644
--- a/decoder/ixheaacd_ext_ch_ele.c
+++ b/decoder/ixheaacd_ext_ch_ele.c
@@ -364,18 +364,20 @@
sum = ixheaacd_mult32x32in64(in[0], filter[0]);
sum = ixheaacd_mac32x32in64_n(sum, &in[0], &filter[1], 6);
- *out += (WORD32)((sum * factor_even) >> 15);
+
+ *out = ixheaacd_add32_sat(*out, (WORD32)((sum * factor_even) >> 15));
+
out++;
for (i = 3; i < length - 4; i += 2) {
sum = 0;
sum = ixheaacd_mac32x32in64_7(sum, &in[i - 3], filter);
- *out += (WORD32)((sum * factor_odd) >> 15);
+ *out = ixheaacd_add32_sat(*out, (WORD32)((sum * factor_odd) >> 15));
out++;
sum = 0;
sum = ixheaacd_mac32x32in64_7(sum, &in[i - 2], filter);
- *out += (WORD32)((sum * factor_even) >> 15);
+ *out = ixheaacd_add32_sat(*out, (WORD32)((sum * factor_even) >> 15));
out++;
}
i = length - 3;
@@ -525,7 +527,7 @@
(WORD32)((WORD64)ixheaacd_mult32x32in64(
alpha_q_im_temp, dmx_im[i]) >>
24);
- r_spec[i] = (factor) * (l_spec[i] - mid_side);
+ r_spec[i] = (factor)*ixheaacd_sub32_sat(l_spec[i], mid_side);
l_spec[i] = l_spec[i] + mid_side;
}
diff --git a/decoder/ixheaacd_mps_dec.c b/decoder/ixheaacd_mps_dec.c
index 3075c1b..851f942 100644
--- a/decoder/ixheaacd_mps_dec.c
+++ b/decoder/ixheaacd_mps_dec.c
@@ -79,9 +79,9 @@
extern ia_huff_icc_nodes_struct ixheaacd_huff_icc_nodes;
extern ia_huff_res_nodes_struct ixheaacd_huff_reshape_nodes;
-VOID ixheaacd_mps_create(ia_mps_dec_state_struct* self, WORD32 bs_frame_len,
- WORD32 residual_coding,
- ia_usac_dec_mps_config_struct* mps212_config) {
+WORD32 ixheaacd_mps_create(ia_mps_dec_state_struct* self, WORD32 bs_frame_len,
+ WORD32 residual_coding,
+ ia_usac_dec_mps_config_struct* mps212_config) {
WORD32 num_ch;
WORD32 err_code = 0;
@@ -109,6 +109,8 @@
err_code = ixheaacd_mps_header_decode(self);
+ if (err_code != 0) return err_code;
+
if ((self->residual_coding) && (self->res_bands > 0)) self->res_ch_count++;
ixheaacd_mps_env_init(self);
@@ -147,7 +149,7 @@
memset(self->opd_smooth.smooth_r_phase, 0,
MAX_PARAMETER_BANDS * sizeof(WORD32));
- return;
+ return 0;
}
static FLOAT32 ixheaacd_tsd_mul_re[] = {
@@ -1424,6 +1426,8 @@
}
}
+ if (data_bands <= 0) return -1;
+
if (!ixheaacd_huff_decode(it_bit_buff, data_array[0], data_array[1],
data_type, diff_type[0], diff_type[1],
pilot_coding_flag, pilot_data, data_bands,
diff --git a/decoder/ixheaacd_mps_interface.h b/decoder/ixheaacd_mps_interface.h
index 7587773..a488aef 100644
--- a/decoder/ixheaacd_mps_interface.h
+++ b/decoder/ixheaacd_mps_interface.h
@@ -20,9 +20,9 @@
#ifndef IXHEAACD_MPS_INTERFACE_H
#define IXHEAACD_MPS_INTERFACE_H
-VOID ixheaacd_mps_create(ia_mps_dec_state_struct* self, WORD32 bs_frame_len,
- WORD32 residual_coding,
- ia_usac_dec_mps_config_struct* usac_mps_config);
+WORD32 ixheaacd_mps_create(ia_mps_dec_state_struct* self, WORD32 bs_frame_len,
+ WORD32 residual_coding,
+ ia_usac_dec_mps_config_struct* usac_mps_config);
VOID ixheaacd_mps_frame_parsing(ia_mps_dec_state_struct* self,
WORD32 independency_flag,
diff --git a/decoder/ixheaacd_mps_parse.c b/decoder/ixheaacd_mps_parse.c
index 9326edf..e5ba760 100644
--- a/decoder/ixheaacd_mps_parse.c
+++ b/decoder/ixheaacd_mps_parse.c
@@ -110,6 +110,12 @@
static int ixheaacd_inverse_smoothing_time_table_q30[] = {16777216, 8388608,
4194304, 2097152};
+static WORD32 bound_check(WORD32 var, WORD32 lower_bound, WORD32 upper_bound) {
+ var = min(var, upper_bound);
+ var = max(var, lower_bound);
+ return var;
+}
+
static VOID ixheaacd_longmult1(unsigned short a[], unsigned short b,
unsigned short d[], int len) {
int k;
@@ -803,9 +809,16 @@
}
for (ps = 0; ps < num_parameter_sets; ps++) {
- for (band = band_start; band < band_stop; band++)
+ for (band = band_start; band < band_stop; band++) {
+ if (param_type == CLD) {
+ out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], -15, 15);
+ } else if (param_type == ICC) // param_type is ICC
+ {
+ out_idx_data[ps][band] = bound_check(out_idx_data[ps][band], 0, 7);
+ }
out_data[ps][band] =
ixheaacd_mps_de_quantize(out_idx_data[ps][band], param_type);
+ }
}
if (ext_frame_flag) {
diff --git a/decoder/ixheaacd_pns_js_thumb.c b/decoder/ixheaacd_pns_js_thumb.c
index 15db806..534ec5b 100644
--- a/decoder/ixheaacd_pns_js_thumb.c
+++ b/decoder/ixheaacd_pns_js_thumb.c
@@ -354,11 +354,12 @@
scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_tmp, size);
}
- if (filter->direction != -1) {
- position = start;
- } else {
+ if (filter->direction == -1) {
position = stop - 1;
if (((win << 7) + position) < filter->order) continue;
+ } else {
+ position = start;
+ if ((((win << 7) + position) + filter->order) > MAX_BINS_LONG) continue;
}
if ((num_ch <= 2) &&
diff --git a/decoder/ixheaacd_sbr_dec.c b/decoder/ixheaacd_sbr_dec.c
index 1adc72a..049433d 100644
--- a/decoder/ixheaacd_sbr_dec.c
+++ b/decoder/ixheaacd_sbr_dec.c
@@ -759,21 +759,16 @@
ptr_pvc_data->prev_pvc_rate = ptr_pvc_data->pvc_rate;
ptr_frame_data->pstr_sbr_header = ptr_header_data;
- if (ptr_header_data->hbe_flag == 0)
- ixheaacd_sbr_env_calc(
- ptr_frame_data, ptr_sbr_dec->sbr_qmf_out_real + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->sbr_qmf_out_imag + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->qmf_buf_real + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->qmf_buf_imag + (SBR_HF_ADJ_OFFSET), NULL,
- ptr_sbr_dec->scratch_buff, pvc_dec_out_buf);
- else
- ixheaacd_sbr_env_calc(
- ptr_frame_data, ptr_sbr_dec->sbr_qmf_out_real + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->sbr_qmf_out_imag + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->qmf_buf_real + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->qmf_buf_imag + (SBR_HF_ADJ_OFFSET),
- ptr_sbr_dec->p_hbe_txposer->x_over_qmf, ptr_sbr_dec->scratch_buff,
- pvc_dec_out_buf);
+ err_code = ixheaacd_sbr_env_calc(
+ ptr_frame_data, ptr_sbr_dec->sbr_qmf_out_real + (SBR_HF_ADJ_OFFSET),
+ ptr_sbr_dec->sbr_qmf_out_imag + (SBR_HF_ADJ_OFFSET),
+ ptr_sbr_dec->qmf_buf_real + (SBR_HF_ADJ_OFFSET),
+ ptr_sbr_dec->qmf_buf_imag + (SBR_HF_ADJ_OFFSET),
+ (ptr_header_data->hbe_flag == 0)
+ ? NULL
+ : ptr_sbr_dec->p_hbe_txposer->x_over_qmf,
+ ptr_sbr_dec->scratch_buff, pvc_dec_out_buf);
+ if (err_code) return err_code;
} else {
for (i = 0; i < 64; i++) {
@@ -1213,22 +1208,16 @@
ptr_frame_data->pstr_sbr_header = ptr_header_data;
ptr_frame_data->sbr_mode = ORIG_SBR;
ptr_frame_data->prev_sbr_mode = ORIG_SBR;
- if (ptr_header_data->hbe_flag == 0)
- ixheaacd_sbr_env_calc(ptr_frame_data,
- ptr_sbr_dec->mps_sbr_qmf_buf_real + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_sbr_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_qmf_buf_real + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
- NULL, ptr_sbr_dec->scratch_buff, NULL);
- else
- ixheaacd_sbr_env_calc(ptr_frame_data,
- ptr_sbr_dec->mps_sbr_qmf_buf_real + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_sbr_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_qmf_buf_real + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->mps_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
- ptr_sbr_dec->p_hbe_txposer->x_over_qmf,
- ptr_sbr_dec->scratch_buff, NULL);
+ err = ixheaacd_sbr_env_calc(
+ ptr_frame_data, ptr_sbr_dec->mps_sbr_qmf_buf_real + SBR_HF_ADJ_OFFSET,
+ ptr_sbr_dec->mps_sbr_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
+ ptr_sbr_dec->mps_qmf_buf_real + SBR_HF_ADJ_OFFSET,
+ ptr_sbr_dec->mps_qmf_buf_imag + SBR_HF_ADJ_OFFSET,
+ (ptr_header_data->hbe_flag == 0) ? NULL
+ : ptr_sbr_dec->p_hbe_txposer->x_over_qmf,
+ ptr_sbr_dec->scratch_buff, NULL);
+ if (err) return err;
for (i = 0; i < no_bins; i++) {
FLOAT32 *p_loc_mps_qmf_output =
p_mps_qmf_output + i * (MAX_NUM_QMF_BANDS_ESBR * 2);
diff --git a/decoder/ixheaacd_sbr_dec.h b/decoder/ixheaacd_sbr_dec.h
index 0beec6d..69a4d23 100644
--- a/decoder/ixheaacd_sbr_dec.h
+++ b/decoder/ixheaacd_sbr_dec.h
@@ -183,11 +183,12 @@
FLOAT32 pv_qmf_buf_imag[][64],
WORD32 pitch_in_bins);
-VOID ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct *frame_data,
- FLOAT32 input_real[][64], FLOAT32 input_imag[][64],
- FLOAT32 input_real1[][64], FLOAT32 input_imag1[][64],
- WORD32 x_over_qmf[MAX_NUM_PATCHES],
- FLOAT32 *scratch_buff, FLOAT32 *env_out);
+WORD32 ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct *frame_data,
+ FLOAT32 input_real[][64], FLOAT32 input_imag[][64],
+ FLOAT32 input_real1[][64],
+ FLOAT32 input_imag1[][64],
+ WORD32 x_over_qmf[MAX_NUM_PATCHES],
+ FLOAT32 *scratch_buff, FLOAT32 *env_out);
WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64],
FLOAT32 ptr_src_buf_imag[][64],
diff --git a/decoder/ixheaacd_sbrdecoder.c b/decoder/ixheaacd_sbrdecoder.c
index c40b37f..e357af2 100644
--- a/decoder/ixheaacd_sbrdecoder.c
+++ b/decoder/ixheaacd_sbrdecoder.c
@@ -566,13 +566,15 @@
ixheaacd_dec_sbrdata_for_pvc(ptr_header_data[0], ptr_frame_data[0],
pstr_sbr_channel[0]->pstr_prev_frame_data);
} else if (ptr_frame_data[0]->sbr_mode == ORIG_SBR) {
- ixheaacd_dec_sbrdata(
+ err = ixheaacd_dec_sbrdata(
ptr_header_data[0], ptr_header_data[1], ptr_frame_data[0],
pstr_sbr_channel[0]->pstr_prev_frame_data,
(stereo || dual_mono) ? ptr_frame_data[1] : NULL,
(stereo || dual_mono) ? pstr_sbr_channel[1]->pstr_prev_frame_data
: NULL,
self->pstr_common_tables);
+
+ if (err) return err;
}
if (ptr_header_data[0]->channel_mode == PS_STEREO &&