This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit b894a6f7c1c1af8cc1b6c5d949ba2e5ae2ab9b02 Author: James Almer <[email protected]> AuthorDate: Tue Sep 15 22:39:17 2026 -0300 Commit: James Almer <[email protected]> CommitDate: Sat Sep 19 19:00:27 2026 -0300 avcodec/libfdk-aacdec: clear and reset some fields when flushing The decoder can't know where a seek landed, so the "delay_samples" way to discard the decoder delay in the first frame is not truly viable, so it needs to be removed. Add a call to aacDecoder_DecodeFrame() with the AACDEC_CLRHIST flag set, as the call to aacDecoder_SetParam() with the AAC_TPDEC_CLEAR_BUFFER setting was seemingly not enough to truly flush all the fdkaac internal buffers. Should fix issue #24527. Signed-off-by: James Almer <[email protected]> --- libavcodec/libfdk-aacdec.c | 53 ++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/libavcodec/libfdk-aacdec.c b/libavcodec/libfdk-aacdec.c index 13f57c670b..15214eb587 100644 --- a/libavcodec/libfdk-aacdec.c +++ b/libavcodec/libfdk-aacdec.c @@ -65,7 +65,6 @@ typedef struct FDKAACDecContext { int output_delay_set; int flush_samples; int skip_samples; - int delay_samples; int output_delay; int discard_padding; int64_t last_pts; @@ -143,7 +142,6 @@ static int get_stream_info(AVCodecContext *avctx, AVFrame *frame) if (!s->output_delay_set && info->outputDelay) { // Set this only once. s->flush_samples = info->outputDelay; - s->delay_samples = info->outputDelay; s->skip_samples = info->outputDelay; s->output_delay = info->outputDelay; s->last_pts = AV_NOPTS_VALUE; @@ -474,7 +472,6 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, AVFrame *frame, AAC_DECODER_ERROR err; UINT valid = avpkt->size; UINT flags = 0; - int input_offset = 0; if (avpkt->size) { err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); @@ -567,35 +564,22 @@ static int fdk_aac_decode_frame(AVCodecContext *avctx, AVFrame *frame, AV_WL32(sd->data, skip_samples + s->skip_samples); s->skip_samples = 0; } - if (frame->pts != AV_NOPTS_VALUE && s->output_delay) { + if (frame->pts != AV_NOPTS_VALUE && s->output_delay) frame->pts = av_sat_sub64(frame->pts, av_rescale_q(s->output_delay, (AVRational){ 1, avctx->sample_rate }, avctx->time_base)); - if (frame->pkt_dts != AV_NOPTS_VALUE && s->output_delay) - frame->pkt_dts = av_sat_sub64(frame->pkt_dts, - av_rescale_q(s->output_delay, - (AVRational){ 1, avctx->sample_rate }, - avctx->time_base)); - s->delay_samples = 0; - s->last_pts = frame->pts; - s->last_dts = frame->pkt_dts; - } else if (s->delay_samples) { - // Trim off samples from the start to compensate for extra decoder - // delay, in the absense of timestamps. - int drop_samples = FFMIN(s->delay_samples, frame->nb_samples); - av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n", - drop_samples, s->delay_samples); - s->delay_samples -= drop_samples; - frame->nb_samples -= drop_samples; - input_offset = drop_samples * avctx->ch_layout.nb_channels; - if (frame->nb_samples <= 0) - return 0; - } + if (frame->pkt_dts != AV_NOPTS_VALUE && s->output_delay) + frame->pkt_dts = av_sat_sub64(frame->pkt_dts, + av_rescale_q(s->output_delay, + (AVRational){ 1, avctx->sample_rate }, + avctx->time_base)); + s->last_pts = frame->pts; + s->last_dts = frame->pkt_dts; } #endif - memcpy(frame->extended_data[0], s->decoder_buffer + input_offset, + memcpy(frame->extended_data[0], s->decoder_buffer, avctx->ch_layout.nb_channels * frame->nb_samples * av_get_bytes_per_sample(avctx->sample_fmt)); @@ -617,6 +601,25 @@ static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx) if ((err = aacDecoder_SetParam(s->handle, AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK) av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n"); + +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 + s->skip_samples = 0; + s->discard_padding = 0; + s->flush_samples = 0; + s->output_delay = 0; + s->last_pts = AV_NOPTS_VALUE; + s->last_dts = AV_NOPTS_VALUE; + s->output_delay_set = 0; + + // Call aacDecoder_DecodeFrame() with flush and clear history flags as the + // above aacDecoder_SetParam() call is seemingly not sufficient. + // Ignore the return code given it will not be AAC_DEC_OK if nothing is + // buffered internally (e.g. trying to flush the decoder before passing a + // single packet to it). + aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, + s->decoder_buffer_size / sizeof(INT_PCM), + AACDEC_FLUSH | AACDEC_CLRHIST); +#endif } const FFCodec ff_libfdk_aac_decoder = { -- 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]
