Coverage Report

Created: 2026-02-26 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_mps_process.c
Line
Count
Source
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
#include <string.h>
21
#include "ixheaac_type_def.h"
22
#include "ixheaacd_memory_standards.h"
23
#include "ixheaacd_mps_struct_def.h"
24
#include "ixheaacd_mps_res_rom.h"
25
#include "ixheaacd_mps_aac_struct.h"
26
#include "ixheaac_constants.h"
27
#include "ixheaac_basic_ops32.h"
28
#include "ixheaac_basic_ops40.h"
29
#include "ixheaacd_bitbuffer.h"
30
#include "ixheaacd_common_rom.h"
31
#include "ixheaacd_sbrdecsettings.h"
32
#include "ixheaacd_sbr_scale.h"
33
#include "ixheaacd_env_extr_part.h"
34
#include "ixheaacd_sbr_rom.h"
35
#include "ixheaacd_hybrid.h"
36
#include "ixheaacd_ps_dec.h"
37
#include "ixheaacd_mps_polyphase.h"
38
#include "ixheaacd_config.h"
39
#include "ixheaacd_qmf_dec.h"
40
#include "ixheaacd_mps_dec.h"
41
#include "ixheaacd_mps_decor.h"
42
#include "ixheaacd_mps_hybfilter.h"
43
#include "ixheaacd_mps_mdct_2_qmf.h"
44
#include "ixheaacd_mps_get_index.h"
45
#include "ixheaacd_mps_macro_def.h"
46
#include "ixheaacd_mps_basic_op.h"
47
#include "ixheaac_error_standards.h"
48
49
9.65k
VOID ixheaacd_mdct_2_qmf(ia_heaac_mps_state_struct *pstr_mps_state) {
50
9.65k
  ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
51
9.65k
  WORD32 ch, rfpsf, qb;
52
9.65k
  WORD32 qmf_global_offset;
53
9.65k
  WORD32 time_slots = pstr_mps_state->time_slots;
54
9.65k
  WORD32 time_slots_x4 = (time_slots << 2);
55
9.65k
  WORD32 qmf_bands = pstr_mps_state->qmf_bands;
56
9.65k
  WORD32 *p_qmf_residual_real_post, *p_qmf_residual_imag_post;
57
9.65k
  VOID *scratch = pstr_mps_state->mps_scratch_mem_v;
58
59
9.65k
  if (pstr_mps_state->up_mix_type != 2) {
60
9.65k
    WORD32 num_ch = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
61
9.65k
    WORD32 rfpsf_max = pstr_mps_state->residual_frames_per_spatial_frame;
62
9.65k
    WORD32 upd_qmf = pstr_mps_state->upd_qmf;
63
64
9.65k
    WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre;
65
9.65k
    WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post;
66
67
9.65k
    WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre;
68
9.65k
    WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post;
69
70
9.65k
    WORD32 *p_res_mdct = p_array_struct->res_mdct;
71
72
35.8k
    for (ch = 0; ch < num_ch; ch++) {
73
26.1k
      if (pstr_mps_state->bs_config.bs_residual_present[ch]) {
74
361
        WORD32 *res_mdct = p_res_mdct;
75
361
        qmf_global_offset = 0;
76
77
361
        p_qmf_residual_real_post = qmf_residual_real_post;
78
361
        p_qmf_residual_imag_post = qmf_residual_imag_post;
79
11.9k
        for (qb = 0; qb < qmf_bands; qb++) {
80
11.5k
          memset(p_qmf_residual_real_post, 0, time_slots_x4);
81
11.5k
          memset(p_qmf_residual_imag_post, 0, time_slots_x4);
82
83
11.5k
          p_qmf_residual_real_post += MAX_TIME_SLOTS;
84
11.5k
          p_qmf_residual_imag_post += MAX_TIME_SLOTS;
85
11.5k
        }
86
87
738
        for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
88
377
          ixheaacd_mdct2qmf_process(upd_qmf, res_mdct, qmf_residual_real_pre,
89
377
                                    qmf_residual_real_post, qmf_residual_imag_pre,
90
377
                                    qmf_residual_imag_post,
91
377
                                    pstr_mps_state->res_block_type[ch][rfpsf], qmf_global_offset,
92
377
                                    &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
93
377
          qmf_global_offset += upd_qmf;
94
377
          res_mdct += MDCTCOEFX2;
95
377
        }
96
361
      }
97
98
26.1k
      qmf_residual_real_pre += QBXTS;
99
26.1k
      qmf_residual_imag_pre += QBXTS;
100
101
26.1k
      qmf_residual_real_post += QBXTS;
102
26.1k
      qmf_residual_imag_post += QBXTS;
103
104
26.1k
      p_res_mdct += RFX2XMDCTCOEF;
105
26.1k
    }
106
9.65k
  }
107
108
9.65k
  if (pstr_mps_state->arbitrary_downmix == 2) {
109
113
    WORD32 arbdmx_upd_qmf = pstr_mps_state->arbdmx_upd_qmf;
110
113
    WORD32 offset = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
111
113
    WORD32 in_ch = pstr_mps_state->num_input_channels;
112
113
    WORD32 rfpsf_max = pstr_mps_state->arbdmx_frames_per_spatial_frame;
113
114
113
    WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
115
113
    WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
116
117
113
    WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post + offset * QBXTS;
118
113
    WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post + offset * QBXTS;
119
120
113
    WORD32 *p_res_mdct = p_array_struct->res_mdct + offset * RFX2XMDCTCOEF;
121
122
257
    for (ch = 0; ch < in_ch; ch++) {
123
144
      WORD32 *res_mdct = p_res_mdct;
124
144
      qmf_global_offset = 0;
125
126
144
      p_qmf_residual_real_post = qmf_residual_real_post;
127
144
      p_qmf_residual_imag_post = qmf_residual_imag_post;
128
4.81k
      for (qb = 0; qb < qmf_bands; qb++) {
129
4.67k
        memset(p_qmf_residual_real_post, 0, time_slots_x4);
130
4.67k
        memset(p_qmf_residual_imag_post, 0, time_slots_x4);
131
132
4.67k
        p_qmf_residual_real_post += MAX_TIME_SLOTS;
133
4.67k
        p_qmf_residual_imag_post += MAX_TIME_SLOTS;
134
4.67k
      }
135
136
307
      for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
137
163
        ixheaacd_mdct2qmf_process(
138
163
            arbdmx_upd_qmf, res_mdct, qmf_residual_real_pre, qmf_residual_real_post,
139
163
            qmf_residual_imag_pre, qmf_residual_imag_post,
140
163
            pstr_mps_state->res_block_type[offset + ch][rfpsf], qmf_global_offset,
141
163
            &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
142
163
        qmf_global_offset += arbdmx_upd_qmf;
143
163
        res_mdct += MDCTCOEFX2;
144
163
      }
145
146
144
      qmf_residual_real_pre += QBXTS;
147
144
      qmf_residual_imag_pre += QBXTS;
148
149
144
      qmf_residual_imag_post += QBXTS;
150
144
      qmf_residual_real_post += QBXTS;
151
152
144
      p_res_mdct += RFX2XMDCTCOEF;
153
144
    }
154
113
  }
155
9.65k
  return;
156
9.65k
}
157
158
9.65k
VOID ixheaacd_hybrid_qmf_analysis(ia_heaac_mps_state_struct *pstr_mps_state) {
159
9.65k
  WORD32 ch;
160
9.65k
  WORD32 in_ch = pstr_mps_state->num_input_channels;
161
9.65k
  WORD32 num_ott_boxes = pstr_mps_state->num_ott_boxes;
162
9.65k
  WORD32 num_ttt_boxes = pstr_mps_state->num_ttt_boxes;
163
9.65k
  WORD32 num_input_channels = in_ch;
164
9.65k
  WORD32 qmf_bands = pstr_mps_state->qmf_bands;
165
9.65k
  WORD32 time_slots = pstr_mps_state->time_slots;
166
9.65k
  WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
167
9.65k
  WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
168
9.65k
  SIZE_T *kernels = pstr_mps_state->kernels;
169
9.65k
  WORD32 *res_bands = pstr_mps_state->res_bands;
170
9.65k
  WORD32 *index = pstr_mps_state->index;
171
172
9.65k
  ia_mps_dec_thyb_filter_state_struct *hyb_filter_state =
173
9.65k
      pstr_mps_state->mps_persistent_mem.hyb_filter_state;
174
9.65k
  ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
175
176
9.65k
  ia_mps_dec_hybrid_tables_struct *hybrid_table_ptr =
177
9.65k
      pstr_mps_state->ia_mps_dec_mps_table.hybrid_table_ptr;
178
179
9.65k
  WORD32 *p_buf_real = p_array_struct->buf_real;
180
9.65k
  WORD32 *p_buf_imag = p_array_struct->buf_imag;
181
182
9.65k
  WORD32 *p_x_real = p_array_struct->x_real;
183
9.65k
  WORD32 *p_x_imag = p_array_struct->x_imag;
184
185
58.1k
  for (ch = 0; ch < in_ch; ch++) {
186
48.5k
    ixheaacd_apply_ana_hyb_filt_bank_create_x(&hyb_filter_state[ch], p_buf_real, p_buf_imag,
187
48.5k
                                              qmf_bands, time_slots, p_x_real, p_x_imag,
188
48.5k
                                              hybrid_table_ptr);
189
48.5k
    pstr_mps_state->index[ch] = hybrid_bands;
190
191
48.5k
    p_buf_real += TSXHB;
192
48.5k
    p_buf_imag += TSXHB;
193
194
48.5k
    p_x_real += TSXHB;
195
48.5k
    p_x_imag += TSXHB;
196
48.5k
  }
197
198
9.65k
  if ((pstr_mps_state->residual_coding) && (pstr_mps_state->up_mix_type != 2)) {
199
261
    WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre;
200
261
    WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre;
201
202
261
    WORD32 *p_dry_real = p_array_struct->w_dry_real;
203
261
    WORD32 *p_dry_imag = p_array_struct->w_dry_imag;
204
205
1.18k
    for (ch = 0; ch < num_ott_boxes; ch++) {
206
928
      if (res_bands[ch] > 0) {
207
292
        ixheaacd_apply_ana_hyb_filt_bank_merge_res_decor(
208
292
            &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
209
292
            qmf_bands, time_slots, p_dry_real, p_dry_imag, hybrid_table_ptr);
210
292
      }
211
928
      qmf_residual_real += QBXTS;
212
928
      qmf_residual_imag += QBXTS;
213
214
928
      p_dry_real += TSXHB;
215
928
      p_dry_imag += TSXHB;
216
928
    }
217
218
456
    for (ch = num_ott_boxes; ch < num_ott_boxes + num_ttt_boxes; ch++, in_ch++) {
219
195
      if (res_bands[ch] > 0) {
220
17
        ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
221
17
            &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
222
17
            qmf_bands, time_slots, p_x_real, p_x_imag, kernels, res_bands[ch], hybrid_bands,
223
17
            num_parameter_bands, &index[in_ch], hybrid_table_ptr);
224
17
      } else
225
178
        index[in_ch] = 0;
226
227
195
      qmf_residual_real += QBXTS;
228
195
      qmf_residual_imag += QBXTS;
229
230
195
      p_x_real += TSXHB;
231
195
      p_x_imag += TSXHB;
232
195
    }
233
261
  }
