[FFmpeg-cvslog] Merge commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85'

Clément Bœsch git at videolan.org
Thu Jun 30 10:26:31 CEST 2016


ffmpeg | branch: master | Clément Bœsch <clement at stupeflix.com> | Thu Jun 30 10:15:51 2016 +0200| [d407e76c42d5ae79791ff88d3bd5185e10ad6047] | committer: Clément Bœsch

Merge commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85'

* commit '2d410ebbaa1e760d6837cb434a6d1d4c3c6f0d85':
  h264: decode the MMCOs into per-slice contexts

Merged-by: Clément Bœsch <clement at stupeflix.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d407e76c42d5ae79791ff88d3bd5185e10ad6047
---

 libavcodec/h264.h       |    9 ++++++---
 libavcodec/h264_refs.c  |   44 +++++++++++++-------------------------------
 libavcodec/h264_slice.c |   21 ++++++++++-----------
 3 files changed, 29 insertions(+), 45 deletions(-)

diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index f0e4573..84cf59e 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -453,6 +453,9 @@ typedef struct H264SliceContext {
     CABACContext cabac;
     uint8_t cabac_state[1024];
     int cabac_init_idc;
+
+    MMCO mmco[MAX_MMCO_COUNT];
+    int  nb_mmco;
 } H264SliceContext;
 
 /**
@@ -728,10 +731,10 @@ void ff_h264_remove_all_refs(H264Context *h);
  */
 int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count);
 
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
-                                   int first_slice);
+int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
+                                   GetBitContext *gb);
 
-int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice);
+int ff_generate_sliding_window_mmcos(const H264Context *h, H264SliceContext *sl);
 
 void ff_h264_hl_decode_mb(const H264Context *h, H264SliceContext *sl);
 int ff_h264_decode_init(AVCodecContext *avctx);
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index e7ae447..c710012 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -601,9 +601,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
     return 0;
 }
 
-int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
+int ff_generate_sliding_window_mmcos(const H264Context *h,
+                                     H264SliceContext *sl)
 {
-    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+    MMCO *mmco = sl->mmco;
     int nb_mmco = 0, i = 0;
 
     if (h->short_ref_count &&
@@ -620,16 +621,8 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
         }
     }
 
-    if (first_slice) {
-        h->nb_mmco = nb_mmco;
-    } else if (!first_slice && nb_mmco >= 0 &&
-               (nb_mmco != h->nb_mmco ||
-                (i = check_opcodes(h->mmco, mmco_temp, nb_mmco)))) {
-        av_log(h->avctx, AV_LOG_ERROR,
-               "Inconsistent MMCO state between slices [%d, %d]\n",
-               nb_mmco, h->nb_mmco);
-        return AVERROR_INVALIDDATA;
-    }
+    sl->nb_mmco = nb_mmco;
+
     return 0;
 }
 
@@ -842,11 +835,11 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
     return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
 }
 
-int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
-                                   int first_slice)
+int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
+                                   GetBitContext *gb)
 {
     int i, ret;
-    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp;
+    MMCO *mmco = sl->mmco;
     int nb_mmco = 0;
 
     if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields
@@ -902,26 +895,15 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
             }
             nb_mmco = i;
         } else {
-            if (first_slice) {
-                ret = ff_generate_sliding_window_mmcos(h, first_slice);
-                if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
-                    return ret;
-            }
+            ret = ff_generate_sliding_window_mmcos(h, sl);
+            if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
+                return ret;
             nb_mmco = -1;
         }
     }
 
-    if (first_slice && nb_mmco != -1) {
-        memcpy(h->mmco, mmco_temp, sizeof(h->mmco));
-        h->nb_mmco = nb_mmco;
-    } else if (!first_slice && nb_mmco >= 0 &&
-               (nb_mmco != h->nb_mmco ||
-                check_opcodes(h->mmco, mmco_temp, nb_mmco))) {
-        av_log(h->avctx, AV_LOG_ERROR,
-               "Inconsistent MMCO state between slices [%d, %d]\n",
-               nb_mmco, h->nb_mmco);
-        return AVERROR_INVALIDDATA;
-    }
+    if (nb_mmco != -1)
+        sl->nb_mmco = nb_mmco;
 
     return 0;
 }
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index a63c9b9..cb52b77 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1421,10 +1421,12 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
             h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag;
             ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
             ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
-            ret = ff_generate_sliding_window_mmcos(h, 1);
+
+            ret = ff_generate_sliding_window_mmcos(h, sl);
             if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
