Coverage Report

Created: 2025-10-10 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_write_bitstream.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
21
#include <limits.h>
22
#include <stddef.h>
23
#include "ixheaac_type_def.h"
24
#include "ixheaac_constants.h"
25
#include "impd_drc_common_enc.h"
26
#include "impd_drc_uni_drc.h"
27
#include "impd_drc_tables.h"
28
#include "impd_drc_api.h"
29
#include "ixheaace_api.h"
30
#include "ixheaace_aac_constants.h"
31
#include "ixheaac_error_standards.h"
32
#include "ixheaace_error_codes.h"
33
#include <stdlib.h>
34
35
#include "ixheaac_basic_ops32.h"
36
#include "ixheaac_basic_ops16.h"
37
#include "ixheaac_basic_ops40.h"
38
#include "ixheaac_basic_ops.h"
39
40
#include "ixheaace_bitbuffer.h"
41
#include "ixheaace_psy_const.h"
42
#include "ixheaace_tns.h"
43
#include "ixheaace_tns_params.h"
44
#include "ixheaace_rom.h"
45
#include "ixheaace_common_rom.h"
46
#include "ixheaace_block_switch.h"
47
#include "ixheaace_psy_data.h"
48
#include "ixheaace_interface.h"
49
#include "ixheaace_bits_count.h"
50
#include "ixheaace_dynamic_bits.h"
51
#include "ixheaace_adjust_threshold_data.h"
52
#include "ixheaace_qc_data.h"
53
#include "ixheaace_write_bitstream.h"
54
#include "ixheaace_sbr_header.h"
55
#include "ixheaace_config.h"
56
57
#include "ixheaace_channel_map.h"
58
#include "ixheaace_write_adts_adif.h"
59
60
static VOID PLATFORM_INLINE
61
ia_enhaacplus_enc_encode_gain_control_data(ixheaace_bit_buf_handle pstr_bit_stream_handle)
62
63
307k
{
64
307k
  ixheaace_write_bits(pstr_bit_stream_handle, 0, 1);
65
307k
}
66
static WORD32 ia_enhaacplus_enc_encode_spectral_data(
67
    WORD32 *pstr_sfb_offset, ixheaace_section_data *pstr_section_data, WORD16 *ptr_quant_spectrum,
68
458k
    ixheaace_bit_buf_handle pstr_bit_stream_handle, ixheaace_huffman_tables *ptr_huffman_tbl) {
69
458k
  WORD32 i, sfb;
70
458k
  WORD32 dbg_val;
71
72
458k
  dbg_val = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
73
74
2.14M
  for (i = 0; i < pstr_section_data->num_of_sections; i++) {
75
1.68M
    for (sfb = pstr_section_data->section[i].sfb_start;
76
14.6M
         sfb < pstr_section_data->section[i].sfb_start + pstr_section_data->section[i].sfb_cnt;
77
13.0M
         sfb++) {
78
13.0M
      ia_enhaacplus_enc_code_values(ptr_quant_spectrum + pstr_sfb_offset[sfb],
79
13.0M
                                    pstr_sfb_offset[sfb + 1] - pstr_sfb_offset[sfb],
80
13.0M
                                    pstr_section_data->section[i].code_book,
81
13.0M
                                    pstr_bit_stream_handle, ptr_huffman_tbl);
82
13.0M
    }
83
1.68M
  }
84
85
458k
  return (ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle) - dbg_val);
