Coverage Report

Created: 2025-08-24 07:17

/src/libxaac/encoder/ixheaace_mps_param_extract.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
 */
20
21
#include <string.h>
22
#include <math.h>
23
#include "ixheaac_type_def.h"
24
#include "impd_drc_common_enc.h"
25
#include "impd_drc_uni_drc.h"
26
#include "impd_drc_tables.h"
27
#include "impd_drc_api.h"
28
#include "ixheaace_api.h"
29
#include "ixheaac_error_standards.h"
30
#include "ixheaace_error_codes.h"
31
#include "ixheaace_mps_common_fix.h"
32
#include "ixheaace_mps_defines.h"
33
#include "ixheaace_bitbuffer.h"
34
#include "ixheaace_mps_common_define.h"
35
#include "ixheaace_mps_param_extract.h"
36
#include "ixheaace_mps_buf.h"
37
#include "ixheaace_mps_lib.h"
38
#include "ixheaace_mps_bitstream.h"
39
#include "ixheaace_mps_struct_def.h"
40
#include "ixheaace_mps_sac_polyphase.h"
41
#include "ixheaace_mps_sac_nlc_enc.h"
42
#include "ixheaace_mps_sac_hybfilter.h"
43
#include "ixheaace_mps_spatial_bitstream.h"
44
#include "ixheaace_mps_tree.h"
45
#include "ixheaace_mps_rom.h"
46
#include "ixheaace_mps_vector_functions.h"
47
#include "ixheaac_constants.h"
48
#include "ixheaace_aac_constants.h"
49
#include "ixheaac_basic_ops32.h"
50
#include "ixheaac_basic_ops40.h"
51
#include "ixheaac_basic_ops.h"
52
53
static UWORD8 ixheaace_mps_212_get_icc_correlation_coherence_border(
54
1.53k
    const WORD32 aot, const WORD32 use_coherence_only) {
55
1.53k
  ixheaace_mps_box_subband_setup pstr_box_subband_setup;
56
57
1.53k
  if (aot == AOT_AAC_ELD) {
58
297
    pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_ld;
59
297
    pstr_box_subband_setup.icc_correlation_coherence_border = 5;
60
1.24k
  } else {
61
1.24k
    pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_usac;
62
1.24k
    pstr_box_subband_setup.icc_correlation_coherence_border = 8;
63
1.24k
  }
64
65
1.53k
  return ((use_coherence_only) ? 0 : pstr_box_subband_setup.icc_correlation_coherence_border);
66
1.53k
}
67
68
static VOID ixheaace_mps_212_calc_correlation_vec(FLOAT32 *const data,
69
                                                  const FLOAT32 *const data_real,
70
                                                  const FLOAT32 *const power_data_1,
71
                                                  const FLOAT32 *const power_data_2,
72
104k
                                                  const WORD32 icc_correlation_coherence_border) {
73
104k
  WORD32 idx;
74
104k
  FLOAT32 p_12;
75
76
835k
  for (idx = 0; idx < icc_correlation_coherence_border; idx++) {
77
731k
    p_12 = power_data_1[idx] * power_data_2[idx];
78
731k
    if (p_12 > 0.0f) {
79
688k
      p_12 = 1.0f / ((FLOAT32)sqrt(p_12));
80
688k
      data[idx] = data_real[idx] * p_12;
81
688k
    } else {
82
42.6k
      data[idx] = 0.9995f;
83
42.6k
    }
84
731k
  }
85
104k
}
86
87
static VOID ixheaace_mps_212_calc_coherence_vec(FLOAT32 *const data,
88
                                                const FLOAT32 *const data_real,
89
                                                const FLOAT32 *const data_imag,
90
                                                const FLOAT32 *const power_data_1,
91
                                                const FLOAT32 *const power_data_2,
92
104k
                                                const WORD32 icc_correlation_coherence_border) {
93
104k
  WORD32 idx;
94
104k
  FLOAT32 coh, p_12, p_12_ri;
95
96
1.84M
  for (idx = 0; idx < icc_correlation_coherence_border; idx++) {
97
1.74M
    p_12_ri = (FLOAT32)(sqrt(data_real[idx] * data_real[idx] + data_imag[idx] * data_imag[idx]));
98
1.74M
    p_12 = power_data_1[idx] * power_data_2[idx];
99
100
1.74M
    if (p_12 > 0.0f) {
101
1.64M
      p_12 = 1.0f / ((FLOAT32)sqrt(p_12));
102
1.64M
      coh = p_12_ri * p_12;
103
1.64M
      data[idx] = coh;
104
1.64M
    } else {
105
93.5k
      data[idx] = 0.9995f;
106
93.5k
    }
107
1.74M
  }
108
104k
}
109
110
static VOID ixheaace_mps_212_quantize_coef(const FLOAT32 *const input, const WORD32 num_bands,
111
                                           const FLOAT32 *const quant_table,
112
                                           const WORD32 idx_offset, const WORD32 num_quant_steps,
113
208k
                                           WORD8 *const quant_out) {
114
208k
  WORD32 band;
115
208k
  WORD32 forward = (quant_table[1] >= quant_table[0]);
116
117
5.15M
  for (band = 0; band < num_bands; band++) {
118
4.94M
    FLOAT32 q_val;
119
4.94M
    FLOAT32 cur_val = input[band];
120
4.94M
    WORD32 upper = num_quant_steps - 1;
121
4.94M
    WORD32 lower = 0;
122
4.94M
    if (forward) {
123
14.5M
      while (upper - lower > 1) {
124
12.1M
        WORD32 idx = (lower + upper) >> 1;
125
12.1M
        q_val = quant_table[idx];
126
12.1M
        if (cur_val <= q_val) {
127
3.18M
          upper = idx;
128
8.92M
        } else {
129
8.92M
          lower = idx;
130
8.92M
        }
131
12.1M
      }
132
133
2.47M
      if ((cur_val - quant_table[lower]) > (quant_table[upper] - cur_val)) {
134
2.14M
        quant_out[band] = (WORD8)(upper - idx_offset);
135
2.14M
      } else {
136
327k
        quant_out[band] = (WORD8)(lower - idx_offset);
137
327k
      }
138
2.47M
    } else {
139
7.71M
      while (upper - lower > 1) {
140
5.23M
        WORD32 idx = (lower + upper) >> 1;
141
5.23M
        q_val = quant_table[idx];
142
5.23M
        if (cur_val >= q_val) {
143
4.72M
          upper = idx;
144
4.72M
        } else {
145
514k
          lower = idx;
146
514k
        }
147
5.23M
      }
148
149
2.47M
      if ((cur_val - quant_table[lower]) < (quant_table[upper] - cur_val)) {
150
166k
        quant_out[band] = (WORD8)(upper - idx_offset);
151
2.30M
      } else {
152
2.30M
        quant_out[band] = (WORD8)(lower - idx_offset);
153
2.30M
      }
154
2.47M
    }
155
4.94M
    if (quant_out[band] != 0) {
156
551k
      quant_out[band] = quant_out[band];
157
551k
    }
158
4.94M
  }
159
208k
}
160
161
VOID ixheaace_mps_212_calc_parameter_band_to_hybrid_band_offset(
162
1.53k
    const WORD32 num_hybrid_bands, UWORD8 *ptr_parameter_band_2_hybrid_band_offset, WORD32 aot) {
163
1.53k
  ixheaace_mps_box_subband_setup pstr_box_subband_setup;
164
1.53k
  if (aot == AOT_AAC_ELD) {
165
297
    pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_ld;
166
297
    pstr_box_subband_setup.icc_correlation_coherence_border = 5;
167
1.24k
  } else {
168
1.24k
    pstr_box_subband_setup.p_subband_2_parameter_index_ld = (UWORD8 *)subband_2_parameter_usac;
169
1.24k
    pstr_box_subband_setup.icc_correlation_coherence_border = 8;
170
1.24k
  }
171
172
1.53k
  const UWORD8 *p_subband_2_parameter_index;
173
174
1.53k
  UWORD8 idx;
175
1.53k
  WORD32 band;
176
177
1.53k
  p_subband_2_parameter_index = pstr_box_subband_setup.p_subband_2_parameter_index_ld;
178
179
98.4k
  for (band = 0, idx = NUM_QMF_BANDS - 1; idx > NUM_QMF_BANDS - num_hybrid_bands; idx--) {
180
96.8k
    if (p_subband_2_parameter_index[idx - 1] - p_subband_2_parameter_index[idx]) {
181
38.9k
      ptr_parameter_band_2_hybrid_band_offset[band++] = (NUM_QMF_BANDS - idx);
182
38.9k
    }
183
96.8k
  }
184
1.53k
  ptr_parameter_band_2_hybrid_band_offset[band++] = (NUM_QMF_BANDS - idx);
185
1.53k
}
186
187
IA_ERRORCODE
188
ixheaace_mps_212_init_tto_box(ixheaace_mps_pstr_tto_box pstr_tto_box,
189
                              const ixheaace_mps_tto_box_config *const pstr_tto_box_config,
190
1.53k
                              UWORD8 *ptr_parameter_band_2_hybrid_band_offset, WORD32 aot) {
191
1.53k
  IA_ERRORCODE error = IA_NO_ERROR;
192
193
1.53k
  {
194
1.53k
    memset(pstr_tto_box, 0, sizeof(ixheaace_mps_tto_box));
195
1.53k
    pstr_tto_box->use_coarse_quant_cld_flag = pstr_tto_box_config->use_coarse_quant_cld_flag;
196
1.53k
    pstr_tto_box->use_coarse_quant_icc_flag = pstr_tto_box_config->use_coarse_quant_icc_flag;
197
1.53k
    pstr_tto_box->box_quant_mode = pstr_tto_box_config->box_quant_mode;
198
1.53k
    pstr_tto_box->icc_correlation_coherence_border =
199
1.53k
        ixheaace_mps_212_get_icc_correlation_coherence_border(
200
1.53k
            aot, pstr_tto_box_config->b_use_coherence_icc_only);
201
1.53k
    pstr_tto_box->num_hybrid_bands_max = pstr_tto_box_config->num_hybrid_bands_max;
202
1.53k
    if (aot == 39) {
203
297
      pstr_tto_box->num_parameter_bands = IXHEAACE_MPS_SAC_BANDS_ld;
204
1.24k
    } else {
205
1.24k
      pstr_tto_box->num_parameter_bands = IXHEAACE_MPS_SAC_BANDS_usac;
206
1.24k
    }
207
1.53k
    pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset =
208
1.53k
        ptr_parameter_band_2_hybrid_band_offset;
209
1.53k
    pstr_tto_box->frame_keep_flag = pstr_tto_box_config->frame_keep_flag;
210
1.53k
    pstr_tto_box->n_cld_quant_steps = pstr_tto_box->use_coarse_quant_cld_flag
211
1.53k
                                          ? IXHEAACE_MPS_MAX_CLD_QUANT_COARSE
212
1.53k
                                          : IXHEAACE_MPS_MAX_CLD_QUANT_FINE;
213
1.53k
    pstr_tto_box->n_cld_quant_offset = pstr_tto_box->use_coarse_quant_cld_flag
214
1.53k
                                           ? IXHEAACE_MPS_OFFSET_CLD_QUANT_COARSE
215
1.53k
                                           : IXHEAACE_MPS_OFFSET_CLD_QUANT_FINE;
216
1.53k
    pstr_tto_box->n_icc_quant_steps = pstr_tto_box->use_coarse_quant_icc_flag
217
1.53k
                                          ? IXHEAACE_MPS_MAX_ICC_QUANT_COARSE
218
1.53k
                                          : IXHEAACE_MPS_MAX_ICC_QUANT_FINE;
219
1.53k
    pstr_tto_box->n_icc_quant_offset = pstr_tto_box->use_coarse_quant_icc_flag
220
1.53k
                                           ? IXHEAACE_MPS_OFFSET_ICC_QUANT_COARSE
221
1.53k
                                           : IXHEAACE_MPS_OFFSET_ICC_QUANT_FINE;
222
1.53k
    pstr_tto_box->p_icc_quant_table =
223
1.53k
        pstr_tto_box->use_coarse_quant_icc_flag ? icc_quant_table_coarse : icc_quant_table_fine;
224
1.53k
    pstr_tto_box->p_cld_quant_table_enc = pstr_tto_box->use_coarse_quant_cld_flag
225
1.53k
                                              ? cld_quant_table_coarse_enc
226
1.53k
                                              : cld_quant_table_fine_enc;
227
228
1.53k
    if ((pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_FINE) &&
229
1.53k
        (pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_EBQ1) &&
230
1.53k
        (pstr_tto_box->box_quant_mode != IXHEAACE_MPS_QUANTMODE_EBQ2)) {
231
0
      return IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED;
232
0
    }
233
1.53k
  }
234
1.53k
  return error;
235
1.53k
}
236
237
IA_ERRORCODE ixheaace_mps_212_apply_tto_box(
238
    ixheaace_mps_pstr_tto_box pstr_tto_box, const WORD32 num_time_slots,
239
    const WORD32 start_time_slot, const WORD32 num_hybrid_bands,
240
    ixheaace_cmplx_str pp_hybrid_data_1[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],
241
    ixheaace_cmplx_str pp_hybrid_data_2[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS], WORD8 *const ptr_icc,
242
    UWORD8 *const pb_icc_quant_coarse, WORD8 *const ptr_cld, UWORD8 *const pb_cld_quant_coarse,
243
104k
    const WORD32 b_use_bb_cues) {
244
104k
  IA_ERRORCODE error = IA_NO_ERROR;
245
246
104k
  WORD32 j, band;
247
104k
  FLOAT32 power_hybrid_data_1[MAX_NUM_PARAM_BANDS] = {0};
248
104k
  FLOAT32 power_hybrid_data_2[MAX_NUM_PARAM_BANDS] = {0};
249
104k
  FLOAT32 prod_hybrid_data_real[MAX_NUM_PARAM_BANDS] = {0};
250
104k
  FLOAT32 prod_hybrid_data_imag[MAX_NUM_PARAM_BANDS] = {0};
251
104k
  const WORD32 num_param_bands = pstr_tto_box->num_parameter_bands;
252
104k
  const WORD32 use_box_quant_mode =
253
104k
      (pstr_tto_box->box_quant_mode == IXHEAACE_MPS_QUANTMODE_EBQ1) ||
254
104k
      (pstr_tto_box->box_quant_mode == IXHEAACE_MPS_QUANTMODE_EBQ2);
255
256
104k
  if ((num_hybrid_bands < 0) || (num_hybrid_bands > pstr_tto_box->num_hybrid_bands_max)) {
257
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
258
0
  }
259
260
2.57M
  for (j = 0, band = 0; band < num_param_bands; band++) {
261
2.47M
    FLOAT32 data_1, data_2;
262
2.47M
    data_1 = 0;
263
2.47M
    data_2 = 0;
264
8.52M
    for (; j < pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset[band]; j++) {
265
6.04M
      data_1 += ixheaace_mps_212_sum_up_cplx_pow_2_dim_2(pp_hybrid_data_1, start_time_slot,
266
6.04M
                                                         num_time_slots, j, j + 1);
267
6.04M
      data_2 += ixheaace_mps_212_sum_up_cplx_pow_2_dim_2(pp_hybrid_data_2, start_time_slot,
268
6.04M
                                                         num_time_slots, j, j + 1);
269
6.04M
    }
270
271
2.47M
    power_hybrid_data_1[band] = data_1;
272
2.47M
    power_hybrid_data_2[band] = data_2;
273
2.47M
  }
274
2.57M
  for (j = 0, band = 0; band < num_param_bands; band++) {
275
2.47M
    FLOAT32 data_real, data_imag;
276
2.47M
    data_real = data_imag = 0;
277
8.52M
    for (; j < pstr_tto_box->ptr_parameter_band_2_hybrid_band_offset[band]; j++) {
278
6.04M
      ixheaace_cmplx_str scalar_prod;
279
6.04M
      ixheaace_mps_212_cplx_scalar_product(&scalar_prod, pp_hybrid_data_1, pp_hybrid_data_2,
280
6.04M
                                           start_time_slot, num_time_slots, j, j + 1);
281
6.04M
      data_real += scalar_prod.re;
282
6.04M
      data_imag += scalar_prod.im;
283
6.04M
    }
284
2.47M
    prod_hybrid_data_real[band] = data_real;
285
2.47M
    prod_hybrid_data_imag[band] = data_imag;
286
2.47M
  }
287
288
104k
  ixheaace_mps_212_calc_correlation_vec(pstr_tto_box->icc, prod_hybrid_data_real,
289
104k
                                        power_hybrid_data_1, power_hybrid_data_2,
290
104k
                                        pstr_tto_box->icc_correlation_coherence_border);
291
292
104k
  ixheaace_mps_212_calc_coherence_vec(
293
104k
      &pstr_tto_box->icc[pstr_tto_box->icc_correlation_coherence_border],
294
104k
      &prod_hybrid_data_real[pstr_tto_box->icc_correlation_coherence_border],
295
104k
      &prod_hybrid_data_imag[pstr_tto_box->icc_correlation_coherence_border],
296
104k
      &power_hybrid_data_1[pstr_tto_box->icc_correlation_coherence_border],
297
104k
      &power_hybrid_data_2[pstr_tto_box->icc_correlation_coherence_border],
298
104k
      num_param_bands - pstr_tto_box->icc_correlation_coherence_border);
299
104k
  if (error) {
300
0
    return error;
301
0
  }
302
104k
  if (!use_box_quant_mode) {
303
104k
    FLOAT32 power_1, power_2, cld;
304
104k
    FLOAT32 max_pow = 30.0f;
305
306
2.57M
    for (band = 0; band < num_param_bands; band++) {
307
2.47M
      power_1 = (FLOAT32)log(power_hybrid_data_1[band] / 2.0f);
308
2.47M
      power_2 = (FLOAT32)log(power_hybrid_data_2[band] / 2.0f);
309
2.47M
      power_1 = MAX(MIN(power_1, max_pow), -max_pow);
310
2.47M
      power_2 = MAX(MIN(power_2, max_pow), -max_pow);
311
2.47M
      cld = (INV_LN_10_10 * (power_1 - power_2));
312
2.47M
      pstr_tto_box->cld[band] = cld;
313
2.47M
    }
314
104k
  }
315
316
104k
  if (b_use_bb_cues) {
317
0
    FLOAT32 temp;
318
0
    temp = 0;
319
0
    for (band = 0; band < num_param_bands; band++) {
320
0
      temp += pstr_tto_box->cld[band];
321
0
    }
322
0
    temp /= num_param_bands;
323
0
    for (band = 0; band < num_param_bands; band++) {
324
0
      pstr_tto_box->cld[band] = temp;
325
0
    }
326
0
  }
327
328
104k
  ixheaace_mps_212_quantize_coef(
329
104k
      pstr_tto_box->icc, num_param_bands, pstr_tto_box->p_icc_quant_table,
330
104k
      pstr_tto_box->n_icc_quant_offset, pstr_tto_box->n_icc_quant_steps, ptr_icc);
331
332
104k
  *pb_icc_quant_coarse = pstr_tto_box->use_coarse_quant_icc_flag;
333
334
104k
  if (!use_box_quant_mode) {
335
104k
    ixheaace_mps_212_quantize_coef(
336
104k
        pstr_tto_box->cld, num_param_bands, pstr_tto_box->p_cld_quant_table_enc,
337
104k
        pstr_tto_box->n_cld_quant_offset, pstr_tto_box->n_cld_quant_steps, ptr_cld);
338
104k
  } else {
339
0
    memset(ptr_cld, 0, num_param_bands * sizeof(WORD8));
340
0
  }
341
104k
  *pb_cld_quant_coarse = pstr_tto_box->use_coarse_quant_cld_flag;
342
343
104k
  return error;
344
104k
}