This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/5.1
in repository ffmpeg.

commit c5279ae2f6e5561f7a0f55b5ed359875a0dc8459
Author:     Kacper Michajłow <[email protected]>
AuthorDate: Thu Jul 30 17:27:09 2026 +0200
Commit:     ffmpeg-devel <[email protected]>
CommitDate: Fri Aug 14 12:40:37 2026 +0000

    avcodec/h264_direct: await both fields of a colocated field pair
    
    When a frame coded picture uses a complementary field pair as its
    colocated picture, ff_h264_direct_ref_list_init() selects the field whose
    POC is closest to the current one and stores it in col_parity. The direct
    mode setup then remaps mb_xy to that parity and reads the colocated
    mb_type, motion_val and ref_index from it.
    
    await_reference_mb_row() waits on the field given by "ref_field_picture &&
    ref_field", which is 1 for any such reference, since the pair is
    referenced as a frame and ref->reference is 3. Only the bottom field is
    therefore awaited, while the data is just as likely to be read from the
    top one. With frame threading the two fields are decoded by different
    threads, so the colocated data can be read while the field it belongs to
    is still being decoded, yielding stale motion vectors and a corrupt
    frame. await_references() already handles the same case correctly for
    motion compensation.
    
    Fixes sporadic failures of fate-h264-conformance-cabac_mot_picaff0_full,
    where display frame 14.
    
    Signed-off-by: Kacper Michajłow <[email protected]>
    (cherry picked from commit 274cb6731bd204e9537a7e588d4a3436fdf51b93)
---
 libavcodec/h264_direct.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index 89553228db..1bc28333ce 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -190,14 +190,19 @@ static void await_reference_mb_row(const H264Context 
*const h, H264Ref *ref,
     int ref_field         = ref->reference - 1;
     int ref_field_picture = ref->parent->field_picture;
     int ref_height        = 16 * h->mb_height >> ref_field_picture;
+    int row               = FFMIN(16 * mb_y >> ref_field_picture, ref_height - 
1);
 
     /* FIXME: It can be safe to access mb stuff
      * even if pixels aren't deblocked yet. */
 
-    ff_thread_await_progress(&ref->parent->tf,
-                             FFMIN(16 * mb_y >> ref_field_picture,
-                                   ref_height - 1),
+    ff_thread_await_progress(&ref->parent->tf, row,
                              ref_field_picture && ref_field);
+
+    /* A frame references a field pair as a whole, so the wait above covers
+     * its bottom field only, while the colocated data is read from the field
+     * selected by col_parity. The two are decoded by different threads. */
+    if (ref_field_picture && !FIELD_PICTURE(h))
+        ff_thread_await_progress(&ref->parent->tf, row, 0);
 }
 
 static void pred_spatial_direct_motion(const H264Context *const h, 
H264SliceContext *sl,

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to