LCOV - code coverage report
Current view: top level - lib_enc - ivas_entropy_coder_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ f7a4b6f767ef1ec4f02b3ec4a38e8e0dbd8aeb80 Lines: 149 150 99.3 %
Date: 2025-05-29 01:58:57 Functions: 7 7 100.0 %

          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             : }

Generated by: LCOV version 1.14