xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_decode_main.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 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 <stdlib.h>
21 #include <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaac_error_standards.h"
24 #include "ixheaacd_memory_standards.h"
25 #include "ixheaacd_sbrdecsettings.h"
26 #include "ixheaacd_sbr_scale.h"
27 #include "ixheaacd_env_extr_part.h"
28 #include "ixheaacd_defines.h"
29 #include "ixheaacd_aac_rom.h"
30 #include "ixheaacd_common_rom.h"
31 #include "ixheaacd_sbr_rom.h"
32 #include "ixheaacd_bitbuffer.h"
33 #include "ixheaacd_pulsedata.h"
34 #include "ixheaacd_pns.h"
35 #include "ixheaacd_interface.h"
36 #include "ixheaacd_info.h"
37 #include "ixheaacd_lt_predict.h"
38 #include "ixheaacd_cnst.h"
39 #include "ixheaacd_ec_defines.h"
40 #include "ixheaacd_ec_struct_def.h"
41 #include "ixheaacd_channelinfo.h"
42 #include "ixheaacd_sbr_common.h"
43 #include "ixheaacd_drc_data_struct.h"
44 #include "ixheaacd_drc_dec.h"
45 #include "ixheaacd_channel.h"
46 #include "ixheaacd_sbrdecoder.h"
47 #include "ixheaacd_audioobjtypes.h"
48 #include "ixheaacd_latmdemux.h"
49 #include "ixheaacd_aacdec.h"
50 #include "ixheaacd_sbr_common.h"
51 #include "ixheaacd_hybrid.h"
52 #include "ixheaacd_ps_dec.h"
53 #include "ixheaacd_mps_polyphase.h"
54 #include "ixheaacd_config.h"
55 #include "ixheaacd_qmf_dec.h"
56 #include "ixheaacd_mps_macro_def.h"
57 #include "ixheaacd_mps_struct_def.h"
58 #include "ixheaacd_mps_res_rom.h"
59 #include "ixheaacd_mps_aac_struct.h"
60 #include "ixheaac_constants.h"
61 #include "ixheaacd_mps_dec.h"
62 #include "ixheaacd_struct_def.h"
63 #include "ixheaacd_bitbuffer.h"
64 #include "ixheaacd_interface.h"
65 #include "ixheaacd_tns_usac.h"
66 
67 #include "ixheaacd_acelp_info.h"
68 #include "ixheaacd_sbrdecsettings.h"
69 #include "ixheaacd_info.h"
70 #include "ixheaacd_sbrdecoder.h"
71 #include "ixheaacd_mps_polyphase.h"
72 #include "ixheaac_sbr_const.h"
73 #include "ixheaacd_main.h"
74 #include "ixheaacd_arith_dec.h"
75 #include "ixheaacd_config.h"
76 #include "ixheaacd_struct.h"
77 #include "ixheaacd_create.h"
78 #include "ixheaacd_dec_main.h"
79 #include "ixheaac_error_standards.h"
80 #include "ixheaacd_headerdecode.h"
81 #include "ixheaacd_error_codes.h"
ixheaacd_samples_sat(WORD8 * outbuffer,WORD32 num_samples_out,WORD32 pcmsize,FLOAT32 (* out_samples)[4096],WORD32 * out_bytes,WORD32 num_channel_out)82 VOID ixheaacd_samples_sat(WORD8 *outbuffer, WORD32 num_samples_out,
83                           WORD32 pcmsize, FLOAT32 (*out_samples)[4096],
84                           WORD32 *out_bytes, WORD32 num_channel_out) {
85   WORD32 num;
86   WORD32 i;
87   WORD32 write_local;
88   FLOAT32 write_local_float;
89 
90   WORD16 *out_buf = (WORD16 *)outbuffer;
91 
92   num = num_channel_out * num_samples_out;
93 
94   if (pcmsize == 16) {
95     for (i = 0; i < num; i++) {
96       write_local_float =
97           (out_samples[i % num_channel_out][i / num_channel_out]);
98 
99       if (write_local_float > 32767.0f) {
100         write_local_float = 32767.0f;
101       } else if (write_local_float < -32768.0f) {
102         write_local_float = -32768.0f;
103       }
104       out_buf[i] = (WORD16)write_local_float;
105     }
106 
107     *out_bytes = num * sizeof(WORD16);
108   } else {
109     WORD8 *out_24bit = (WORD8 *)out_buf;
110     for (i = 0; i < num; i++) {
111       write_local_float =
112           (out_samples[i % num_channel_out][i / num_channel_out] * 256);
113 
114       if (write_local_float > 8388607.0f) {
115         write_local_float = 8388607.0f;
116       } else if (write_local_float < -8388608.0f) {
117         write_local_float = -8388608.0f;
118       }
119       write_local = (WORD32)write_local_float;
120 
121       *out_24bit++ = (WORD32)write_local & 0xff;
122       *out_24bit++ = ((WORD32)write_local >> 8) & 0xff;
123       *out_24bit++ = ((WORD32)write_local >> 16) & 0xff;
124     }
125 
126     *out_bytes = num * 3 * sizeof(WORD8);
127   }
128 }
129 
ixheaacd_samples_sat_mc(WORD8 * outbuffer,WORD32 num_samples_out,FLOAT32 (* out_samples)[4096],WORD32 * out_bytes,WORD32 num_channel_out,WORD32 ch_fac)130 VOID ixheaacd_samples_sat_mc(WORD8* outbuffer, WORD32 num_samples_out,
131     FLOAT32(*out_samples)[4096], WORD32* out_bytes,
132     WORD32 num_channel_out, WORD32 ch_fac) {
133   WORD32 num;
134   WORD32 i;
135   FLOAT32 write_local_float;
136 
137   WORD16* out_buf = (WORD16*)outbuffer;
138 
139   num = num_channel_out * num_samples_out;
140   if (num_channel_out == 1) {
141     for (i = 0; i < num; i++) {
142       write_local_float =
143           (out_samples[i % num_channel_out][i / num_channel_out]);
144 
145       if (write_local_float > 32767.0f) {
146         write_local_float = 32767.0f;
147       } else if (write_local_float < -32768.0f) {
148         write_local_float = -32768.0f;
149       }
150       out_buf[i * ch_fac] = (WORD16)write_local_float;
151     }
152   } else if (num_channel_out == 2) {
153     for (i = 0; i < num_samples_out; i++) {
154       write_local_float =
155           (out_samples[(2*i) % num_channel_out][(2 * i) / num_channel_out]);
156 
157       if (write_local_float > 32767.0f) {
158           write_local_float = 32767.0f;
159       } else if (write_local_float < -32768.0f) {
160           write_local_float = -32768.0f;
161       }
162       out_buf[i * ch_fac] = (WORD16)write_local_float;
163 
164       write_local_float =
165           (out_samples[((2 * i) + 1) % num_channel_out][((2 * i) + 1) / num_channel_out]);
166 
167       if (write_local_float > 32767.0f) {
168           write_local_float = 32767.0f;
169       } else if (write_local_float < -32768.0f) {
170           write_local_float = -32768.0f;
171       }
172       out_buf[i * ch_fac + 1] = (WORD16)write_local_float;
173     }
174   }
175   *out_bytes = num * sizeof(WORD16);
176 }
177 
178 /* audio pre roll frame parsing*/
ixheaacd_audio_preroll_parsing(ia_dec_data_struct * pstr_dec_data,UWORD8 * conf_buf,WORD32 * preroll_units,WORD32 * preroll_frame_offset,ia_aac_dec_state_struct * aac_dec_handle,WORD32 * config_changed,WORD32 * apply_crossfade)179 static WORD32 ixheaacd_audio_preroll_parsing(
180     ia_dec_data_struct *pstr_dec_data, UWORD8 *conf_buf, WORD32 *preroll_units,
181     WORD32 *preroll_frame_offset, ia_aac_dec_state_struct *aac_dec_handle,
182     WORD32 *config_changed, WORD32 *apply_crossfade) {
183   ia_bit_buf_struct *temp_buff =
184       (ia_bit_buf_struct *)&(pstr_dec_data->dec_bit_buf);
185 
186   WORD32 ext_ele_present = 0;
187   WORD32 ext_ele_use_dflt_len = 0;
188   WORD32 ext_ele_payload_len = 0;
189   WORD32 num_pre_roll_frames = 0;
190 
191   WORD32 frame_idx = 0;
192   WORD32 temp = 0;
193 
194   WORD32 config_len = 0;
195   WORD32 loop;
196 
197   if (pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config
198           .str_usac_dec_config.usac_element_type[0] == ID_USAC_EXT) {
199     temp = ixheaacd_show_bits_buf(temp_buff, 3);
200     ext_ele_present = (temp >> 1) & 0x1;
201 
202     if (ext_ele_present) {
203       ext_ele_use_dflt_len = temp & 0x1;
204       if (ext_ele_use_dflt_len != 0) return 0;
205 
206       ixheaacd_read_bits_buf(temp_buff, 3);
207 
208       ext_ele_payload_len = ixheaacd_read_bits_buf(temp_buff, 8);
209 
210       if (ext_ele_payload_len == 255) {
211         WORD32 val_add = 0;
212         val_add = ixheaacd_read_bits_buf(temp_buff, 16);
213         ext_ele_payload_len =
214             (UWORD32)((WORD32)ext_ele_payload_len + val_add - 2);
215       }
216 
217       config_len = ixheaacd_read_bits_buf(temp_buff, 4);
218       if (config_len == 15) {
219         WORD32 val_add = 0;
220         val_add = ixheaacd_read_bits_buf(temp_buff, 4);
221         config_len += val_add;
222         if (val_add == 15) {
223           WORD32 val_add1 = 0;
224           val_add1 = ixheaacd_read_bits_buf(temp_buff, 8);
225           config_len += val_add1;
226         }
227       }
228 
229       for (loop = 0; loop < config_len; loop++)
230         conf_buf[loop] = ixheaacd_read_bits_buf(temp_buff, 8);
231 
232       if (aac_dec_handle->preroll_config_present == 1) {
233         if (!(memcmp(aac_dec_handle->preroll_config_prev, conf_buf,
234                      sizeof(UWORD8) * config_len))) {
235           config_len = 0;
236         }
237         if (memcmp(aac_dec_handle->preroll_config_prev, conf_buf,
238                    sizeof(UWORD8) * config_len) != 0) {
239           *config_changed = 1;
240         } else {
241           *config_changed = 0;
242         }
243       }
244       aac_dec_handle->preroll_config_present = 1;
245       memcpy(aac_dec_handle->preroll_config_prev, conf_buf,
246              sizeof(UWORD8) * config_len);
247 
248       *apply_crossfade = ixheaacd_read_bits_buf(temp_buff, 1);
249       ixheaacd_read_bits_buf(temp_buff, 1);
250 
251       num_pre_roll_frames = ixheaacd_read_bits_buf(temp_buff, 2);
252       if (num_pre_roll_frames == 3) {
253         WORD32 val_add = 0;
254         val_add = ixheaacd_read_bits_buf(temp_buff, 4);
255         num_pre_roll_frames += val_add;
256       }
257 
258       if (num_pre_roll_frames > MAX_AUDIO_PREROLLS) {
259         if (pstr_dec_data->str_usac_data.ec_flag) {
260           num_pre_roll_frames = 0;
261           longjmp(*(pstr_dec_data->xaac_jmp_buf),
262                   IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
263         } else {
264           return IA_FATAL_ERROR;
265         }
266       }
267 
268       for (frame_idx = 0; frame_idx < num_pre_roll_frames; frame_idx++) {
269         WORD32 au_len = 0;
270         au_len = ixheaacd_read_bits_buf(temp_buff, 16);
271         if (au_len == 65535) {
272           WORD32 val_add = ixheaacd_read_bits_buf(temp_buff, 16);
273           au_len += val_add;
274         }
275         if (config_len != 0) {
276           preroll_frame_offset[frame_idx] =
277               temp_buff->size - temp_buff->cnt_bits;
278         }
279         temp_buff->ptr_read_next += au_len;
280         temp_buff->cnt_bits -= au_len * 8;
281         if (temp_buff->cnt_bits < 0) {
282           if (pstr_dec_data->str_usac_data.ec_flag) {
283             temp_buff->cnt_bits = 0;
284             longjmp(*(pstr_dec_data->xaac_jmp_buf),
285                     IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES);
286           } else {
287             return IA_FATAL_ERROR;
288           }
289         }
290       }
291     }
292   }
293   if (config_len == 0)
294     *preroll_units = 0;
295   else
296     *preroll_units = num_pre_roll_frames;
297 
298   return config_len;
299 }
300 
ixheaacd_dec_main(VOID * temp_handle,WORD8 * inbuffer,WORD8 * outbuffer,WORD32 * out_bytes,WORD32 frames_done,WORD32 pcmsize,WORD32 * num_channel_out)301 WORD32 ixheaacd_dec_main(VOID *temp_handle, WORD8 *inbuffer, WORD8 *outbuffer,
302                          WORD32 *out_bytes, WORD32 frames_done, WORD32 pcmsize,
303                          WORD32 *num_channel_out) {
304   WORD32 err = 0;
305   ia_exhaacplus_dec_api_struct *handle =
306       (ia_exhaacplus_dec_api_struct *)temp_handle;
307   ia_aac_dec_state_struct *aac_dec_handle = handle->p_state_aac;
308 
309   WORD32 tmp;
310   ia_audio_specific_config_struct *pstr_audio_specific_config =
311       (ia_audio_specific_config_struct *)
312           aac_dec_handle->ia_audio_specific_config;
313   WORD32 suitable_tracks = 1;
314   WORD32 num_samples_out;
315   ia_dec_data_struct *pstr_dec_data;
316   UWORD8 config[MAX_PREROLL_SIZE];
317   WORD32 config_len;
318   WORD32 delay;
319   WORD preroll_frame_offset[MAX_PREROLL_FRAME_OFFSET] = {0};
320   WORD preroll_units = -1;
321   WORD32 access_units = 0;
322   WORD32 bits_consumed = 0;
323 
324   if (frames_done == 0) {
325     if ((pstr_audio_specific_config->channel_configuration > 2) ||
326         (pstr_audio_specific_config->channel_configuration == 0)) {
327       return -1;
328     }
329 
330     pstr_dec_data = (ia_dec_data_struct *)aac_dec_handle->pstr_dec_data;
331 
332     tmp = pstr_audio_specific_config->channel_configuration;
333 
334     suitable_tracks =
335         ixheaacd_frm_data_init(pstr_audio_specific_config, pstr_dec_data);
336 
337     pstr_audio_specific_config->channel_configuration = tmp;
338 
339     if (suitable_tracks <= 0) {
340       return -1;
341     }
342   }
343 
344   {
345     WORD32 tot_out_bytes = 0;
346     jmp_buf local;
347     pstr_dec_data = (ia_dec_data_struct *)aac_dec_handle->pstr_dec_data;
348     pstr_dec_data->str_usac_data.frame_ok = 1;
349     pstr_dec_data->str_usac_data.ec_flag = aac_dec_handle->p_config->ui_err_conceal;
350     if (pstr_dec_data->str_usac_data.ec_flag) {
351       err = setjmp(local);
352     }
353 
354     if (aac_dec_handle->p_config->ui_err_conceal) {
355       if (err == 0) {
356         if (pstr_dec_data->dec_bit_buf.cnt_bits) {
357           aac_dec_handle->ui_in_bytes += (pstr_dec_data->dec_bit_buf.cnt_bits >> 3);
358           if (aac_dec_handle->ui_in_bytes > IA_MAX_INP_BUFFER_SIZE) {
359             aac_dec_handle->ui_in_bytes = 0;
360           }
361         }
362       } else {
363         pstr_dec_data->str_usac_data.frame_ok = 0;
364       }
365     }
366 
367     if (frames_done == 0) {
368       WORD32 delay;
369       pstr_dec_data->str_usac_data.first_frame = 1;
370       if (aac_dec_handle->decode_create_done == 0) {
371         delay = ixheaacd_decode_create(
372             handle, pstr_dec_data,
373             pstr_dec_data->str_frame_data.scal_out_select + 1);
374         if (delay == -1) return -1;
375       }
376       pstr_dec_data->dec_bit_buf.max_size =
377           handle->p_mem_info_aac[IA_MEMTYPE_INPUT].ui_size;
378       *num_channel_out = pstr_dec_data->str_frame_data.scal_out_num_channels;
379       return 0;
380     }
381 
382     pstr_dec_data->dec_bit_buf.ptr_bit_buf_base = (UWORD8 *)inbuffer;
383     pstr_dec_data->dec_bit_buf.size = aac_dec_handle->ui_in_bytes << 3;
384     pstr_dec_data->dec_bit_buf.ptr_bit_buf_end =
385         (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes - 1;
386     pstr_dec_data->dec_bit_buf.ptr_read_next = (UWORD8 *)inbuffer;
387     pstr_dec_data->dec_bit_buf.bit_pos = 7;
388     pstr_dec_data->dec_bit_buf.cnt_bits = pstr_dec_data->dec_bit_buf.size;
389     pstr_dec_data->dec_bit_buf.xaac_jmp_buf = &(aac_dec_handle->xaac_jmp_buf);
390     if (pstr_dec_data->str_usac_data.ec_flag) {
391       pstr_dec_data->xaac_jmp_buf = &local;
392     }
393     pstr_dec_data->str_usac_data.usac_flag = aac_dec_handle->usac_flag;
394     pstr_dec_data->str_usac_data.esbr_hq = handle->aac_config.ui_hq_esbr;
395     pstr_dec_data->str_usac_data.enh_sbr = 1;
396     pstr_dec_data->str_usac_data.enh_sbr_ps = handle->aac_config.ui_enh_sbr_ps;
397     if (pstr_dec_data->dec_bit_buf.size > pstr_dec_data->dec_bit_buf.max_size)
398       pstr_dec_data->dec_bit_buf.max_size = pstr_dec_data->dec_bit_buf.size;
399     /* audio pre roll frame parsing*/
400 
401     if (aac_dec_handle->bs_format == LOAS_BSFORMAT && pstr_dec_data->str_usac_data.frame_ok) {
402       WORD32 sync = ixheaacd_read_bits_buf(&pstr_dec_data->dec_bit_buf, 11);
403       if (sync == 0x2b7) {
404         WORD32 result = ixheaacd_latm_audio_mux_element(
405           &pstr_dec_data->dec_bit_buf, &aac_dec_handle->latm_struct_element,
406           aac_dec_handle,
407           (ia_sampling_rate_info_struct *)&handle->aac_tables
408           .pstr_huffmann_tables->str_sample_rate_info[0]);
409         if (result < 0) {
410           if (aac_dec_handle->p_config->ui_err_conceal)
411             pstr_dec_data->str_usac_data.frame_ok = 0;
412           else
413             return result;
414         }
415       }
416       bits_consumed = pstr_dec_data->dec_bit_buf.size - pstr_dec_data->dec_bit_buf.cnt_bits;
417     }
418 
419     do {
420       config_len = 0;
421       if (err == 0 || aac_dec_handle->p_config->ui_err_conceal == 0) {
422         if (access_units == 0 &&
423             pstr_audio_specific_config->str_usac_config.str_usac_dec_config.preroll_flag) {
424           config_len = ixheaacd_audio_preroll_parsing(
425               pstr_dec_data, &config[0], &preroll_units, &preroll_frame_offset[0], aac_dec_handle,
426               &aac_dec_handle->drc_config_changed, &aac_dec_handle->apply_crossfade);
427 
428           if (config_len == IA_FATAL_ERROR) return IA_FATAL_ERROR;
429         }
430 
431         if (config_len != 0) {
432           ia_bit_buf_struct config_bit_buf = {0};
433 
434           config_bit_buf.ptr_bit_buf_base = config;
435           config_bit_buf.size = config_len << 3;
436           config_bit_buf.ptr_read_next = config_bit_buf.ptr_bit_buf_base;
437           config_bit_buf.ptr_bit_buf_end = (UWORD8 *)config + config_len;
438           config_bit_buf.bit_pos = 7;
439           config_bit_buf.cnt_bits = config_bit_buf.size;
440           if (pstr_dec_data->str_usac_data.ec_flag) {
441             config_bit_buf.xaac_jmp_buf = &local;
442           } else {
443             config_bit_buf.xaac_jmp_buf = &(aac_dec_handle->xaac_jmp_buf);
444           }
445 
446           suitable_tracks = ixheaacd_frm_data_init(pstr_audio_specific_config, pstr_dec_data);
447 
448           if (suitable_tracks <= 0) return -1;
449 
450           aac_dec_handle->decode_create_done = 0;
451           if (aac_dec_handle->p_config->ui_err_conceal) {
452             if (pstr_dec_data->str_usac_data.frame_ok == 1 && err == 0) {
453               err = ixheaacd_config(
454                   &config_bit_buf,
455                   &(pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config),
456                   &(pstr_audio_specific_config->channel_configuration),
457                   aac_dec_handle->p_config->ui_err_conceal);
458               if (err != 0) {
459                 if (frames_done == 0)
460                   return -1;
461                 else
462                   pstr_dec_data->str_usac_data.frame_ok = 0;
463               }
464             }
465           } else {
466             err = ixheaacd_config(
467                 &config_bit_buf,
468                 &(pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config),
469                 &(pstr_audio_specific_config->channel_configuration),
470                 aac_dec_handle->p_config->ui_err_conceal);
471             if (err != 0) {
472               return err;
473             }
474           }
475 
476           pstr_dec_data->str_frame_data.str_audio_specific_config.sampling_frequency =
477               pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config
478                   .usac_sampling_frequency;
479           delay = ixheaacd_decode_create(handle, pstr_dec_data,
480                                          pstr_dec_data->str_frame_data.scal_out_select + 1);
481           if (delay == -1) return -1;
482           *num_channel_out = pstr_dec_data->str_frame_data.scal_out_num_channels;
483         }
484       } else {
485         pstr_dec_data->str_usac_data.frame_ok = 0;
486       }
487 
488       pstr_dec_data->dec_bit_buf.ptr_bit_buf_base = (UWORD8 *)inbuffer;
489       pstr_dec_data->dec_bit_buf.size = aac_dec_handle->ui_in_bytes << 3;
490       pstr_dec_data->dec_bit_buf.ptr_bit_buf_end =
491           (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes - 1;
492       pstr_dec_data->dec_bit_buf.ptr_read_next = (UWORD8 *)inbuffer;
493       pstr_dec_data->dec_bit_buf.bit_pos = 7;
494       pstr_dec_data->dec_bit_buf.cnt_bits = pstr_dec_data->dec_bit_buf.size;
495       pstr_dec_data->dec_bit_buf.xaac_jmp_buf = &(aac_dec_handle->xaac_jmp_buf);
496 
497       pstr_dec_data->str_usac_data.usac_flag = aac_dec_handle->usac_flag;
498       pstr_dec_data->str_usac_data.esbr_hq = handle->aac_config.ui_hq_esbr;
499       pstr_dec_data->str_usac_data.enh_sbr = 1;
500       pstr_dec_data->str_usac_data.enh_sbr_ps = handle->aac_config.ui_enh_sbr_ps;
501 
502       if (preroll_frame_offset[access_units] &&
503           ((pstr_dec_data->str_usac_data.ec_flag && pstr_dec_data->str_usac_data.frame_ok == 1) ||
504            pstr_dec_data->str_usac_data.ec_flag == 0)) {
505         pstr_dec_data->dec_bit_buf.cnt_bits =
506             pstr_dec_data->dec_bit_buf.size -
507             preroll_frame_offset[access_units];
508         pstr_dec_data->dec_bit_buf.bit_pos =
509             7 - preroll_frame_offset[access_units] % 8;
510         pstr_dec_data->dec_bit_buf.ptr_read_next =
511             pstr_dec_data->dec_bit_buf.ptr_read_next +
512             (preroll_frame_offset[access_units] / 8);
513       } else {
514         pstr_dec_data->dec_bit_buf.cnt_bits =
515           pstr_dec_data->dec_bit_buf.size -
516           (bits_consumed);
517         pstr_dec_data->dec_bit_buf.bit_pos =
518           7 - (bits_consumed) % 8;
519         pstr_dec_data->dec_bit_buf.ptr_read_next =
520           pstr_dec_data->dec_bit_buf.ptr_read_next +
521           (bits_consumed / 8);
522       }
523 
524       if (pstr_dec_data->str_usac_data.ec_flag) {
525         if (!aac_dec_handle->decode_create_done && pstr_dec_data->str_usac_data.frame_ok == 1 &&
526             config_len != 0)
527           return IA_FATAL_ERROR;
528       } else {
529         if (!aac_dec_handle->decode_create_done) return IA_FATAL_ERROR;
530       }
531 
532       err =
533           ixheaacd_usac_process(pstr_dec_data, num_channel_out, aac_dec_handle);
534 
535       switch (pstr_dec_data->str_usac_data.sbr_ratio_idx) {
536         case 0:
537           handle->aac_config.ui_sbr_mode = 0;
538           break;
539         case 1:
540           handle->aac_config.ui_sbr_mode = 1;
541           break;
542         case 2:
543           handle->aac_config.ui_sbr_mode = 1;
544           break;
545         case 3:
546           handle->aac_config.ui_sbr_mode = 3;
547           break;
548 
549         default:
550           handle->aac_config.ui_sbr_mode = 0;
551       }
552 
553       if (err == -1) return err;
554 
555       num_samples_out = pstr_dec_data->str_usac_data.output_samples;
556       if (!handle->aac_config.peak_limiter_off && pstr_dec_data->str_usac_data.ec_flag) {
557         aac_dec_handle->peak_limiter.num_channels = *num_channel_out;
558 
559         ixheaacd_peak_limiter_process_float(&aac_dec_handle->peak_limiter,
560                                             pstr_dec_data->str_usac_data.time_sample_vector,
561                                             num_samples_out);
562       }
563 
564       ixheaacd_samples_sat((WORD8 *)outbuffer + tot_out_bytes, num_samples_out,
565                            pcmsize,
566                            pstr_dec_data->str_usac_data.time_sample_vector,
567                            out_bytes, *num_channel_out);
568       {
569         WORD32 preroll_counter =
570             pstr_dec_data->str_frame_data.str_audio_specific_config
571                 .str_usac_config.str_usac_dec_config.preroll_counter;
572 
573         UWORD8 i;  // for looping index used for payload calculation
574         WORD32 payload_buffer_offset = 0;
575         WORD32 copy_bytes =
576             pstr_dec_data->str_frame_data.str_audio_specific_config
577                 .str_usac_config.str_usac_dec_config
578                 .usac_ext_gain_payload_len[preroll_counter] *
579             sizeof(WORD8);
580 
581         pstr_audio_specific_config->str_usac_config.str_usac_dec_config
582             .usac_ext_gain_payload_len[preroll_counter] =
583             pstr_dec_data->str_frame_data.str_audio_specific_config
584                 .str_usac_config.str_usac_dec_config
585                 .usac_ext_gain_payload_len[preroll_counter];
586 
587         for (i = 0; i < preroll_counter; i++)
588           payload_buffer_offset +=
589               pstr_dec_data->str_frame_data.str_audio_specific_config
590                   .str_usac_config.str_usac_dec_config
591                   .usac_ext_gain_payload_len[i] *
592               sizeof(WORD8);
593 
594         memcpy(pstr_audio_specific_config->str_usac_config.str_usac_dec_config
595                        .usac_ext_gain_payload_buf +
596                    payload_buffer_offset,
597                pstr_dec_data->str_frame_data.str_audio_specific_config
598                        .str_usac_config.str_usac_dec_config
599                        .usac_ext_gain_payload_buf +
600                    payload_buffer_offset,
601                copy_bytes);
602 
603         pstr_audio_specific_config->str_usac_config.str_usac_dec_config
604             .preroll_bytes[preroll_counter] = *out_bytes;
605 
606         preroll_counter++;
607 
608         if (preroll_counter > (MAX_AUDIO_PREROLLS + 1)) return IA_FATAL_ERROR;
609 
610         pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config
611             .str_usac_dec_config.preroll_counter = preroll_counter;
612 
613         ia_usac_decoder_config_struct *pstr_usac_dec_config_state =
614             &pstr_audio_specific_config->str_usac_config.str_usac_dec_config;
615         ia_usac_decoder_config_struct *pstr_usac_dec_config_dec_data =
616             &pstr_dec_data->str_frame_data.str_audio_specific_config.str_usac_config
617             .str_usac_dec_config;
618         pstr_usac_dec_config_state->num_config_extensions =
619             pstr_usac_dec_config_dec_data->num_config_extensions;
620         pstr_usac_dec_config_state->num_elements =
621             pstr_usac_dec_config_dec_data->num_elements;
622         memcpy(pstr_usac_dec_config_state->usac_cfg_ext_info_buf,
623             pstr_usac_dec_config_dec_data->usac_cfg_ext_info_buf,
624             sizeof(pstr_usac_dec_config_state->usac_cfg_ext_info_buf));
625         memcpy(pstr_usac_dec_config_state->usac_ext_ele_payload_present,
626             pstr_usac_dec_config_dec_data->usac_ext_ele_payload_present,
627             sizeof(pstr_usac_dec_config_dec_data->usac_ext_ele_payload_present));
628         memcpy(pstr_usac_dec_config_state->usac_ext_ele_payload_buf,
629             pstr_usac_dec_config_dec_data->usac_ext_ele_payload_buf,
630             sizeof(pstr_usac_dec_config_state->usac_ext_ele_payload_buf));
631       }
632 
633       access_units++;
634       preroll_units--;
635       tot_out_bytes += (*out_bytes);
636     } while (preroll_units >= 0);
637     *out_bytes = tot_out_bytes;
638   }
639 
640   if (aac_dec_handle->bs_format == LOAS_BSFORMAT) {
641     pstr_dec_data->dec_bit_buf.ptr_bit_buf_base = (UWORD8 *)inbuffer;
642     pstr_dec_data->dec_bit_buf.size = aac_dec_handle->ui_in_bytes << 3;
643     pstr_dec_data->dec_bit_buf.ptr_bit_buf_end =
644       (UWORD8 *)inbuffer + aac_dec_handle->ui_in_bytes - 1;
645     pstr_dec_data->dec_bit_buf.ptr_read_next = (UWORD8 *)inbuffer;
646     pstr_dec_data->dec_bit_buf.bit_pos = 7;
647     pstr_dec_data->dec_bit_buf.cnt_bits = pstr_dec_data->dec_bit_buf.size;
648     pstr_dec_data->dec_bit_buf.xaac_jmp_buf = &(aac_dec_handle->xaac_jmp_buf);
649 
650     ixheaacd_read_bits_buf(&pstr_dec_data->dec_bit_buf, 11);
651     aac_dec_handle->i_bytes_consumed =
652         ixheaacd_read_bits_buf(&pstr_dec_data->dec_bit_buf, 13) + 3;
653   }
654 
655   return err;
656 }
657