86
458k
}
87
88
static VOID ia_enhaacplus_enc_encode_global_gain(WORD32 global_gain, WORD32 log_norm,
89
                                                 WORD32 scalefac,
90
458k
                                                 ixheaace_bit_buf_handle pstr_bit_stream_handle) {
91
458k
  ixheaace_write_bits(pstr_bit_stream_handle,
92
458k
                      global_gain - scalefac + GLOBAL_GAIN_OFFSET - 4 * log_norm, 8);
93
458k
}
94
95
static VOID ia_enhaacplus_enc_encode_ics_info(WORD32 block_type, WORD32 win_shape,
96
                                              WORD32 grouping_mask,
97
                                              ixheaace_section_data *pstr_section_data,
98
                                              ixheaace_bit_buf_handle pstr_bit_stream_handle,
99
316k
                                              WORD32 aot) {
100
316k
  WORD32 tmp;
101
102
316k
  switch (aot) {
103
15.5k
    case AOT_AAC_LD:
104
15.5k
      tmp = ((ICS_RESERVED_BIT << 3) | (block_type << 1) | win_shape);
105
15.5k
      ixheaace_write_bits(pstr_bit_stream_handle, tmp, 4);
106
15.5k
      break;
107
108
65.9k
    case AOT_AAC_LC:
109
172k
    case AOT_SBR:
110
196k
    case AOT_PS:
111
196k
      tmp = ((ICS_RESERVED_BIT << 3) | (block_type << 1) | win_shape);
112
196k
      ixheaace_write_bits(pstr_bit_stream_handle, tmp, 4);
113
196k
      break;
114
316k
  }
115
316k
  switch (block_type) {
116
235k
    case LONG_WINDOW:
117
252k
    case START_WINDOW:
118
266k
    case STOP_WINDOW:
119
120
266k
      switch (aot) {
121
52.8k
        case AOT_AAC_LC:
122
132k
        case AOT_SBR:
123
147k
        case AOT_PS:
124
147k
          tmp = pstr_section_data->max_sfb_per_grp << 1;
125
147k
          ixheaace_write_bits(pstr_bit_stream_handle, tmp, 7);
126
147k
          break;
127
128
15.5k
        case AOT_AAC_LD:
129
15.5k
          tmp = pstr_section_data->max_sfb_per_grp << 1;
130
15.5k
          ixheaace_write_bits(pstr_bit_stream_handle, tmp, 7);
131
15.5k
          break;
132
104k
        default:
133
104k
          ixheaace_write_bits(pstr_bit_stream_handle, pstr_section_data->max_sfb_per_grp, 6);
134
266k
      }
135
266k
      break;
136
137
266k
    case SHORT_WINDOW:
138
139
      // Write grouping bits
140
141
49.1k
      tmp = pstr_section_data->max_sfb_per_grp << (TRANS_FAC - 1) | grouping_mask;
142
49.1k
      ixheaace_write_bits(pstr_bit_stream_handle, tmp, TRANS_FAC - 1 + 4);
143
144
49.1k
      break;
145
316k
  }
146
316k
}
147
148
static WORD32 ia_enhaacplus_enc_encode_section_data(
149
458k
    ixheaace_section_data *pstr_section_data, ixheaace_bit_buf_handle pstr_bit_stream_handle) {
150
458k
  WORD32 sect_escape_val = 0, sect_len_bits = 0;
151
458k
  WORD32 sect_len;
152
458k
  WORD32 i;
153
458k
  WORD32 dbg_val = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
154
155
458k
  switch (pstr_section_data->block_type) {
156
324k
    case LONG_WINDOW:
157
351k
    case START_WINDOW:
158
375k
    case STOP_WINDOW:
159
160
375k
      sect_escape_val = SECT_ESC_VAL_LONG;
161
375k
      sect_len_bits = SECT_BITS_LONG;
162
375k
      break;
163
164
82.9k
    case SHORT_WINDOW:
165
166
82.9k
      sect_escape_val = SECT_ESC_VAL_SHORT;
167
82.9k
      sect_len_bits = SECT_BITS_SHORT;
168
82.9k
      break;
169
458k
  }
170
171
2.14M
  for (i = 0; i < pstr_section_data->num_of_sections; i++) {
172
1.68M
    ixheaace_write_bits(pstr_bit_stream_handle, pstr_section_data->section[i].code_book, 4);
173
174
1.68M
    sect_len = pstr_section_data->section[i].sfb_cnt;
175
176
2.01M
    while (sect_len >= sect_escape_val) {
177
328k
      ixheaace_write_bits(pstr_bit_stream_handle, sect_escape_val, (UWORD8)sect_len_bits);
178
179
328k
      sect_len -= sect_escape_val;
180
328k
    }
181
182
1.68M
    ixheaace_write_bits(pstr_bit_stream_handle, sect_len, (UWORD8)sect_len_bits);
183
1.68M
  }
184
185
458k
  return (ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle) - dbg_val);
186
458k
}
187
188
static VOID ia_enhaacplus_enc_code_scale_factor_delta_lav(WORD32 delta,
189
                                                            ixheaace_bit_buf_handle ptr_bitstream,
190
                                                            const UWORD16 *ptr_pltabscf,
191
6.29M
                                                            const UWORD32 *ptr_pctabscf) {
192
6.29M
  WORD32 code_word, code_length;
193
194
6.29M
  code_word = ptr_pctabscf[delta];
195
6.29M
  code_length = ptr_pltabscf[delta];
196
197
6.29M
  ixheaace_write_bits(ptr_bitstream, code_word, (UWORD8)code_length);
198
6.29M
}
199
static WORD32 ia_enhaacplus_enc_encode_scalefactor_data(
200
    UWORD16 *ptr_max_val_in_sfb, ixheaace_section_data *pstr_section_data, WORD16 *ptr_scalefac,
201
458k
    ixheaace_bit_buf_handle pstr_bit_stream_handle, ixheaace_huffman_tables *pstr_huffman_tbl) {
202
458k
  WORD32 i, j, last_val_scf, delta_scf;
203
458k
  WORD32 dbg_val = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
204
458k
  const UWORD16 *ptr_pltabscf = &pstr_huffman_tbl->huff_ltabscf[CODE_BCK_SCF_LAV];
205
458k
  const UWORD32 *ptr_pctabscf = &pstr_huffman_tbl->huff_ctabscf[CODE_BCK_SCF_LAV];
206
207
458k
  last_val_scf = ptr_scalefac[pstr_section_data->first_scf];
208
209
2.14M
  for (i = 0; i < pstr_section_data->num_of_sections; i++) {
210
1.68M
    if (pstr_section_data->section[i].code_book != CODE_BCK_ZERO_NO) {
211
1.13M
      for (j = pstr_section_data->section[i].sfb_start;
212
7.43M
           j < pstr_section_data->section[i].sfb_start + pstr_section_data->section[i].sfb_cnt;
213
6.29M
           j++) {
214
6.29M
        if (ptr_max_val_in_sfb[j] == 0) {
215
441k
          delta_scf = 0;
216
5.85M
        } else {
217
5.85M
          delta_scf = -(ptr_scalefac[j] - last_val_scf);
218
219
5.85M
          last_val_scf = ptr_scalefac[j];
220
5.85M
        }
221
6.29M
        ia_enhaacplus_enc_code_scale_factor_delta_lav(delta_scf, pstr_bit_stream_handle,
222
6.29M
                                                          ptr_pltabscf, ptr_pctabscf);
223
6.29M
      }
224
1.13M
    }
225
1.68M
  }
226
227
458k
  return (ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle) - dbg_val);