234
235
9.65k
  in_ch = num_input_channels + num_ttt_boxes;
236
9.65k
  if (pstr_mps_state->arbitrary_downmix == 2) {
237
113
    WORD32 offset = num_ott_boxes + num_ttt_boxes;
238
239
113
    WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
240
113
    WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
241
242
113
    p_x_real = p_array_struct->x_real + in_ch * TSXHB;
243
113
    p_x_imag = p_array_struct->x_imag + in_ch * TSXHB;
244
257
    for (ch = 0; ch < num_input_channels; ch++, in_ch++) {
245
144
      ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
246
144
          &hyb_filter_state[offset + ch + num_input_channels], qmf_residual_real,
247
144
          qmf_residual_imag, qmf_bands, time_slots, p_x_real, p_x_imag, kernels,
248
144
          pstr_mps_state->arbdmx_residual_bands, hybrid_bands, num_parameter_bands, &index[in_ch],
249
144
          hybrid_table_ptr);
250
251
144
      qmf_residual_real += QBXTS;
252
144
      qmf_residual_imag += QBXTS;
253
254
144
      p_x_real += TSXHB;
255
144
      p_x_imag += TSXHB;
256
144
    }
257
113
  }
258
9.65k
}
259
260
ATTR_NO_SANITIZE_INTEGER
261
9.65k
VOID ixheaacd_merge_res_decor(ia_heaac_mps_state_struct *pstr_mps_state) {
262
9.65k
  WORD32 ts, qs, row, res;
263
264
9.65k
  WORD32 temp_1;
265
9.65k
  SIZE_T *idx;
266
267
9.65k
  ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
268
9.65k
  ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
269
9.65k
  WORD32 time_slots = pstr_mps_state->time_slots;
270
9.65k
  WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
271
9.65k
  WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
272
9.65k
  WORD32 num_w_channels = pstr_mps_state->num_w_channels;
273
9.65k
  WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
274
9.65k
  SIZE_T *kernels_ptr = pstr_mps_state->kernels;
275
276
9.65k
  WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
277
9.65k
  WORD32 *buf_real_ch4, *buf_imag_ch4;
278
9.65k
  WORD32 *buf_real_ch3, *buf_imag_ch3;
279
280
9.65k
  p_buf_real = p_array_struct->buffer_real + TSXHBX5;
281
9.65k
  p_buf_imag = p_array_struct->buffer_imag + TSXHBX5;
282
283
275k
  for (ts = 0; ts < time_slots; ts++) {
284
265k
    p_buf_re = p_buf_real;
285
265k
    p_buf_im = p_buf_imag;
286
287
265k
    buf_real_ch4 = p_buf_real - TSXHB;
288
265k
    buf_imag_ch4 = p_buf_imag - TSXHB;
289
290
265k
    buf_real_ch3 = buf_real_ch4 - TSXHB;
291
265k
    buf_imag_ch3 = buf_imag_ch4 - TSXHB;
292
293
15.7M
    for (qs = 0; qs < hybrid_bands; qs++) {
294
15.4M
      if ((kernels_ptr[qs] < ((UWORD32)(p_aux_struct->ttt_config[0][0].stop_band)) &&
295
1.00M
           p_aux_struct->ttt_config[0][0].use_ttt_decorr) ||
296
15.1M
          (kernels_ptr[qs] >= ((UWORD32)p_aux_struct->ttt_config[1][0].start_band) &&
297
14.4M
           p_aux_struct->ttt_config[1][0].use_ttt_decorr)) {
298
448k
        temp_1 = (WORD32)ONE_BY_SQRT_TWO_Q30;
299
300
448k
        *p_buf_re = ixheaacd_mps_mult32_shr_30(*p_buf_re, temp_1);
301
448k
        *p_buf_re += (*buf_real_ch3 + *buf_real_ch4);
302
303
448k
        *p_buf_im = ixheaacd_mps_mult32_shr_30(*p_buf_im, temp_1);
304
448k
        *p_buf_im += (*buf_imag_ch3 + *buf_imag_ch4);
305
448k
      }
306
15.4M
      p_buf_re++;
307
15.4M
      p_buf_im++;
308
309
15.4M
      buf_real_ch4++;
310
15.4M
      buf_imag_ch4++;
311
312
15.4M
      buf_real_ch3++;
313
15.4M
      buf_imag_ch3++;
314
15.4M
    }
315
265k
    p_buf_real += MAX_HYBRID_BANDS;
316
265k
    p_buf_imag += MAX_HYBRID_BANDS;
317
265k
  }
318
319
9.65k
  if (pstr_mps_state->residual_coding) {
320
976
    for (row = num_direct_signals; row < num_w_channels; row++) {
321
715
      WORD32 resband;
322
715
      res = ixheaacd_get_res_idx(pstr_mps_state, row);
323
715
      resband = pstr_mps_state->res_bands[res];
324
325
715
      if (resband == 1 && (num_parameter_bands == 20 || num_parameter_bands == 28))
326
14
        pstr_mps_state->index[res] = 3;
327
701
      else {
328
701
        idx = &kernels_ptr[0];
329
8.96k
        for (qs = 0; qs < hybrid_bands; qs++) {
330
8.26k
          if (*idx++ >= (SIZE_T)resband) {
331
513
            pstr_mps_state->index[res] = qs;
332
513
            qs = hybrid_bands;
333
513
          }
334
8.26k
        }
335
701
      }
336
715
    }
337
261
  }
338
9.65k
}
339
340
9.65k
VOID ixheaacd_create_w(ia_heaac_mps_state_struct *pstr_mps_state) {
341
9.65k
  WORD32 k;
342
9.65k
  ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
343
9.65k
  WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
344
9.65k
  WORD32 counter = num_direct_signals + pstr_mps_state->num_decor_signals;
345
9.65k
  WORD32 time_slots = pstr_mps_state->time_slots;
346
9.65k
  WORD32 offset = num_direct_signals * TSXHB;
347
9.65k
  WORD32 *p_buffer_real = p_array_struct->buf_real + offset;
348
9.65k
  WORD32 *p_buffer_imag = p_array_struct->buf_imag + offset;
349
350
9.65k
  WORD32 *p_buf_real = p_array_struct->buffer_real + offset;
351
9.65k
  WORD32 *p_buf_imag = p_array_struct->buffer_imag + offset;
352
353
31.4k
  for (k = num_direct_signals; k < counter; k++) {
354
21.7k
    ixheaacd_decorr_apply(pstr_mps_state, time_slots, p_buffer_real, p_buffer_imag, p_buf_real,
355
21.7k
                          p_buf_imag, k);
356
357
21.7k
    p_buffer_real += TSXHB;
358
21.7k
    p_buffer_imag += TSXHB;
359
360
21.7k
    p_buf_real += TSXHB;
361
21.7k
    p_buf_imag += TSXHB;
362
21.7k
  }
363
9.65k
  ixheaacd_merge_res_decor(pstr_mps_state);
364
9.65k
}
365
366
366
VOID ixheaacd_update_buffers(ia_heaac_mps_state_struct *pstr_mps_state) {
367
366
  ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
368
366
  WORD32 *temp_addr = p_array_struct->qmf_residual_real_post;
369
366
  p_array_struct->qmf_residual_real_post = p_array_struct->qmf_residual_real_pre;
370
366
  p_array_struct->qmf_residual_real_pre = temp_addr;
371
372
366
  temp_addr = p_array_struct->qmf_residual_imag_post;
373
366
  p_array_struct->qmf_residual_imag_post = p_array_struct->qmf_residual_imag_pre;
374
366
  p_array_struct->qmf_residual_imag_pre = temp_addr;
375
376
366
  p_array_struct->buffer_real = p_array_struct->qmf_residual_real_post;
377
366
  p_array_struct->buffer_imag = p_array_struct->qmf_residual_imag_post;
378
379
366
  p_array_struct->m1_param = (ia_mps_dec_m1_param_struct *)p_array_struct->buffer_real;
380
366
}