xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_mps_tree.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker  *                                                                            *
3*15dc779aSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker  *
5*15dc779aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker  *
9*15dc779aSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker  *
11*15dc779aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker  * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker  *
17*15dc779aSAndroid Build Coastguard Worker  *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker  */
20*15dc779aSAndroid Build Coastguard Worker 
21*15dc779aSAndroid Build Coastguard Worker #include <stdlib.h>
22*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_error_standards.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_error_codes.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_common_fix.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_defines.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_common_define.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_bitbuffer.h"
29*15dc779aSAndroid Build Coastguard Worker 
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_bitstream.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_param_extract.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_frame_windowing.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_tree.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_buf.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_lib.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_onset_detect.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_static_gain.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_filter.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_delay.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_dmx_tdom_enh.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_main_structure.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_tools_rom.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_qmf.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_structure.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_struct_def.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_sac_polyphase.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_sac_nlc_enc.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_sac_hybfilter.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_spatial_bitstream.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaace_mps_rom.h"
51*15dc779aSAndroid Build Coastguard Worker 
ixheaace_mps_212_space_tree_frame_keep_212(const ixheaace_mps_pstr_space_tree pstr_space_tree,ixheaace_mps_spatial_frame * const pstr_spatial_frame,const WORD32 avoid_keep)52*15dc779aSAndroid Build Coastguard Worker static VOID ixheaace_mps_212_space_tree_frame_keep_212(
53*15dc779aSAndroid Build Coastguard Worker     const ixheaace_mps_pstr_space_tree pstr_space_tree,
54*15dc779aSAndroid Build Coastguard Worker     ixheaace_mps_spatial_frame *const pstr_spatial_frame, const WORD32 avoid_keep) {
55*15dc779aSAndroid Build Coastguard Worker   WORD32 band;
56*15dc779aSAndroid Build Coastguard Worker 
57*15dc779aSAndroid Build Coastguard Worker   if (avoid_keep) {
58*15dc779aSAndroid Build Coastguard Worker     for (band = 0; band < pstr_space_tree->num_param_bands; band++) {
59*15dc779aSAndroid Build Coastguard Worker       pstr_space_tree->icc_prev[0][band] = pstr_spatial_frame->ott_data.icc[0][0][band];
60*15dc779aSAndroid Build Coastguard Worker       pstr_space_tree->cld_prev[0][band] = pstr_spatial_frame->ott_data.cld[0][0][band];
61*15dc779aSAndroid Build Coastguard Worker     }
62*15dc779aSAndroid Build Coastguard Worker   } else {
63*15dc779aSAndroid Build Coastguard Worker     if (pstr_space_tree->frame_count % 2) {
64*15dc779aSAndroid Build Coastguard Worker       for (band = 0; band < pstr_space_tree->num_param_bands; band++) {
65*15dc779aSAndroid Build Coastguard Worker         pstr_spatial_frame->ott_data.icc[0][0][band] = pstr_space_tree->icc_prev[0][band];
66*15dc779aSAndroid Build Coastguard Worker         pstr_space_tree->cld_prev[0][band] = pstr_spatial_frame->ott_data.cld[0][0][band];
67*15dc779aSAndroid Build Coastguard Worker       }
68*15dc779aSAndroid Build Coastguard Worker     } else {
69*15dc779aSAndroid Build Coastguard Worker       for (band = 0; band < pstr_space_tree->num_param_bands; band++) {
70*15dc779aSAndroid Build Coastguard Worker         pstr_space_tree->icc_prev[0][band] = pstr_spatial_frame->ott_data.icc[0][0][band];
71*15dc779aSAndroid Build Coastguard Worker         pstr_spatial_frame->ott_data.cld[0][0][band] = pstr_space_tree->cld_prev[0][band];
72*15dc779aSAndroid Build Coastguard Worker       }
73*15dc779aSAndroid Build Coastguard Worker     }
74*15dc779aSAndroid Build Coastguard Worker   }
75*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->frame_count++;
76*15dc779aSAndroid Build Coastguard Worker   if (pstr_space_tree->frame_count == MAX_KEEP_FRAMECOUNT) {
77*15dc779aSAndroid Build Coastguard Worker     pstr_space_tree->frame_count = 0;
78*15dc779aSAndroid Build Coastguard Worker   }
79*15dc779aSAndroid Build Coastguard Worker }
80*15dc779aSAndroid Build Coastguard Worker 
81*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE
ixheaace_mps_212_space_tree_init(ixheaace_mps_pstr_space_tree pstr_space_tree,const ixheaace_mps_space_tree_setup * const pstr_space_tree_setup,UWORD8 * ptr_parameter_band_2_hybrid_band_offset,const WORD32 frame_keep_flag,WORD32 aot)82*15dc779aSAndroid Build Coastguard Worker ixheaace_mps_212_space_tree_init(ixheaace_mps_pstr_space_tree pstr_space_tree,
83*15dc779aSAndroid Build Coastguard Worker                                  const ixheaace_mps_space_tree_setup *const pstr_space_tree_setup,
84*15dc779aSAndroid Build Coastguard Worker                                  UWORD8 *ptr_parameter_band_2_hybrid_band_offset,
85*15dc779aSAndroid Build Coastguard Worker                                  const WORD32 frame_keep_flag, WORD32 aot) {
86*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE error = IA_NO_ERROR;
87*15dc779aSAndroid Build Coastguard Worker   WORD32 box = 0;
88*15dc779aSAndroid Build Coastguard Worker 
89*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->frame_count = 0;
90*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->frame_keep_flag = frame_keep_flag;
91*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->num_param_bands = pstr_space_tree_setup->num_param_bands;
92*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->use_coarse_quant_tto_icc_flag =
93*15dc779aSAndroid Build Coastguard Worker       pstr_space_tree_setup->use_coarse_quant_tto_icc_flag;
94*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->use_coarse_quant_tto_cld_flag =
95*15dc779aSAndroid Build Coastguard Worker       pstr_space_tree_setup->use_coarse_quant_tto_cld_flag;
96*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->quant_mode = pstr_space_tree_setup->quant_mode;
97*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->num_channels_in_max = pstr_space_tree_setup->num_channels_in_max;
98*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->num_hybrid_bands_max = pstr_space_tree_setup->num_hybrid_bands_max;
99*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->descr.num_ott_boxes = 1;
100*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->descr.num_in_channels = 1;
101*15dc779aSAndroid Build Coastguard Worker   pstr_space_tree->descr.num_out_channels = 2;
102*15dc779aSAndroid Build Coastguard Worker 
103*15dc779aSAndroid Build Coastguard Worker   if (pstr_space_tree->descr.num_ott_boxes > IXHEAACE_MPS_MAX_NUM_BOXES) {
104*15dc779aSAndroid Build Coastguard Worker     return IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED;
105*15dc779aSAndroid Build Coastguard Worker   }
106*15dc779aSAndroid Build Coastguard Worker 
107*15dc779aSAndroid Build Coastguard Worker   for (box = 0; box < pstr_space_tree->descr.num_ott_boxes; box++) {
108*15dc779aSAndroid Build Coastguard Worker     ixheaace_mps_tto_box_config box_config;
109*15dc779aSAndroid Build Coastguard Worker     box_config.b_use_coherence_icc_only = 0;
110*15dc779aSAndroid Build Coastguard Worker     box_config.subband_config = pstr_space_tree->num_param_bands;
111*15dc779aSAndroid Build Coastguard Worker     box_config.use_coarse_quant_cld_flag = pstr_space_tree->use_coarse_quant_tto_cld_flag;
112*15dc779aSAndroid Build Coastguard Worker     box_config.use_coarse_quant_icc_flag = pstr_space_tree->use_coarse_quant_tto_icc_flag;
113*15dc779aSAndroid Build Coastguard Worker     box_config.box_quant_mode = pstr_space_tree->quant_mode;
114*15dc779aSAndroid Build Coastguard Worker     box_config.num_hybrid_bands_max = pstr_space_tree->num_hybrid_bands_max;
115*15dc779aSAndroid Build Coastguard Worker     box_config.frame_keep_flag = pstr_space_tree->frame_keep_flag;
116*15dc779aSAndroid Build Coastguard Worker 
117*15dc779aSAndroid Build Coastguard Worker     error = ixheaace_mps_212_init_tto_box(pstr_space_tree->pstr_tto_box[box], &box_config,
118*15dc779aSAndroid Build Coastguard Worker                                           ptr_parameter_band_2_hybrid_band_offset, aot);
119*15dc779aSAndroid Build Coastguard Worker     if (error) {
120*15dc779aSAndroid Build Coastguard Worker       return error;
121*15dc779aSAndroid Build Coastguard Worker     }
122*15dc779aSAndroid Build Coastguard Worker   }
123*15dc779aSAndroid Build Coastguard Worker 
124*15dc779aSAndroid Build Coastguard Worker   return error;
125*15dc779aSAndroid Build Coastguard Worker }
126*15dc779aSAndroid Build Coastguard Worker 
ixheaace_mps_212_space_tree_apply(ixheaace_mps_pstr_space_tree pstr_space_tree,const WORD32 param_set,const WORD32 num_channels_in,const WORD32 num_time_slots,const WORD32 start_time_slot,const WORD32 num_hybrid_bands,FLOAT32 * p_frame_window_ana_mps,ixheaace_cmplx_str ppp_cmplx_hybrid_1[IXHEAACE_MPS_MAX_INPUT_CHANNELS][MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],ixheaace_cmplx_str ppp_cmplx_hybrid_2[IXHEAACE_MPS_MAX_INPUT_CHANNELS][MAX_ANA_TIME_SLOT][MAX_QMF_BANDS],ixheaace_mps_spatial_frame * const pstr_spatial_frame,const WORD32 avoid_keep)127*15dc779aSAndroid Build Coastguard Worker IA_ERRORCODE ixheaace_mps_212_space_tree_apply(
128*15dc779aSAndroid Build Coastguard Worker     ixheaace_mps_pstr_space_tree pstr_space_tree, const WORD32 param_set,
129*15dc779aSAndroid Build Coastguard Worker     const WORD32 num_channels_in, const WORD32 num_time_slots, const WORD32 start_time_slot,
130*15dc779aSAndroid Build Coastguard Worker     const WORD32 num_hybrid_bands, FLOAT32 *p_frame_window_ana_mps,
131*15dc779aSAndroid Build Coastguard Worker     ixheaace_cmplx_str ppp_cmplx_hybrid_1[IXHEAACE_MPS_MAX_INPUT_CHANNELS][MAX_ANA_TIME_SLOT]
132*15dc779aSAndroid Build Coastguard Worker                                          [MAX_QMF_BANDS],
133*15dc779aSAndroid Build Coastguard Worker     ixheaace_cmplx_str ppp_cmplx_hybrid_2[IXHEAACE_MPS_MAX_INPUT_CHANNELS][MAX_ANA_TIME_SLOT]
134*15dc779aSAndroid Build Coastguard Worker                                          [MAX_QMF_BANDS],
135*15dc779aSAndroid Build Coastguard Worker     ixheaace_mps_spatial_frame *const pstr_spatial_frame, const WORD32 avoid_keep) {
136*15dc779aSAndroid Build Coastguard Worker   IA_ERRORCODE error = IA_NO_ERROR;
137*15dc779aSAndroid Build Coastguard Worker   WORD32 box;
138*15dc779aSAndroid Build Coastguard Worker   const ixheaace_mps_tree_setup *pstr_tree_setup = NULL;
139*15dc779aSAndroid Build Coastguard Worker   pstr_tree_setup = &tree_setup_table;
140*15dc779aSAndroid Build Coastguard Worker 
141*15dc779aSAndroid Build Coastguard Worker   if ((num_channels_in != pstr_tree_setup->num_channels_in) ||
142*15dc779aSAndroid Build Coastguard Worker       (num_channels_in > pstr_space_tree->num_channels_in_max) ||
143*15dc779aSAndroid Build Coastguard Worker       (num_hybrid_bands > pstr_space_tree->num_hybrid_bands_max)) {
144*15dc779aSAndroid Build Coastguard Worker     return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
145*15dc779aSAndroid Build Coastguard Worker   }
146*15dc779aSAndroid Build Coastguard Worker 
147*15dc779aSAndroid Build Coastguard Worker   for (box = 0; box < pstr_tree_setup->n_tto_boxes; box++) {
148*15dc779aSAndroid Build Coastguard Worker     const ixheaace_mps_tto_descriptor *pstr_tto_descriptor =
149*15dc779aSAndroid Build Coastguard Worker         &pstr_tree_setup->tto_descriptor[box];
150*15dc779aSAndroid Build Coastguard Worker     WORD32 i;
151*15dc779aSAndroid Build Coastguard Worker     WORD32 in_ch[2], out_ch[2], win[2];
152*15dc779aSAndroid Build Coastguard Worker 
153*15dc779aSAndroid Build Coastguard Worker     in_ch[0] = pstr_tto_descriptor->in_ch1;
154*15dc779aSAndroid Build Coastguard Worker     in_ch[1] = pstr_tto_descriptor->in_ch2;
155*15dc779aSAndroid Build Coastguard Worker     out_ch[0] = pstr_tto_descriptor->in_ch3;
156*15dc779aSAndroid Build Coastguard Worker     out_ch[1] = pstr_tto_descriptor->in_ch4;
157*15dc779aSAndroid Build Coastguard Worker     win[0] = pstr_tto_descriptor->w_ch1;
158*15dc779aSAndroid Build Coastguard Worker     win[1] = pstr_tto_descriptor->w_ch2;
159*15dc779aSAndroid Build Coastguard Worker 
160*15dc779aSAndroid Build Coastguard Worker     for (i = 0; i < 2; i++) {
161*15dc779aSAndroid Build Coastguard Worker       if (win[i] == WIN_ACTIV) {
162*15dc779aSAndroid Build Coastguard Worker         ixheaace_mps_212_analysis_windowing(num_time_slots, start_time_slot,
163*15dc779aSAndroid Build Coastguard Worker                                             p_frame_window_ana_mps, ppp_cmplx_hybrid_1[in_ch[i]],
164*15dc779aSAndroid Build Coastguard Worker                                             ppp_cmplx_hybrid_2[out_ch[i]], num_hybrid_bands);
165*15dc779aSAndroid Build Coastguard Worker       }
166*15dc779aSAndroid Build Coastguard Worker     }
167*15dc779aSAndroid Build Coastguard Worker 
168*15dc779aSAndroid Build Coastguard Worker     error = ixheaace_mps_212_apply_tto_box(
169*15dc779aSAndroid Build Coastguard Worker         pstr_space_tree->pstr_tto_box[pstr_tto_descriptor->box_id], num_time_slots,
170*15dc779aSAndroid Build Coastguard Worker         start_time_slot, num_hybrid_bands, ppp_cmplx_hybrid_2[pstr_tto_descriptor->in_ch3],
171*15dc779aSAndroid Build Coastguard Worker         ppp_cmplx_hybrid_2[pstr_tto_descriptor->in_ch4],
172*15dc779aSAndroid Build Coastguard Worker         pstr_spatial_frame->ott_data.icc[pstr_tto_descriptor->box_id][param_set],
173*15dc779aSAndroid Build Coastguard Worker         &(pstr_spatial_frame->icc_lossless_data
174*15dc779aSAndroid Build Coastguard Worker               .bs_quant_coarse_xxx[pstr_tto_descriptor->box_id][param_set]),
175*15dc779aSAndroid Build Coastguard Worker         pstr_spatial_frame->ott_data.cld[pstr_tto_descriptor->box_id][param_set],
176*15dc779aSAndroid Build Coastguard Worker         &(pstr_spatial_frame->cld_lossless_data
177*15dc779aSAndroid Build Coastguard Worker               .bs_quant_coarse_xxx[pstr_tto_descriptor->box_id][param_set]),
178*15dc779aSAndroid Build Coastguard Worker         pstr_spatial_frame->b_use_bb_cues);
179*15dc779aSAndroid Build Coastguard Worker     if (error) {
180*15dc779aSAndroid Build Coastguard Worker       return error;
181*15dc779aSAndroid Build Coastguard Worker     }
182*15dc779aSAndroid Build Coastguard Worker   }
183*15dc779aSAndroid Build Coastguard Worker 
184*15dc779aSAndroid Build Coastguard Worker   if (pstr_space_tree->frame_keep_flag == 1) {
185*15dc779aSAndroid Build Coastguard Worker     ixheaace_mps_212_space_tree_frame_keep_212(pstr_space_tree, pstr_spatial_frame, avoid_keep);
186*15dc779aSAndroid Build Coastguard Worker   }
187*15dc779aSAndroid Build Coastguard Worker   return error;
188*15dc779aSAndroid Build Coastguard Worker }
189