PR #24614 opened by nilfm99 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24614 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24614.patch
Tentative suggested fix to #24613; more details in the issue description. When the bitstream does not signal a reorder limit, the decoder derives the required delay from observed POC ordering. A reference B-frame may precede lower-POC pictures in decoding order. Reserve one additional reorder slot before selecting an output picture in that case. Keep predictive buffer growth at verbose log level while retaining the existing warning for growth based on observed ordering. >From 16ff1e578edd15227826691b719602d3040ab3c4 Mon Sep 17 00:00:00 2001 From: Nil Fons Miret <[email protected]> Date: Thu, 17 Sep 2026 18:55:36 +0000 Subject: [PATCH] avcodec/h264: account for reference B-frames in reorder depth When the bitstream does not signal a reorder limit, the decoder derives the required delay from observed POC ordering. A reference B-frame may precede lower-POC pictures in decoding order. Reserve one additional reorder slot before selecting an output picture in that case. Keep predictive buffer growth at verbose log level while retaining the existing warning for growth based on observed ordering. --- libavcodec/h264_slice.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 0ce8e46c72..278c50f9e5 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1296,7 +1296,7 @@ static int h264_select_output_frame(H264Context *h) const SPS *sps = h->ps.sps; H264Picture *out = h->cur_pic_ptr; H264Picture *cur = h->cur_pic_ptr; - int i, pics, out_of_order, out_idx; + int i, pics, out_of_order, out_idx, reference_delay = 0; cur->mmco_reset = h->mmco_reset; h->mmco_reset = 0; @@ -1316,9 +1316,21 @@ static int h264_select_output_frame(H264Context *h) } } out_of_order = H264_MAX_DPB_FRAMES - i; - if( cur->f->pict_type == AV_PICTURE_TYPE_B - || (h->last_pocs[H264_MAX_DPB_FRAMES-2] > INT_MIN && h->last_pocs[H264_MAX_DPB_FRAMES-1] - (int64_t)h->last_pocs[H264_MAX_DPB_FRAMES-2] > 2)) + if (cur->f->pict_type == AV_PICTURE_TYPE_B) { out_of_order = FFMAX(out_of_order, 1); + + /* A reference B-frame may precede B-frames with a lower POC in + * decoding order. Reserve one more slot before outputting it, as + * increasing the delay after seeing those frames would be too late. */ + if (!h->droppable && out_of_order < H264_MAX_DPB_FRAMES - 1) { + out_of_order++; + reference_delay = 1; + } + } else if (h->last_pocs[H264_MAX_DPB_FRAMES-2] > INT_MIN && + h->last_pocs[H264_MAX_DPB_FRAMES-1] - + (int64_t)h->last_pocs[H264_MAX_DPB_FRAMES-2] > 2) { + out_of_order = FFMAX(out_of_order, 1); + } if (out_of_order == H264_MAX_DPB_FRAMES) { av_log(h->avctx, AV_LOG_VERBOSE, "Invalid POC %d<%d\n", cur->poc, h->last_pocs[0]); for (i = 1; i < H264_MAX_DPB_FRAMES; i++) @@ -1326,7 +1338,8 @@ static int h264_select_output_frame(H264Context *h) h->last_pocs[0] = cur->poc; cur->mmco_reset = 1; } else if(h->avctx->has_b_frames < out_of_order && !sps->bitstream_restriction_flag){ - int loglevel = h->avctx->frame_num > 1 ? AV_LOG_WARNING : AV_LOG_VERBOSE; + int loglevel = h->avctx->frame_num > 1 && !reference_delay + ? AV_LOG_WARNING : AV_LOG_VERBOSE; av_log(h->avctx, loglevel, "Increasing reorder buffer to %d\n", out_of_order); h->avctx->has_b_frames = out_of_order; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
