shithub: opus

Download patch

ref: 6d0628493550f4ef0eaecf3058a502404bc6dca2
parent: 4667b6992a738683e4b7d6667b9850ca0ee5fd7b
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Wed Oct 26 20:11:26 EDT 2016

Account for redundancy signalling when computing st->silk_mode.maxBits

Without that, we could bust the budget and end up with the
if (ec_tell(&enc) <= 8*nb_compr_bytes)
being false, followed by an assert failure later.

--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -1894,14 +1894,21 @@
         st->silk_mode.useCBR = !st->use_vbr;
 
         /* Call SILK encoder for the low band */
-        nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
 
-        st->silk_mode.maxBits = nBytes*8;
+        /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */
+        st->silk_mode.maxBits = IMIN(1275, max_data_bytes-1-redundancy_bytes)*8;
+        if (redundancy)
+        {
+           /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */
+           st->silk_mode.maxBits -= 1;
+           if (st->mode == MODE_HYBRID)
+              st->silk_mode.maxBits -= 20;
+        }
         if (st->silk_mode.useCBR)
         {
            if (st->mode == MODE_HYBRID)
            {
-              st->silk_mode.maxBits = st->silk_mode.bitRate * frame_size / st->Fs;
+              st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs);
            }
         } else {
            /* Constrained VBR. */
@@ -1908,7 +1915,7 @@
            if (st->mode == MODE_HYBRID)
            {
               /* Compute SILK bitrate corresponding to the max total bits available */
-              opus_int32 maxBitRate = compute_silk_rate_for_hybrid(nBytes*8*st->Fs / frame_size,
+              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);
               st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
            }