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 871487 : 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 871487 : Word16 range = pArith->range;
64 : Word16 m;
65 871487 : Word16 offset = negate( pArith->vals[0] ); /* Q0 */
66 : ivas_error error;
67 871487 : error = IVAS_ERR_OK;
68 871487 : move32();
69 :
70 12542655 : FOR( i = 0; i < range + 1; i++ )
71 : {
72 11671168 : n[i] = 0;
73 11671168 : move16();
74 : }
75 :
76 18208163 : FOR( i = 0; i < length; i++ )
77 : {
78 17336676 : n[pInput[i] + offset] = add( n[pInput[i] + offset], 1 ); /* Q0 */
79 17336676 : move16();
80 : }
81 :
82 871487 : curr_bps = 0;
83 871487 : move32();
84 11671168 : FOR( i = 0; i < range; i++ )
85 : {
86 10799681 : curr_dist[i] = L_deposit_l( n[i] );
87 10799681 : move32();
88 10799681 : curr_bps = L_sub( curr_bps, W_extract_l( W_mult0_32_32( curr_dist[i], pArith->saved_dist_arr[0][i] ) ) );
89 : }
90 871487 : curr_bps_min = curr_bps;
91 871487 : 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 871487 : model_idx = 0;
99 871487 : move16();
100 :
101 3485948 : FOR( m = 0; m < pArith->num_models - 1; m++ )
102 : {
103 2614461 : curr_bps_new = 0;
104 2614461 : move32();
105 35013504 : FOR( i = 0; i < range; i++ )
106 : {
107 32399043 : 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 2614461 : IF( LT_32( curr_bps_new, curr_bps_min ) )
116 : {
117 780366 : model_idx = m;
118 780366 : move16();
119 780366 : curr_bps_min = curr_bps_new;
120 780366 : move32();
121 : }
122 : }
123 :
124 871487 : IF( LT_32( curr_bps_min, curr_bps ) )
125 : {
126 502718 : *ppCum_freq = pArith->cum_freq[model_idx + 1]; /* Q0 */
127 502718 : model_idx = add( model_idx, 1 ); /* Q0 */
128 : }
129 : ELSE
130 : {
131 368769 : model_idx = 0;
132 368769 : move16();
133 368769 : *ppCum_freq = pArith->cum_freq[0]; /* Q0 */
134 : }
135 :
136 871487 : *model_index = model_idx; /* Q0 */
137 871487 : move16();
138 :
139 871487 : return error;
140 : }
141 : /*-----------------------------------------------------------------------------------------*
142 : * Function ivas_arith_encode_array_fx()
143 : *
144 : * Arith encoding of an array of symbols
145 : *-----------------------------------------------------------------------------------------*/
146 :
147 871487 : 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 871487 : Word16 *pCum_freq = NULL;
157 : Tastat as;
158 :
159 871487 : IF( in_len > 0 && GT_16( pArith->range, 1 ) )
160 : {
161 871487 : IF( pArith->dyn_model_bits > 0 )
162 : {
163 871487 : ivas_get_dyn_freq_model_fx( pInput, in_len, &model_index, pArith, &pCum_freq );
164 871487 : IF( GT_16( add( hMetaData->nb_bits_tot, pArith->dyn_model_bits ), wc_strat_arith ) )
165 : {
166 3 : return -1;
167 : }
168 :
169 871484 : 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 871484 : ari_start_encoding_14bits_ivas_fx( &as );
177 :
178 18123289 : FOR( i = 0; i < in_len; i++ )
179 : {
180 17274696 : ind = sub( pInput[i], pArith->vals[0] ); /* Q0 */
181 17274696 : ivas_ari_encode_14bits_ext_fx( hMetaData, &as, ind, (const UWord16 *) pCum_freq );
182 17274696 : IF( GT_16( hMetaData->nb_bits_tot, wc_strat_arith ) )
183 : {
184 22891 : return -1;
185 : }
186 : }
187 :
188 848593 : ivas_ari_done_encoding_14bits_fx( hMetaData, &as );
189 848593 : IF( GT_16( hMetaData->nb_bits_tot, wc_strat_arith ) )
190 : {
191 5552 : return -1;
192 : }
193 : }
194 :
195 843041 : return 0;
196 : }
197 :
198 :
199 : /*-----------------------------------------------------------------------------------------*
200 : * Function ivas_arithCoder_encode_array_diff_fx()
201 : *
202 : * Differential arith encoding
203 : *-----------------------------------------------------------------------------------------*/
204 :
205 228370 : 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 228370 : IF( length > 0 )
218 : {
219 3518512 : FOR( n = 0; n < length; n++ )
220 : {
221 3290142 : pIn_old_scratch[n] = sub( pIn_new[n], pIn_old_scratch[n] ); /* Q0 */
222 3290142 : move16();
223 : }
224 :
225 228370 : ivas_wrap_arround_fx( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length );
226 :
227 228370 : arith_result = ivas_arith_encode_array_fx( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith ); /* Q0 */
228 228370 : IF( arith_result < 0 )
229 : {
230 963 : return -1;
231 : }
232 : }
233 :
234 227407 : return 0;
235 : }
236 :
237 :
238 : /*-----------------------------------------------------------------------------------------*
239 : * Function ivas_huffman_encode_fx()
240 : *
241 : * ivas_huffman_encode
242 : *-----------------------------------------------------------------------------------------*/
243 :
244 4675048 : 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 4675048 : min_sym_val = huff_cfg->codebook[0]; /* Q0 */
255 4675048 : move16();
256 :
257 4675048 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; /* Q0 */
258 4675048 : *hlen = codebook[1]; /* Q0 */
259 4675048 : move16();
260 4675048 : *hcode = codebook[2]; /* Q0 */
261 4675048 : move16();
262 :
263 4675048 : return;
264 : }
265 :
266 :
267 : /*-----------------------------------------------------------------------------------------*
268 : * Function arith_encode_cell_array_fx()
269 : *
270 : * Arithmetic encode a cell array
271 : *-----------------------------------------------------------------------------------------*/
272 :
273 764425 : 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 764425 : Word16 total_symbol_len = 0;
282 764425 : move16();
283 : Word16 i;
284 : Word16 arith_result;
285 :
286 6829497 : FOR( i = 0; i < nB; i++ )
287 : {
288 6065072 : total_symbol_len = add( total_symbol_len, imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */
289 : }
290 :
291 764425 : assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) );
292 :
293 764425 : IF( total_symbol_len > 0 )
294 : {
295 643117 : IF( GT_16( pArith->range, 1 ) )
296 : {
297 643117 : arith_result = ivas_arith_encode_array_fx( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith ); /* Q0 */
298 643117 : IF( arith_result < 0 )
299 : {
300 27483 : return -1;
301 : }
302 : }
303 : }
304 :
305 736942 : 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 257115 : 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 257115 : total_symbol_len = 0;
329 257115 : move16();
330 2314035 : FOR( i = 0; i < nB; i++ )
331 : {
332 2056920 : total_symbol_len = add( total_symbol_len, ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ) ); /* Q0 */
333 : }
334 :
335 257115 : assert( LE_16( total_symbol_len, ( IVAS_MAX_INPUT_LEN ) ) );
336 :
337 257115 : IF( total_symbol_len > 0 )
338 : {
339 228370 : IF( GT_16( pArith_diff->range, 1 ) )
340 : {
341 228370 : arith_result = ivas_arithCoder_encode_array_diff_fx( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith ); /* Q0 */
342 228370 : IF( arith_result < 0 )
343 : {
344 963 : return -1;
345 : }
346 : }
347 : }
348 :
349 256152 : 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 764425 : 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 764425 : idx1 = 0;
381 764425 : move16();
382 764425 : IF( EQ_16( any_diff, 1 ) )
383 : {
384 257153 : idx = 0;
385 257153 : total_len = 0;
386 257153 : move16();
387 257153 : move16();
388 2314377 : FOR( i = 0; i < nB; i++ )
389 : {
390 2057224 : len = ( imult1616( pCell_dims[i].dim1, pCell_dims[i].dim2 ) ); /* Q0 */
391 2057224 : move16();
392 2057224 : IF( pDo_diff[i] != 0 )
393 : {
394 4833516 : FOR( j = 0; j < len; j++ )
395 : {
396 3290598 : input_old[idx] = pSymbol_old_re[total_len + j]; /* Q0 */
397 3290598 : input_new[idx++] = pSymbol_re[total_len + j]; /* Q0 */
398 3290598 : move16();
399 3290598 : move16();
400 : }
401 1542918 : cell_dim_diff[i].dim1 = pCell_dims[i].dim1; /* Q0 */
402 1542918 : cell_dim_diff[i].dim2 = pCell_dims[i].dim2; /* Q0 */
403 1542918 : cell_dim[i].dim1 = 0;
404 1542918 : cell_dim[i].dim2 = 0;
405 1542918 : move16();
406 1542918 : move16();
407 1542918 : move16();
408 1542918 : move16();
409 : }
410 : ELSE
411 : {
412 1611172 : FOR( j = 0; j < len; j++ )
413 : {
414 1096866 : input[idx1++] = pSymbol_re[total_len + j]; /* Q0 */
415 1096866 : move16();
416 : }
417 514306 : cell_dim_diff[i].dim1 = 0;
418 514306 : cell_dim_diff[i].dim2 = 0;
419 514306 : cell_dim[i].dim1 = pCell_dims[i].dim1; /* Q0 */
420 514306 : cell_dim[i].dim2 = pCell_dims[i].dim2; /* Q0 */
421 514306 : move16();
422 514306 : move16();
423 514306 : move16();
424 514306 : move16();
425 : }
426 2057224 : total_len = add( total_len, len ); /* Q0 */
427 : }
428 :
429 257153 : arith_result = arith_encode_cell_array_fx( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith ); /* Q0 */
430 257153 : IF( arith_result < 0 )
431 : {
432 38 : return -1;
433 : }
434 :
435 257115 : 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 257115 : move16();
437 257115 : IF( arith_result < 0 )
438 : {
439 963 : return -1;
440 : }
441 : }
442 : ELSE
443 : {
444 507272 : arith_result = arith_encode_cell_array_fx( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith ); /* Q0 */
445 507272 : IF( arith_result < 0 )
446 : {
447 27445 : return -1;
448 : }
449 : }
450 :
451 735979 : return 0;
452 : }
|