[PR] [release/4.4] avcodec/h264_direct: do not read the other field's rows of colocated mb_type (PR #24273)
ffmpeg-devel via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24273 opened by ffmpeg-devel URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24273 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24273.patch **Backport:** https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24155 From c51951a19182c14f10c70ad45eb442f1825c0ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]> Date: Thu, 30 Jul 2026 17:29:04 +0200 Subject: [PATCH 1/2] avcodec/h264_slice: clear the ER picture when starting a second field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit h264_frame_start() clears h->er.cur_pic, and decode_nal_units() only sets it again for pictures that are not field coded, right before running error concealment. A second field goes through neither, so h->er.cur_pic keeps pointing at whatever frame coded picture the context decoded earlier. With frame threading the two fields of a pair are decoded by different contexts, so whether this triggers depends on what the context that picks up the second field decoded before, which is why the number of bogus warnings varies between runs. Signed-off-by: Kacper Michajłow <[email protected]> (cherry picked from commit f1d318e5eb2eb487d2be4b4b721b93ae76fd5ba7) --- libavcodec/h264_slice.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 7e8ca89505..e60a7619a7 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1668,6 +1668,10 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, int field = h->picture_structure == PICT_BOTTOM_FIELD; release_unused_pictures(h, 0); h->cur_pic_ptr->tf.owner[field] = h->avctx; + /* h264_frame_start(), which clears this for every other picture, is + * not called for a second field. */ + if (CONFIG_ERROR_RESILIENCE) + ff_h264_set_erpic(&h->er.cur_pic, NULL); } /* Some macroblocks can be accessed before they're available in case * of lost slices, MBAFF or threading. */ -- 2.52.0 From 1016733cfe9a85967937a201808d53064c81eff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]> Date: Sat, 15 Aug 2026 00:36:22 +0200 Subject: [PATCH 2/2] avcodec/h264_direct: do not read the other field's rows of colocated mb_type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To determine whether the colocated picture is field coded, the temporal and spatial direct setup peek at sl->ref_list[1][0].parent->mb_type[mb_xy] before mb_xy has been remapped to the colocated field's parity. That row belongs to the current field's parity, while await_reference_mb_row() above waited on the parity of the referenced field, so whenever the two differ the load is unsynchronised and with frame threading can observe macroblocks of a field that is still being decoded. Every macroblock of a field picture has MB_TYPE_INTERLACED set, so checking field_picture first gives the same result in all correctly synchronized cases without touching the mb_type array. This also fixes few TSAN reported warnings. Fixes: https://trac.ffmpeg.org/ticket/10891 Signed-off-by: Kacper Michajłow <[email protected]> (cherry picked from commit c3a8a223b29260dc170d41c62f9b3b33f6b97b2d) --- libavcodec/h264_direct.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 7f4c34bc84..63460eae6f 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -293,7 +293,8 @@ static void pred_spatial_direct_motion(const H264Context *const h, H264SliceCont return; } - if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL + if (sl->ref_list[1][0].parent->field_picture || + IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (sl->mb_y & ~1) + sl->col_parity; mb_xy = sl->mb_x + @@ -511,7 +512,8 @@ static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext await_reference_mb_row(h, &sl->ref_list[1][0], sl->mb_y + !!IS_INTERLACED(*mb_type)); - if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL + if (sl->ref_list[1][0].parent->field_picture || + IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL mb_y = (sl->mb_y & ~1) + sl->col_parity; mb_xy = sl->mb_x + -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]