Fixes a stereo rate mismatch bug
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Fri, 12 Aug 2011 20:17:27 +0000 (16:17 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Fri, 12 Aug 2011 20:22:29 +0000 (16:22 -0400)
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
silk/float/silk_main_FLP.h
silk/silk_control_codec.c
silk/silk_enc_API.c

index 88a9a4a..fa13f8d 100644 (file)
@@ -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
 );
 
 /****************/
index 43761ab..ddd5a61 100644 (file)
@@ -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
 );
 
 /****************/
index 0ddfac9..3075b34 100644 (file)
@@ -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      */
     /********************************************/
index 957b8f9..91e08ba 100644 (file)
@@ -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;
         }