diff mbox series

[FFmpeg-devel,2/3] h264: fix data-race with FF_DECODE_ERROR_CONCEALMENT_ACTIVE

Message ID 20230912114015.59937-2-thomas@gllm.fr
State New
Headers show
Series [FFmpeg-devel,1/3] error_resilience: set the decode_error_flags outside | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Thomas Guillem Sept. 12, 2023, 11:40 a.m. UTC
Set the FF_DECODE_ERROR_CONCEALMENT_ACTIVE flags on the AVFrane before
outputing it. Store in in the H264Picture in the meantime, where it
won't be read/write by other threads.

Fix the following data-race:

WARNING: ThreadSanitizer: data race (pid=55134)
  Write of size 4 at 0x7b5000007f78 by thread T1 (mutexes: write M58):
    #0 decode_nal_units src/libavcodec/h264dec.c:783 (ffmpeg+0xb1a678)
    #1 h264_decode_frame src/libavcodec/h264dec.c:1014 (ffmpeg+0xb1a678)
    #2 frame_worker_thread src/libavcodec/pthread_frame.c:228 (ffmpeg+0xdeea6e)

  Previous read of size 4 at 0x7b5000007f78 by thread T14 (mutexes: write M60):
    #0 frame_copy_props src/libavutil/frame.c:321 (ffmpeg+0x1793739)
    #1 av_frame_replace src/libavutil/frame.c:530 (ffmpeg+0x17946f4)
    #2 ff_thread_replace_frame src/libavcodec/utils.c:898 (ffmpeg+0xfb1cff)
    #3 ff_h264_replace_picture src/libavcodec/h264_picture.c:159 (ffmpeg+0x149cd2d)
    #4 ff_h264_update_thread_context src/libavcodec/h264_slice.c:413 (ffmpeg+0x14abee4)
    #5 update_context_from_thread src/libavcodec/pthread_frame.c:355 (ffmpeg+0xdec38c)
    #6 submit_packet src/libavcodec/pthread_frame.c:494 (ffmpeg+0xdeced3)
    #7 ff_thread_decode_frame src/libavcodec/pthread_frame.c:545 (ffmpeg+0xdeced3)
    #8 decode_simple_internal src/libavcodec/decode.c:431 (ffmpeg+0x9e1e20)
    #9 decode_simple_receive_frame src/libavcodec/decode.c:607 (ffmpeg+0x9e1e20)
    #10 decode_receive_frame_internal src/libavcodec/decode.c:635 (ffmpeg+0x9e1e20)
    #11 avcodec_send_packet src/libavcodec/decode.c:732 (ffmpeg+0x9e28fa)
    #12 packet_decode src/fftools/ffmpeg_dec.c:555 (ffmpeg+0x229888)
    #13 decoder_thread src/fftools/ffmpeg_dec.c:702 (ffmpeg+0x229888)
---
 libavcodec/h264_slice.c | 1 +
 libavcodec/h264dec.c    | 4 +++-
 libavcodec/h264dec.h    | 2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 6cd7bb8fe7..249c764d13 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -535,6 +535,7 @@  FF_ENABLE_DEPRECATION_WARNINGS
     pic->f->crop_right  = h->crop_right;
     pic->f->crop_top    = h->crop_top;
     pic->f->crop_bottom = h->crop_bottom;
+    pic->decode_error_flags = 0;
 
     pic->needs_fg = h->sei.common.film_grain_characteristics.present && !h->avctx->hwaccel &&
         !(h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN);
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 553f300c3d..24e849fc5b 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -780,7 +780,7 @@  end:
             ff_h264_set_erpic(&h->er.next_pic, sl->ref_list[1][0].parent);
 
         if (ff_er_frame_end(&h->er) > 0)
-            h->cur_pic_ptr->f->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
+            h->cur_pic_ptr->decode_error_flags |= FF_DECODE_ERROR_CONCEALMENT_ACTIVE;
         if (use_last_pic)
             memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0]));
     }
@@ -849,6 +849,8 @@  static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
     if (ret < 0)
         return ret;
 
+    dst->decode_error_flags |= srcp->decode_error_flags;
+
     if (srcp->needs_fg && (ret = av_frame_copy_props(dst, srcp->f)) < 0)
         return ret;
 
diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h
index beaab3902c..cb3d5cef00 100644
--- a/libavcodec/h264dec.h
+++ b/libavcodec/h264dec.h
@@ -152,6 +152,8 @@  typedef struct H264Picture {
 
     int mb_width, mb_height;
     int mb_stride;
+
+    int decode_error_flags;
 } H264Picture;
 
 typedef struct H264Ref {