/src/libxaac/encoder/iusace_arith_enc.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 <string.h> |
22 | | #include <math.h> |
23 | | #include <stdlib.h> |
24 | | #include "ixheaac_type_def.h" |
25 | | #include "ixheaace_adjust_threshold_data.h" |
26 | | #include "iusace_bitbuffer.h" |
27 | | #include "ixheaace_mps_common_define.h" |
28 | | |
29 | | /* DRC */ |
30 | | #include "impd_drc_common_enc.h" |
31 | | #include "impd_drc_uni_drc.h" |
32 | | #include "impd_drc_tables.h" |
33 | | #include "impd_drc_api.h" |
34 | | #include "impd_drc_uni_drc_eq.h" |
35 | | #include "impd_drc_uni_drc_filter_bank.h" |
36 | | #include "impd_drc_gain_enc.h" |
37 | | #include "impd_drc_struct_def.h" |
38 | | |
39 | | #include "iusace_cnst.h" |
40 | | #include "iusace_tns_usac.h" |
41 | | #include "iusace_psy_mod.h" |
42 | | #include "iusace_config.h" |
43 | | #include "iusace_arith_enc.h" |
44 | | #include "iusace_block_switch_const.h" |
45 | | #include "iusace_rom.h" |
46 | | |
47 | 189M | #define ARITH_ESCAPE (16) |
48 | | |
49 | | static VOID iusace_arith_map_context(WORD32 pres_n, WORD32 prev_n, WORD32 *ptr_c_prev, |
50 | 1.09M | WORD32 *ptr_c_pres, WORD32 arith_reset_flag) { |
51 | 1.09M | WORD32 i, k; |
52 | 1.09M | FLOAT32 ratio; |
53 | 1.09M | WORD32 c_prev[516]; |
54 | 1.09M | WORD32 c_pres[516]; |
55 | | |
56 | 1.09M | if (arith_reset_flag) { |
57 | 732k | memset(ptr_c_pres, 0, 516 * sizeof(WORD32)); |
58 | 732k | memset(ptr_c_prev, 0, 516 * sizeof(WORD32)); |
59 | 732k | } else { |
60 | 357k | memcpy(&c_prev[2], &ptr_c_prev[2], (prev_n / 2 + 2) * sizeof(WORD32)); |
61 | 357k | memcpy(&c_pres[2], &ptr_c_pres[2], (prev_n / 2 + 2) * sizeof(WORD32)); |
62 | | |
63 | 357k | ratio = (FLOAT32)(prev_n) / (FLOAT32)(pres_n); |
64 | 122M | for (i = 0; i < (pres_n / 2); i++) { |
65 | 121M | k = (WORD32)((FLOAT32)(i)*ratio); |
66 | 121M | ptr_c_pres[2 + i] = c_pres[2 + k]; |
67 | 121M | ptr_c_prev[2 + i] = c_prev[2 + k]; |
68 | 121M | } |
69 | | |
70 | 357k | ptr_c_pres[(pres_n / 2) + 2] = c_pres[(prev_n / 2) + 2]; |
71 | 357k | ptr_c_pres[(pres_n / 2) + 3] = c_pres[(prev_n / 2) + 3]; |
72 | 357k | ptr_c_prev[(pres_n / 2) + 2] = c_prev[(prev_n / 2) + 2]; |
73 | 357k | ptr_c_prev[(pres_n / 2) + 3] = c_prev[(prev_n / 2) + 3]; |
74 | 357k | } |
75 | 1.09M | return; |
76 | 1.09M | } |
77 | | |
78 | 482M | static WORD32 iusace_arith_get_state(WORD32 *c_pres, WORD32 *c_prev, WORD32 *s, WORD32 idx) { |
79 | 482M | WORD32 s_tmp = *s; |
80 | | |
81 | 482M | s_tmp = s_tmp >> 4; |
82 | 482M | s_tmp = s_tmp + (c_prev[idx + 1] << 12); |
83 | 482M | s_tmp = (s_tmp & 0xFFF0) + c_pres[idx - 1]; |
84 | | |
85 | 482M | *s = s_tmp; |
86 | | |
87 | 482M | if (idx > 3) { |
88 | 462M | if ((c_pres[idx - 1] + c_pres[idx - 2] + c_pres[idx - 3]) < 5) { |
89 | 251M | return (s_tmp + 0x10000); |
90 | 251M | } |
91 | 462M | } |
92 | | |
93 | 231M | return (s_tmp); |
94 | 482M | } |
95 | | |
96 | 672M | static UWORD16 iusace_arith_get_pk(WORD32 c) { |
97 | 672M | WORD32 j; |
98 | 672M | WORD32 i, i_min, i_max; |
99 | | |
100 | 672M | i_min = -1; |
101 | 672M | i_max = (sizeof(iusace_ari_lookup_m) / sizeof(iusace_ari_lookup_m[0])) - 1; |
102 | 6.68G | while ((i_max - i_min) > 1) { |
103 | 6.26G | i = i_min + ((i_max - i_min) / 2); |
104 | 6.26G | j = iusace_ari_hash_m[i]; |
105 | 6.26G | if (c < j) |
106 | 2.71G | i_max = i; |
107 | 3.55G | else if (c > j) |
108 | 3.29G | i_min = i; |
109 | 256M | else |
110 | 256M | return (iusace_ari_hash_m_lsb[i]); |
111 | 6.26G | } |
112 | | |
113 | 415M | return (iusace_ari_lookup_m[i_max]); |
114 | 672M | } |
115 | | |
116 | | static VOID iusace_copy_bit_buf(ia_bit_buf_struct *it_bit_buff_dest, |
117 | 8.24M | ia_bit_buf_struct *it_bit_buff_src) { |
118 | 8.24M | if (it_bit_buff_src != NULL && it_bit_buff_dest != NULL) { |
119 | 3.88M | it_bit_buff_dest->cnt_bits = it_bit_buff_src->cnt_bits; |
120 | 3.88M | it_bit_buff_dest->ptr_write_next = it_bit_buff_src->ptr_write_next; |
121 | 3.88M | it_bit_buff_dest->write_position = it_bit_buff_src->write_position; |
122 | 3.88M | } |
123 | 8.24M | return; |
124 | 8.24M | } |
125 | | |
126 | | static WORD32 iusace_arith_encode_level2(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, |
127 | | WORD32 *ptr_c_pres, WORD32 *ptr_c_prev, WORD32 *quant, |
128 | 5.49M | WORD32 n, WORD32 nt, WORD32 use_stop) { |
129 | 5.49M | WORD32 qs[32]; |
130 | 5.49M | iusace_state_arith as, as_stop; |
131 | | |
132 | 5.49M | WORD32 a, b, a1, b1, m; |
133 | 5.49M | WORD32 s, t, i, l, lev, esc_nb; |
134 | 5.49M | UWORD16 pki; |
135 | 5.49M | WORD32 bp_start = bp; |
136 | 5.49M | WORD32 bp_stop = bp; |
137 | 5.49M | WORD32 stop = 0; |
138 | 5.49M | WORD32 sopt; |
139 | 5.49M | WORD32 a2, b2; |
140 | 5.49M | ia_bit_buf_struct it_bit_buff_temp; |
141 | 5.49M | memset(&it_bit_buff_temp, 0, sizeof(it_bit_buff_temp)); |
142 | 5.49M | iusace_copy_bit_buf(&it_bit_buff_temp, pstr_it_bit_buff); |
143 | | |
144 | 5.49M | as.low = 0; |
145 | 5.49M | as.high = 65535; |
146 | 5.49M | as.value = 0; |
147 | | |
148 | 5.49M | sopt = ptr_c_prev[0] << 12; |
149 | | |
150 | 484M | for (i = 0; i < n; i++) { |
151 | 480M | if ((use_stop == 1 || use_stop == 2) && (stop == 0)) { |
152 | 194M | WORD32 j; |
153 | | |
154 | 194M | stop = 1; |
155 | 6.28G | for (j = i; j < n; j++) { |
156 | 6.28G | if (quant[2 * j] != 0 || quant[2 * j + 1] != 0) { |
157 | 190M | stop = 0; |
158 | 190M | break; |
159 | 190M | } |
160 | 6.28G | } |
161 | | |
162 | 194M | if (stop) { |
163 | 3.48M | s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); |
164 | 3.48M | t = s & 0xFFFFF; |
165 | | |
166 | 3.48M | pki = iusace_arith_get_pk(t); |
167 | | |
168 | 3.48M | if (use_stop == 1) { |
169 | 1.44M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
170 | 1.44M | pki = iusace_arith_get_pk(t + (1 << 17)); |
171 | 1.44M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, 0, iusace_ari_cf_m[pki]); |
172 | | |
173 | 1.44M | break; |
174 | 2.04M | } else { |
175 | 2.04M | bp_stop = bp; |
176 | 2.04M | as_stop.low = as.low; |
177 | 2.04M | as_stop.high = as.high; |
178 | 2.04M | as_stop.value = as.value; |
179 | | |
180 | 2.04M | bp_stop = |
181 | 2.04M | iusace_arith_encode(NULL, bp_stop, &as_stop, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
182 | | |
183 | 2.04M | pki = iusace_arith_get_pk(t + (1 << 17)); |
184 | 2.04M | bp_stop = iusace_arith_encode(NULL, bp_stop, &as_stop, (0), iusace_ari_cf_m[pki]); |
185 | 2.04M | } |
186 | 3.48M | } |
187 | 194M | } |
188 | 478M | s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); |
189 | 478M | t = s & 0xFFFFF; |
190 | | |
191 | 478M | a = quant[2 * i]; |
192 | 478M | b = quant[2 * i + 1]; |
193 | 478M | a1 = abs(a); |
194 | 478M | b1 = abs(b); |
195 | | |
196 | 478M | ptr_c_pres[i] = a1 + b1 + 1; |
197 | 478M | if (ptr_c_pres[i] > 0xF) { |
198 | 38.6M | ptr_c_pres[i] = 0xF; |
199 | 38.6M | } |
200 | | |
201 | 478M | lev = 0; |
202 | 478M | esc_nb = 0; |
203 | | |
204 | 665M | while ((a1) > 3 || (b1) > 3) { |
205 | 186M | pki = iusace_arith_get_pk(t + (esc_nb << 17)); |
206 | | |
207 | 186M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
208 | | |
209 | 186M | qs[lev++] = (a1 & 1) | ((b1 & 1) << 1); |
210 | 186M | a1 >>= 1; |
211 | 186M | b1 >>= 1; |
212 | 186M | esc_nb++; |
213 | | |
214 | 186M | if (esc_nb > 7) { |
215 | 3.55M | esc_nb = 7; |
216 | 3.55M | } |
217 | 186M | } |
218 | 478M | m = a1 + (b1 << 2); |
219 | 478M | pki = iusace_arith_get_pk(t + (esc_nb << 17)); |
220 | 478M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, m, iusace_ari_cf_m[pki]); |
221 | | |
222 | 478M | a2 = a1; |
223 | 478M | b2 = b1; |
224 | | |
225 | 665M | for (l = lev - 1; l >= 0; l--) { |
226 | 186M | WORD32 lsbidx = (a2 == 0) ? 1 : ((b2 == 0) ? 0 : 2); |
227 | 186M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, qs[l], iusace_ari_cf_r[lsbidx]); |
228 | | |
229 | 186M | a2 = (a2 << 1) | (qs[l] & 1); |
230 | 186M | b2 = (b2 << 1) | ((qs[l] >> 1) & 1); |
231 | 186M | } |
232 | 478M | } |
233 | | |
234 | 5.49M | if (use_stop == 2) { |
235 | 2.74M | bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); |
236 | 2.74M | if (stop) { |
237 | 2.04M | bp_stop = iusace_arith_done(NULL, bp_stop, &as_stop); |
238 | | |
239 | 2.04M | if (bp_stop < bp) { |
240 | 1.44M | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
241 | 1.44M | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
242 | 1.44M | n, nt, 1); |
243 | 1.44M | } else { |
244 | 596k | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
245 | 596k | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
246 | 596k | n, nt, 0); |
247 | 596k | } |
248 | 2.04M | } else { |
249 | 708k | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
250 | 708k | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
251 | 708k | n, nt, 0); |
252 | 708k | } |
253 | 2.74M | } else { |
254 | 2.74M | bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); |
255 | | |
256 | 183M | for (; i < nt; i++) { |
257 | 180M | ptr_c_pres[i] = 1; |
258 | 180M | } |
259 | | |
260 | 301M | for (i = 0; i < n; i++) { |
261 | 299M | if (quant[2 * i] != 0) { |
262 | 94.6M | if (quant[2 * i] > 0) { |
263 | 47.5M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
264 | 47.5M | bp++; |
265 | 47.5M | } else { |
266 | 47.0M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
267 | 47.0M | bp++; |
268 | 47.0M | } |
269 | 94.6M | } |
270 | | |
271 | 299M | if (quant[2 * i + 1] != 0) { |
272 | 94.1M | if (quant[2 * i + 1] > 0) { |
273 | 47.1M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
274 | 47.1M | bp++; |
275 | 47.1M | } else { |
276 | 46.9M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
277 | 46.9M | bp++; |
278 | 46.9M | } |
279 | 94.1M | } |
280 | 299M | } |
281 | | |
282 | 363M | for (i = 0; i < nt; i++) { |
283 | 360M | ptr_c_prev[i] = ptr_c_pres[i]; |
284 | 360M | ptr_c_pres[i] = 1; |
285 | 360M | } |
286 | 2.74M | } |
287 | | |
288 | 5.49M | return bp; |
289 | 5.49M | } |
290 | | |
291 | | WORD32 iusace_arith_enc_spec(ia_bit_buf_struct *it_bit_buf, WORD32 window_sequence, |
292 | | WORD32 *ptr_x_ac_enc, WORD32 max_spec_coefficients, |
293 | | WORD32 *ptr_c_pres, WORD32 *ptr_c_prev, WORD32 *ptr_size_prev, |
294 | 732k | WORD32 arith_reset_flag, WORD32 ccfl) { |
295 | 732k | LOOPIDX i; |
296 | 732k | WORD32 write_flag = (it_bit_buf != NULL); |
297 | 732k | WORD32 size; |
298 | 732k | WORD32 num_wins = (window_sequence == EIGHT_SHORT_SEQUENCE) ? MAX_SHORT_WINDOWS : 1; |
299 | 732k | WORD32 bits_data_written = 0; |
300 | | |
301 | 732k | switch (window_sequence) { |
302 | 310k | case ONLY_LONG_SEQUENCE: |
303 | 392k | case LONG_START_SEQUENCE: |
304 | 393k | case STOP_START_SEQUENCE: |
305 | 466k | case LONG_STOP_SEQUENCE: |
306 | 466k | size = ccfl; |
307 | 466k | break; |
308 | 266k | case EIGHT_SHORT_SEQUENCE: |
309 | 266k | size = ccfl >> 3; |
310 | 266k | break; |
311 | 0 | default: |
312 | 0 | size = ccfl >> 3; |
313 | 0 | break; |
314 | 732k | } |
315 | | |
316 | 732k | iusace_arith_map_context(size, *ptr_size_prev, ptr_c_pres, ptr_c_prev, arith_reset_flag); |
317 | | |
318 | 732k | if (max_spec_coefficients > 0) { |
319 | 3.27M | for (i = 0; i < num_wins; i++) { |
320 | 2.57M | bits_data_written = iusace_arith_encode_level2( |
321 | 2.57M | it_bit_buf, bits_data_written, ptr_c_pres + 2, ptr_c_prev + 2, &ptr_x_ac_enc[i * size], |
322 | 2.57M | max_spec_coefficients / 2, size / 2, 2); |
323 | 2.57M | } |
324 | 702k | } |
325 | | |
326 | 732k | if (write_flag) { |
327 | 334k | *ptr_size_prev = size; |
328 | 334k | } |
329 | | |
330 | 732k | return bits_data_written; |
331 | 732k | } |
332 | | |
333 | | WORD32 iusace_tcx_coding(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 tcx_size, |
334 | 178k | WORD32 max_tcx_size, WORD32 *ptr_quant, WORD32 *c_pres, WORD32 *c_prev) { |
335 | 178k | WORD32 bits_written = 0; |
336 | | |
337 | 178k | iusace_arith_map_context(tcx_size, max_tcx_size, c_pres, c_prev, 0); |
338 | | |
339 | 178k | bits_written = |
340 | 178k | iusace_arith_encode_level2(pstr_it_bit_buff, bits_written, c_pres + 2, c_prev + 2, |
341 | 178k | &ptr_quant[0], tcx_size / 2, tcx_size / 2, 2); |
342 | | |
343 | 178k | iusace_arith_map_context(max_tcx_size, tcx_size, c_pres, c_prev, 0); |
344 | | |
345 | 178k | return bits_written; |
346 | 178k | } |
347 | | |
348 | 7.53M | WORD32 iusace_arith_done(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s) { |
349 | 7.53M | WORD32 low, high; |
350 | 7.53M | WORD32 bits_to_follow; |
351 | | |
352 | 7.53M | low = s->low; |
353 | 7.53M | high = s->high; |
354 | 7.53M | bits_to_follow = s->value + 1; |
355 | | |
356 | 7.53M | if (low < 16384) { |
357 | 5.04M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
358 | 5.04M | bp++; |
359 | 13.2M | while (bits_to_follow) { |
360 | 8.23M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
361 | 8.23M | bp++; |
362 | 8.23M | bits_to_follow--; |
363 | 8.23M | } |
364 | 5.04M | } else { |
365 | 2.48M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
366 | 2.48M | bp++; |
367 | 6.60M | while (bits_to_follow) { |
368 | 4.11M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
369 | 4.11M | bp++; |
370 | 4.11M | bits_to_follow--; |
371 | 4.11M | } |
372 | 2.48M | } |
373 | | |
374 | 7.53M | s->low = low; |
375 | 7.53M | s->high = high; |
376 | 7.53M | s->value = bits_to_follow; |
377 | | |
378 | 7.53M | return bp; |
379 | 7.53M | } |
380 | | |
381 | | WORD32 iusace_arith_encode(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s, |
382 | 858M | WORD32 symbol, UWORD16 const *cum_freq) { |
383 | 858M | WORD32 low, high, range; |
384 | 858M | WORD32 bits_to_follow; |
385 | | |
386 | 858M | high = s->high; |
387 | 858M | low = s->low; |
388 | 858M | range = high - low + 1; |
389 | | |
390 | 858M | if (symbol > 0) { |
391 | 532M | high = low + ((range * cum_freq[symbol - 1]) >> 14) - 1; |
392 | 532M | } |
393 | | |
394 | 858M | low = low + ((range * cum_freq[symbol]) >> 14); |
395 | | |
396 | 858M | bits_to_follow = s->value; |
397 | | |
398 | 2.45G | for (;;) { |
399 | 2.45G | if (high < 32768) { |
400 | 610M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
401 | 610M | bp++; |
402 | 859M | while (bits_to_follow) { |
403 | 249M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
404 | 249M | bp++; |
405 | 249M | bits_to_follow--; |
406 | 249M | } |
407 | 1.84G | } else if (low >= 32768) { |
408 | 557M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
409 | 557M | bp++; |
410 | 733M | while (bits_to_follow) { |
411 | 176M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
412 | 176M | bp++; |
413 | 176M | bits_to_follow--; |
414 | 176M | } |
415 | 557M | low -= 32768; |
416 | 557M | high -= 32768; |
417 | 1.28G | } else if (low >= 16384 && high < 49152) { |
418 | 428M | bits_to_follow += 1; |
419 | 428M | low -= 16384; |
420 | 428M | high -= 16384; |
421 | 428M | } else |
422 | 858M | break; |
423 | | |
424 | 1.59G | low += low; |
425 | 1.59G | high += high + 1; |
426 | 1.59G | } |
427 | | |
428 | 858M | s->low = low; |
429 | 858M | s->high = high; |
430 | 858M | s->value = bits_to_follow; |
431 | | |
432 | 858M | return bp; |
433 | 858M | } |