[FFmpeg-devel] [PATCH 2/2] avcodec/h264: Use only one ERContext

Michael Niedermayer michaelni at gmx.at
Sat Apr 4 12:36:43 CEST 2015


This fixes slice threads with error concealment

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavcodec/h264.c         |    4 ++++
 libavcodec/h264_picture.c |    1 +
 libavcodec/h264_slice.c   |   12 ++++++------
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 62cb241..bbc7460 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -498,7 +498,11 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
     sl->ref_cache[1][scan8[7]  + 1] =
     sl->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
 
+    if (sl != h->slice_ctx) {
+        memset(er, 0, sizeof(*er));
+    } else
     if (CONFIG_ERROR_RESILIENCE) {
+
         /* init ER */
         er->avctx          = h->avctx;
         er->decode_mb      = h264_er_decode_mb;
diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c
index 76286ae..1880a58 100644
--- a/libavcodec/h264_picture.c
+++ b/libavcodec/h264_picture.c
@@ -184,6 +184,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
         ff_vdpau_h264_picture_complete(h);
 
 #if CONFIG_ERROR_RESILIENCE
+    av_assert0(sl == h->slice_ctx);
     /*
      * FIXME: Error handling code does not seem to support interlaced
      * when slices span multiple rows
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 3f400de..26a95ba 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1207,7 +1207,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
         if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
-            ff_h264_field_end(h, sl, 1);
+            ff_h264_field_end(h, h->slice_ctx, 1);
         }
 
         h->current_slice = 0;
@@ -2273,7 +2273,7 @@ static void decode_finish_row(const H264Context *h, H264SliceContext *sl)
 
     ff_h264_draw_horiz_band(h, sl, top, height);
 
-    if (h->droppable || sl->er.error_occurred)
+    if (h->droppable || sl->h264->slice_ctx[0].er.error_occurred)
         return;
 
     ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
@@ -2288,7 +2288,7 @@ static void er_add_slice(H264SliceContext *sl,
         return;
 
     if (CONFIG_ERROR_RESILIENCE) {
-        ERContext *er = &sl->er;
+        ERContext *er = &sl->h264->slice_ctx[0].er;
 
         ff_er_add_slice(er, startx, starty, endx, endy, status);
     }
@@ -2316,13 +2316,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                      avctx->codec_id != AV_CODEC_ID_H264 ||
                      (CONFIG_GRAY && (h->flags & CODEC_FLAG_GRAY));
 
-    if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && sl->er.error_status_table) {
+    if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->slice_ctx[0].er.error_status_table) {
         const int start_i  = av_clip(sl->resync_mb_x + sl->resync_mb_y * h->mb_width, 0, h->mb_num - 1);
         if (start_i) {
-            int prev_status = sl->er.error_status_table[sl->er.mb_index2xy[start_i - 1]];
+            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))
-                sl->er.error_occurred = 1;
+                h->slice_ctx[0].er.error_occurred = 1;
         }
     }
 
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list