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 111393a78b avcodec/aac: Reset SBR context (HE-AAC) when flushing AAC 
decoder
111393a78b is described below

commit 111393a78b3af7b66c717288bed0ac047bec07bb
Author:     Peter Krefting <[email protected]>
AuthorDate: Mon Oct 19 09:07:17 2026 +0100
Commit:     Lynne <[email protected]>
CommitDate: Sat Nov 7 06:22:42 2026 +0000

    avcodec/aac: Reset SBR context (HE-AAC) when flushing AAC decoder
    
    When calling avcodec_flush_buffers() on the AAC decoder, decoding an
    HE-AAC stream, the SBR state would not be cleared properly.
    
    See: https://ffmpeg.org/pipermail/ffmpeg-devel/2020-January/255176.html
    Assisted-by: OpenCode Big Pickle
---
 libavcodec/aac/aacdec.c               |  1 +
 libavcodec/aac/aacdec.h               |  1 +
 libavcodec/aac/aacdec_proc_template.c |  1 +
 libavcodec/aacsbr.h                   |  5 +++++
 libavcodec/aacsbr_template.c          | 18 ++++++++++++++++++
 5 files changed, 26 insertions(+)

diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c
index d66c363b58..ba167eaab7 100644
--- a/libavcodec/aac/aacdec.c
+++ b/libavcodec/aac/aacdec.c
@@ -566,6 +566,7 @@ static av_cold void flush(AVCodecContext *avctx)
                 for (j = 0; j <= 1; j++) {
                     memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved));
                 }
+                ac->proc.sbr_ctx_reset(ac, che);
             }
         }
     }
diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index 18412fb97a..1fb89ace61 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -458,6 +458,7 @@ typedef struct AACDecProc {
     void (*sbr_apply)(AACDecContext *ac, ChannelElement *che, int id_aac, int 
fl960,
                       void /* INTFLOAT */ *L, void /* INTFLOAT */ *R);
     void (*sbr_ctx_close)(ChannelElement *che);
+    void (*sbr_ctx_reset)(AACDecContext *ac, ChannelElement *che);
 } AACDecProc;
 
 /**
diff --git a/libavcodec/aac/aacdec_proc_template.c 
b/libavcodec/aac/aacdec_proc_template.c
index 327f3117b5..b56302a93f 100644
--- a/libavcodec/aac/aacdec_proc_template.c
+++ b/libavcodec/aac/aacdec_proc_template.c
@@ -444,5 +444,6 @@ static av_cold void AAC_RENAME(aac_proc_init)(AACDecProc 
*aac_proc)
     SET(sbr_decode_extension);
     SET(sbr_apply);
     SET(sbr_ctx_close);
+    SET(sbr_ctx_reset);
 #undef SET
 }
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index afc8ad188a..c330a13183 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -82,6 +82,11 @@ int ff_aac_sbr_ctx_alloc_init_fixed(AACDecContext *ac, 
ChannelElement **che, int
 void ff_aac_sbr_ctx_close(ChannelElement *che);
 void ff_aac_sbr_ctx_close_fixed(ChannelElement *che);
 
+/** Reset the SBR context contained in a ChannelElement, discarding all
+ *  inter-frame state while keeping the allocated transform contexts. */
+void ff_aac_sbr_ctx_reset(AACDecContext *ac, ChannelElement *che);
+void ff_aac_sbr_ctx_reset_fixed(AACDecContext *ac, ChannelElement *che);
+
 /** Decode one SBR element. */
 int ff_aac_sbr_decode_extension(AACDecContext *ac, ChannelElement *che,
                                 GetBitContext *gb, int crc, int cnt, int 
id_aac,
diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
index f398d79a61..b084b0b82e 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -123,6 +123,24 @@ av_cold void 
AAC_RENAME(ff_aac_sbr_ctx_close)(ChannelElement *che)
     av_tx_uninit(&sbr->mdct_ana);
 }
 
+av_cold void AAC_RENAME(ff_aac_sbr_ctx_reset)(AACDecContext *ac, 
ChannelElement *che)
+{
+    SpectralBandReplication *sbr = get_sbr(che);
+    int id_aac = sbr->id_aac;
+
+    /* Discard all inter-frame state. The transform contexts (mdct_ana,
+     * mdct) and the function pointer tables (dsp, c) at the end of the
+     * struct are set up once in ff_aac_sbr_ctx_alloc_init() and hold no
+     * stream state, so they are deliberately left untouched. */
+    memset(sbr, 0, offsetof(SpectralBandReplication, mdct_ana));
+
+    sbr->id_aac = id_aac;
+    sbr_turnoff(sbr);
+    sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE 
- (1280 - 128);
+    sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE 
- (1280 - 128);
+    AAC_RENAME(ff_ps_ctx_init)(&sbr->ps);
+}
+
 static int qsort_comparison_function_int16(const void *a, const void *b)
 {
     return *(const int16_t *)a - *(const int16_t *)b;

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