h264: postpone generating the implicit MMCOs
authorAnton Khirnov <anton@khirnov.net>
Mon, 9 May 2016 12:25:56 +0000 (14:25 +0200)
committerAnton Khirnov <anton@khirnov.net>
Sun, 12 Jun 2016 18:27:53 +0000 (20:27 +0200)
Do it right before the MMCOs are applied to the DPB. This will allow
moving the frame_start() call out of the slice header parsing, since
generating the implicit MMCOs needs to be done after frame_start().

libavcodec/h264.h
libavcodec/h264_picture.c
libavcodec/h264_refs.c
libavcodec/h264_slice.c

index 227cdab..ee64981 100644 (file)
@@ -442,6 +442,7 @@ typedef struct H264SliceContext {
 
     MMCO mmco[MAX_MMCO_COUNT];
     int  nb_mmco;
+    int explicit_ref_marking;
 } H264SliceContext;
 
 /**
@@ -579,6 +580,7 @@ typedef struct H264Context {
     MMCO mmco[MAX_MMCO_COUNT];
     int  nb_mmco;
     int mmco_reset;
+    int explicit_ref_marking;
 
     int long_ref_count;     ///< number of actual long term references
     int short_ref_count;    ///< number of actual short term references
@@ -672,13 +674,11 @@ void ff_h264_remove_all_refs(H264Context *h);
 /**
  * Execute the reference picture marking (memory management control operations).
  */
-int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count);
+int ff_h264_execute_ref_pic_marking(H264Context *h);
 
 int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
                                    GetBitContext *gb);
 
-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);
 void ff_h264_decode_init_vlc(void);
index b16e3c0..cd7ff82 100644 (file)
@@ -154,7 +154,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
 
     if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {
         if (!h->droppable) {
-            err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco);
+            err = ff_h264_execute_ref_pic_marking(h);
             h->poc.prev_poc_msb = h->poc.poc_msb;
             h->poc.prev_poc_lsb = h->poc.poc_lsb;
         }
index dae5565..c4b33af 100644 (file)
@@ -536,11 +536,10 @@ static int check_opcodes(MMCO *mmco1, MMCO *mmco2, int n_mmcos)
     return 0;
 }
 
-int ff_generate_sliding_window_mmcos(const H264Context *h,
-                                     H264SliceContext *sl)
+static void generate_sliding_window_mmcos(H264Context *h)
 {
-    MMCO *mmco = sl->mmco;
-    int nb_mmco = 0, i = 0;
+    MMCO *mmco = h->mmco;
+    int nb_mmco = 0;
 
     assert(h->long_ref_count + h->short_ref_count <= h->ps.sps->ref_frame_count);
 
@@ -558,17 +557,21 @@ int ff_generate_sliding_window_mmcos(const H264Context *h,
         }
     }
 
-    sl->nb_mmco = nb_mmco;
-
-    return 0;
+    h->nb_mmco = nb_mmco;
 }
 
-int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
+int ff_h264_execute_ref_pic_marking(H264Context *h)
 {
+    MMCO *mmco = h->mmco;
+    int mmco_count;
     int i, av_uninit(j);
     int current_ref_assigned = 0, err = 0;
     H264Picture *av_uninit(pic);
 
+    if (!h->explicit_ref_marking)
+        generate_sliding_window_mmcos(h);
+    mmco_count = h->nb_mmco;
+
     if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0)
         av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");
 
@@ -739,7 +742,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)
 int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
                                    GetBitContext *gb)
 {
-    int i, ret;
+    int i;
     MMCO *mmco = sl->mmco;
     int nb_mmco = 0;
 
@@ -750,8 +753,10 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
             mmco[0].long_arg = 0;
             nb_mmco          = 1;
         }
+        sl->explicit_ref_marking = 1;
     } else {
-        if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag
+        sl->explicit_ref_marking = get_bits1(gb);
+        if (sl->explicit_ref_marking) {
             for (i = 0; i < MAX_MMCO_COUNT; i++) {
                 MMCOOpcode opcode = get_ue_golomb_31(gb);
 
@@ -795,16 +800,10 @@ int ff_h264_decode_ref_pic_marking(const H264Context *h, H264SliceContext *sl,
                     break;
             }
             nb_mmco = i;
-        } else {
-            ret = ff_generate_sliding_window_mmcos(h, sl);
-            if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE)
-                return ret;
-            nb_mmco = -1;
         }
     }
 
-    if (nb_mmco != -1)
-        sl->nb_mmco = nb_mmco;
+    sl->nb_mmco = nb_mmco;
 
     return 0;
 }
index 6967edb..23f4343 100644 (file)
@@ -418,6 +418,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
     memcpy(h->mmco, h1->mmco, sizeof(h->mmco));
     h->nb_mmco         = h1->nb_mmco;
     h->mmco_reset      = h1->mmco_reset;
+    h->explicit_ref_marking = h1->explicit_ref_marking;
     h->long_ref_count  = h1->long_ref_count;
     h->short_ref_count = h1->short_ref_count;
 
@@ -430,7 +431,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
         return 0;
 
     if (!h->droppable) {
-        err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->nb_mmco);
+        err = ff_h264_execute_ref_pic_marking(h);
         h->poc.prev_poc_msb = h->poc.poc_msb;
         h->poc.prev_poc_lsb = h->poc.poc_lsb;
     }
@@ -1202,11 +1203,8 @@ static int h264_slice_header_parse(H264Context *h, H264SliceContext *sl)
             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, sl);
-            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
-                return ret;
-
-            ret = ff_h264_execute_ref_pic_marking(h, sl->mmco, sl->nb_mmco);
+            h->explicit_ref_marking = 0;
+            ret = ff_h264_execute_ref_pic_marking(h);
             if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 return ret;
             /* Error concealment: If a ref is missing, copy the previous ref
@@ -1344,6 +1342,7 @@ 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);
 
+    sl->explicit_ref_marking = 0;
     if (h->nal_ref_idc) {
         ret = ff_h264_decode_ref_pic_marking(h, sl, &sl->gb);
         if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
@@ -1442,6 +1441,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
 
         memcpy(h->mmco, sl->mmco, sl->nb_mmco * sizeof(*h->mmco));
         h->nb_mmco = sl->nb_mmco;
+        h->explicit_ref_marking = sl->explicit_ref_marking;
     }
 
     ret = ff_h264_build_ref_list(h, sl);