[FFmpeg-devel] [PATCH] avcodec/error_resilience: Use atomic set on writing error_occurred per slice

Michael Niedermayer michael at niedermayer.cc
Mon Nov 27 00:26:56 EET 2017


This is more correct if multiple slices are handled in parallel

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 libavcodec/error_resilience.c | 6 +++---
 libavcodec/error_resilience.h | 2 +-
 libavcodec/h263dec.c          | 2 +-
 libavcodec/h264_slice.c       | 4 ++--
 libavcodec/mpegvideo.c        | 3 ++-
 libavcodec/vc1dec.c           | 2 +-
 6 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 8f172beca6..c9da30b84b 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -808,7 +808,7 @@ void ff_er_frame_start(ERContext *s)
     memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END,
            s->mb_stride * s->mb_height * sizeof(uint8_t));
     atomic_init(&s->error_count, 3 * s->mb_num);
-    s->error_occurred = 0;
+    atomic_init(&s->error_occurred, 0);
 }
 
 static int er_supported(ERContext *s)
@@ -864,7 +864,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty,
     }
 
     if (status & ER_MB_ERROR) {
-        s->error_occurred = 1;
+        atomic_store_explicit(&s->error_occurred, 1, memory_order_relaxed);
         atomic_store(&s->error_count, INT_MAX);
     }
 
@@ -892,7 +892,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty,
 
         prev_status &= ~ VP_START;
         if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) {
-            s->error_occurred = 1;
+            atomic_store_explicit(&s->error_occurred, 1, memory_order_relaxed);
             atomic_store(&s->error_count, INT_MAX);
         }
     }
diff --git a/libavcodec/error_resilience.h b/libavcodec/error_resilience.h
index 664a765659..5c000e13d1 100644
--- a/libavcodec/error_resilience.h
+++ b/libavcodec/error_resilience.h
@@ -62,7 +62,7 @@ typedef struct ERContext {
     ptrdiff_t b8_stride;
 
     atomic_int error_count;
-    int error_occurred;
+    atomic_int error_occurred;
     uint8_t *error_status_table;
     uint8_t *er_temp_buffer;
     int16_t *dc_val[3];
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index b222de793b..6fa8a657a4 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -637,7 +637,7 @@ retry:
             if (ff_h263_resync(s) < 0)
                 break;
             if (prev_y * s->mb_width + prev_x < s->mb_y * s->mb_width + s->mb_x)
-                s->er.error_occurred = 1;
+                atomic_store_explicit(&s->er.error_occurred, 1, memory_order_relaxed);
         }
 
         if (s->msmpeg4_version < 4 && s->h263_pred)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index da76b9293f..5b37596d81 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -2480,7 +2480,7 @@ static void decode_finish_row(const H264Context *h, H264SliceContext *sl)
 
     ff_h264_draw_horiz_band(h, sl, top, height);
 
-    if (h->droppable || sl->h264->slice_ctx[0].er.error_occurred)
+    if (h->droppable || atomic_load_explicit(&sl->h264->slice_ctx[0].er.error_occurred, memory_order_relaxed))
         return;
 
     ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
@@ -2532,7 +2532,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             int prev_status = h->slice_ctx[0].er.error_status_table[h->slice_ctx[0].er.mb_index2xy[start_i - 1]];
             prev_status &= ~ VP_START;
             if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END))
-                h->slice_ctx[0].er.error_occurred = 1;
+                atomic_store_explicit(&h->slice_ctx[0].er.error_occurred, 1, memory_order_relaxed);
         }
     }
 
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 2eb19c21bb..2581589bb7 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -49,6 +49,7 @@
 #include "thread.h"
 #include "wmv2.h"
 #include <limits.h>
+#include <stdatomic.h>
 
 static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,
                                    int16_t *block, int n, int qscale)
@@ -2592,6 +2593,6 @@ void ff_set_qscale(MpegEncContext * s, int qscale)
 
 void ff_mpv_report_decode_progress(MpegEncContext *s)
 {
-    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
+    if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !atomic_load_explicit(&s->er.error_occurred, memory_order_relaxed))
         ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0);
 }
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 96b8bb5364..648c7370fe 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -1058,7 +1058,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                 get_bits_count(&s->gb), s->gb.size_in_bits);
 //  if (get_bits_count(&s->gb) > buf_size * 8)
 //      return -1;
-        if(s->er.error_occurred && s->pict_type == AV_PICTURE_TYPE_B) {
+        if(atomic_load_explicit(&s->er.error_occurred, memory_order_relaxed) && s->pict_type == AV_PICTURE_TYPE_B) {
             ret = AVERROR_INVALIDDATA;
             goto err;
         }
-- 
2.15.0



More information about the ffmpeg-devel mailing list