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