This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/9.0
in repository ffmpeg.

commit 5ee24ba241f71e05c316291d8b675c5ec4affe81
Author:     Lynne <[email protected]>
AuthorDate: Wed Sep 23 20:27:47 2026 +0900
Commit:     James Almer <[email protected]>
CommitDate: Thu Sep 24 23:20:27 2026 -0300

    avcodec/opus/enc: signal silence explicitly
    
    Silent frames were coded with zero bytes, which decoders take as a lost
    frame and conceal by extrapolating the preceding audio, rather than
    outputting silence. A packet of such frames is also only one or two
    bytes long, and the MPEG-TS muxer rejects packets shorter than two.
    
    Code the silence flag in a two byte frame like libopus does, and keep
    the encoder state in sync with the decoder after it: the decoder
    predicts the band energies of the next frame from CELT_ENERGY_SILENCE,
    and the pre-emphasis filter state at the start of the next overlap is
    zero. As silent frames no longer have a size of zero, leave them out of
    the rate control explicitly.
    
    (cherry picked from commit b726a3b8c48f0945a9fbee9a308e7b22b183db5c)
---
 libavcodec/opus/enc.c           | 11 +++++++++--
 libavcodec/opus/enc_psy.c       |  7 +++++--
 tests/ref/fate/opus-enc-silence |  4 ++--
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/libavcodec/opus/enc.c b/libavcodec/opus/enc.c
index bd48960c5e..e63293b63e 100644
--- a/libavcodec/opus/enc.c
+++ b/libavcodec/opus/enc.c
@@ -437,8 +437,15 @@ static void celt_encode_frame(OpusEncContext *s, 
OpusRangeCoder *rc,
     if (f->silence) {
         if (f->framebits >= 16)
             ff_opus_rc_enc_log(rc, 1, 15); /* Silence (if using explicit 
signalling) */
-        for (int ch = 0; ch < s->channels; ch++)
-            memset(s->last_quantized_energy[ch], 0.0f, 
sizeof(float)*CELT_MAX_BANDS);
+        for (int ch = 0; ch < s->channels; ch++) {
+            /* The decoder sets all band energies to CELT_ENERGY_SILENCE on
+             * a silence frame, and predicts the next frame's from them. */
+            for (int i = 0; i < CELT_MAX_BANDS; i++)
+                s->last_quantized_energy[ch][i] = CELT_ENERGY_SILENCE;
+            /* The frame is all zeros, so this is the pre emphasis filter state
+             * at the point the next frame's overlap starts */
+            f->block[ch].emph_coeff = 0.0f;
+        }
         return;
     }
 
diff --git a/libavcodec/opus/enc_psy.c b/libavcodec/opus/enc_psy.c
index a7a1f1ff8e..7b44978f19 100644
--- a/libavcodec/opus/enc_psy.c
+++ b/libavcodec/opus/enc_psy.c
@@ -311,7 +311,10 @@ void ff_opus_psy_celt_frame_init(OpusPsyContext *s, 
CeltFrame *f, int index)
 
     f->silence = silence;
     if (f->silence) {
-        f->framebits = 0; /* Otherwise the silence flag eats up 16(!) bits */
+        /* Explicitly signal silence in a 2 byte frame, like libopus does.
+         * A zero length frame would instead signal a lost frame to decoders,
+         * which conceal it by extrapolating the preceding audio. */
+        f->framebits = 16;
         f->intensity_stereo = f->end_band; /* Read by postencode_update for 
avg_is_band */
         return;
     }
@@ -546,7 +549,7 @@ void ff_opus_psy_postencode_update(OpusPsyContext *s, 
CeltFrame *f)
 
     for (i = 0; i < s->p.frames; i++) {
         s->avg_is_band += f[i].intensity_stereo;
-        if (f[i].framebits > 0)
+        if (!f[i].silence && f[i].framebits > 0)
             s->lambda *= ideal_fbits / f[i].framebits;
     }
 
diff --git a/tests/ref/fate/opus-enc-silence b/tests/ref/fate/opus-enc-silence
index dd8e02e02d..37f039f1f4 100644
--- a/tests/ref/fate/opus-enc-silence
+++ b/tests/ref/fate/opus-enc-silence
@@ -4,5 +4,5 @@
 #codec_id 0: opus
 #sample_rate 0: 48000
 #channel_layout_name 0: stereo
-0,       -120,       -120,      960,        1, 0x00fc00fc
-0,        840,        840,      168,        1, 0x00fc00fc, S=1, Skip Samples,  
     10, 0x009f001b
+0,       -120,       -120,      960,        3, 0x05f002f9
+0,        840,        840,      168,        3, 0x05f002f9, S=1, Skip Samples,  
     10, 0x009f001b

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to