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 "string.h" 21 #include "ixheaacd_sbr_common.h" 22 #include <ixheaacd_type_def.h> 23 24 #include "ixheaacd_constants.h" 25 #include <ixheaacd_basic_ops32.h> 26 #include <ixheaacd_basic_ops16.h> 27 #include <ixheaacd_basic_ops40.h> 28 #include "ixheaacd_basic_ops.h" 29 30 #include <ixheaacd_basic_op.h> 31 #include "ixheaacd_intrinsics.h" 32 #include "ixheaacd_bitbuffer.h" 33 #include "ixheaacd_sbrdecsettings.h" 34 #include "ixheaacd_sbr_scale.h" 35 #include "ixheaacd_lpp_tran.h" 36 #include "ixheaacd_env_extr_part.h" 37 #include <ixheaacd_sbr_rom.h> 38 39 #include "ixheaacd_hybrid.h" 40 #include "ixheaacd_ps_dec.h" 41 42 #include "ixheaacd_env_extr.h" 43 #include "ixheaacd_ps_bitdec.h" 44 45 const WORD16 ixheaacd_num_bands[3] = {10, 20, 34}; 46 47 static WORD32 ixheaacd_clamp(WORD32 i, WORD16 min, WORD16 max) { 48 WORD32 result = i; 49 50 if (i < min) { 51 result = min; 52 } else { 53 if (i > max) { 54 result = max; 55 } 56 } 57 58 return result; 59 } 60 61 WORD16 ixheaacd_divideby2(WORD op) { 62 FLAG sign = (op < 0); 63 64 if (sign) { 65 op = -(op); 66 } 67 68 op = (op >> 1); 69 70 if (sign) { 71 op = -op; 72 } 73 74 return (WORD16)op; 75 } 76 77 WORD16 ixheaacd_divideby3(WORD op) { 78 WORD16 temp, ret; 79 FLAG sign = (op < 0); 80 81 if (sign) { 82 op = -(op); 83 } 84 85 temp = (WORD16)(op << 2); 86 87 temp = ixheaacd_mult16_shl(temp, 0x2aab); 88 89 ret = (temp >> 2); 90 91 if (sign) { 92 ret = -(ret); 93 } 94 95 return (WORD16)ret; 96 } 97 98 VOID ixheaacd_decode_ps_data(ia_ps_dec_struct *ptr_ps_dec) { 99 WORD e, i, temp; 100 WORD16 iid_mode = (WORD16)((ptr_ps_dec->iid_mode) ? 1 : 2); 101 WORD16 icc_mode = (WORD16)((ptr_ps_dec->icc_mode) ? 1 : 2); 102 WORD16 num_iid_levels = 103 (WORD16)(ptr_ps_dec->iid_quant ? NUM_IID_LEVELS_FINE : NUM_IID_LEVELS); 104 105 if (!ptr_ps_dec->ps_data_present) { 106 ptr_ps_dec->num_env = 0; 107 } 108 109 for (e = 0; e < ptr_ps_dec->num_env; e++) { 110 WORD16 *p_iid_par_prev; 111 WORD16 *p_icc_par_prev; 112 113 if (e == 0) { 114 p_iid_par_prev = ptr_ps_dec->iid_par_prev; 115 p_icc_par_prev = ptr_ps_dec->icc_par_prev; 116 } else { 117 p_iid_par_prev = ptr_ps_dec->iid_par_table[e - 1]; 118 p_icc_par_prev = ptr_ps_dec->icc_par_table[e - 1]; 119 } 120 121 if (ptr_ps_dec->enable_iid) { 122 if (ptr_ps_dec->iid_dt[e]) { 123 for (i = 0; i < ixheaacd_num_bands[ptr_ps_dec->iid_mode]; i++) { 124 temp = 125 ixheaacd_add16(*p_iid_par_prev, ptr_ps_dec->iid_par_table[e][i]); 126 ptr_ps_dec->iid_par_table[e][i] = ixheaacd_clamp( 127 temp, ixheaacd_negate16(num_iid_levels), num_iid_levels); 128 p_iid_par_prev += iid_mode; 129 } 130 } else { 131 ptr_ps_dec->iid_par_table[e][0] = 132 ixheaacd_clamp(ptr_ps_dec->iid_par_table[e][0], 133 ixheaacd_negate16(num_iid_levels), num_iid_levels); 134 for (i = 1; i < ixheaacd_num_bands[ptr_ps_dec->iid_mode]; i++) { 135 temp = ixheaacd_add16(ptr_ps_dec->iid_par_table[e][i - 1], 136 ptr_ps_dec->iid_par_table[e][i]); 137 ptr_ps_dec->iid_par_table[e][i] = ixheaacd_clamp( 138 temp, ixheaacd_negate16(num_iid_levels), num_iid_levels); 139 } 140 } 141 } else { 142 memset(ptr_ps_dec->iid_par_table[e], 0, 143 sizeof(WORD16) * ixheaacd_num_bands[ptr_ps_dec->iid_mode]); 144 } 145 146 if (iid_mode == 2) { 147 for (i = (ixheaacd_num_bands[ptr_ps_dec->iid_mode] * iid_mode - 1); 148 i != 0; i--) { 149 ptr_ps_dec->iid_par_table[e][i] = 150 ptr_ps_dec->iid_par_table[e][ixheaacd_shr32(i, 1)]; 151 } 152 } 153 154 if (ptr_ps_dec->enable_icc) { 155 if (ptr_ps_dec->icc_dt[e]) { 156 for (i = 0; i < ixheaacd_num_bands[ptr_ps_dec->icc_mode]; i++) { 157 temp = 158 ixheaacd_add16(*p_icc_par_prev, ptr_ps_dec->icc_par_table[e][i]); 159 ptr_ps_dec->icc_par_table[e][i] = 160 ixheaacd_clamp(temp, 0, (WORD16)(NUM_ICC_LEVELS - 1)); 161 p_icc_par_prev += icc_mode; 162 } 163 } else { 164 ptr_ps_dec->icc_par_table[e][0] = ixheaacd_clamp( 165 ptr_ps_dec->icc_par_table[e][0], 0, (WORD16)(NUM_ICC_LEVELS - 1)); 166 for (i = 1; i < ixheaacd_num_bands[ptr_ps_dec->icc_mode]; i++) { 167 temp = ixheaacd_add16(ptr_ps_dec->icc_par_table[e][i - 1], 168 ptr_ps_dec->icc_par_table[e][i]); 169 ptr_ps_dec->icc_par_table[e][i] = 170 ixheaacd_clamp(temp, 0, (WORD16)(NUM_ICC_LEVELS - 1)); 171 } 172 } 173 } else { 174 memset(ptr_ps_dec->icc_par_table[e], 0, 175 sizeof(WORD16) * ixheaacd_num_bands[ptr_ps_dec->icc_mode]); 176 } 177 178 if (icc_mode == 2) { 179 for (i = (ixheaacd_num_bands[ptr_ps_dec->icc_mode] * icc_mode - 1); 180 i != 0; i--) { 181 ptr_ps_dec->icc_par_table[e][i] = 182 ptr_ps_dec->icc_par_table[e][ixheaacd_shr32(i, 1)]; 183 } 184 } 185 } 186 187 if (ptr_ps_dec->num_env == 0) { 188 ptr_ps_dec->num_env = 1; 189 190 if (ptr_ps_dec->enable_iid) { 191 memcpy(ptr_ps_dec->iid_par_table[0], ptr_ps_dec->iid_par_prev, 192 sizeof(WORD16) * NUM_BANDS_FINE); 193 } else { 194 memset(ptr_ps_dec->iid_par_table[0], 0, sizeof(WORD16) * NUM_BANDS_FINE); 195 } 196 197 if (ptr_ps_dec->enable_icc) { 198 memcpy(ptr_ps_dec->icc_par_table[0], ptr_ps_dec->icc_par_prev, 199 sizeof(WORD16) * NUM_BANDS_FINE); 200 } else { 201 memset(ptr_ps_dec->icc_par_table[0], 0, sizeof(WORD16) * NUM_BANDS_FINE); 202 } 203 } 204 205 memcpy(ptr_ps_dec->iid_par_prev, 206 ptr_ps_dec->iid_par_table[ptr_ps_dec->num_env - 1], 207 sizeof(WORD16) * NUM_BANDS_FINE); 208 209 memcpy(ptr_ps_dec->icc_par_prev, 210 ptr_ps_dec->icc_par_table[ptr_ps_dec->num_env - 1], 211 sizeof(WORD16) * NUM_BANDS_FINE); 212 213 ptr_ps_dec->ps_data_present = 0; 214 215 if (ptr_ps_dec->frame_class == 0) { 216 WORD env_count; 217 WORD16 shift = 0; 218 219 switch (ptr_ps_dec->num_env) { 220 case 1: 221 shift = 0; 222 break; 223 case 2: 224 shift = 1; 225 break; 226 case 4: 227 shift = 2; 228 break; 229 } 230 ptr_ps_dec->border_position[0] = 0; 231 env_count = 0; 232 233 for (e = 1; e < ptr_ps_dec->num_env; e++) { 234 env_count = add_d(env_count, MAX_NUM_COLUMNS); 235 ptr_ps_dec->border_position[e] = (WORD16)(env_count >> shift); 236 } 237 ptr_ps_dec->border_position[ptr_ps_dec->num_env] = MAX_NUM_COLUMNS; 238 } else { 239 ptr_ps_dec->border_position[0] = 0; 240 241 if (ptr_ps_dec->border_position[ptr_ps_dec->num_env] < MAX_NUM_COLUMNS) { 242 ptr_ps_dec->num_env++; 243 add_d(ptr_ps_dec->num_env, 1); 244 ptr_ps_dec->border_position[ptr_ps_dec->num_env] = MAX_NUM_COLUMNS; 245 246 memcpy(ptr_ps_dec->iid_par_table[ptr_ps_dec->num_env - 1], 247 ptr_ps_dec->iid_par_table[ptr_ps_dec->num_env - 2], 248 sizeof(WORD16) * NUM_BANDS_FINE); 249 250 memcpy(ptr_ps_dec->icc_par_table[ptr_ps_dec->num_env - 1], 251 ptr_ps_dec->icc_par_table[ptr_ps_dec->num_env - 2], 252 sizeof(WORD16) * NUM_BANDS_FINE); 253 } 254 255 for (e = 1; e < ptr_ps_dec->num_env; e++) { 256 WORD threshold; 257 threshold = sub_d(MAX_NUM_COLUMNS, sub_d(ptr_ps_dec->num_env, e)); 258 259 if (ptr_ps_dec->border_position[e] > threshold) { 260 ptr_ps_dec->border_position[e] = threshold; 261 } else { 262 threshold = add_d(ptr_ps_dec->border_position[e - 1], 1); 263 264 if (ptr_ps_dec->border_position[e] < threshold) { 265 ptr_ps_dec->border_position[e] = threshold; 266 } 267 } 268 } 269 } 270 271 for (e = 0; e < ptr_ps_dec->num_env; e++) { 272 if (ptr_ps_dec->iid_mode == 2) 273 ixheaacd_map_34_params_to_20(ptr_ps_dec->iid_par_table[e]); 274 275 if (ptr_ps_dec->icc_mode == 2) 276 ixheaacd_map_34_params_to_20(ptr_ps_dec->icc_par_table[e]); 277 } 278 } 279