228
458k
}
229
230
static VOID ia_enhaacplus_enc_encode_ms_info(WORD32 sfb_cnt, WORD32 sfb_grp, WORD32 max_sfb,
231
                                             WORD32 ms_digest, WORD32 *js_flags,
232
142k
                                             ixheaace_bit_buf_handle pstr_bit_stream_handle) {
233
142k
  WORD32 sfb, sfb_offset;
234
142k
  UWORD32 tmp_var = 0;
235
142k
  WORD32 *jsflag;
236
142k
  UWORD8 num_of_bits, remaining = 0;
237
238
142k
  switch (ms_digest) {
239
11.9k
    case MS_NONE:
240
11.9k
      ixheaace_write_bits(pstr_bit_stream_handle, SI_MS_MASK_NONE, 2);
241
11.9k
      break;
242
243
115k
    case MS_ALL:
244
115k
      ixheaace_write_bits(pstr_bit_stream_handle, SI_MS_MASK_ALL, 2);
245
115k
      break;
246
247
15.5k
    case MS_SOME:
248
15.5k
      ixheaace_write_bits(pstr_bit_stream_handle, SI_MS_MASK_SOME, 2);
249
250
15.5k
      if (max_sfb > 32) {
251
2.36k
        num_of_bits = 32;
252
2.36k
        remaining = (UWORD8)(max_sfb - 32);
253
2.36k
      } else
254
13.2k
        num_of_bits = (UWORD8)max_sfb;
255
256
43.6k
      for (sfb_offset = 0; sfb_offset < sfb_cnt; sfb_offset += sfb_grp) {
257
28.0k
        WORD8 flag;
258
28.0k
        jsflag = &js_flags[sfb_offset];
259
28.0k
        tmp_var = 0;
260
261
477k
        for (sfb = num_of_bits - 1; sfb >= 0; sfb--) {
262
448k
          flag = (WORD8)(*jsflag++);
263
448k
          tmp_var = ((tmp_var << 1) | flag);
264
448k
        }
265
266
28.0k
        ixheaace_write_bits(pstr_bit_stream_handle, tmp_var, num_of_bits);
267
268
28.0k
        if (remaining) {
269
17.1k
          for (sfb = remaining - 1; sfb >= 0; sfb--) {
270
14.7k
            flag = (WORD8)(*jsflag++);
271
14.7k
            tmp_var = ((tmp_var << 1) | flag);
272
14.7k
          }
273
274
2.36k
          ixheaace_write_bits(pstr_bit_stream_handle, tmp_var, remaining);
275
2.36k
        }
276
28.0k
      }
277
278
15.5k
      break;
279
142k
  }
280
142k
}
281
282
static VOID ia_enhaacplus_enc_encode_tns_data(
283
    ixheaace_temporal_noise_shaping_params pstr_tns_info, WORD32 block_type,
284
458k
    ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot) {
285
458k
  WORD32 i, k;
286
458k
  WORD32 tns_present;
287
458k
  WORD32 num_windows;
288
458k
  WORD32 coef_bits;
289
290
458k
  UWORD32 tmp;
291
458k
  UWORD8 val;
292
293
458k
  num_windows = (block_type == 2 ? TRANS_FAC : 1);
294
295
458k
  tns_present = 0;
296
297
1.49M
  for (i = 0; i < num_windows; i++) {
298
1.03M
    if (pstr_tns_info.tns_active[i] == 1) {
299
347k
      tns_present = 1;
300
347k
    }
301
1.03M
  }
302
303
458k
  if (tns_present == 0) {
304
241k
    ixheaace_write_bits(pstr_bit_stream_handle, 0, 1);
305
306
241k
    if (AOT_AAC_LD == aot) {
307
16.0k
      ia_enhaacplus_enc_encode_gain_control_data(pstr_bit_stream_handle);
308
16.0k
    }
309
241k
  } else {
310
    /* there is data to be written*/
311
312
216k
    ixheaace_write_bits(pstr_bit_stream_handle, 1, 1); /* data_present */
313
314
216k
    if (aot == AOT_AAC_LD) {
315
7.16k
      ia_enhaacplus_enc_encode_gain_control_data(pstr_bit_stream_handle);
316
7.16k
    }
317
318
747k
    for (i = 0; i < num_windows; i++) {
319
531k
      ixheaace_write_bits(pstr_bit_stream_handle, pstr_tns_info.tns_active[i],
320
531k
                          (UWORD8)(block_type == 2 ? 1 : 2));
321
322
531k
      if (pstr_tns_info.tns_active[i]) {
323
347k
        tmp = ((pstr_tns_info.coef_res[i] == 4 ? 1 : 0)
324
347k
                   << ((block_type == 2 ? 4 : 6) + (block_type == 2 ? 3 : 5)) |
325
347k
               pstr_tns_info.length[i] << (block_type == 2 ? 3 : 5) | pstr_tns_info.order[i]);
326
327
347k
        val = (UWORD8)(1 + (block_type == 2 ? 4 : 6) + (block_type == 2 ? 3 : 5));
328
329
347k
        ixheaace_write_bits(pstr_bit_stream_handle, tmp, val);
330
331
347k
        if (pstr_tns_info.order[i]) {
332
347k
          ixheaace_write_bits(pstr_bit_stream_handle, FILTER_DIRECTION, 1);
333
334
347k
          if (pstr_tns_info.coef_res[i] == 4) {
335
171k
            coef_bits = 3;
336
337
566k
            for (k = 0; k < pstr_tns_info.order[i]; k++) {
338
545k
              if (pstr_tns_info.coef[i * TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT + k] > 3 ||
339
421k
                  pstr_tns_info.coef[i * TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT + k] < -4) {
340
150k
                coef_bits = 4;
341
150k
                break;
342
150k
              }
343
545k
            }
344
175k
          } else {
345
175k
            coef_bits = 2;
346
347
484k
            for (k = 0; k < pstr_tns_info.order[i]; k++) {
348
361k
              if (pstr_tns_info.coef[i * TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT + k] > 1 ||
349
312k
                  pstr_tns_info.coef[i * TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT + k] < -2) {
350
52.6k
                coef_bits = 3;
351
52.6k
                break;
352
52.6k
              }
353
361k
            }
354
175k
          }
355
356
347k
          ixheaace_write_bits(pstr_bit_stream_handle, -(coef_bits - pstr_tns_info.coef_res[i]),
357
347k
                              1); /*coef_compres*/
358
359
2.20M
          for (k = 0; k < pstr_tns_info.order[i]; k++) {
360
1.86M
            static const WORD32 rmask[] = {0, 1, 3, 7, 15};
361
362
1.86M
            ixheaace_write_bits(
363
1.86M
                pstr_bit_stream_handle,
364
1.86M
                pstr_tns_info.coef[i * TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT + k] &
365
1.86M
                    rmask[coef_bits],
366
1.86M
                (UWORD8)coef_bits);
367
1.86M
          }
368
347k
        }
369
347k
      }
370
531k
    }
371
216k
  }
372
458k
}
373
374
static VOID PLATFORM_INLINE
375
307k
ia_enhaacplus_enc_encode_pulse_data(ixheaace_bit_buf_handle pstr_bit_stream_handle) {
376
307k
  ixheaace_write_bits(pstr_bit_stream_handle, 0, 1);
377
307k
}
378
379
static IA_ERRORCODE ia_enhaacplus_enc_write_ic_stream(
380
    WORD32 common_window, WORD32 win_shape, WORD32 grouping_mask, WORD32 *pstr_sfb_offset,
381
    WORD16 *ptr_scf, UWORD16 *ptr_max_val_in_sfb, WORD32 global_gain, WORD16 *ptr_quant_spec,
382
    ixheaace_section_data *pstr_section_data, ixheaace_bit_buf_handle pstr_bit_stream_handle,
383
    WORD32 aot, ixheaace_temporal_noise_shaping_params pstr_tns_info,
384
458k
    ixheaace_aac_tables *pstr_aac_tables) {
385
458k
  WORD32 log_norm = -1;
386
387
458k
  ia_enhaacplus_enc_encode_global_gain(
388
458k
      global_gain, log_norm, ptr_scf[pstr_section_data->first_scf], pstr_bit_stream_handle);
389
458k
  if (!common_window) {
390
173k
    ia_enhaacplus_enc_encode_ics_info(pstr_section_data->block_type, win_shape, grouping_mask,
391
173k
                                      pstr_section_data, pstr_bit_stream_handle, aot);
392
173k
  }
393
394
458k
  if (ia_enhaacplus_enc_encode_section_data(pstr_section_data, pstr_bit_stream_handle) !=
395
458k
      pstr_section_data->side_info_bits) {
396
0
    return IA_EXHEAACE_EXE_FATAL_INVALID_SIDE_INFO_BITS;
397
0
  }
398
399
458k
  if (ia_enhaacplus_enc_encode_scalefactor_data(
400
458k
          ptr_max_val_in_sfb, pstr_section_data, ptr_scf, pstr_bit_stream_handle,
401
458k
          pstr_aac_tables->pstr_huff_tab) != pstr_section_data->scale_fac_bits) {
402
358
    return IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_BITS;
403
358
  }
404
405
458k
  if (aot == AOT_AAC_LC || aot == AOT_AAC_LD || aot == AOT_SBR || aot == AOT_PS) {
406
307k
    ia_enhaacplus_enc_encode_pulse_data(pstr_bit_stream_handle);
407
307k
  }
408
458k
  ia_enhaacplus_enc_encode_tns_data(pstr_tns_info, pstr_section_data->block_type,
409
458k
                                    pstr_bit_stream_handle, aot);
410
411
458k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
412
283k
    ia_enhaacplus_enc_encode_gain_control_data(pstr_bit_stream_handle);
413
283k
  }
