shithub: opus

Download patch

ref: f3cff05eeb83ec8c055b7331338d705af220358d
parent: 95c48711f60092ad9108fe78d4b84c5a3eac84ad
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Sat Jul 15 23:01:41 EDT 2017

Better rate allocation for stereo SILK in hybrid mode

SILK was being allocated too few bits for stereo hybrid, often resulting
in forced narrowing of the width. We now allocate more bits to SILK
and reduce the threshold for narrowing. This improves quality enough that
the bitrate threshold for switching to SILK can be increased to 44 kb/s.

--- a/silk/stereo_LR_to_MS.c
+++ b/silk/stereo_LR_to_MS.c
@@ -109,7 +109,7 @@
     if( total_rate_bps < 1 ) {
         total_rate_bps = 1;
     }
-    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );
+    min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
     silk_assert( min_mid_rate_bps < 32767 );
     /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
     frac_3_Q16 = silk_MUL( 3, frac_Q16 );
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -154,7 +154,7 @@
 static const opus_int32 mode_thresholds[2][2] = {
       /* voice */ /* music */
       {  64000,      16000}, /* mono */
-      {  36000,      16000}, /* stereo */
+      {  44000,      16000}, /* stereo */
 };
 
 static const opus_int32 fec_thresholds[] = {
@@ -762,7 +762,7 @@
    return 0;
 }
 
-static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec) {
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) {
    int entry;
    int i;
    int N;
@@ -779,6 +779,8 @@
       {32000, 22000, 22000, 28000, 28000},
       {64000, 38000, 38000, 50000, 50000}
    };
+   /* Do the allocation per-channel. */
+   rate /= channels;
    entry = 1 + frame20ms + 2*fec;
    N = sizeof(rate_table)/sizeof(rate_table[0]);
    for (i=1;i<N;i++)
@@ -805,6 +807,10 @@
    }
    if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
       silk_rate += 300;
+   silk_rate *= channels;
+   /* The CELT layer saves a bit more than SILK for stereo, so we boost SILK. */
+   if (channels == 2 && rate >= 12000)
+      silk_rate += 1000;
    return silk_rate;
 }
 
@@ -1673,7 +1679,8 @@
         if( st->mode == MODE_HYBRID ) {
             /* Base rate for SILK */
             st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
-                  curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
+                  curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+                  st->stream_channels);
             if (!st->energy_masking)
             {
                /* Increasingly attenuate high band when it gets allocated fewer bits */
@@ -1788,7 +1795,8 @@
            {
               /* Compute SILK bitrate corresponding to the max total bits available */
               opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
-                    curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded);
+                    curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
+                    st->stream_channels);
               st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
            }
         }