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 "options.h"
35 : #include "ivas_cnst.h"
36 : #ifdef DEBUGGING
37 : #include "debug.h"
38 : #endif
39 : #include "prot.h"
40 : #include "ivas_prot.h"
41 : #include "ivas_rom_com.h"
42 : #include "math.h"
43 : #include <assert.h>
44 : #include "wmc_auto.h"
45 :
46 :
47 : /*-----------------------------------------------------------------------------------------*
48 : * Function ivas_get_dyn_freq_model()
49 : *
50 : * Chooses frequency model dynamically
51 : *-----------------------------------------------------------------------------------------*/
52 :
53 14295700 : static ivas_error ivas_get_dyn_freq_model(
54 : int16_t *pInput,
55 : const int16_t length,
56 : int16_t *model_index,
57 : ivas_arith_t *pArith,
58 : int16_t **ppCum_freq )
59 : {
60 : float curr_dist[IVAS_MAX_QUANT_LEVELS];
61 : int16_t i, n[IVAS_MAX_QUANT_LEVELS + 1], model_idx;
62 : float curr_bps, curr_bps_min, curr_bps_new;
63 14295700 : int16_t range = pArith->range;
64 14295700 : int16_t m, offset = -pArith->vals[0];
65 : ivas_error error;
66 :
67 14295700 : error = IVAS_ERR_OK;
68 :
69 207041214 : for ( i = 0; i < range + 1; i++ )
70 : {
71 192745514 : n[i] = 0;
72 : }
73 :
74 261510374 : for ( i = 0; i < length; i++ )
75 : {
76 247214674 : n[pInput[i] + offset] += 1;
77 : }
78 :
79 14295700 : curr_bps = 0;
80 192745514 : for ( i = 0; i < range; i++ )
81 : {
82 178449814 : curr_dist[i] = (float) n[i];
83 178449814 : curr_bps -= ( curr_dist[i] * pArith->saved_dist_arr[0][i] );
84 : }
85 14295700 : curr_bps_min = curr_bps;
86 :
87 14295700 : model_idx = 0;
88 :
89 57182800 : for ( m = 0; m < pArith->num_models - 1; m++ )
90 : {
91 42887100 : curr_bps_new = 0;
92 578236542 : for ( i = 0; i < range; i++ )
93 : {
94 535349442 : curr_bps_new -= ( curr_dist[i] * pArith->saved_dist_arr[m + 1][i] );
95 : }
96 :
97 42887100 : if ( curr_bps_new < curr_bps_min )
98 : {
99 13132341 : model_idx = m;
100 13132341 : curr_bps_min = curr_bps_new;
101 : }
102 : }
103 :
104 14295700 : if ( curr_bps_min < curr_bps )
105 : {
106 8373555 : *ppCum_freq = pArith->cum_freq[model_idx + 1];
107 8373555 : model_idx = model_idx + 1;
108 : }
109 : else
110 : {
111 5922145 : model_idx = 0;
112 5922145 : *ppCum_freq = pArith->cum_freq[0];
113 : }
114 :
115 14295700 : *model_index = model_idx;
116 :
117 14295700 : return error;
118 : }
119 :
120 :
121 : /*-----------------------------------------------------------------------------------------*
122 : * Function ivas_arith_encode_array()
123 : *
124 : * Arith encoding of an array of symbols
125 : *-----------------------------------------------------------------------------------------*/
126 :
127 14295700 : static int16_t ivas_arith_encode_array(
128 : int16_t *pInput,
129 : ivas_arith_t *pArith,
130 : BSTR_ENC_HANDLE hMetaData,
131 : const int16_t in_len,
132 : const int16_t wc_strat_arith )
133 : {
134 : int16_t model_index, i, ind;
135 14295700 : int16_t *pCum_freq = NULL;
136 : Tastat as;
137 :
138 14295700 : if ( in_len > 0 && pArith->range > 1 )
139 : {
140 14295700 : if ( pArith->dyn_model_bits > 0 )
141 : {
142 14295700 : ivas_get_dyn_freq_model( pInput, in_len, &model_index, pArith, &pCum_freq );
143 14295700 : if ( ( hMetaData->nb_bits_tot + pArith->dyn_model_bits ) > wc_strat_arith )
144 : {
145 279 : return -1;
146 : }
147 :
148 14295421 : push_next_indice( hMetaData, model_index, pArith->dyn_model_bits );
149 : }
150 : else
151 : {
152 0 : pCum_freq = pArith->cum_freq[0];
153 : }
154 :
155 14295421 : ari_start_encoding_14bits( &as );
156 :
157 260453646 : for ( i = 0; i < in_len; i++ )
158 : {
159 246472163 : ind = pInput[i] - pArith->vals[0];
160 :
161 246472163 : ivas_ari_encode_14bits_ext( hMetaData, &as, ind, (const uint16_t *) pCum_freq );
162 246472163 : if ( hMetaData->nb_bits_tot > wc_strat_arith )
163 : {
164 313938 : return -1;
165 : }
166 : }
167 :
168 13981483 : ivas_ari_done_encoding_14bits( hMetaData, &as );
169 13981483 : if ( hMetaData->nb_bits_tot > wc_strat_arith )
170 : {
171 92525 : return -1;
172 : }
173 : }
174 :
175 13888958 : return 0;
176 : }
177 :
178 :
179 : /*-----------------------------------------------------------------------------------------*
180 : * Function ivas_arithCoder_encode_array_diff()
181 : *
182 : * Differential arith encoding
183 : *-----------------------------------------------------------------------------------------*/
184 :
185 3993391 : static int16_t ivas_arithCoder_encode_array_diff(
186 : ivas_arith_t *pArith_diff,
187 : int16_t *pIn_new,
188 : int16_t *pIn_old_scratch,
189 : const int16_t length,
190 : BSTR_ENC_HANDLE hMetaData,
191 : const int16_t wc_strat_arith )
192 : {
193 : int16_t n;
194 : int16_t arith_result;
195 :
196 3993391 : if ( length > 0 )
197 : {
198 63004417 : for ( n = 0; n < length; n++ )
199 : {
200 59011026 : pIn_old_scratch[n] = pIn_new[n] - pIn_old_scratch[n];
201 : }
202 :
203 3993391 : ivas_wrap_arround( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length );
204 :
205 3993391 : arith_result = ivas_arith_encode_array( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith );
206 3993391 : if ( arith_result < 0 )
207 : {
208 13311 : return -1;
209 : }
210 : }
211 :
212 3980080 : return 0;
213 : }
214 :
215 :
216 : /*-----------------------------------------------------------------------------------------*
217 : * Function ivas_huffman_encode()
218 : *
219 : * ivas_huffman_encode
220 : *-----------------------------------------------------------------------------------------*/
221 :
222 82516146 : void ivas_huffman_encode(
223 : ivas_huffman_cfg_t *huff_cfg,
224 : int16_t in,
225 : int16_t *hcode,
226 : int16_t *hlen )
227 : {
228 : int16_t min_sym_val;
229 : const int16_t *codebook;
230 :
231 82516146 : min_sym_val = huff_cfg->codebook[0];
232 :
233 82516146 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
234 82516146 : *hlen = codebook[1];
235 82516146 : *hcode = codebook[2];
236 :
237 82516146 : return;
238 : }
239 :
240 :
241 : /*-----------------------------------------------------------------------------------------*
242 : * Function arith_encode_cell_array()
243 : *
244 : * Arithmetic encode a cell array
245 : *-----------------------------------------------------------------------------------------*/
246 :
247 12651484 : static int16_t arith_encode_cell_array(
248 : ivas_cell_dim_t *pCell_dims,
249 : BSTR_ENC_HANDLE hMetaData,
250 : const int16_t nB,
251 : ivas_arith_t *pArith,
252 : int16_t *pSymbol,
253 : const int16_t wc_strat_arith )
254 : {
255 12651484 : int16_t total_symbol_len = 0;
256 : int16_t i;
257 : int16_t arith_result;
258 :
259 112015528 : for ( i = 0; i < nB; i++ )
260 : {
261 99364044 : total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
262 : }
263 :
264 12651484 : assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
265 :
266 12651484 : if ( total_symbol_len > 0 )
267 : {
268 10302309 : if ( pArith->range > 1 )
269 : {
270 10302309 : arith_result = ivas_arith_encode_array( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith );
271 10302309 : if ( arith_result < 0 )
272 : {
273 393431 : return -1;
274 : }
275 : }
276 : }
277 :
278 12258053 : return 0;
279 : }
280 :
281 :
282 : /*-----------------------------------------------------------------------------------------*
283 : * Function arith_encode_cell_array_diff()
284 : *
285 : * Arithmetic encode a cell array - differential
286 : *-----------------------------------------------------------------------------------------*/
287 :
288 4633742 : static int16_t arith_encode_cell_array_diff(
289 : const ivas_cell_dim_t *pCell_dims,
290 : BSTR_ENC_HANDLE hMetaData,
291 : int16_t nB,
292 : ivas_arith_t *pArith_diff,
293 : int16_t *pSymbol_old,
294 : int16_t *pSymbol,
295 : const int16_t wc_strat_arith )
296 : {
297 : int16_t i, total_symbol_len;
298 : int16_t arith_result;
299 :
300 4633742 : total_symbol_len = 0;
301 41703678 : for ( i = 0; i < nB; i++ )
302 : {
303 37069936 : total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
304 : }
305 :
306 4633742 : assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
307 :
308 4633742 : if ( total_symbol_len > 0 )
309 : {
310 3993391 : if ( pArith_diff->range > 1 )
311 : {
312 3993391 : arith_result = ivas_arithCoder_encode_array_diff( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith );
313 3993391 : if ( arith_result < 0 )
314 : {
315 13311 : return -1;
316 : }
317 : }
318 : }
319 :
320 4620431 : return 0;
321 : }
322 :
323 :
324 : /*-----------------------------------------------------------------------------------------*
325 : * Function ivas_arith_encode_cmplx_cell_array()
326 : *
327 : * Arithmetic encode a cell array
328 : *-----------------------------------------------------------------------------------------*/
329 :
330 12651484 : int16_t ivas_arith_encode_cmplx_cell_array(
331 : ivas_arith_t *pArith_re,
332 : ivas_arith_t *pArith_re_diff,
333 : const int16_t *pDo_diff,
334 : const int16_t nB,
335 : int16_t *pSymbol_re,
336 : int16_t *pSymbol_old_re,
337 : ivas_cell_dim_t *pCell_dims,
338 : BSTR_ENC_HANDLE hMetaData,
339 : const int16_t any_diff,
340 : const int16_t wc_strat_arith )
341 : {
342 : int16_t input_old[IVAS_MAX_INPUT_LEN];
343 : int16_t input_new[IVAS_MAX_INPUT_LEN];
344 : int16_t input[IVAS_MAX_INPUT_LEN];
345 : ivas_cell_dim_t cell_dim[IVAS_MAX_NUM_BANDS], cell_dim_diff[IVAS_MAX_NUM_BANDS];
346 : int16_t len, idx, i, j, idx1;
347 : int16_t total_len;
348 : int16_t arith_result;
349 :
350 12651484 : idx1 = 0;
351 12651484 : if ( any_diff == 1 )
352 : {
353 4634281 : idx = 0;
354 4634281 : total_len = 0;
355 41708529 : for ( i = 0; i < nB; i++ )
356 : {
357 37074248 : len = ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
358 37074248 : if ( pDo_diff[i] != 0 )
359 : {
360 86822790 : for ( j = 0; j < len; j++ )
361 : {
362 59017104 : input_old[idx] = pSymbol_old_re[total_len + j];
363 59017104 : input_new[idx++] = pSymbol_re[total_len + j];
364 : }
365 27805686 : cell_dim_diff[i].dim1 = pCell_dims[i].dim1;
366 27805686 : cell_dim_diff[i].dim2 = pCell_dims[i].dim2;
367 27805686 : cell_dim[i].dim1 = 0;
368 27805686 : cell_dim[i].dim2 = 0;
369 : }
370 : else
371 : {
372 28940930 : for ( j = 0; j < len; j++ )
373 : {
374 19672368 : input[idx1++] = pSymbol_re[total_len + j];
375 : }
376 9268562 : cell_dim_diff[i].dim1 = 0;
377 9268562 : cell_dim_diff[i].dim2 = 0;
378 9268562 : cell_dim[i].dim1 = pCell_dims[i].dim1;
379 9268562 : cell_dim[i].dim2 = pCell_dims[i].dim2;
380 : }
381 37074248 : total_len += len;
382 : }
383 :
384 4634281 : arith_result = arith_encode_cell_array( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith );
385 4634281 : if ( arith_result < 0 )
386 : {
387 539 : return -1;
388 : }
389 :
390 4633742 : arith_result = arith_encode_cell_array_diff( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith );
391 4633742 : if ( arith_result < 0 )
392 : {
393 13311 : return -1;
394 : }
395 : }
396 : else
397 : {
398 8017203 : arith_result = arith_encode_cell_array( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith );
399 8017203 : if ( arith_result < 0 )
400 : {
401 392892 : return -1;
402 : }
403 : }
404 :
405 12244742 : return 0;
406 : }
|