414
415
458k
  if (ia_enhaacplus_enc_encode_spectral_data(
416
458k
          pstr_sfb_offset, pstr_section_data, ptr_quant_spec, pstr_bit_stream_handle,
417
458k
          pstr_aac_tables->pstr_huff_tab) != pstr_section_data->huffman_bits) {
418
0
    return IA_EXHEAACE_EXE_FATAL_INVALID_HUFFMAN_BITS;
419
0
  }
420
458k
  return IA_NO_ERROR;
421
458k
}
422
423
static IA_ERRORCODE ia_enhaacplus_enc_write_single_chan_elem(
424
    WORD32 instance_tag, WORD32 *pstr_sfb_offset, ixheaace_qc_out_channel *pstr_qc_out_ch,
425
    ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot,
426
143k
    ixheaace_temporal_noise_shaping_params pstr_tns_info, ixheaace_aac_tables *pstr_aac_tables) {
427
143k
  IA_ERRORCODE err_code;
428
429
143k
  switch (aot) {
430
26.2k
    case AOT_AAC_LC:
431
64.8k
    case AOT_SBR:
432
88.9k
    case AOT_PS:
433
88.9k
      ixheaace_write_bits(pstr_bit_stream_handle, ID_SCE, 3);
434
88.9k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
435
88.9k
      break;
436
6.81k
    case AOT_AAC_LD:
437
6.81k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
438
6.81k
      break;
439
143k
  }
440
441
143k
  err_code = ia_enhaacplus_enc_write_ic_stream(
442
143k
      0, pstr_qc_out_ch->win_shape, pstr_qc_out_ch->grouping_mask, pstr_sfb_offset,
443
143k
      pstr_qc_out_ch->scalefactor, pstr_qc_out_ch->max_val_in_sfb, pstr_qc_out_ch->global_gain,
444
143k
      pstr_qc_out_ch->quant_spec, &(pstr_qc_out_ch->section_data), pstr_bit_stream_handle, aot,
445
143k
      pstr_tns_info, pstr_aac_tables);
446
447
143k
  if (err_code != IA_NO_ERROR) {
448
64
    return err_code;
449
64
  }
450
451
143k
  return IA_NO_ERROR;
452
143k
}
453
454
static IA_ERRORCODE ia_enhaacplus_enc_write_channel_pair_element(
455
    WORD32 instance_tag, WORD32 ms_digest, WORD32 ms_flags[MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
456
    WORD32 *pstr_sfb_offset[2], ixheaace_qc_out_channel pstr_qc_out_ch[2],
457
    ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot,
458
    ixheaace_temporal_noise_shaping_params pstr_tns_info[2],
459
142k
    ixheaace_aac_tables *pstr_aac_tables) {
460
142k
  IA_ERRORCODE err_code;
461
462
142k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
463
88.2k
    ixheaace_write_bits(pstr_bit_stream_handle, ID_CPE, 3);
464
88.2k
  }
465
466
142k
  switch (aot) {
467
7.67k
    case AOT_AAC_LD:
468
7.67k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
469
7.67k
      ixheaace_write_bits(pstr_bit_stream_handle, 1, 1); /* common window */
470
7.67k
      break;
471
472
33.0k
    case AOT_AAC_LC:
473
88.2k
    case AOT_SBR:
474
88.2k
    case AOT_PS:
475
88.2k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
476
88.2k
      ixheaace_write_bits(pstr_bit_stream_handle, 1, 1);
477
88.2k
      break;
478
142k
  }
479
480
142k
  ia_enhaacplus_enc_encode_ics_info(pstr_qc_out_ch[0].section_data.block_type,
481
142k
                                    pstr_qc_out_ch[0].win_shape, pstr_qc_out_ch[0].grouping_mask,
482
142k
                                    &(pstr_qc_out_ch[0].section_data), pstr_bit_stream_handle,
483
142k
                                    aot);
484
485
142k
  ia_enhaacplus_enc_encode_ms_info(pstr_qc_out_ch[0].section_data.sfb_cnt,
486
142k
                                   pstr_qc_out_ch[0].section_data.sfb_per_group,
487
142k
                                   pstr_qc_out_ch[0].section_data.max_sfb_per_grp, ms_digest,
488
142k
                                   ms_flags, pstr_bit_stream_handle);
489
142k
  err_code = ia_enhaacplus_enc_write_ic_stream(
490
142k
      1, pstr_qc_out_ch[0].win_shape, pstr_qc_out_ch[0].grouping_mask, pstr_sfb_offset[0],
491
142k
      pstr_qc_out_ch[0].scalefactor, pstr_qc_out_ch[0].max_val_in_sfb,
492
142k
      pstr_qc_out_ch[0].global_gain, pstr_qc_out_ch[0].quant_spec,
493
142k
      &(pstr_qc_out_ch[0].section_data), pstr_bit_stream_handle, aot, pstr_tns_info[0],
494
142k
      pstr_aac_tables);
495
496
142k
  if (err_code != IA_NO_ERROR) {
497
167
    return err_code;
498
167
  }
499
500
142k
  err_code = ia_enhaacplus_enc_write_ic_stream(
501
142k
      1, pstr_qc_out_ch[1].win_shape, pstr_qc_out_ch[1].grouping_mask, pstr_sfb_offset[1],
502
142k
      pstr_qc_out_ch[1].scalefactor, pstr_qc_out_ch[1].max_val_in_sfb,
503
142k
      pstr_qc_out_ch[1].global_gain, pstr_qc_out_ch[1].quant_spec,
504
142k
      &(pstr_qc_out_ch[1].section_data), pstr_bit_stream_handle, aot, pstr_tns_info[1],
505
142k
      pstr_aac_tables);
506
507
142k
  if (err_code != IA_NO_ERROR) {
508
67
    return err_code;
509
67
  }
510
511
142k
  return IA_NO_ERROR;
512
142k
}
513
514
static VOID ia_enhaacplus_enc_write_fill_element_LD(
515
    const UWORD8 *ptr_anc_bytes, WORD32 total_fill_bits,
516
74.1k
    ixheaace_bit_buf_handle pstr_bit_stream_handle) {
517
74.1k
  WORD32 i, cnt, cnt1, remaining = 0;
518
519
  /*
520
    Write fill Element(s):
521
    amount of a fill element can be 7+X*8 Bits, X element of [0..270]
522
  */
523
  // ID_FIL and the FILL element payload size, ( 3+ 4 bits) are not sent.
524
  // but they are accounted in the earlier code, so subtracting it here
525
526
74.1k
  total_fill_bits -= 7;
527
204k
  while (total_fill_bits > 0) {
528
130k
    cnt = MIN((total_fill_bits >> 3), ((1 << 4) - 1));
529
530
130k
    if (ptr_anc_bytes) {
531
1.72M
      for (i = 0; i < cnt; i++) {
532
1.59M
        ixheaace_write_bits(pstr_bit_stream_handle, *ptr_anc_bytes++, 8);
533
1.59M
        total_fill_bits -= 8;
534
1.59M
      }
535
130k
      if (total_fill_bits < 8) {
536
57.5k
        ixheaace_write_bits(pstr_bit_stream_handle, *ptr_anc_bytes++, (UWORD8)total_fill_bits);
537
57.5k
        ixheaace_write_bits(pstr_bit_stream_handle, 0, (UWORD8)(8 - total_fill_bits));
538
57.5k
        total_fill_bits = 0;
539
57.5k
      }
540
130k
    } else {
541
0
      cnt1 = cnt >> 2;
542
0
      remaining = cnt - (cnt1 << 2);
543
544
0
      for (i = 0; i < cnt1; i++) {
545
0
        ixheaace_write_bits(pstr_bit_stream_handle, 0, 32);
546
0
        total_fill_bits -= 32;
547
0
      }
548
0
      if (remaining)
549
0
        for (i = 0; i < remaining; i++) {
550
0
          ixheaace_write_bits(pstr_bit_stream_handle, 0, 8);
551
0
          total_fill_bits -= 8;
552
0
        }
553
0
    }
554
130k
  }
555
74.1k
}
556
557
static VOID ia_enhaacplus_enc_write_fill_element_LC(const UWORD8 *ptr_anc_bytes,
558
                                                    WORD32 total_fill_bits,
559
283k
                                                    ixheaace_bit_buf_handle pstr_h_bit_stream) {
560
283k
  WORD32 i, cnt, esc_count;
561
562
549k
  while (total_fill_bits >= (3 + 4)) {
563
266k
    cnt = MIN((total_fill_bits - (3 + 4)) / 8, ((1 << 4) - 1));
564
565
266k
    ixheaace_write_bits(pstr_h_bit_stream, ID_FIL, 3);
566
567
266k
    ixheaace_write_bits(pstr_h_bit_stream, cnt, 4);
568
569
266k
    total_fill_bits -= (3 + 4);
570
571
266k
    if (cnt == (1 << 4) - 1) {
572
186k
      esc_count = MIN((total_fill_bits / 8) - ((1 << 4) - 1), (1 << 8) - 1);
573
574
186k
      ixheaace_write_bits(pstr_h_bit_stream, esc_count, 8);
575
576
186k
      total_fill_bits -= 8;
577
578
186k
      cnt += esc_count - 1;
579
186k
    }
580
581
36.5M
    for (i = 0; i < cnt; i++) {
582
36.3M
      if (ptr_anc_bytes)
583
1.63M
        ixheaace_write_bits(pstr_h_bit_stream, *ptr_anc_bytes++, 8);
584
34.6M
      else
585
34.6M
        ixheaace_write_bits(pstr_h_bit_stream, 0, 8);
586
587
36.3M
      total_fill_bits -= 8;
588
36.3M
    }
589
266k
  }
590
283k
}
591
592
static IA_ERRORCODE ia_enhaacplus_enc_write_single_channel_element_LFE(
593
    WORD32 instance_tag, WORD32 *ptr_sfb_offset, ixheaace_qc_out_channel *pstr_qc_out_ch,
594
    ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot,
595
29.6k
    ixheaace_temporal_noise_shaping_params pstr_tns_info, ixheaace_aac_tables *pstr_aac_tables) {
596
29.6k
  IA_ERRORCODE err_code;
597
29.6k
  switch (aot) {
598
6.64k
    case AOT_AAC_LC:
599
18.9k
    case AOT_SBR:
600
18.9k
    case AOT_PS:
601
18.9k
      ixheaace_write_bits(pstr_bit_stream_handle, ID_LFE, 3);
602
18.9k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
603
18.9k
      break;
604
605
1.09k
    case AOT_AAC_LD:
606
1.09k
      ixheaace_write_bits(pstr_bit_stream_handle, instance_tag, 4);
607
1.09k
      break;
608
29.6k
  }
609
610
29.6k
  err_code = ia_enhaacplus_enc_write_ic_stream(
611
29.6k
      0, pstr_qc_out_ch->win_shape, pstr_qc_out_ch->grouping_mask, ptr_sfb_offset,
612
29.6k
      pstr_qc_out_ch->scalefactor, pstr_qc_out_ch->max_val_in_sfb, pstr_qc_out_ch->global_gain,
613
29.6k
      pstr_qc_out_ch->quant_spec, &(pstr_qc_out_ch->section_data), pstr_bit_stream_handle, aot,
614
29.6k
      pstr_tns_info, pstr_aac_tables);
615
616
29.6k
  if (err_code != IA_NO_ERROR) {
617
60
    return err_code;
618
60
  }
619
29.6k
  return IA_NO_ERROR;
620
29.6k
}
621
622
static IA_ERRORCODE ia_enhaacplus_enc_write_single_channel_ind_coupling_element(
623
    WORD32 *ptr_sfb_offset, ixheaace_qc_out_channel *pstr_qc_out_ch,
624
    ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot,
625
0
    ixheaace_temporal_noise_shaping_params pstr_tns_info, ixheaace_aac_tables *pstr_aac_tables) {
626
0
  IA_ERRORCODE err_code;
627
0
  ixheaace_write_bits(pstr_bit_stream_handle, ID_CCE, 3);
628
629
  /*Flag indication that this is an independent coupling channel*/
630
0
  ixheaace_write_bits(pstr_bit_stream_handle, 1, 1);
631
632
  /*number of coupled channel elements*/
633
0
  ixheaace_write_bits(pstr_bit_stream_handle, NUM_COUPLED_ELE, 3);
634
635
  /*Flag indicating target is CPE*/
636
0
  ixheaace_write_bits(pstr_bit_stream_handle, 1, 1);
637
638
  /*Instance tag of target CPE*/
639
0
  ixheaace_write_bits(pstr_bit_stream_handle, 0, 4);
640
641
0
  ixheaace_write_bits(pstr_bit_stream_handle, 3, 2);
642
643
  /*Flag indicating coupling after TNS*/
644
0
  ixheaace_write_bits(pstr_bit_stream_handle, 1, 1);
645
646
  /*Flag indicating sign of coupling*/
647
0
  ixheaace_write_bits(pstr_bit_stream_handle, 0, 1);
648
649
  /*Flag indicating Scale of coupling*/
650
0
  ixheaace_write_bits(pstr_bit_stream_handle, SCALE_COUPLING_LEVEL0, 2);
651
652
0
  err_code = ia_enhaacplus_enc_write_ic_stream(
653
0
      0, pstr_qc_out_ch->win_shape, pstr_qc_out_ch->grouping_mask, ptr_sfb_offset,
654
0
      pstr_qc_out_ch->scalefactor, pstr_qc_out_ch->max_val_in_sfb, pstr_qc_out_ch->global_gain,
655
0
      pstr_qc_out_ch->quant_spec, &(pstr_qc_out_ch->section_data), pstr_bit_stream_handle, aot,
656
0
      pstr_tns_info, pstr_aac_tables);
657
0
  if (err_code != IA_NO_ERROR) {
658
0
    return err_code;
659
0
  }
660
661
0
  ia_enhaacplus_enc_code_scale_factor_delta(-1, pstr_bit_stream_handle,
662
0
                                            pstr_aac_tables->pstr_huff_tab);
663
664
0
  return IA_NO_ERROR;
665
0
}
666
667
IA_ERRORCODE ia_enhaacplus_enc_write_bitstream(
668
    ixheaace_bit_buf_handle pstr_bit_stream_handle, ixheaace_element_info pstr_element_info,
669
    ixheaace_qc_out *pstr_qc_out, ixheaace_psy_out *pstr_psy_out, WORD32 *glob_used_bits,
670
    const UWORD8 *ptr_anc_bytes, ixheaace_aac_tables *pstr_aac_tables, FLAG flag_last_element,
671
    WORD32 *write_program_config_element, WORD32 i_num_coup_channels, WORD32 i_channels_mask,
672
316k
    WORD32 i_samp_freq, WORD32 ele_idx, WORD32 aot, WORD32 *total_fill_bits) {
673
316k
  IA_ERRORCODE err_code;
674
316k
  WORD32 bit_markup, element_used_bits, frame_bits;
675
676
316k
  bit_markup = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
677
678
316k
  *glob_used_bits = 0;
679
680
316k
  {
681
316k
    WORD32 *ptr_sfb_offset[2];
682
316k
    ixheaace_temporal_noise_shaping_params tns_info[2];
683
684
316k
    element_used_bits = 0;
685
686
316k
    if ((*write_program_config_element == 1) && (ele_idx == 0)) {
687
0
      WORD32 samp_rate = i_samp_freq, ch_mask = i_channels_mask, n_cc_ch = i_num_coup_channels;
688
689
      /*Write Program Config Element*/
690
0
      ixheaace_write_bits(pstr_bit_stream_handle, ID_PCE, 3);
691
0
      ia_enhaacplus_enc_write_pce(samp_rate, ch_mask, n_cc_ch, pstr_bit_stream_handle);
692
0
      *write_program_config_element = 0;
693
0
    }
694
695
316k
    switch (pstr_element_info.el_type) {
696
143k
      case ID_SCE: /* single channel */
697
698
143k
        ptr_sfb_offset[0] =
699
143k
            pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->sfb_offsets;
700
143k
        tns_info[0] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->tns_info;
701
702
143k
        err_code = ia_enhaacplus_enc_write_single_chan_elem(
703
143k
            pstr_element_info.instance_tag, ptr_sfb_offset[0],
704
143k
            pstr_qc_out->qc_channel[pstr_element_info.channel_index[0]], pstr_bit_stream_handle,
705
143k
            aot, tns_info[0], pstr_aac_tables);
706
707
143k
        if (err_code != IA_NO_ERROR) {
708
64
          return err_code;
709
64
        }
710
143k
        break;
711
712
143k
      case ID_CCE: /* single channel independent coupling element*/
713
714
0
        ptr_sfb_offset[0] =
715
0
            pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->sfb_offsets;
716
0
        tns_info[0] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->tns_info;
717
718
0
        err_code = ia_enhaacplus_enc_write_single_channel_ind_coupling_element(
719
0
            ptr_sfb_offset[0], pstr_qc_out->qc_channel[pstr_element_info.channel_index[0]],
720
0
            pstr_bit_stream_handle, aot, tns_info[0], pstr_aac_tables);
721
722
0
        if (err_code != IA_NO_ERROR) {
723
0
          return err_code;
724
0
        }
725
0
        break;
726
727
29.6k
      case ID_LFE: /* single channel */
728
729
29.6k
        ptr_sfb_offset[0] =
730
29.6k
            pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->sfb_offsets;
731
29.6k
        tns_info[0] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->tns_info;
732
733
29.6k
        err_code = ia_enhaacplus_enc_write_single_channel_element_LFE(
734
29.6k
            pstr_element_info.instance_tag, ptr_sfb_offset[0],
735
29.6k
            pstr_qc_out->qc_channel[pstr_element_info.channel_index[0]], pstr_bit_stream_handle,
736
29.6k
            aot, tns_info[0], pstr_aac_tables);
737
738
29.6k
        if (err_code != IA_NO_ERROR) {
739
60
          return err_code;
740
60
        }
741
29.6k
        break;
742
743
142k
      case ID_CPE: /* channel pair */
744
142k
      {
745
142k
        WORD32 ms_digest = pstr_psy_out->psy_out_element.tools_info.ms_digest;
746
142k
        WORD32 *ms_flags = pstr_psy_out->psy_out_element.tools_info.ms_mask;
747
748
142k
        ptr_sfb_offset[0] =
749
142k
            pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->sfb_offsets;
750
142k
        ptr_sfb_offset[1] =
751
142k
            pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[1]]->sfb_offsets;
752
753
142k
        tns_info[0] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->tns_info;
754
142k
        tns_info[1] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[1]]->tns_info;
755
756
142k
        err_code = ia_enhaacplus_enc_write_channel_pair_element(
757
142k
            pstr_element_info.instance_tag, ms_digest, ms_flags, ptr_sfb_offset,
758
142k
            pstr_qc_out->qc_channel[pstr_element_info.channel_index[0]], pstr_bit_stream_handle,
759
142k
            aot, tns_info, pstr_aac_tables);
760
142k
        if (err_code != IA_NO_ERROR) {
761
234
          return err_code;
762
234
        }
763
142k
      } break;
764
765
142k
      default:
766
0
        return IA_EXHEAACE_INIT_FATAL_INVALID_ELEMENT_TYPE;
767
768
316k
    } /* switch */