-            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco);
+
+            ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco);
             if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
             /* Error concealment: If a ref is missing, copy the previous ref
@@ -1575,15 +1577,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
         ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,
                                   sl->slice_type_nos, &sl->pwt, h->avctx);
 
-    // If frame-mt is enabled, only update mmco tables for the first slice
-    // in a field. Subsequent slices can temporarily clobber h->nb_mmco
-    // or h->mmco, which will cause ref list mix-ups and decoding errors
-    // further down the line. This may break decoding if the first slice is
-    // corrupt, thus we only do this if frame-mt is enabled.
     if (h->nal_ref_idc) {
-        ret = ff_h264_decode_ref_pic_marking(h, &sl->gb,
-                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
-                                             h->current_slice == 0);
+        ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
         if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
             return AVERROR_INVALIDDATA;
     }
@@ -1674,10 +1669,14 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
         sl->resync_mb_y = sl->mb_y = sl->mb_y + 1;
     av_assert1(sl->mb_y < h->mb_height);
 
-    if (!h->setup_finished)
+    if (!h->setup_finished) {
         ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
                          h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc);
 
+        memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
+        h->nb_mmco = sl->nb_mmco;
+    }
+
     ret = ff_h264_build_ref_list(h, sl);
     if (ret < 0)
         return ret;


======================================================================

diff --cc libavcodec/h264_refs.c
index e7ae447,dae5565..c710012
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@@ -601,13 -536,16 +601,14 @@@ static int check_opcodes(MMCO *mmco1, M
      return 0;
  }
  
- int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
+ int ff_generate_sliding_window_mmcos(const H264Context *h,
+                                      H264SliceContext *sl)
  {
-     MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;
+     MMCO *mmco = sl->mmco;
      int nb_mmco = 0, i = 0;
  
 -    assert(h->long_ref_count + h->short_ref_count <= h->ps.sps->ref_frame_count);
 -
      if (h->short_ref_count &&
 -        h->long_ref_count + h->short_ref_count == h->ps.sps->ref_frame_count &&
 +        h->long_ref_count + h->short_ref_count >= h->ps.sps->ref_frame_count &&
          !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) {
          mmco[0].opcode        = MMCO_SHORT2UNUSED;
          mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
diff --cc libavcodec/h264_slice.c
index a63c9b9,6967edb..cb52b77
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@@ -1418,13 -1199,14 +1418,15 @@@ static int h264_slice_header_parse(H264
              h->poc.prev_frame_num++;
              h->poc.prev_frame_num        %= 1 << sps->log2_max_frame_num;
              h->cur_pic_ptr->frame_num = h->poc.prev_frame_num;
 +            h->cur_pic_ptr->invalid_gap = !sps->gaps_in_frame_num_allowed_flag;
              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
              ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
-             ret = ff_generate_sliding_window_mmcos(h, 1);
+ 
+             ret = ff_generate_sliding_window_mmcos(h, sl);
              if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                  return ret;
-             ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco);
+ 
+             ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco);
              if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                  return ret;
              /* Error concealment: If a ref is missing, copy the previous ref
@@@ -1573,17 -1342,10 +1575,10 @@@
          (pps->weighted_bipred_idc == 1 &&
           sl->slice_type_nos == AV_PICTURE_TYPE_B))
          ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,
 -                                  sl->slice_type_nos, &sl->pwt);
 +                                  sl->slice_type_nos, &sl->pwt, h->avctx);
  
-     // If frame-mt is enabled, only update mmco tables for the first slice
-     // in a field. Subsequent slices can temporarily clobber h->nb_mmco
-     // or h->mmco, which will cause ref list mix-ups and decoding errors
-     // further down the line. This may break decoding if the first slice is
-     // corrupt, thus we only do this if frame-mt is enabled.
      if (h->nal_ref_idc) {
-         ret = ff_h264_decode_ref_pic_marking(h, &sl->gb,
-                                              !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||
-                                              h->current_slice == 0);
+         ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
          if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
              return AVERROR_INVALIDDATA;
      }
@@@ -1672,9 -1434,9 +1667,9 @@@ int ff_h264_decode_slice_header(H264Con
                                   FIELD_OR_MBAFF_PICTURE(h);
      if (h->picture_structure == PICT_BOTTOM_FIELD)
          sl->resync_mb_y = sl->mb_y = sl->mb_y + 1;
 -    assert(sl->mb_y < h->mb_height);
 +    av_assert1(sl->mb_y < h->mb_height);
  
-     if (!h->setup_finished)
+     if (!h->setup_finished) {
          ff_h264_init_poc(h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc,
                           h->ps.sps, &h->poc, h->picture_structure, h->nal_ref_idc);
  



More information about the ffmpeg-cvslog mailing list