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 865982 : 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 865982 : int16_t range = pArith->range;
64 865982 : int16_t m, offset = -pArith->vals[0];
65 : ivas_error error;
66 :
67 865982 : error = IVAS_ERR_OK;
68 :
69 12468308 : for ( i = 0; i < range + 1; i++ )
70 : {
71 11602326 : n[i] = 0;
72 : }
73 :
74 18152638 : for ( i = 0; i < length; i++ )
75 : {
76 17286656 : n[pInput[i] + offset] += 1;
77 : }
78 :
79 865982 : curr_bps = 0;
80 11602326 : for ( i = 0; i < range; i++ )
81 : {
82 10736344 : curr_dist[i] = (float) n[i];
83 10736344 : curr_bps -= ( curr_dist[i] * pArith->saved_dist_arr[0][i] );
84 : }
85 865982 : curr_bps_min = curr_bps;
86 :
87 865982 : model_idx = 0;
88 :
89 3463928 : for ( m = 0; m < pArith->num_models - 1; m++ )
90 : {
91 2597946 : curr_bps_new = 0;
92 34806978 : for ( i = 0; i < range; i++ )
93 : {
94 32209032 : curr_bps_new -= ( curr_dist[i] * pArith->saved_dist_arr[m + 1][i] );
95 : }
96 :
97 2597946 : if ( curr_bps_new < curr_bps_min )
98 : {
99 778327 : model_idx = m;
100 778327 : curr_bps_min = curr_bps_new;
101 : }
102 : }
103 :
104 865982 : if ( curr_bps_min < curr_bps )
105 : {
106 499708 : *ppCum_freq = pArith->cum_freq[model_idx + 1];
107 499708 : model_idx = model_idx + 1;
108 : }
109 : else
110 : {
111 366274 : model_idx = 0;
112 366274 : *ppCum_freq = pArith->cum_freq[0];
113 : }
114 :
115 865982 : *model_index = model_idx;
116 :
117 865982 : return error;
118 : }
119 :
120 :
121 : /*-----------------------------------------------------------------------------------------*
122 : * Function ivas_arith_encode_array()
123 : *
124 : * Arith encoding of an array of symbols
125 : *-----------------------------------------------------------------------------------------*/
126 :
127 865982 : 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 865982 : int16_t *pCum_freq = NULL;
136 : Tastat as;
137 :
138 865982 : if ( in_len > 0 && pArith->range > 1 )
139 : {
140 865982 : if ( pArith->dyn_model_bits > 0 )
141 : {
142 865982 : ivas_get_dyn_freq_model( pInput, in_len, &model_index, pArith, &pCum_freq );
143 865982 : if ( ( hMetaData->nb_bits_tot + pArith->dyn_model_bits ) > wc_strat_arith )
144 : {
145 2 : return -1;
146 : }
147 :
148 865980 : 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 865980 : ari_start_encoding_14bits( &as );
156 :
157 18070467 : for ( i = 0; i < in_len; i++ )
158 : {
159 17226623 : ind = pInput[i] - pArith->vals[0];
160 :
161 17226623 : ivas_ari_encode_14bits_ext( hMetaData, &as, ind, (const uint16_t *) pCum_freq );
162 17226623 : if ( hMetaData->nb_bits_tot > wc_strat_arith )
163 : {
164 22136 : return -1;
165 : }
166 : }
167 :
168 843844 : ivas_ari_done_encoding_14bits( hMetaData, &as );
169 843844 : if ( hMetaData->nb_bits_tot > wc_strat_arith )
170 : {
171 5280 : return -1;
172 : }
173 : }
174 :
175 838564 : return 0;
176 : }
177 :
178 :
179 : /*-----------------------------------------------------------------------------------------*
180 : * Function ivas_arithCoder_encode_array_diff()
181 : *
182 : * Differential arith encoding
183 : *-----------------------------------------------------------------------------------------*/
184 :
185 226250 : 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 226250 : if ( length > 0 )
197 : {
198 3487124 : for ( n = 0; n < length; n++ )
199 : {
200 3260874 : pIn_old_scratch[n] = pIn_new[n] - pIn_old_scratch[n];
201 : }
202 :
203 226250 : ivas_wrap_arround( pIn_old_scratch, pArith_diff->vals[0], pArith_diff->vals[pArith_diff->range - 1], length );
204 :
205 226250 : arith_result = ivas_arith_encode_array( pIn_old_scratch, pArith_diff, hMetaData, length, wc_strat_arith );
206 226250 : if ( arith_result < 0 )
207 : {
208 903 : return -1;
209 : }
210 : }
211 :
212 225347 : return 0;
213 : }
214 :
215 :
216 : /*-----------------------------------------------------------------------------------------*
217 : * Function ivas_huffman_encode()
218 : *
219 : * ivas_huffman_encode
220 : *-----------------------------------------------------------------------------------------*/
221 :
222 4632982 : 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 4632982 : min_sym_val = huff_cfg->codebook[0];
232 :
233 4632982 : codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )];
234 4632982 : *hlen = codebook[1];
235 4632982 : *hcode = codebook[2];
236 :
237 4632982 : return;
238 : }
239 :
240 :
241 : /*-----------------------------------------------------------------------------------------*
242 : * Function arith_encode_cell_array()
243 : *
244 : * Arithmetic encode a cell array
245 : *-----------------------------------------------------------------------------------------*/
246 :
247 759404 : 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 759404 : int16_t total_symbol_len = 0;
256 : int16_t i;
257 : int16_t arith_result;
258 :
259 6795624 : for ( i = 0; i < nB; i++ )
260 : {
261 6036220 : total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
262 : }
263 :
264 759404 : assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
265 :
266 759404 : if ( total_symbol_len > 0 )
267 : {
268 639732 : if ( pArith->range > 1 )
269 : {
270 639732 : arith_result = ivas_arith_encode_array( pSymbol, pArith, hMetaData, total_symbol_len, wc_strat_arith );
271 639732 : if ( arith_result < 0 )
272 : {
273 26515 : return -1;
274 : }
275 : }
276 : }
277 :
278 732889 : return 0;
279 : }
280 :
281 :
282 : /*-----------------------------------------------------------------------------------------*
283 : * Function arith_encode_cell_array_diff()
284 : *
285 : * Arithmetic encode a cell array - differential
286 : *-----------------------------------------------------------------------------------------*/
287 :
288 254398 : 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 254398 : total_symbol_len = 0;
301 2289582 : for ( i = 0; i < nB; i++ )
302 : {
303 2035184 : total_symbol_len += ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
304 : }
305 :
306 254398 : assert( total_symbol_len <= ( IVAS_MAX_INPUT_LEN ) );
307 :
308 254398 : if ( total_symbol_len > 0 )
309 : {
310 226250 : if ( pArith_diff->range > 1 )
311 : {
312 226250 : arith_result = ivas_arithCoder_encode_array_diff( pArith_diff, pSymbol, pSymbol_old, total_symbol_len, hMetaData, wc_strat_arith );
313 226250 : if ( arith_result < 0 )
314 : {
315 903 : return -1;
316 : }
317 : }
318 : }
319 :
320 253495 : return 0;
321 : }
322 :
323 :
324 : /*-----------------------------------------------------------------------------------------*
325 : * Function ivas_arith_encode_cmplx_cell_array()
326 : *
327 : * Arithmetic encode a cell array
328 : *-----------------------------------------------------------------------------------------*/
329 :
330 759404 : 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 759404 : idx1 = 0;
351 759404 : if ( any_diff == 1 )
352 : {
353 254435 : idx = 0;
354 254435 : total_len = 0;
355 2289915 : for ( i = 0; i < nB; i++ )
356 : {
357 2035480 : len = ( pCell_dims[i].dim1 * pCell_dims[i].dim2 );
358 2035480 : if ( pDo_diff[i] != 0 )
359 : {
360 4787928 : for ( j = 0; j < len; j++ )
361 : {
362 3261318 : input_old[idx] = pSymbol_old_re[total_len + j];
363 3261318 : input_new[idx++] = pSymbol_re[total_len + j];
364 : }
365 1526610 : cell_dim_diff[i].dim1 = pCell_dims[i].dim1;
366 1526610 : cell_dim_diff[i].dim2 = pCell_dims[i].dim2;
367 1526610 : cell_dim[i].dim1 = 0;
368 1526610 : cell_dim[i].dim2 = 0;
369 : }
370 : else
371 : {
372 1595976 : for ( j = 0; j < len; j++ )
373 : {
374 1087106 : input[idx1++] = pSymbol_re[total_len + j];
375 : }
376 508870 : cell_dim_diff[i].dim1 = 0;
377 508870 : cell_dim_diff[i].dim2 = 0;
378 508870 : cell_dim[i].dim1 = pCell_dims[i].dim1;
379 508870 : cell_dim[i].dim2 = pCell_dims[i].dim2;
380 : }
381 2035480 : total_len += len;
382 : }
383 :
384 254435 : arith_result = arith_encode_cell_array( cell_dim, hMetaData, nB, pArith_re, input, wc_strat_arith );
385 254435 : if ( arith_result < 0 )
386 : {
387 37 : return -1;
388 : }
389 :
390 254398 : arith_result = arith_encode_cell_array_diff( cell_dim_diff, hMetaData, nB, pArith_re_diff, input_old, input_new, wc_strat_arith );
391 254398 : if ( arith_result < 0 )
392 : {
393 903 : return -1;
394 : }
395 : }
396 : else
397 : {
398 504969 : arith_result = arith_encode_cell_array( pCell_dims, hMetaData, nB, pArith_re, pSymbol_re, wc_strat_arith );
399 504969 : if ( arith_result < 0 )
400 : {
401 26478 : return -1;
402 : }
403 : }
404 :
405 731986 : return 0;
406 : }
|