]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264_slice.c
Merge commit '64c81b2cd0dcf1fe66c381a5d2c707dddcf35a7e'
[ffmpeg] / libavcodec / h264_slice.c
index e9a89d11f7c972cd822a79332ae733f7bd0174cd..1d34bcc04582222f9068245efaf2f92ee1cc1d01 100644 (file)
@@ -384,9 +384,11 @@ void ff_h264_init_dequant_tables(H264Context *h)
 /**
  * Mimic alloc_tables(), but for every context thread.
  */
-static void clone_tables(H264Context *dst, H264Context *src, int i)
+static void clone_tables(H264Context *dst, H264SliceContext *sl,
+                         H264Context *src, int i)
 {
-    dst->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * src->mb_stride;
+    sl->intra4x4_pred_mode     = src->intra4x4_pred_mode + i * 8 * 2 * src->mb_stride;
+
     dst->non_zero_count         = src->non_zero_count;
     dst->slice_table            = src->slice_table;
     dst->cbp_table              = src->cbp_table;
@@ -521,6 +523,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
     memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));
 
     if (!inited) {
+        H264SliceContext *orig_slice_ctx = h->slice_ctx;
+
         for (i = 0; i < MAX_SPS_COUNT; i++)
             av_freep(h->sps_buffers + i);
 
@@ -545,6 +549,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
         memset(&h->cur_pic, 0, sizeof(h->cur_pic));
         memset(&h->last_pic_for_ec, 0, sizeof(h->last_pic_for_ec));
 
+        h->slice_ctx = orig_slice_ctx;
+
         h->avctx             = dst;
         h->DPB               = NULL;
         h->qscale_table_pool = NULL;
@@ -600,7 +606,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
     h->coded_picture_number = h1->coded_picture_number;
     h->first_field          = h1->first_field;
     h->picture_structure    = h1->picture_structure;
-    h->qscale               = h1->qscale;
     h->droppable            = h1->droppable;
     h->low_delay            = h1->low_delay;
 
@@ -877,13 +882,13 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y,
  * @param field  0/1 initialize the weight for interlaced MBAFF
  *                -1 initializes the rest
  */
-static void implicit_weight_table(H264Context *h, int field)
+static void implicit_weight_table(H264Context *h, H264SliceContext *sl, int field)
 {
     int ref0, ref1, i, cur_poc, ref_start, ref_count0, ref_count1;
 
     for (i = 0; i < 2; i++) {
-        h->luma_weight_flag[i]   = 0;
-        h->chroma_weight_flag[i] = 0;
+        sl->luma_weight_flag[i]   = 0;
+        sl->chroma_weight_flag[i] = 0;
     }
 
     if (field < 0) {
@@ -894,8 +899,8 @@ static void implicit_weight_table(H264Context *h, int field)
         }
         if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF(h) &&
             h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) {
-            h->use_weight        = 0;
-            h->use_weight_chroma = 0;
+            sl->use_weight        = 0;
+            sl->use_weight_chroma = 0;
             return;
         }
         ref_start  = 0;
@@ -908,10 +913,10 @@ static void implicit_weight_table(H264Context *h, int field)
         ref_count1 = 16 + 2 * h->ref_count[1];
     }
 
-    h->use_weight               = 2;
-    h->use_weight_chroma        = 2;
-    h->luma_log2_weight_denom   = 5;
-    h->chroma_log2_weight_denom = 5;
+    sl->use_weight               = 2;
+    sl->use_weight_chroma        = 2;
+    sl->luma_log2_weight_denom   = 5;
+    sl->chroma_log2_weight_denom = 5;
 
     for (ref0 = ref_start; ref0 < ref_count0; ref0++) {
         int poc0 = h->ref_list[0][ref0].poc;
@@ -929,10 +934,10 @@ static void implicit_weight_table(H264Context *h, int field)
                 }
             }
             if (field < 0) {
-                h->implicit_weight[ref0][ref1][0] =
-                h->implicit_weight[ref0][ref1][1] = w;
+                sl->implicit_weight[ref0][ref1][0] =
+                sl->implicit_weight[ref0][ref1][1] = w;
             } else {
-                h->implicit_weight[ref0][ref1][field] = w;
+                sl->implicit_weight[ref0][ref1][field] = w;
             }
         }
     }
