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

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 564f92cce2 avcodec/ac3dec_fixed: preserve overlap across dependent 
substreams
564f92cce2 is described below

commit 564f92cce23ae95399476617b8a1dc357f002a47
Author:     Ayoub Nabil Boubagrat 
<[email protected]>
AuthorDate: Tue Aug 18 14:40:56 2026 +0200
Commit:     James Almer <[email protected]>
CommitDate: Wed Aug 19 01:54:15 2026 +0000

    avcodec/ac3dec_fixed: preserve overlap across dependent substreams
    
    ac-3 cores and dependent e-ac-3 substreams may use different
    coefficient scales while owning separate delay slots.
    
    the global reset added in 5ba2a2c841 cleared both sets of slots on
    every substream switch, corrupting the mdct overlap of valid 7.1
    streams.
    
    track the scale per substream and clear only its own delay slots when
    it changes. add a fate test using the existing the_great_wall sample.
    
    Signed-off-by: Ayoub Nabil Boubagrat 
<[email protected]>
---
 libavcodec/ac3dec.c | 30 +++++++++++++++++-------------
 libavcodec/ac3dec.h |  3 +++
 tests/fate/ac3.mak  |  9 ++++++++-
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index e3a711ebbf..9f85446bf4 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -1398,9 +1398,6 @@ static int ac3_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
     AC3DecodeContext *s = avctx->priv_data;
     int blk, ch, err, offset, ret;
     int i;
-#if USE_FIXED
-    int previous_coeff_bits;
-#endif
     int skip = 0, got_independent_frame = 0;
     const uint8_t *channel_map;
     uint8_t extended_channel_map[EAC3_MAX_CHANNELS];
@@ -1435,9 +1432,6 @@ static int ac3_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 
     buf = s->input_buffer;
 dependent_frame:
-#if USE_FIXED
-    previous_coeff_bits = fixed_coeff_bits(s);
-#endif
     /* initialize the GetBitContext with the start of valid AC-3 Frame */
     if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0)
         return ret;
@@ -1445,13 +1439,6 @@ dependent_frame:
     /* parse the syncinfo */
     err = parse_frame_header(s);
 
-#if USE_FIXED
-    /* Do not mix Q0 and Q2 overlap samples if a malformed or explicitly
-     * forced stream switches between E-AC-3 and AC-3. */
-    if (!err && previous_coeff_bits != fixed_coeff_bits(s))
-        memset(s->delay, 0, sizeof(s->delay));
-#endif
-
     if (err) {
         switch (err) {
         case AC3_PARSE_ERROR_SYNC:
@@ -1573,6 +1560,23 @@ dependent_frame:
     /* decode the audio blocks */
     channel_map = ff_ac3_dec_channel_map[s->output_mode & 
~AC3_OUTPUT_LFEON][s->lfe_on];
     offset = s->frame_type == EAC3_FRAME_TYPE_DEPENDENT ? AC3_MAX_CHANNELS : 0;
+#if USE_FIXED
+    /* delay[] holds overlap samples scaled by the coefficient format that was
+     * in use when they were produced. The independent and the dependent
+     * substream own disjoint delay slots and may legitimately use different
+     * formats, so only drop the overlap of the substream whose format really
+     * changed, as happens when a malformed or explicitly forced stream
+     * switches between E-AC-3 and AC-3. */
+    if (!err) {
+        const int coeff_bits = fixed_coeff_bits(s);
+        const int slot       = offset ? 1 : 0;
+
+        if (s->delay_coeff_bits[slot] != coeff_bits) {
+            memset(s->delay[offset], 0, AC3_MAX_CHANNELS * 
sizeof(s->delay[0]));
+            s->delay_coeff_bits[slot] = coeff_bits;
+        }
+    }
+#endif
     for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
         output[ch] = s->output[ch + offset];
         s->outptr[ch] = s->output[ch + offset];
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index 1a4da07fa3..c0e6f683ef 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -252,6 +252,9 @@ typedef struct AC3DecodeContext {
     DECLARE_ALIGNED(16, int,   fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; 
      ///< fixed-point transform coefficients
     DECLARE_ALIGNED(32, INTFLOAT, 
transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS];   ///< transform 
coefficients
     DECLARE_ALIGNED(32, INTFLOAT, delay)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE];   
      ///< delay - added to the next block
+#if USE_FIXED
+    int delay_coeff_bits[2];            ///< coefficient format of delay[], 
per substream
+#endif
     DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE];                     
         ///< window coefficients
     DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE];                 
         ///< temporary storage for output before windowing
     DECLARE_ALIGNED(32, SHORTFLOAT, 
output)[EAC3_MAX_CHANNELS][AC3_BLOCK_SIZE];            ///< output after imdct 
transform and windowing
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index 90977a80c0..70aa4f4568 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -63,10 +63,17 @@ FATE_EAC3 += fate-eac3-5
 fate-eac3-5: CMD = pcm -i $(TARGET_SAMPLES)/eac3/the_great_wall_7.1.eac3
 fate-eac3-5: REF = $(SAMPLES)/eac3/the_great_wall_7.1.pcm
 
-$(FATE_AC3) $(FATE_EAC3): CMP = oneoff
+# the fixed decoder has to keep the overlap of the independent substream when
+# the dependent substream uses a different coefficient format
+FATE_EAC3_FIXED += fate-eac3-fixed-dependent-substream
+fate-eac3-fixed-dependent-substream: CMD = pcm -c ac3_fixed -i 
$(TARGET_SAMPLES)/eac3/the_great_wall_7.1.eac3
+fate-eac3-fixed-dependent-substream: REF = 
$(SAMPLES)/eac3/the_great_wall_7.1.pcm
+
+$(FATE_AC3) $(FATE_EAC3) $(FATE_EAC3_FIXED): CMP = oneoff
 
 FATE_AC3-$(call  PCM, AC3,  AC3 AC3_FIXED, PCM_S16LE_MUXER ARESAMPLE_FILTER)  
+= $(FATE_AC3)
 FATE_EAC3-$(call PCM, EAC3, EAC3,          PCM_S16LE_MUXER ARESAMPLE_FILTER) 
+= $(FATE_EAC3)
+FATE_EAC3-$(call PCM, EAC3, EAC3 AC3_FIXED, PCM_S16LE_MUXER ARESAMPLE_FILTER) 
+= $(FATE_EAC3_FIXED)
 
 FATE_AC3-$(call ENCDEC, AC3, MP4 MOV, WAV_MUXER WAV_DEMUXER ARESAMPLE_FILTER 
PCM_S16LE_ENCODER PIPE_PROTOCOL) += fate-ac3-encode
 fate-ac3-encode: CMD = enc_dec_pcm mp4 wav s16le $(subst 
$(SAMPLES),$(TARGET_SAMPLES),$(REF)) -c:a ac3 -b:a 128k

-- 
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