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