PR #25815 opened by Forgejo_Fairy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25815 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25815.patch
An SPS transition can increase `has_b_frames` after the previous sequence has emptied the delayed-picture queue. The existing `has_b_frames == 0` condition then prevents resetting `next_outputed_poc` at the new sequence boundary, causing pictures to be discarded against the preceding sequence's final POC. The JM reproduction in #25751 returns only 31 of 60 frames in strict mode; an explicitly signaled reorder-depth increase from zero to two also triggers the loss in normal mode. Check `pics == 1` after insertion instead, retaining the existing key-picture/MMCO-reset condition and handling of nonempty queues. Add `fate-h264-sps-reorder-transition` with all 60 expected frame hashes. The regression boundary was verified by building 44be1d6478cd and its immediate parent 51ae2142d5ec: strict decoding returns 31 and 60 frames respectively. Fixed output is byte-identical to the good parent's output and to normal decoding of the original sample on current master. Validation on ARM64: the reported input and control return all 60 frames with one and four decoding threads in both compliance modes; the signaled-depth variant returns 60 in both modes; repeated concatenation returns 120 frames. The new FATE test passes with one and four threads and fails against unmodified master. All 219 enabled H.264 FATE tests pass with four threads. The 2,287-byte synthetic [FATE sample and investigation tooling](https://code.ffmpeg.org/Forgejo_Fairy/FFmpeg/src/branch/fairy/issue25751-tooling/tools/issue25751) are preserved separately. The sample has not yet been submitted to samples-request at ffmpeg dot org; it needs installation as `h264/sps-reorder-transition.h264` before merge. SHA-256: `c627d756ab0f1463dbf6dfaa1d1a68cf575c78331feec9d5976fd3bbed476e7d`. Fixes #25751. >From b568fe542352a5445e9c6fb714fe7004e1f88644 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Fri, 6 Nov 2026 17:55:25 +0000 Subject: [PATCH] avcodec/h264: reset output POC at an empty-queue sequence boundary A new SPS can increase has_b_frames after the previous sequence has already emptied the delayed-picture queue. The has_b_frames == 0 condition then prevents resetting next_outputed_poc at the new IDR, and pictures with POCs below the previous sequence's final POC are silently discarded. Check whether the current picture is the only queued picture instead. Keep the existing key-picture/MMCO-reset condition and the handling of boundaries with older pictures still queued. Fixes #25751. The supplied 60-frame JM stream previously returned only 31 frames with strict compliance. Also fixes a signaled reorder-depth increase from zero to two in normal compliance mode. Add a FATE test with hashes verified against normal-mode decoding and the historical good parent 51ae2142d5ec. The 2,287-byte sample is generated by the recipe in #25751; SHA-256: c627d756ab0f1463dbf6dfaa1d1a68cf575c78331feec9d5976fd3bbed476e7d Regression introduced by 44be1d6478cd1549ec06d06d06db46c4287a3782. Assisted-by: Fairy --- libavcodec/h264_slice.c | 4 +- tests/fate/h264.mak | 4 +- tests/ref/fate/h264-sps-reorder-transition | 69 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/h264-sps-reorder-transition diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 2bcb64378dc..c987af8dd82 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1370,7 +1370,9 @@ static int h264_select_output_frame(H264Context *h) out = h->delayed_pic[i]; out_idx = i; } - if (h->avctx->has_b_frames == 0 && + // The previous sequence may have left the queue empty before the + // current SPS increased the reorder delay. + if (pics == 1 && ((h->delayed_pic[0]->f->flags & AV_FRAME_FLAG_KEY) || h->delayed_pic[0]->mmco_reset)) h->next_outputed_poc = INT_MIN; out_of_order = out->poc < h->next_outputed_poc; diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak index 1ee70f216df..a742f9cb39f 100644 --- a/tests/fate/h264.mak +++ b/tests/fate/h264.mak @@ -206,7 +206,8 @@ FATE_H264 := $(FATE_H264:%=fate-h264-conformance-%) \ FATE_H264-$(call FRAMECRC, H264, H264, H264_PARSER SCALE_FILTER) += $(FATE_H264_REINIT_TESTS:%=fate-h264-reinit-%) FATE_H264-$(call FRAMECRC, H264, H264, H264_PARSER) += $(FATE_H264) -FATE_H264-$(call FRAMEMD5, H264, H264, H264_PARSER) += fate-h264-extreme-plane-pred +FATE_H264-$(call FRAMEMD5, H264, H264, H264_PARSER) += fate-h264-extreme-plane-pred \ + fate-h264-sps-reorder-transition FATE_H264-$(call FRAMEMD5, MOV, H264) += fate-h264-crop-to-container FATE_H264-$(call DEMDEC, H264, H264, H264_PARSER) += fate-h264-encparams @@ -486,6 +487,7 @@ fate-h264-intra-refresh-recovery: CMD = framecrc -i $(TARGET_SAM fate-h264-invalid-ref-mod: CMD = framecrc -i $(TARGET_SAMPLES)/h264/h264refframeregression.mp4 -an -frames 10 -pix_fmt yuv420p10le -vf scale fate-h264-lossless: CMD = framecrc -i $(TARGET_SAMPLES)/h264/lossless.h264 fate-h264-mixed-nal-coding: CMD = framecrc -i $(TARGET_SAMPLES)/h264/mixed-nal-coding.mp4 +fate-h264-sps-reorder-transition: CMD = framemd5 -strict strict -i $(TARGET_SAMPLES)/h264/sps-reorder-transition.h264 fate-h264-ref-pic-mod-overflow: CMD = framecrc -i $(TARGET_SAMPLES)/h264/ref-pic-mod-overflow.h264 fate-h264-twofields-packet: CMD = framecrc -i $(TARGET_SAMPLES)/h264/twofields_packet.mp4 -an -frames 30 fate-h264-unescaped-extradata: CMD = framecrc -i $(TARGET_SAMPLES)/h264/unescaped_extradata.mp4 -an -frames 10 diff --git a/tests/ref/fate/h264-sps-reorder-transition b/tests/ref/fate/h264-sps-reorder-transition new file mode 100644 index 00000000000..44dc7e68a07 --- /dev/null +++ b/tests/ref/fate/h264-sps-reorder-transition @@ -0,0 +1,69 @@ +#format: frame checksums +#version: 2 +#hash: MD5 +#tb 0: 1/30 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 128x96 +#sar 0: 0/1 +#stream#, dts, pts, duration, size, hash +0, 0, 0, 1, 18432, 5543cb79e302cdf2ad0bb65ad6630505 +0, 1, 1, 1, 18432, db1d45f3bb38c43221d85132b4adbe8a +0, 2, 2, 1, 18432, a34ed513a3c7de30cfa86a4095c47898 +0, 3, 3, 1, 18432, 34b67681f90af1b19791383187bebe6a +0, 4, 4, 1, 18432, e58799d612f5a33fc2a01b4ac70d7a66 +0, 5, 5, 1, 18432, af3133dc0d37caa23bc5c4feee0d3776 +0, 6, 6, 1, 18432, 270ee423094ba95a5bb698ed45ceb230 +0, 7, 7, 1, 18432, 95768c632cde52455be3573101948575 +0, 8, 8, 1, 18432, 68e530fe3022229047cf61ad3c6994c7 +0, 9, 9, 1, 18432, 61714395674aa411b8288e810361d717 +0, 10, 10, 1, 18432, 3763d2f5a0f5da511b7166d0b1c8e987 +0, 11, 11, 1, 18432, e31722d4aa182d51f5868ca9641c23f6 +0, 12, 12, 1, 18432, 04a9a0de3fe748999a02f20d08de7168 +0, 13, 13, 1, 18432, 75b10d7eb05a105d3904f95950bac6ce +0, 14, 14, 1, 18432, c58543b0d8a2a43dfc7a61d99e7c8bbf +0, 15, 15, 1, 18432, 094ce727cc6fd0035032261ba4f42cf3 +0, 16, 16, 1, 18432, f5428a153d7f90963dd470d47dcf0b45 +0, 17, 17, 1, 18432, c32647f73898ca6a10a19f203ebe56be +0, 18, 18, 1, 18432, ebac6a32d913b6bed806d778d4600f60 +0, 19, 19, 1, 18432, 3344db9049b988f659a8cc4ed1313a69 +0, 20, 20, 1, 18432, f4dec42b144c959ebe35ef508ab44366 +0, 21, 21, 1, 18432, cde3c2f4d390e1baf203171494068c2a +0, 22, 22, 1, 18432, 72e8b667ed30c7650df5c4e7028441e0 +0, 23, 23, 1, 18432, 26dc66a1e1d107bc47870f0c1bd1bbb4 +0, 24, 24, 1, 18432, c03ccf7c9b5c2e0c649a32e42a24c430 +0, 25, 25, 1, 18432, a648271c54d5612ca7a2036ec93266d3 +0, 26, 26, 1, 18432, 0ac0859621abe057ec89899eda71adcc +0, 27, 27, 1, 18432, ebb061b6cd6755b53b1b535b989720fc +0, 28, 28, 1, 18432, 321c028ae9b3a2ba89aa96022c67e10d +0, 29, 29, 1, 18432, 99e267bc2c43f382f4255f557ca378fb +0, 30, 30, 1, 18432, 0c4999012f103a26115fe52ff380fbde +0, 31, 31, 1, 18432, 8edabc6fb777d4b2b0dded3995df4b87 +0, 32, 32, 1, 18432, 6f1771389341dd2d3a547e3b4dcb7b4b +0, 33, 33, 1, 18432, 12603f26a006861e6bb28226eedbe954 +0, 34, 34, 1, 18432, bf41e5d363b4065912f2fb521bcca4a1 +0, 35, 35, 1, 18432, 3cdaaeb2ff504ca577fa94b38c79fa97 +0, 36, 36, 1, 18432, 9150b84696a2c4cf5f36cd5f20e6f039 +0, 37, 37, 1, 18432, 8030de682d992de77d47dc48b1e24bb6 +0, 38, 38, 1, 18432, 45a19d4abf55189578ed34f75d4bb246 +0, 39, 39, 1, 18432, 91f33132729293777fbda8e3ab6adc2e +0, 40, 40, 1, 18432, ff2f1128d0e4e452955ff180ed6348a0 +0, 41, 41, 1, 18432, b433b6147828d17770b5623f0492107c +0, 42, 42, 1, 18432, 55b3d3c9f18d5b7c0a40801c31b617c3 +0, 43, 43, 1, 18432, d757f48644c854ece01ebfff21b1de84 +0, 44, 44, 1, 18432, 9756dde24789f9c93517600292f26f8c +0, 45, 45, 1, 18432, a24122db94d69a551108da6140381d32 +0, 46, 46, 1, 18432, 2b81a296d73ed50a4edf7af128e2313e +0, 47, 47, 1, 18432, 779a8e52204d4bf813ffbd7a066d5915 +0, 48, 48, 1, 18432, c32fe34cd6879f2b2807c49881ff84d2 +0, 49, 49, 1, 18432, 1b2b92bd8b61bd1f7f9956a7c22984f7 +0, 50, 50, 1, 18432, c979ca373ad3439b61c2a14a6f8df7ae +0, 51, 51, 1, 18432, a9a5075a4bd6abbdf10ff84081d162ae +0, 52, 52, 1, 18432, 45c9b533d45f6f455c0d3053b17ed0aa +0, 53, 53, 1, 18432, 4f30af554a8a07ceaf3ba75c700b08dc +0, 54, 54, 1, 18432, 6a977b1a3045fc24a6ea1a30e1112f06 +0, 55, 55, 1, 18432, 4ab9f7c3cdc5259447228e5d2bf61ffa +0, 56, 56, 1, 18432, 0d92ddf0bdae8962122e48589875fc74 +0, 57, 57, 1, 18432, 47568bf9e09f3b08db967481b6cbef80 +0, 58, 58, 1, 18432, 097816e295cf40aa6adf2998f99dd7e1 +0, 59, 59, 1, 18432, d59e283de1d1076ea4b76ffc4e8a2fdb -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