@@ -1224,7 +1229,6 @@ static int h264_slice_header_init(H264Context *h, int reinit)
             c->uvlinesize        = h->uvlinesize;
             c->chroma_x_shift    = h->chroma_x_shift;
             c->chroma_y_shift    = h->chroma_y_shift;
-            c->qscale            = h->qscale;
             c->droppable         = h->droppable;
             c->low_delay         = h->low_delay;
             c->mb_width          = h->mb_width;
@@ -1235,8 +1239,10 @@ static int h264_slice_header_init(H264Context *h, int reinit)
             c->workaround_bugs   = h->workaround_bugs;
             c->pict_type         = h->pict_type;
 
+            h->slice_ctx[i].h264 = c;
+
             init_scan_tables(c);
-            clone_tables(c, h, i);
+            clone_tables(c, &h->slice_ctx[i], h, i);
             c->context_initialized = 1;
         }
 
@@ -1277,7 +1283,7 @@ static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a)
  *
  * @return 0 if okay, <0 if an error occurred, 1 if decoding must not be multithreaded
  */
-int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
+int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Context *h0)
 {
     unsigned int first_mb_in_slice;
     unsigned int pps_id;
@@ -1811,15 +1817,15 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
     if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||
         (h->pps.weighted_bipred_idc == 1 &&
          h->slice_type_nos == AV_PICTURE_TYPE_B))
-        ff_pred_weight_table(h);
+        ff_pred_weight_table(h, sl);
     else if (h->pps.weighted_bipred_idc == 2 &&
              h->slice_type_nos == AV_PICTURE_TYPE_B) {
-        implicit_weight_table(h, -1);
+        implicit_weight_table(h, sl, -1);
     } else {
-        h->use_weight = 0;
+        sl->use_weight = 0;
         for (i = 0; i < 2; i++) {
-            h->luma_weight_flag[i]   = 0;
-            h->chroma_weight_flag[i] = 0;
+            sl->luma_weight_flag[i]   = 0;
+            sl->chroma_weight_flag[i] = 0;
         }
     }
 
@@ -1837,11 +1843,11 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
     }
 
     if (FRAME_MBAFF(h)) {
-        ff_h264_fill_mbaff_ref_list(h);
+        ff_h264_fill_mbaff_ref_list(h, sl);
 
         if (h->pps.weighted_bipred_idc == 2 && h->slice_type_nos == AV_PICTURE_TYPE_B) {
-            implicit_weight_table(h, 0);
-            implicit_weight_table(h, 1);
+            implicit_weight_table(h, sl, 0);
+            implicit_weight_table(h, sl, 1);
         }
     }
 
@@ -1864,9 +1870,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
         av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
         return AVERROR_INVALIDDATA;
     }
-    h->qscale       = tmp;
-    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
+    sl->qscale       = tmp;
+    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
     // FIXME qscale / qp ... stuff
     if (h->slice_type == AV_PICTURE_TYPE_SP)
         get_bits1(&h->gb); /* sp_for_switch_flag */
@@ -1936,7 +1942,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
             }
         }
     }
-    h->qp_thresh = 15 -
+    sl->qp_thresh = 15 -
                    FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) -
                    FFMAX3(0,
                           h->pps.chroma_qp_index_offset[0],
@@ -2007,11 +2013,11 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)
                h->cur_pic_ptr->field_poc[0],
                h->cur_pic_ptr->field_poc[1],
                h->ref_count[0], h->ref_count[1],
-               h->qscale,
+               sl->qscale,
                h->deblocking_filter,
                h->slice_alpha_c0_offset, h->slice_beta_offset,
-               h->use_weight,
-               h->use_weight == 1 && h->use_weight_chroma ? "c" : "",
+               sl->use_weight,
+               sl->use_weight == 1 && sl->use_weight_chroma ? "c" : "",
                h->slice_type == AV_PICTURE_TYPE_B ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "");
     }
 
