From 3120e225c24e1be35df9a76dd4bf9ce57e8111ca Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Fri, 12 Aug 2011 16:17:27 -0400 Subject: [PATCH] Fixes a stereo rate mismatch bug This is a tentative fix for a bug found in fuzzing where the encoder switched from mono to stereo while in the process of changing bandwidth. The result was that the newly added side would use the new sampling rate, while the mid hadn't switched yet, causing an encoder/decoder mismatch. The fix is that the side rate selection gets overridden to use the mid rate. The bug would occur when compiling with fuzzing enabled and using: ./test_opus 0 48000 2 24000 input.sw output.sw --- silk/fixed/silk_main_FIX.h | 3 ++- silk/float/silk_main_FLP.h | 3 ++- silk/silk_control_codec.c | 6 ++++-- silk/silk_enc_API.c | 4 +++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/silk/fixed/silk_main_FIX.h b/silk/fixed/silk_main_FIX.h index 88a9a4af..fa13f8d3 100644 --- a/silk/fixed/silk_main_FIX.h +++ b/silk/fixed/silk_main_FIX.h @@ -81,7 +81,8 @@ opus_int silk_control_encoder( silk_EncControlStruct *encControl, /* I: Control structure */ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb /* I Channel number */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz ); /****************/ diff --git a/silk/float/silk_main_FLP.h b/silk/float/silk_main_FLP.h index 43761ab4..ddd5a612 100644 --- a/silk/float/silk_main_FLP.h +++ b/silk/float/silk_main_FLP.h @@ -79,7 +79,8 @@ opus_int silk_control_encoder( silk_EncControlStruct *encControl, /* I: Control structure */ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb /* I Channel number */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz ); /****************/ diff --git a/silk/silk_control_codec.c b/silk/silk_control_codec.c index 0ddfac9a..3075b347 100644 --- a/silk/silk_control_codec.c +++ b/silk/silk_control_codec.c @@ -65,7 +65,8 @@ opus_int silk_control_encoder( silk_EncControlStruct *encControl, /* I: Control structure */ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb /* I Channel number */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz ) { opus_int fs_kHz, ret = 0; @@ -96,7 +97,8 @@ opus_int silk_control_encoder( /* Determine internal sampling rate */ /********************************************/ fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn ); - + if (force_fs_kHz) + fs_kHz = force_fs_kHz; /********************************************/ /* Prepare resampler and buffered data */ /********************************************/ diff --git a/silk/silk_enc_API.c b/silk/silk_enc_API.c index 957b8f96..91e08ba6 100644 --- a/silk/silk_enc_API.c +++ b/silk/silk_enc_API.c @@ -201,7 +201,9 @@ opus_int silk_Encode( TargetRate_bps = SKP_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 ); for( n = 0; n < encControl->nChannelsInternal; n++ ) { - if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n ) ) != 0 ) { + /* JMV: Force the side channel to the same rate as the mid. Is this the right way? */ + int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; + if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { SKP_assert( 0 ); return ret; }