From 0bc0a6db7f3bbb69d47e2c0220c407565e2a388f Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 4 Mar 2026 10:53:18 -0500 Subject: [PATCH 1/4] Adding debug code and aligning with float --- lib_com/bitstream_fx.c | 185 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 166 insertions(+), 19 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 634659c7f..e03b8e589 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -1026,6 +1026,9 @@ ivas_error check_ind_list_limits( /* the re-allocation can be avoided by increasing the limits in get_ivas_max_num_indices() or get_ivas_max_num_indices_metadata() */ IF( GE_16( (Word16) ( &hBstr->ind_list[hBstr->nb_ind_tot] - ivas_ind_list_zero ), *( hBstr->ivas_max_num_indices ) ) ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: The maximum number of indices %d has been exceeded in frame %d! Increase the limits in get_ivas_max_num_indices() or get_max_num_indices_metadata().\n", *( hBstr->ivas_max_num_indices ), frame ); +#endif /* reallocate the buffer of indices with increased limit */ IF( NE_32( ( error = ind_list_realloc( *hBstr->ivas_ind_list_zero, *( hBstr->ivas_max_num_indices ) + STEP_MAX_NUM_INDICES, hBstr->st_ivas ) ), IVAS_ERR_OK ) ) @@ -1039,6 +1042,9 @@ ivas_error check_ind_list_limits( { IF( hBstr->nb_ind_tot == 0 ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: Trying to overwrite an existing indice ID = %d in frame %d!\n", hBstr->ind_list[hBstr->nb_ind_tot].id, frame ); +#endif /* move the pointer to the next available empty slot */ ivas_ind_list_last = &ivas_ind_list_zero[*( hBstr->ivas_max_num_indices )]; WHILE( hBstr->ind_list[0].nb_bits > 0 && hBstr->ind_list < ivas_ind_list_last ) @@ -1048,6 +1054,9 @@ ivas_error check_ind_list_limits( IF( hBstr->ind_list >= ivas_ind_list_last ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: The maximum number of indices %d has been exceeded in frame %d! Increase the limits in get_ivas_max_num_indices() or get_max_num_indices_metadata().\n", *( hBstr->ivas_max_num_indices ), frame ); +#endif /* no available empty slot -> need to re-allocate the buffer */ IF( NE_32( ( error = ind_list_realloc( *hBstr->ivas_ind_list_zero, *( hBstr->ivas_max_num_indices ) + STEP_MAX_NUM_INDICES, hBstr->st_ivas ) ), IVAS_ERR_OK ) ) @@ -2964,6 +2973,18 @@ ivas_error push_indice( error = IVAS_ERR_OK; move32(); +#ifdef DEBUGGING + if ( nb_bits < ( 32 - 1 ) && ( value >> nb_bits ) > 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice ID = %d with value %d exceeds the range of %d bits (frame %d) !\n", id, value, nb_bits, frame ); + } + + if ( nb_bits > 16 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice ID = %d with value %d is trying to allocate %d bits which exceeds 16 bits (frame %d) !\n", id, value, nb_bits, frame ); + } + +#endif /* check the limits of the list of indices */ IF( NE_32( ( error = check_ind_list_limits( hBstr ) ), IVAS_ERR_OK ) ) @@ -3045,6 +3066,18 @@ ivas_error push_next_indice( error = IVAS_ERR_OK; move32(); +#ifdef DEBUGGING + if ( nb_bits < ( 32 - 1 ) && ( value >> nb_bits ) > 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice with value %d exceeds the range of %d bits (frame %d) !\n", value, nb_bits, frame ); + } + + if ( nb_bits > 16 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice with value %d is trying to allocate %d bits which exceeds 16 bits !\n", value, nb_bits ); + } + +#endif /* check the limits of the list of indices */ IF( NE_32( ( error = check_ind_list_limits( hBstr ) ), IVAS_ERR_OK ) ) @@ -3537,6 +3570,9 @@ static Word16 write_indices_to_stream_fx( Word16 i, k; Word16 value, nb_bits; UWord16 mask; +#ifdef ENABLE_BITRATE_VERIFICATION + int16_t total_nb_bits = 0; +#endif FOR( i = 0; i < num_indices; i++ ) { @@ -3547,6 +3583,9 @@ static Word16 write_indices_to_stream_fx( IF( nb_bits > 0 ) { +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits += nb_bits; +#endif /* mask from MSB to LSB */ mask = (UWord16) L_shl( 1, sub( nb_bits, 1 ) ); @@ -3569,9 +3608,22 @@ static Word16 write_indices_to_stream_fx( mask = (UWord16) L_shr( mask, 1 ); } } +#ifdef DEBUGGING + else if ( nb_bits == 0 ) + { + /* fprintf( stderr, "Warning: %s: nb_bits == 0!\n", __func__ ); */ + } + else + { + /* fprintf( stderr, "Warning: %s: nb_bits == %d!\n", __func__, nb_bits ); */ + } +#endif } - +#ifdef ENABLE_BITRATE_VERIFICATION + return total_nb_bits; +#else return 0; +#endif } @@ -3598,6 +3650,9 @@ static ivas_error write_indices_element_fx( Indice *ind_list_metadata; Word16 n, n_channels; +#ifdef ENABLE_BITRATE_VERIFICATION + int16_t total_nb_bits; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -3645,6 +3700,12 @@ static ivas_error write_indices_element_fx( move16(); } } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Bitstream writing error in frame %d. Exiting!\n", frame ); + } +#endif } n_channels = 1; @@ -3677,15 +3738,33 @@ static ivas_error write_indices_element_fx( pt_stream_loc += nb_bits_tot_metadata - 1; pt_stream_end = pt_stream_loc + 1; +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits = +#endif write_indices_to_stream_fx( ind_list_metadata, &pt_stream_loc, -1, nb_ind_tot_metadata ); +#ifdef ENABLE_BITRATE_VERIFICATION + if ( total_nb_bits != nb_bits_tot_metadata ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Written bits: %d vs. Reference bits: %d\n", total_nb_bits, nb_bits_tot_metadata ); + } +#endif /* restore previous pointer position */ pt_stream_loc = pt_stream_backup; } +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits = +#endif write_indices_to_stream_fx( sts[n]->hBstr->ind_list, &pt_stream_loc, 1, sts[n]->hBstr->nb_ind_tot ); +#ifdef ENABLE_BITRATE_VERIFICATION + if ( total_nb_bits != sts[n]->hBstr->nb_bits_tot ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Written bits: %d vs. Reference bits: %d\n", total_nb_bits, sts[n]->hBstr->nb_bits_tot ); + } +#endif if ( pt_stream_loc > pt_stream_end ) { pt_stream_end = pt_stream_loc; @@ -3808,6 +3887,11 @@ ivas_error write_indices_ivas_fx( { Word16 i, n; UWord16 *pt_stream; +#ifdef ENABLE_BITRATE_VERIFICATION + Encoder_State **sts; + int32_t ivas_total_brate; + int16_t ch; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -3820,6 +3904,46 @@ ivas_error write_indices_ivas_fx( move16(); } +#ifdef ENABLE_BITRATE_VERIFICATION + i = 0; + + for ( n = 0; n < st_ivas->nSCE; n++ ) + { + sts = st_ivas->hSCE[n]->hCoreCoder; + i += sts[0]->hBstr->nb_bits_tot; + + if ( st_ivas->hSCE[n]->hMetaData != NULL ) + { + i += st_ivas->hSCE[n]->hMetaData->nb_bits_tot; + } + } + + for ( n = 0; n < st_ivas->nCPE; n++ ) + { + sts = st_ivas->hCPE[n]->hCoreCoder; + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + i += sts[ch]->hBstr->nb_bits_tot; + } + + if ( st_ivas->hCPE[n]->hMetaData != NULL ) + { + i += st_ivas->hCPE[n]->hMetaData->nb_bits_tot; + } + } + + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + if ( st_ivas->hEncoderConfig->Opt_SC_VBR ) + { + ivas_total_brate = st_ivas->hSCE[0]->hCoreCoder[0]->total_brate; + } + + if ( i * FRAMES_PER_SEC != ivas_total_brate && i >= ACELP_11k60 / FRAMES_PER_SEC ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Actual bitrate: %ld vs. Reference bitrate: %d\n", i * 50L, ivas_total_brate ); + } +#endif + /*-----------------------------------------------------------------* * Encode Payload *-----------------------------------------------------------------*/ @@ -3951,6 +4075,9 @@ static void decoder_selectCodec( move16(); break; default: /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bitrates */ +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "Error illegal total bitrate (= %d) \n", total_brate ); +#endif st->codec_mode = st->last_codec_mode; move16(); st->bfi = 1; @@ -4044,6 +4171,12 @@ static void dec_prm_core( Decoder_State *st ) BREAK; } } +#ifdef DEBUGGING + if ( n == FRAME_SIZE_NB ) + { + assert( !"Bitrate not supported: not part of EVS" ); + } +#endif /* Get bandwidth mode */ st->bwidth = get_next_indice_fx( st, FrameSizeConfig[frame_size_index].bandwidth_bits ); @@ -4096,7 +4229,7 @@ static void dec_prm_core( Decoder_State *st ) /*-----------------------------------------------------------------* * decision_matrix_core_dec() * - * Read core mode signalling bits from the bitstream + * Read core signaling bits from the bitstream * Set st->core, and st->bwidth if signalled together with the core. *-----------------------------------------------------------------*/ @@ -4152,17 +4285,20 @@ static void decision_matrix_core_dec( } /*-----------------------------------------------------------------* - * Read ACELP signalling bits from the bitstream + * Read ACELP signaling bits from the bitstream *-----------------------------------------------------------------*/ IF( st->core == ACELP_CORE ) { - /* find the section in the ACELP signalling table corresponding to bitrate */ + /* find the section in the ACELP signaling table corresponding to bitrate */ start_idx = 0; move16(); WHILE( acelp_sig_tbl[start_idx] != st->total_brate ) { start_idx = add( start_idx, 1 ); +#ifdef DEBUGGING + assert( ( start_idx < 194 ) && "ERROR: start_idx larger than acelp_sig_tbl[].\n" ); +#endif } /* skip the bitrate */ @@ -4172,12 +4308,12 @@ static void decision_matrix_core_dec( nBits = extract_l( acelp_sig_tbl[start_idx] ); start_idx = add( start_idx, 1 ); - /* retrieve the signalling indice */ + /* retrieve the signaling indice */ ind = acelp_sig_tbl[start_idx + get_next_indice_fx( st, nBits )]; st->bwidth = extract_l( L_and( L_shr( ind, 3 ), 0x7 ) ); move16(); - /* convert signalling indice into signalling information */ + /* convert signaling indice into signaling information */ if ( EQ_32( L_and( ind, 0x7 ), LR_MDCT ) ) { st->core = HQ_CORE; @@ -4186,7 +4322,7 @@ static void decision_matrix_core_dec( } /*-----------------------------------------------------------------* - * Read HQ signalling bits from the bitstream + * Read HQ signaling bits from the bitstream * Set HQ core type *-----------------------------------------------------------------*/ @@ -4304,7 +4440,7 @@ void mdct_switching_dec_fx( } ELSE IF( EQ_16( st->codec_mode, MODE2 ) && EQ_16( st->mdct_sw_enable, MODE2 ) ) { - /* Read ahead core mode signaling */ + /* Read ahead core signaling */ Word16 next_bit_pos_save; Word16 core_save; Word16 bwidth_save; @@ -4591,7 +4727,7 @@ ivas_error read_indices_fx( } } - /* G.RX DTX handler*/ + /* RX DTX handler*/ /* handle SID_FIRST, SID_BAD, SPEECH_LOST, NO_DATA */ /* (total_brate, bfi , st_CNG) = rx_handler(received frame type, [previous frame type], past CNG state, past core) */ curr_ft_good_sp = 0; @@ -5232,7 +5368,7 @@ static UWord16 get_indice_preview( /*-------------------------------------------------------------------* * evs_dec_previewFrame() * - * Signalling index preview + * Signalling index preview for JBM *-------------------------------------------------------------------*/ void evs_dec_previewFrame( @@ -5252,14 +5388,14 @@ void evs_dec_previewFrame( move16(); *partialCopyOffset = 0; move16(); - total_brate = L_mult0( bitstreamSize, 50 ); + total_brate = L_mult0( bitstreamSize, FRAMES_PER_SEC ); IF( EQ_32( total_brate, ACELP_13k20 ) ) { /* find the section in the ACELP signalling table corresponding to bitrate */ start_idx = 0; move16(); - WHILE( acelp_sig_tbl[start_idx] != total_brate ) + WHILE( NE_32( acelp_sig_tbl[start_idx], total_brate ) ) { start_idx = add( start_idx, 1 ); assert( ( start_idx < MAX_ACELP_SIG ) && "ERROR: start_idx larger than acelp_sig_tbl[].\n" ); @@ -5269,22 +5405,33 @@ void evs_dec_previewFrame( start_idx = add( start_idx, 1 ); /* retrieve the number of bits */ nBits = extract_l( acelp_sig_tbl[start_idx++] ); - - /* retrieve the signalling indice */ + /* retrieve the signaling indice */ ind = acelp_sig_tbl[( start_idx + get_indice_preview( bitstream, bitstreamSize, 0, nBits ) )]; move32(); - /* convert signalling indice into RF flag. */ + /* convert signaling indice into RF flag. */ rf_flag = s_and( extract_l( L_shr( ind, 7 ) ), 0x1 ); assert( rf_flag == ( ( ind >> 7 ) & 0x1 ) ); IF( rf_flag != 0 ) { /* read the fec offset at which the partial copy is received */ ind = get_indice_preview( bitstream, bitstreamSize, sub( bitstreamSize, 5 ), 2 ); - IF( ind == 0 ) *partialCopyOffset = 2; - ELSE IF( EQ_32( ind, 1 ) ) *partialCopyOffset = 3; - ELSE IF( EQ_32( ind, 2 ) ) *partialCopyOffset = 5; - ELSE IF( EQ_32( ind, 3 ) ) *partialCopyOffset = 7; + IF( ind == 0 ) + { + *partialCopyOffset = 2; + } + ELSE IF( EQ_32( ind, 1 ) ) + { + *partialCopyOffset = 3; + } + ELSE IF( EQ_32( ind, 2 ) ) + { + *partialCopyOffset = 5; + } + ELSE IF( EQ_32( ind, 3 ) ) + { + *partialCopyOffset = 7; + } move16(); /* the last three bits in a packet is the RF frame type */ *partialCopyFrameType = get_indice_preview( bitstream, bitstreamSize, bitstreamSize - 3, 3 ); -- GitLab From 6b9cb43b8c74f9d6c65b2663daa3a1b52c49927e Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 4 Mar 2026 11:01:07 -0500 Subject: [PATCH 2/4] fix clang format --- lib_com/bitstream_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index e03b8e589..587ee52b9 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -3741,8 +3741,8 @@ static ivas_error write_indices_element_fx( #ifdef ENABLE_BITRATE_VERIFICATION total_nb_bits = #endif - write_indices_to_stream_fx( ind_list_metadata, &pt_stream_loc, -1, - nb_ind_tot_metadata ); + write_indices_to_stream_fx( ind_list_metadata, &pt_stream_loc, -1, + nb_ind_tot_metadata ); #ifdef ENABLE_BITRATE_VERIFICATION if ( total_nb_bits != nb_bits_tot_metadata ) @@ -3756,8 +3756,8 @@ static ivas_error write_indices_element_fx( #ifdef ENABLE_BITRATE_VERIFICATION total_nb_bits = #endif - write_indices_to_stream_fx( sts[n]->hBstr->ind_list, &pt_stream_loc, 1, - sts[n]->hBstr->nb_ind_tot ); + write_indices_to_stream_fx( sts[n]->hBstr->ind_list, &pt_stream_loc, 1, + sts[n]->hBstr->nb_ind_tot ); #ifdef ENABLE_BITRATE_VERIFICATION if ( total_nb_bits != sts[n]->hBstr->nb_bits_tot ) -- GitLab From 08b2d282f1a3359eb4705eb71064140f29d9f30b Mon Sep 17 00:00:00 2001 From: Tommy Vaillancourt Date: Wed, 4 Mar 2026 13:05:41 -0500 Subject: [PATCH 3/4] replace NO_DATA_TYPE by NO_DATA_RECEIVED to align with float --- lib_com/bitstream_fx.c | 2 +- lib_com/cnst.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_com/bitstream_fx.c b/lib_com/bitstream_fx.c index 587ee52b9..768f34767 100644 --- a/lib_com/bitstream_fx.c +++ b/lib_com/bitstream_fx.c @@ -270,7 +270,7 @@ Word16 rate2EVSmode( { /* EVS Primary modes */ case FRAME_NO_DATA: - return NO_DATA_TYPE; + return NO_DATA_RECEIVED; case SID_2k40: return PRIMARY_SID; case PPP_NELP_2k80: diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 14cad4e9d..f2f1a64e6 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -2683,7 +2683,7 @@ enum PRIMARY_SID, PRIMARY_FUT1, SPEECH_LOST, - NO_DATA_TYPE + NO_DATA_RECEIVED }; enum -- GitLab From 3a1584a5df13f8b23cb91960462c3696f38b5d0c Mon Sep 17 00:00:00 2001 From: vaclav Date: Thu, 26 Mar 2026 11:16:19 +0100 Subject: [PATCH 4/4] add the switch define to options.h to be inline with float --- lib_com/options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_com/options.h b/lib_com/options.h index b2727be5a..a403b4bbe 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -65,6 +65,7 @@ /*#define DBG_WAV_WRITER*/ /* Enable dbgwrite_wav() function for generating ".wav" files */ #define SUPPORT_FORCE_TCX10_TCX20 /* VA: Enable -force tcx10|tcx20 command-line option */ /*#define DEBUG_MODE_JBM */ /* define to output JBM relevant parameters */ +#define ENABLE_BITRATE_VERIFICATION /* Enable bitrate verification - use when playing with bit budget */ /*#define DEBUG_APA_SILENCE_NON_SCALED*/ /* Switch APA into mode that replaces contents of non-scaled frames with silence. Useful for identifying scaled regions in the audio output of the decoder */ #endif /* DEBUGGING */ -- GitLab