/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 | 227M | #define ARITH_ESCAPE (16) |
48 | | |
49 | | static VOID iusace_arith_map_context(WORD32 pres_n, WORD32 prev_n, WORD32 *ptr_c_prev, |
50 | 1.36M | WORD32 *ptr_c_pres, WORD32 arith_reset_flag) { |
51 | 1.36M | WORD32 i, k; |
52 | 1.36M | FLOAT32 ratio; |
53 | 1.36M | WORD32 c_prev[516]; |
54 | 1.36M | WORD32 c_pres[516]; |
55 | | |
56 | 1.36M | if (arith_reset_flag) { |
57 | 946k | memset(ptr_c_pres, 0, 516 * sizeof(WORD32)); |
58 | 946k | memset(ptr_c_prev, 0, 516 * sizeof(WORD32)); |
59 | 946k | } else { |
60 | 422k | memcpy(&c_prev[2], &ptr_c_prev[2], (prev_n / 2 + 2) * sizeof(WORD32)); |
61 | 422k | memcpy(&c_pres[2], &ptr_c_pres[2], (prev_n / 2 + 2) * sizeof(WORD32)); |
62 | | |
63 | 422k | ratio = (FLOAT32)(prev_n) / (FLOAT32)(pres_n); |
64 | 145M | for (i = 0; i < (pres_n / 2); i++) { |
65 | 144M | k = (WORD32)((FLOAT32)(i)*ratio); |
66 | 144M | ptr_c_pres[2 + i] = c_pres[2 + k]; |
67 | 144M | ptr_c_prev[2 + i] = c_prev[2 + k]; |
68 | 144M | } |
69 | | |
70 | 422k | ptr_c_pres[(pres_n / 2) + 2] = c_pres[(prev_n / 2) + 2]; |
71 | 422k | ptr_c_pres[(pres_n / 2) + 3] = c_pres[(prev_n / 2) + 3]; |
72 | 422k | ptr_c_prev[(pres_n / 2) + 2] = c_prev[(prev_n / 2) + 2]; |
73 | 422k | ptr_c_prev[(pres_n / 2) + 3] = c_prev[(prev_n / 2) + 3]; |
74 | 422k | } |
75 | 1.36M | return; |
76 | 1.36M | } |
77 | | |
78 | 616M | static WORD32 iusace_arith_get_state(WORD32 *c_pres, WORD32 *c_prev, WORD32 *s, WORD32 idx) { |
79 | 616M | WORD32 s_tmp = *s; |
80 | | |
81 | 616M | s_tmp = s_tmp >> 4; |
82 | 616M | s_tmp = s_tmp + (c_prev[idx + 1] << 12); |
83 | 616M | s_tmp = (s_tmp & 0xFFF0) + c_pres[idx - 1]; |
84 | | |
85 | 616M | *s = s_tmp; |
86 | | |
87 | 616M | if (idx > 3) { |
88 | 590M | if ((c_pres[idx - 1] + c_pres[idx - 2] + c_pres[idx - 3]) < 5) { |
89 | 325M | return (s_tmp + 0x10000); |
90 | 325M | } |
91 | 590M | } |
92 | | |
93 | 290M | return (s_tmp); |
94 | 616M | } |
95 | | |
96 | 844M | static UWORD16 iusace_arith_get_pk(WORD32 c) { |
97 | 844M | WORD32 j; |
98 | 844M | WORD32 i, i_min, i_max; |
99 | | |
100 | 844M | i_min = -1; |
101 | 844M | i_max = (sizeof(iusace_ari_lookup_m) / sizeof(iusace_ari_lookup_m[0])) - 1; |
102 | 8.39G | while ((i_max - i_min) > 1) { |
103 | 7.87G | i = i_min + ((i_max - i_min) / 2); |
104 | 7.87G | j = iusace_ari_hash_m[i]; |
105 | 7.87G | if (c < j) |
106 | 3.40G | i_max = i; |
107 | 4.46G | else if (c > j) |
108 | 4.14G | i_min = i; |
109 | 323M | else |
110 | 323M | return (iusace_ari_hash_m_lsb[i]); |
111 | 7.87G | } |
112 | | |
113 | 520M | return (iusace_ari_lookup_m[i_max]); |
114 | 844M | } |
115 | | |
116 | | static VOID iusace_copy_bit_buf(ia_bit_buf_struct *it_bit_buff_dest, |
117 | 10.4M | ia_bit_buf_struct *it_bit_buff_src) { |
118 | 10.4M | if (it_bit_buff_src != NULL && it_bit_buff_dest != NULL) { |
119 | 4.95M | it_bit_buff_dest->cnt_bits = it_bit_buff_src->cnt_bits; |
120 | 4.95M | it_bit_buff_dest->ptr_write_next = it_bit_buff_src->ptr_write_next; |
121 | 4.95M | it_bit_buff_dest->write_position = it_bit_buff_src->write_position; |
122 | 4.95M | } |
123 | 10.4M | return; |
124 | 10.4M | } |
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 | 6.99M | WORD32 n, WORD32 nt, WORD32 use_stop) { |
129 | 6.99M | WORD32 qs[32]; |
130 | 6.99M | iusace_state_arith as, as_stop; |
131 | | |
132 | 6.99M | WORD32 a, b, a1, b1, m; |
133 | 6.99M | WORD32 s, t, i, l, lev, esc_nb; |
134 | 6.99M | UWORD16 pki; |
135 | 6.99M | WORD32 bp_start = bp; |
136 | 6.99M | WORD32 bp_stop = bp; |
137 | 6.99M | WORD32 stop = 0; |
138 | 6.99M | WORD32 sopt; |
139 | 6.99M | WORD32 a2, b2; |
140 | 6.99M | ia_bit_buf_struct it_bit_buff_temp; |
141 | 6.99M | memset(&it_bit_buff_temp, 0, sizeof(it_bit_buff_temp)); |
142 | 6.99M | iusace_copy_bit_buf(&it_bit_buff_temp, pstr_it_bit_buff); |
143 | | |
144 | 6.99M | as.low = 0; |
145 | 6.99M | as.high = 65535; |
146 | 6.99M | as.value = 0; |
147 | | |
148 | 6.99M | sopt = ptr_c_prev[0] << 12; |
149 | | |
150 | 619M | for (i = 0; i < n; i++) { |
151 | 613M | if ((use_stop == 1 || use_stop == 2) && (stop == 0)) { |
152 | 247M | WORD32 j; |
153 | | |
154 | 247M | stop = 1; |
155 | 8.63G | for (j = i; j < n; j++) { |
156 | 8.63G | if (quant[2 * j] != 0 || quant[2 * j + 1] != 0) { |
157 | 243M | stop = 0; |
158 | 243M | break; |
159 | 243M | } |
160 | 8.63G | } |
161 | | |
162 | 247M | if (stop) { |
163 | 4.39M | s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); |
164 | 4.39M | t = s & 0xFFFFF; |
165 | | |
166 | 4.39M | pki = iusace_arith_get_pk(t); |
167 | | |
168 | 4.39M | if (use_stop == 1) { |
169 | 1.80M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
170 | 1.80M | pki = iusace_arith_get_pk(t + (1 << 17)); |
171 | 1.80M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, 0, iusace_ari_cf_m[pki]); |
172 | | |
173 | 1.80M | break; |
174 | 2.58M | } else { |
175 | 2.58M | bp_stop = bp; |
176 | 2.58M | as_stop.low = as.low; |
177 | 2.58M | as_stop.high = as.high; |
178 | 2.58M | as_stop.value = as.value; |
179 | | |
180 | 2.58M | bp_stop = |
181 | 2.58M | iusace_arith_encode(NULL, bp_stop, &as_stop, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
182 | | |
183 | 2.58M | pki = iusace_arith_get_pk(t + (1 << 17)); |
184 | 2.58M | bp_stop = iusace_arith_encode(NULL, bp_stop, &as_stop, (0), iusace_ari_cf_m[pki]); |
185 | 2.58M | } |
186 | 4.39M | } |
187 | 247M | } |
188 | 612M | s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); |
189 | 612M | t = s & 0xFFFFF; |
190 | | |
191 | 612M | a = quant[2 * i]; |
192 | 612M | b = quant[2 * i + 1]; |
193 | 612M | a1 = abs(a); |
194 | 612M | b1 = abs(b); |
195 | | |
196 | 612M | ptr_c_pres[i] = a1 + b1 + 1; |
197 | 612M | if (ptr_c_pres[i] > 0xF) { |
198 | 45.6M | ptr_c_pres[i] = 0xF; |
199 | 45.6M | } |
200 | | |
201 | 612M | lev = 0; |
202 | 612M | esc_nb = 0; |
203 | | |
204 | 835M | while ((a1) > 3 || (b1) > 3) { |
205 | 223M | pki = iusace_arith_get_pk(t + (esc_nb << 17)); |
206 | | |
207 | 223M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); |
208 | | |
209 | 223M | qs[lev++] = (a1 & 1) | ((b1 & 1) << 1); |
210 | 223M | a1 >>= 1; |
211 | 223M | b1 >>= 1; |
212 | 223M | esc_nb++; |
213 | | |
214 | 223M | if (esc_nb > 7) { |
215 | 4.73M | esc_nb = 7; |
216 | 4.73M | } |
217 | 223M | } |
218 | 612M | m = a1 + (b1 << 2); |
219 | 612M | pki = iusace_arith_get_pk(t + (esc_nb << 17)); |
220 | 612M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, m, iusace_ari_cf_m[pki]); |
221 | | |
222 | 612M | a2 = a1; |
223 | 612M | b2 = b1; |
224 | | |
225 | 835M | for (l = lev - 1; l >= 0; l--) { |
226 | 223M | WORD32 lsbidx = (a2 == 0) ? 1 : ((b2 == 0) ? 0 : 2); |
227 | 223M | bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, qs[l], iusace_ari_cf_r[lsbidx]); |
228 | | |
229 | 223M | a2 = (a2 << 1) | (qs[l] & 1); |
230 | 223M | b2 = (b2 << 1) | ((qs[l] >> 1) & 1); |
231 | 223M | } |
232 | 612M | } |
233 | | |
234 | 6.99M | if (use_stop == 2) { |
235 | 3.49M | bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); |
236 | 3.49M | if (stop) { |
237 | 2.58M | bp_stop = iusace_arith_done(NULL, bp_stop, &as_stop); |
238 | | |
239 | 2.58M | if (bp_stop < bp) { |
240 | 1.80M | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
241 | 1.80M | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
242 | 1.80M | n, nt, 1); |
243 | 1.80M | } else { |
244 | 777k | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
245 | 777k | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
246 | 777k | n, nt, 0); |
247 | 777k | } |
248 | 2.58M | } else { |
249 | 911k | iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); |
250 | 911k | bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, |
251 | 911k | n, nt, 0); |
252 | 911k | } |
253 | 3.49M | } else { |
254 | 3.49M | bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); |
255 | | |
256 | 231M | for (; i < nt; i++) { |
257 | 227M | ptr_c_pres[i] = 1; |
258 | 227M | } |
259 | | |
260 | 384M | for (i = 0; i < n; i++) { |
261 | 381M | if (quant[2 * i] != 0) { |
262 | 119M | if (quant[2 * i] > 0) { |
263 | 59.8M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
264 | 59.8M | bp++; |
265 | 59.8M | } else { |
266 | 59.2M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
267 | 59.2M | bp++; |
268 | 59.2M | } |
269 | 119M | } |
270 | | |
271 | 381M | if (quant[2 * i + 1] != 0) { |
272 | 118M | if (quant[2 * i + 1] > 0) { |
273 | 59.3M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
274 | 59.3M | bp++; |
275 | 59.3M | } else { |
276 | 59.0M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
277 | 59.0M | bp++; |
278 | 59.0M | } |
279 | 118M | } |
280 | 381M | } |
281 | | |
282 | 462M | for (i = 0; i < nt; i++) { |
283 | 458M | ptr_c_prev[i] = ptr_c_pres[i]; |
284 | 458M | ptr_c_pres[i] = 1; |
285 | 458M | } |
286 | 3.49M | } |
287 | | |
288 | 6.99M | return bp; |
289 | 6.99M | } |
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 | 946k | WORD32 arith_reset_flag, WORD32 ccfl) { |
295 | 946k | LOOPIDX i; |
296 | 946k | WORD32 write_flag = (it_bit_buf != NULL); |
297 | 946k | WORD32 size; |
298 | 946k | WORD32 num_wins = (window_sequence == EIGHT_SHORT_SEQUENCE) ? MAX_SHORT_WINDOWS : 1; |
299 | 946k | WORD32 bits_data_written = 0; |
300 | | |
301 | 946k | switch (window_sequence) { |
302 | 409k | case ONLY_LONG_SEQUENCE: |
303 | 512k | case LONG_START_SEQUENCE: |
304 | 513k | case STOP_START_SEQUENCE: |
305 | 605k | case LONG_STOP_SEQUENCE: |
306 | 605k | size = ccfl; |
307 | 605k | break; |
308 | 340k | case EIGHT_SHORT_SEQUENCE: |
309 | 340k | size = ccfl >> 3; |
310 | 340k | break; |
311 | 0 | default: |
312 | 0 | size = ccfl >> 3; |
313 | 0 | break; |
314 | 946k | } |
315 | | |
316 | 946k | iusace_arith_map_context(size, *ptr_size_prev, ptr_c_pres, ptr_c_prev, arith_reset_flag); |
317 | | |
318 | 946k | if (max_spec_coefficients > 0) { |
319 | 4.18M | for (i = 0; i < num_wins; i++) { |
320 | 3.28M | bits_data_written = iusace_arith_encode_level2( |
321 | 3.28M | it_bit_buf, bits_data_written, ptr_c_pres + 2, ptr_c_prev + 2, &ptr_x_ac_enc[i * size], |
322 | 3.28M | max_spec_coefficients / 2, size / 2, 2); |
323 | 3.28M | } |
324 | 903k | } |
325 | | |
326 | 946k | if (write_flag) { |
327 | 438k | *ptr_size_prev = size; |
328 | 438k | } |
329 | | |
330 | 946k | return bits_data_written; |
331 | 946k | } |
332 | | |
333 | | WORD32 iusace_tcx_coding(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 tcx_size, |
334 | 211k | WORD32 max_tcx_size, WORD32 *ptr_quant, WORD32 *c_pres, WORD32 *c_prev) { |
335 | 211k | WORD32 bits_written = 0; |
336 | | |
337 | 211k | iusace_arith_map_context(tcx_size, max_tcx_size, c_pres, c_prev, 0); |
338 | | |
339 | 211k | bits_written = |
340 | 211k | iusace_arith_encode_level2(pstr_it_bit_buff, bits_written, c_pres + 2, c_prev + 2, |
341 | 211k | &ptr_quant[0], tcx_size / 2, tcx_size / 2, 2); |
342 | | |
343 | 211k | iusace_arith_map_context(max_tcx_size, tcx_size, c_pres, c_prev, 0); |
344 | | |
345 | 211k | return bits_written; |
346 | 211k | } |
347 | | |
348 | 9.57M | WORD32 iusace_arith_done(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s) { |
349 | 9.57M | WORD32 low, high; |
350 | 9.57M | WORD32 bits_to_follow; |
351 | | |
352 | 9.57M | low = s->low; |
353 | 9.57M | high = s->high; |
354 | 9.57M | bits_to_follow = s->value + 1; |
355 | | |
356 | 9.57M | if (low < 16384) { |
357 | 6.45M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
358 | 6.45M | bp++; |
359 | 16.9M | while (bits_to_follow) { |
360 | 10.4M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
361 | 10.4M | bp++; |
362 | 10.4M | bits_to_follow--; |
363 | 10.4M | } |
364 | 6.45M | } else { |
365 | 3.11M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
366 | 3.11M | bp++; |
367 | 8.26M | while (bits_to_follow) { |
368 | 5.15M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
369 | 5.15M | bp++; |
370 | 5.15M | bits_to_follow--; |
371 | 5.15M | } |
372 | 3.11M | } |
373 | | |
374 | 9.57M | s->low = low; |
375 | 9.57M | s->high = high; |
376 | 9.57M | s->value = bits_to_follow; |
377 | | |
378 | 9.57M | return bp; |
379 | 9.57M | } |
380 | | |
381 | | WORD32 iusace_arith_encode(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s, |
382 | 1.06G | WORD32 symbol, UWORD16 const *cum_freq) { |
383 | 1.06G | WORD32 low, high, range; |
384 | 1.06G | WORD32 bits_to_follow; |
385 | | |
386 | 1.06G | high = s->high; |
387 | 1.06G | low = s->low; |
388 | 1.06G | range = high - low + 1; |
389 | | |
390 | 1.06G | if (symbol > 0) { |
391 | 649M | high = low + ((range * cum_freq[symbol - 1]) >> 14) - 1; |
392 | 649M | } |
393 | | |
394 | 1.06G | low = low + ((range * cum_freq[symbol]) >> 14); |
395 | | |
396 | 1.06G | bits_to_follow = s->value; |
397 | | |
398 | 3.02G | for (;;) { |
399 | 3.02G | if (high < 32768) { |
400 | 750M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
401 | 750M | bp++; |
402 | 1.05G | while (bits_to_follow) { |
403 | 306M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
404 | 306M | bp++; |
405 | 306M | bits_to_follow--; |
406 | 306M | } |
407 | 2.27G | } else if (low >= 32768) { |
408 | 686M | iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); |
409 | 686M | bp++; |
410 | 900M | while (bits_to_follow) { |
411 | 213M | iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); |
412 | 213M | bp++; |
413 | 213M | bits_to_follow--; |
414 | 213M | } |
415 | 686M | low -= 32768; |
416 | 686M | high -= 32768; |
417 | 1.59G | } else if (low >= 16384 && high < 49152) { |
418 | 524M | bits_to_follow += 1; |
419 | 524M | low -= 16384; |
420 | 524M | high -= 16384; |
421 | 524M | } else |
422 | 1.06G | break; |
423 | | |
424 | 1.96G | low += low; |
425 | 1.96G | high += high + 1; |
426 | 1.96G | } |
427 | | |
428 | 1.06G | s->low = low; |
429 | 1.06G | s->high = high; |
430 | 1.06G | s->value = bits_to_follow; |
431 | | |
432 | 1.06G | return bp; |
433 | 1.06G | } |