Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include <assert.h>
35 : #include "options.h"
36 : #include "ivas_cnst.h"
37 : #include "prot_fx.h"
38 : #include "ivas_rom_com.h"
39 : #include "math.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 :
46 : /*-----------------------------------------------------------------------------------------*
47 : * Function ivas_get_dyn_freq_model_fx()
48 : *
49 : * Chooses frequency model dynamically
50 : *-----------------------------------------------------------------------------------------*/
51 :
52 884923 : static ivas_error ivas_get_dyn_freq_model_fx(
53 : Word16 *pInput, /* Q0 */
54 : const Word16 length, /* Q0 */
55 : Word16 *model_index, /* Q0 */
56 : ivas_arith_t *pArith,
57 : Word16 **ppCum_freq /* Q0 */
58 : )
59 : {
60 : Word32 curr_dist[IVAS_MAX_QUANT_LEVELS];
61 : Word16 i, n[IVAS_MAX_QUANT_LEVELS + 1], model_idx;
62 : Word32 curr_bps, curr_bps_min, curr_bps_new;
63 884923 : Word16 range = pArith->range;
64 : Word16 m;
65 884923 : Word16 offset = negate( pArith->vals[0] ); /* Q0 */
66 : ivas_error error;
67 884923 : error = IVAS_ERR_OK;
68 884923 : move32();
69 :
70 12722387 : FOR( i = 0; i < range + 1; i++ )
71 : {
72 11837464 : n[i] = 0;
73 11837464 : move16();
74 : }
75 :
76 18416959 : FOR( i = 0; i < length; i++ )
77 : {
78 17532036 : n[pInput[i] + offset] = add( n[pInput[i] + offset], 1 ); /* Q0 */
79 17532036 : move16();
80 : }
81 :
82 884923 : curr_bps = 0;
83 884923 : move32();
84 11837464 : FOR( i = 0; i < range; i++ )
85 : {
86 10952541 : curr_dist[i] = L_deposit_l( n[i] );
87 10952541 : move32();
88 10952541 : curr_bps = L_sub( curr_bps, W_extract_l( W_mult0_32_32( curr_dist[i], pArith->saved_dist_arr[0][i] ) ) );
89 : }
90 884923 : curr_bps_min = curr_bps;
91 884923 : move32();
92 : #ifdef DEBUGGING
93 : {
94 : float a = curr_bps_min / 32768.0f;
95 : dbgwrite_txt( &a, 1, "fixed_curr_bps_min.txt", NULL );
96 : }
97 : #endif
98 884923 : model_idx = 0;
99 884923 : move16();
100 :
101 3539692 : FOR( m = 0; m < pArith->num_models - 1; m++ )
102 : {
103 2654769 : curr_bps_new = 0;
104 2654769 : move32();
105 35512392 : FOR( i = 0; i < range; i++ )
106 : {
107 32857623 : curr_bps_new = L_sub( curr_bps_new, W_extract_l( W_mult0_32_32( curr_dist[i], pArith->saved_dist_arr[m + 1][i] ) ) );
108 : }
109 : #ifdef DEBUGGING
110 : {
111 : float a = curr_bps_new / 32768.0f;
112 : dbgwrite_txt( &a, 1, "fixed_curr_bps_new.txt", NULL );
113 : }
114 : #endif
115 2654769 : IF( LT_32( curr_bps_new, curr_bps_min ) )
116 : {
117 794028 : model_idx = m;
118 794028 : move16();
119 794028 : curr_bps_min = curr_bps_new;
120 794028 : move32();
121 : }
122 : }
123 :
124 884923 : IF( LT_32( curr_bps_min, curr_bps ) )
125 : {
126 508723 : *ppCum_freq = pArith->cum_freq[model_idx + 1]; /* Q0 */
127 508723 : model_idx = add( model_idx, 1 ); /* Q0 */
128 : }
129 : ELSE
130 : {
131 376200 : model_idx = 0;
132 376200 : move16();
133 376200 : *ppCum_freq = pArith->cum_freq[0]; /* Q0 */
134 : }
135 :
136 884923 : *model_index = model_idx; /* Q0 */
137 884923 : move16();
138 :
139 884923 : return error;
140 : }
141 : /*-----------------------------------------------------------------------------------------*
142 : * Function ivas_arith_encode_array_fx()
143 : *
144 : * Arith encoding of an array of symbols
145 : *-----------------------------------------------------------------------------------------*/
146 :
147 884923 : static Word16 ivas_arith_encode_array_fx(
148 : Word16 *pInput, /* Q0 */
149 : ivas_arith_t *pArith,
150 : BSTR_ENC_HANDLE hMetaData,
151 : const Word16 in_len, /* Q0 */
152 : const Word16 wc_strat_arith /* Q0 */
153 : )
154 : {
155 : Word16 model_index, i, ind;
156 884923 : Word16 *pCum_freq = NULL;
157 : Tastat as;
158 :
159 884923 : IF( in_len > 0 && GT_16( pArith->range, 1 ) )
160 : {
161 884923 : IF( pArith->dyn_model_bits > 0 )
162 : {
163 884923 : ivas_get_dyn_freq_model_fx( pInput, in_len, &model_index, pArith, &pCum_freq );
164 884923 : IF( GT_16( add( hMetaData->nb_bits_tot, pArith->dyn_model_bits ), wc_strat_arith ) )
165 : {
166 2 : return -1;
167 : }
168 :
169 884921 : push_next_indice( hMetaData, model_index, pArith->dyn_model_bits );
170 : }
171 : ELSE
172 : {
173 0 : pCum_freq = pArith->cum_freq[0]; /* Q0 */
174 : }
175 :
176 884921 : ari_start_encoding_14bits_ivas_fx( &as );
177 :
178 18331017 : FOR( i = 0; i < in_len; i++ )
179 : {
180 17469264 : ind = sub( pInput[i], pArith->vals[0] ); /* Q0 */
181 17469264 : ivas_ari_encode_14bits_ext_fx( hMetaData, &as, ind, (const UWord16 *) pCum_freq );
182 17469264 : IF( GT_16( hMetaData->nb_bits_tot, wc_strat_arith ) )
183 : {
184 23168 : return -1;
185 : }
186 : }
187 :
188 861753 : ivas_ari_done_encoding_14bits_fx( hMetaData, &as );
189 861753 : IF( GT_16( hMetaData->nb_bits_tot, wc_strat_arith ) )
190 : {
191 5603 : return -1;
192 : }
193 : }
194 :
195 856150 : return 0;
196 : }
197 :
198 :
199 : /*-----------------------------------------------------------------------------------------*
200 : * Function ivas_arithCoder_encode_array_diff_fx()
201 : *
202 : * Differential arith encoding
203 : *-----------------------------------------------------------------------------------------*/
204 :
205 230730 : static Word16 ivas_arithCoder_encode_array_diff_fx(
206 : ivas_arith_t *pArith_diff,
207 : Word16 *pIn_new, /* Q0 */
208 : Word16 *pIn_old_scratch, /* Q0 */
209 : const Word16 length, /* Q0 */
210 : BSTR_ENC_HANDLE hMetaData,
211 : const Word16 wc_strat_arith /* Q0 */
212 : )
213 : {
214 : Word16 n;
215 : Word16 arith_result;
216 :
217 230730 : IF( length > 0 )
218 : {
219 3557454 : FOR( n = 0; n < length; n++ )
220 : {
221 3326724 : pIn_old_scratch[n] = sub( pIn_new[n], pIn_old_scratch[n] ); /* Q0 */
222 3326724 : move16();
223 : }
224 :
225 230730 : ivas_wrap_arround_fx( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length );
226 :
227 230730 : arith_result = ivas_arith_encode_array_fx( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith ); /* Q0 */
228 230730 : IF( arith_result < 0 )
229 : {
230 975 : return -1;
231 : }
232 : }
233 :
234 229755 : return 0;
235 : }
236 :
237 :
238 : /*-----------------------------------------------------------------------------------------*
239 : * Function ivas_huffman_encode_fx()
240 : *
241 : * ivas_huffman_encode
242 : *-----------------------------------------------------------------------------------------*/
243 :
244 4731402 : void ivas_huffman_encode_fx(
245 : ivas_huffman_cfg_t *huff_cfg,
246 : Word16 in, /* Q0 */
247 : Word16 *hcode, /* Q0 */
248 : Word16 *hlen /* Q0 */
249 : )
250 : {
251 : Word16 min_sym_val;
252 : const Word16 *codebook;
253 :
254 4731402 : min_sym_val = huff_cfg->codebook[0]; /* Q0 */
255 4731402 : move16();
256 :
257 4731402 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; /* Q0 */
258 4731402 : *hlen = codebook[1]; /* Q0 */
259 4731402 : move16();
260 4731402 : *hcode = codebook[2]; /* Q0 */
261 4731402 : move16();
262 :
263 4731402 : return;
264 : }
265 :
266 :
267 : /*-----------------------------------------------------------------------------------------*
268 : * Function arith_encode_cell_array_fx()
269 : *
270 : * Arithmetic encode a cell array
271 : *-----------------------------------------------------------------------------------------*/
272 :
273 776606 : static Word16 arith_encode_cell_array_fx(
274 : ivas_cell_dim_t *pCell_dims,
275 : BSTR_ENC_HANDLE hMetaData,
276 : const Word16 nB, /* Q0 */
277 : ivas_arith_t *pArith,
278 : Word16 *pSymbol, /* Q0 */
279 : const Word16 wc_strat_arith )
280 : {
281 776606 : Word16 total_symbol_len = 0;
282 776606 : move16();
283 : Word16 i;
284 : Word16 arith_result;
285 :
286 6933570 : FOR( i = 0; i < nB; i++ )
287 : {
288 6156964 : total_symbol_len = add( total_symbol_len, imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */
289 : }
290 :
291 776606 : assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) );
292 :
293 776606 : IF( total_symbol_len > 0 )
294 : {
295 654193 : IF( GT_16( pArith->range, 1 ) )
296 : {
297 654193 : arith_result = ivas_arith_encode_array_fx( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith ); /* Q0 */
298 654193 : IF( arith_result < 0 )
299 : {
300 27798 : return -1;
301 : }
302 : }
303 : }
304 :
305 748808 : return 0;
306 : }
307 :
308 :
309 : /*-----------------------------------------------------------------------------------------*
310 : * Function arith_encode_cell_array_diff_fx()
311 : *
312 : * Arithmetic encode a cell array - differential
313 : *-----------------------------------------------------------------------------------------*/
314 :
315 259599 : static Word16 arith_encode_cell_array_diff_fx(
316 : const ivas_cell_dim_t *pCell_dims,
317 : BSTR_ENC_HANDLE hMetaData,
318 : Word16 nB, /* Q0 */
319 : ivas_arith_t *pArith_diff,
320 : Word16 *pSymbol_old, /* Q0 */
321 : Word16 *pSymbol, /* Q0 */
322 : const Word16 wc_strat_arith /* Q0 */
323 : )
324 : {
325 : Word16 i, total_symbol_len;
326 : Word16 arith_result;
327 :
328 259599 : total_symbol_len = 0;
329 259599 : move16();
330 2336391 : FOR( i = 0; i < nB; i++ )
331 : {
332 2076792 : total_symbol_len = add( total_symbol_len, ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ) ); /* Q0 */
333 : }
334 :
335 259599 : assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) );
336 :
337 259599 : IF( total_symbol_len > 0 )
338 : {
339 230730 : IF( GT_16( pArith_diff->range, 1 ) )
340 : {
341 230730 : arith_result = ivas_arithCoder_encode_array_diff_fx( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith ); /* Q0 */
342 230730 : IF( arith_result < 0 )
343 : {
344 975 : return -1;
345 : }
346 : }
347 : }
348 :
349 258624 : return 0;
350 : }
351 :
352 :
353 : /*-----------------------------------------------------------------------------------------*
354 : * Function ivas_arith_encode_cmplx_cell_array_fx()
355 : *
356 : * Arithmetic encode a cell array
357 : *-----------------------------------------------------------------------------------------*/
358 :
359 776606 : Word16 ivas_arith_encode_cmplx_cell_array_fx(
360 : ivas_arith_t *pArith_re,
361 : ivas_arith_t *pArith_re_diff,
362 : const Word16 *pDo_diff, /* Q0 */
363 : const Word16 nB, /* Q0 */
364 : Word16 *pSymbol_re, /* Q0 */
365 : Word16 *pSymbol_old_re, /* Q0 */
366 : ivas_cell_dim_t *pCell_dims,
367 : BSTR_ENC_HANDLE hMetaData,
368 : const Word16 any_diff, /* Q0 */
369 : const Word16 wc_strat_arith /* Q0 */
370 : )
371 : {
372 : Word16 input_old[IVAS_MAX_INPUT_LEN];
373 : Word16 input_new[IVAS_MAX_INPUT_LEN];
374 : Word16 input[IVAS_MAX_INPUT_LEN];
375 : ivas_cell_dim_t cell_dim[IVAS_MAX_NUM_BANDS], cell_dim_diff[IVAS_MAX_NUM_BANDS];
376 : Word16 len, idx, i, j, idx1;
377 : Word16 total_len;
378 : Word16 arith_result;
379 :
380 776606 : idx1 = 0;
381 776606 : move16();
382 776606 : IF( EQ_16( any_diff, 1 ) )
383 : {
384 259637 : idx = 0;
385 259637 : total_len = 0;
386 259637 : move16();
387 259637 : move16();
388 2336733 : FOR( i = 0; i < nB; i++ )
389 : {
390 2077096 : len = ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */
391 2077096 : move16();
392 2077096 : IF( pDo_diff[i] != 0 )
393 : {
394 4885002 : FOR( j = 0; j < len; j++ )
395 : {
396 3327180 : input_old[idx] = pSymbol_old_re[total_len + j]; /* Q0 */
397 3327180 : input_new[idx++] = pSymbol_re[total_len + j]; /* Q0 */
398 3327180 : move16();
399 3327180 : move16();
400 : }
401 1557822 : cell_dim_diff[i].dim1 = pCell_dims[i].dim1; /* Q0 */
402 1557822 : cell_dim_diff[i].dim2 = pCell_dims[i].dim2; /* Q0 */
403 1557822 : cell_dim[i].dim1 = 0;
404 1557822 : cell_dim[i].dim2 = 0;
405 1557822 : move16();
406 1557822 : move16();
407 1557822 : move16();
408 1557822 : move16();
409 : }
410 : ELSE
411 : {
412 1628334 : FOR( j = 0; j < len; j++ )
413 : {
414 1109060 : input[idx1++] = pSymbol_re[total_len + j]; /* Q0 */
415 1109060 : move16();
416 : }
417 519274 : cell_dim_diff[i].dim1 = 0;
418 519274 : cell_dim_diff[i].dim2 = 0;
419 519274 : cell_dim[i].dim1 = pCell_dims[i].dim1; /* Q0 */
420 519274 : cell_dim[i].dim2 = pCell_dims[i].dim2; /* Q0 */
421 519274 : move16();
422 519274 : move16();
423 519274 : move16();
424 519274 : move16();
425 : }
426 2077096 : total_len = add( total_len, len ); /* Q0 */
427 : }
428 :
429 259637 : arith_result = arith_encode_cell_array_fx( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith ); /* Q0 */
430 259637 : IF( arith_result < 0 )
431 : {
432 38 : return -1;
433 : }
434 :
435 259599 : arith_result = arith_encode_cell_array_diff_fx( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith ); /* Q0 */
436 259599 : move16();
437 259599 : IF( arith_result < 0 )
438 : {
439 975 : return -1;
440 : }
441 : }
442 : ELSE
443 : {
444 516969 : arith_result = arith_encode_cell_array_fx( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith ); /* Q0 */
445 516969 : IF( arith_result < 0 )
446 : {
447 27760 : return -1;
448 : }
449 : }
450 :
451 747833 : return 0;
452 : }
|