From b63e22cff9601ab2249ce5b6371a5ca9e663ce09 Mon Sep 17 00:00:00 2001
From: Jean-Marc Valin <jmvalin@amazon.com>
Date: Tue, 19 Dec 2023 01:55:28 -0500
Subject: [PATCH] Fix desync for CBR DRED

The encoder wouldn't reserve enough bits for CELT, causing it
to not have enough bits to code the switching redundancy flag
when it should have.
---
 src/opus_encoder.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index d90de3262..9222596a8 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -2143,8 +2143,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
             opus_int32 dred_bytes = dred_bitrate_bps/(frame_rate*8);
             /* Allow CELT to steal up to 25% of the remaining bits. */
             max_celt_bytes = nb_compr_bytes - dred_bytes*3/4;
-            /* But try to give CELT at least 4 bytes */
-            max_celt_bytes = IMAX(ec_tell(&enc)/8 + 4, max_celt_bytes);
+            /* But try to give CELT at least 5 bytes to prevent a mismatch with
+               the redundancy signaling. */
+            max_celt_bytes = IMAX((ec_tell(&enc)+7)/8 + 5, max_celt_bytes);
             /* Subject to the original max. */
             nb_compr_bytes = IMIN(nb_compr_bytes, max_celt_bytes);
         }
-- 
GitLab