[PR] [release/5.1] avcodec/h264_direct: do not read the other field's rows of colocated mb_type (PR #24274)
ffmpeg-devel via ffmpeg-devel <[email protected]>
| Newsgroups | gmane.comp.video.ffmpeg.devel |
|---|---|
| Message-ID | <[email protected]> |
PR #24274 opened by ffmpeg-devel URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24274 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24274.patch **Backport:** https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24155 From 9748b8900b3f0b5825368cd3e2d38ae59e17e828 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 117a780235..af69064e9b 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1759,6 +1759,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 7499ccc61aaf933956b5979477b58d28a1354eb3 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 1bc28333ce..20bac73961 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -292,7 +292,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 + @@ -510,7 +511,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]