769
770
315k
    element_used_bits -= bit_markup;
771
772
315k
    bit_markup = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
773
774
315k
    frame_bits = element_used_bits + bit_markup;
775
315k
  }
776
777
315k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
778
195k
    ia_enhaacplus_enc_write_fill_element_LC(ptr_anc_bytes, pstr_qc_out->tot_anc_bits_used,
779
195k
                                            pstr_bit_stream_handle);
780
195k
  }
781
782
315k
  if (flag_last_element) {
783
161k
    if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
784
87.2k
      ia_enhaacplus_enc_write_fill_element_LC(NULL, *total_fill_bits, pstr_bit_stream_handle);
785
786
87.2k
      *total_fill_bits = 0;
787
788
87.2k
      ixheaace_write_bits(pstr_bit_stream_handle, ID_END, 3);
789
87.2k
    }
790
791
161k
    if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
792
74.1k
      {
793
74.1k
        WORD32 i, cnt = 0;
794
74.1k
        ia_enhaacplus_enc_write_fill_element_LD(ptr_anc_bytes, pstr_qc_out->tot_anc_bits_used,
795
74.1k
                                                pstr_bit_stream_handle);
796
797
74.1k
        *total_fill_bits += pstr_qc_out->total_fill_bits;
798
74.1k
        *total_fill_bits += pstr_qc_out->align_bits;
799
74.1k
        cnt = *total_fill_bits >> 3;
800
9.22M
        for (i = 0; i < cnt; i++) {
801
9.14M
          ixheaace_write_bits(pstr_bit_stream_handle, 0, 8);
802
9.14M
        }
803
74.1k
        cnt = *total_fill_bits - (cnt << 3);
804
74.1k
        ixheaace_write_bits(pstr_bit_stream_handle, 0, (UWORD8)cnt);
805
74.1k
        *total_fill_bits = 0;
806
74.1k
      }
807
74.1k
    }
808
    /* byte alignement */
809
810
161k
    ixheaace_write_bits(pstr_bit_stream_handle, 0,
811
161k
                        (UWORD8)((8 - (pstr_bit_stream_handle->cnt_bits % 8)) % 8));
812
161k
  }
813
814
315k
  *glob_used_bits -= bit_markup;
815
816
315k
  bit_markup = ia_enhaacplus_enc_get_bits_available(pstr_bit_stream_handle);
817
818
315k
  *glob_used_bits += bit_markup;
819
820
315k
  frame_bits += *glob_used_bits;
821
822
315k
  if (frame_bits != pstr_qc_out->tot_static_bits_used + pstr_qc_out->tot_dyn_bits_used +
823
315k
                        pstr_qc_out->tot_anc_bits_used + +pstr_qc_out->total_fill_bits +
824
315k
                        pstr_qc_out->align_bits) {
825
194k
  }
826
827
315k
  return IA_NO_ERROR;
828
316k
}