This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 202cde51adef18e0f90cd3211165edf0e3e1bf7e Author: Rainbaby <[email protected]> AuthorDate: Fri Aug 28 16:18:06 2026 +0900 Commit: Peter Ross <[email protected]> CommitDate: Mon Nov 2 22:18:06 2026 +0000 avcodec/cavsdec: do not re-parse slice headers The scanner advanced only past the picture start code, so every slice header was parsed twice, the second time with a stale h->stc. The second parse is what produced the wrong "weighted prediction not yet supported" warning of trac ticket 3885; decoded output is unchanged. A start code that is not a slice now ends the picture's data and is left unread; decoding past it fails unless a pending skip run covers the remaining macroblocks. Fixes: https://trac.ffmpeg.org/ticket/3885 Signed-off-by: Rainbaby <[email protected]> --- libavcodec/cavs.h | 1 + libavcodec/cavsdec.c | 57 +++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index fc80bf5aa9..2172ac9ac0 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -192,6 +192,7 @@ typedef struct AVSContext { int mbx, mby, mbidx; ///< macroblock coordinates int flags; ///< availability flags of neighbouring macroblocks int stc; ///< last start code + int pic_data_end; ///< a unit that is not a slice ended the picture's data uint8_t *cy, *cu, *cv; ///< current MB sample pointers int left_qp; uint8_t *top_qp; diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 953d2fc503..73212305c0 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -928,9 +928,6 @@ static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type) static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) { - if (h->stc > 0xAF) - av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc); - if (h->stc >= h->mb_height) { av_log(h->avctx, AV_LOG_ERROR, "stc 0x%02x is too large\n", h->stc); return AVERROR_INVALIDDATA; @@ -967,10 +964,19 @@ static inline int check_for_slice(AVSContext *h) if (!align && (show_bits(gb, 8) == 0x80)) align = 8; if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) { - skip_bits_long(gb, 24 + align); - h->stc = get_bits(gb, 8); - if (h->stc >= h->mb_height) + GetBitContext peek; + int stc; + + peek = *gb; + skip_bits_long(&peek, 24 + align); + stc = get_bits(&peek, 8); + /* any other unit ends the picture's data; leave it to the caller */ + if (stc > (SLICE_MAX_START_CODE & 0xFF)) { + h->pic_data_end = 1; return 0; + } + *gb = peek; + h->stc = stc; decode_slice_header(h, gb); return 1; } @@ -1098,17 +1104,36 @@ static int decode_pic(AVSContext *h) } ret = 0; + h->pic_data_end = 0; if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { do { - check_for_slice(h); + ret = check_for_slice(h); + if (ret < 0) + break; + if (h->pic_data_end) { + av_log(h->avctx, AV_LOG_ERROR, + "picture data ended before MB %d\n", h->mbidx); + ret = AVERROR_INVALIDDATA; + break; + } ret = decode_mb_i(h, 0); if (ret < 0) break; } while (ff_cavs_next_mb(h)); } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) { do { - if (check_for_slice(h)) + ret = check_for_slice(h); + if (ret < 0) + break; + if (ret) skip_count = -1; + /* past the picture's data, only a pending skip run can code MBs */ + if (h->pic_data_end && !(h->skip_mode_flag && skip_count > 0)) { + av_log(h->avctx, AV_LOG_ERROR, + "picture data ended before MB %d\n", h->mbidx); + ret = AVERROR_INVALIDDATA; + break; + } if (h->skip_mode_flag && (skip_count < 0)) { if (get_bits_left(&h->gb) < 1) { ret = AVERROR_INVALIDDATA; @@ -1134,8 +1159,18 @@ static int decode_pic(AVSContext *h) } while (ff_cavs_next_mb(h)); } else { /* AV_PICTURE_TYPE_B */ do { - if (check_for_slice(h)) + ret = check_for_slice(h); + if (ret < 0) + break; + if (ret) skip_count = -1; + /* past the picture's data, only a pending skip run can code MBs */ + if (h->pic_data_end && !(h->skip_mode_flag && skip_count > 0)) { + av_log(h->avctx, AV_LOG_ERROR, + "picture data ended before MB %d\n", h->mbidx); + ret = AVERROR_INVALIDDATA; + break; + } if (h->skip_mode_flag && (skip_count < 0)) { if (get_bits_left(&h->gb) < 1) { ret = AVERROR_INVALIDDATA; @@ -1314,9 +1349,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, //mpeg_decode_user_data(avctx, buf_ptr, input_size); break; default: - if (stc <= SLICE_MAX_START_CODE) { - decode_slice_header(h, &h->gb); - } + /* slice start codes are consumed by check_for_slice() */ break; } } -- 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]
