This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch release/9.0 in repository ffmpeg.
commit b7401b97bda943bd37cf6b0a1ce0ba712768743c Author: J. Brandt Buckley <[email protected]> AuthorDate: Fri Aug 21 09:49:15 2026 -0600 Commit: Michael Niedermayer <[email protected]> CommitDate: Thu Sep 17 02:53:57 2026 +0200 avcodec/vc1_block: don't drop the last macroblock when 1 bit remains The P- and B-picture per-MB guards added in 2a8785966c bail out of the loop to error concealment when get_bits_left() <= 1, but P- and B-picture MBs can legitimately cost exactly 1 bit in certain cases. This patch relaxes the guards to accommodate those cases. ## Explanation With the SKIPMB bitplane in Raw mode a skipped macroblock is a single SKIPMBBIT (SMPTE ST 421:2013, 7.1.3.7, p.109) and then "may only contain the HYBRIDPRED syntax element" (8.3.4.4, p.140), which is only read when predictors A and C are in-bounds and the predicted vector differs from A or C by more than 32 quarter-pels (8.3.5.3.5, Figure 55, pp.149-150). That condition isn't met in a static region so such a MB costs just 1 bit. A direct+skipped B-picture MB likewise reads nothing beyond its raw flag (Table 30, p.86). In Simple/Main profile a picture is byte-aligned with no stop bit, so if a picture ends with a 1-bit skipped macroblock and its last coded bit lands on a byte boundary, the final MB is reached with exactly one bit left. The guard then conceals a valid macroblock, sets FF_DECODE_ERROR_CONCEALMENT_ACTIVE on an undamaged frame, and the damage propagates to every frame up to the next keyframe. (Advanced Profile BDUs end in a trailing '1' bit per Annex E.2/E.3 p.437, so they always have at least two bit left and are therefore unaffected.) ## Reproducing Reproducible with an existing sample (prior to this patch): $ ffmpeg -i https://samples.ffmpeg.org/V-codecs/WMV9/wmv-samples/[email protected] -map 0:v -f null - 2>&1 | grep -A1 concealing [wmv3 @ 0x122605430] concealing 75 DC, 75 AC, 75 MV errors in P frame [vist#0:0/wmv3 @ 0x122604080] [dec:wmv3 @ 0x122604df0] corrupt decoded frame [wmv3 @ 0x122605430] concealing 50 DC, 50 AC, 50 MV errors in P frame [vist#0:0/wmv3 @ 0x122604080] [dec:wmv3 @ 0x122604df0] corrupt decoded frame [wmv3 @ 0x122605430] concealing 100 DC, 100 AC, 100 MV errors in P frame [vist#0:0/wmv3 @ 0x122604080] [dec:wmv3 @ 0x122604df0] corrupt decoded frame ## References - SMPTE ST 421:2013 spec: https://pub.smpte.org/doc/st421/20131008-pub/ Signed-off-by: J. Brandt Buckley <[email protected]> (cherry picked from commit ec8411e8548de7270f6e799cdc94f45b7a7a92d3) Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/vc1_block.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index 10cb459082..a84c853b6f 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -2788,7 +2788,7 @@ static void vc1_decode_p_blocks(VC1Context *v) update_block_index(s); if (v->fcm == ILACE_FIELD || (v->fcm == PROGRESSIVE && v->mv_type_is_raw) || v->skip_is_raw) - if (get_bits_left(&v->gb) <= 1) { + if (get_bits_left(&v->gb) < 1) { ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); return; } @@ -2873,7 +2873,7 @@ static void vc1_decode_b_blocks(VC1Context *v) update_block_index(s); if (v->fcm == ILACE_FIELD || v->skip_is_raw || v->dmb_is_raw) - if (get_bits_left(&v->gb) <= 1) { + if (get_bits_left(&v->gb) < 1) { ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); return; } -- 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]