@@ -2120,7 +2126,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
  *
  * @return non zero if the loop filter can be skipped
  */
-static int fill_filter_caches(H264Context *h, int mb_type)
+static int fill_filter_caches(H264Context *h, H264SliceContext *sl, int mb_type)
 {
     const int mb_xy = h->mb_xy;
     int top_xy, left_xy[LEFT_MBS];
@@ -2149,14 +2155,14 @@ static int fill_filter_caches(H264Context *h, int mb_type)
         }
     }
 
-    h->top_mb_xy        = top_xy;
-    h->left_mb_xy[LTOP] = left_xy[LTOP];
-    h->left_mb_xy[LBOT] = left_xy[LBOT];
+    sl->top_mb_xy        = top_xy;
+    sl->left_mb_xy[LTOP] = left_xy[LTOP];
+    sl->left_mb_xy[LBOT] = left_xy[LBOT];
     {
         /* For sufficiently low qp, filtering wouldn't do anything.
          * This is a conservative estimate: could also check beta_offset
          * and more accurate chroma_qp. */
-        int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
+        int qp_thresh = sl->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
         int qp        = h->cur_pic.qscale_table[mb_xy];
         if (qp <= qp_thresh &&
             (left_xy[LTOP] < 0 ||
@@ -2187,9 +2193,9 @@ static int fill_filter_caches(H264Context *h, int mb_type)
         if (h->slice_table[left_xy[LBOT]] == 0xFFFF)
             left_type[LTOP] = left_type[LBOT] = 0;
     }
-    h->top_type        = top_type;
-    h->left_type[LTOP] = left_type[LTOP];
-    h->left_type[LBOT] = left_type[LBOT];
+    sl->top_type        = top_type;
+    sl->left_type[LTOP] = left_type[LTOP];
+    sl->left_type[LBOT] = left_type[LBOT];
 
     if (IS_INTRA(mb_type))
         return 0;
@@ -2265,7 +2271,7 @@ static int fill_filter_caches(H264Context *h, int mb_type)
     return 0;
 }
 
-static void loop_filter(H264Context *h, int start_x, int end_x)
+static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int end_x)
 {
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize, mb_x, mb_y;
@@ -2313,16 +2319,16 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
                 }
                 backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize,
                                  uvlinesize, 0);
-                if (fill_filter_caches(h, mb_type))
+                if (fill_filter_caches(h, sl, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
+                sl->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
+                sl->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
 
                 if (FRAME_MBAFF(h)) {
-                    ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
+                    ff_h264_filter_mb(h, sl, mb_x, mb_y, dest_y, dest_cb, dest_cr,
                                       linesize, uvlinesize);
                 } else {
-                    ff_h264_filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb,
+                    ff_h264_filter_mb_fast(h, sl, mb_x, mb_y, dest_y, dest_cb,
                                            dest_cr, linesize, uvlinesize);
                 }
             }
@@ -2330,8 +2336,8 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
     h->slice_type   = old_slice_type;
     h->mb_x         = end_x;
     h->mb_y         = end_mb_y - FRAME_MBAFF(h);
-    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);
-    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);
+    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
 }
 
 static void predict_field_decoding_flag(H264Context *h)
@@ -2390,7 +2396,8 @@ static void er_add_slice(H264Context *h, int startx, int starty,
 
 static int decode_slice(struct AVCodecContext *avctx, void *arg)
 {
-    H264Context *h = *(void **)arg;
+    H264SliceContext *sl = arg;
+    H264Context       *h = sl->h264;
     int lf_x_start = h->mb_x;
 
     h->mb_skip_run = -1;
@@ -2420,25 +2427,25 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                               h->gb.buffer + get_bits_count(&h->gb) / 8,
                               (get_bits_left(&h->gb) + 7) / 8);
 
-        ff_h264_init_cabac_states(h);
+        ff_h264_init_cabac_states(h, sl);
 
         for (;;) {
             // START_TIMER
-            int ret = ff_h264_decode_mb_cabac(h);
+            int ret = ff_h264_decode_mb_cabac(h, sl);
             int eos;
             // STOP_TIMER("decode_mb_cabac")
 
             if (ret >= 0)
-                ff_h264_hl_decode_mb(h);
+                ff_h264_hl_decode_mb(h, sl);
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF(h)) {
                 h->mb_y++;
 
-                ret = ff_h264_decode_mb_cabac(h);
+                ret = ff_h264_decode_mb_cabac(h, sl);
 
                 if (ret >= 0)
-                    ff_h264_hl_decode_mb(h);
+                    ff_h264_hl_decode_mb(h, sl);
                 h->mb_y--;
             }
             eos = get_cabac_terminate(&h->cabac);
@@ -2448,7 +2455,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
                              h->mb_y, ER_MB_END);
                 if (h->mb_x >= lf_x_start)
-                    loop_filter(h, lf_x_start, h->mb_x + 1);
+                    loop_filter(h, sl, lf_x_start, h->mb_x + 1);
                 return 0;
             }
             if (h->cabac.bytestream > h->cabac.bytestream_end + 2 )
@@ -2464,7 +2471,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             }
 
             if (++h->mb_x >= h->mb_width) {
-                loop_filter(h, lf_x_start, h->mb_x);
+                loop_filter(h, sl, lf_x_start, h->mb_x);
                 h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
                 ++h->mb_y;
@@ -2481,24 +2488,24 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                 er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x - 1,
                              h->mb_y, ER_MB_END);
                 if (h->mb_x > lf_x_start)
-                    loop_filter(h, lf_x_start, h->mb_x);
+                    loop_filter(h, sl, lf_x_start, h->mb_x);
                 return 0;
             }
         }
     } else {
         for (;;) {
-            int ret = ff_h264_decode_mb_cavlc(h);
+            int ret = ff_h264_decode_mb_cavlc(h, sl);
 
             if (ret >= 0)
-                ff_h264_hl_decode_mb(h);
+                ff_h264_hl_decode_mb(h, sl);
 
             // FIXME optimal? or let mb_decode decode 16x32 ?
             if (ret >= 0 && FRAME_MBAFF(h)) {
                 h->mb_y++;
-                ret = ff_h264_decode_mb_cavlc(h);
+                ret = ff_h264_decode_mb_cavlc(h, sl);
 
                 if (ret >= 0)
-                    ff_h264_hl_decode_mb(h);
+                    ff_h264_hl_decode_mb(h, sl);
                 h->mb_y--;
             }
 
@@ -2511,7 +2518,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
             }
 
             if (++h->mb_x >= h->mb_width) {
-                loop_filter(h, lf_x_start, h->mb_x);
+                loop_filter(h, sl, lf_x_start, h->mb_x);
                 h->mb_x = lf_x_start = 0;
                 decode_finish_row(h);
                 ++h->mb_y;
@@ -2547,7 +2554,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
                     er_add_slice(h, h->resync_mb_x, h->resync_mb_y,
                                  h->mb_x - 1, h->mb_y, ER_MB_END);
                     if (h->mb_x > lf_x_start)
-                        loop_filter(h, lf_x_start, h->mb_x);
+                        loop_filter(h, sl, lf_x_start, h->mb_x);
 
                     return 0;
                 } else {
@@ -2579,7 +2586,7 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
         h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
         return 0;
     if (context_count == 1) {
-        return decode_slice(avctx, &h);
+        return decode_slice(avctx, &h->slice_ctx[0]);
     } else {
         av_assert0(context_count > 0);
         for (i = 1; i < context_count; i++) {
@@ -2590,8 +2597,8 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
             hx->x264_build     = h->x264_build;
         }
 
-        avctx->execute(avctx, decode_slice, h->thread_context,
-                       NULL, context_count, sizeof(void *));
+        avctx->execute(avctx, decode_slice, h->slice_ctx,
+                       NULL, context_count, sizeof(h->slice_ctx[0]));
 
         /* pull back stuff from slices to master context */
         hx                   = h->thread_context[context_count - 1];