]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264.c
h264: move {mv,ref}_cache into the per-slice context
[ffmpeg] / libavcodec / h264.c
index 684c78fcdc41c481f4d96655c21b6ba49982e334..ee6d86334b02e233e59c942cd99687055002cb4a 100644 (file)
@@ -56,11 +56,12 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
                               int mb_x, int mb_y, int mb_intra, int mb_skipped)
 {
     H264Context *h = opaque;
+    H264SliceContext *sl = &h->slice_ctx[0];
 
     h->mb_x  = mb_x;
     h->mb_y  = mb_y;
     h->mb_xy = mb_x + mb_y * h->mb_stride;
-    memset(h->non_zero_count_cache, 0, sizeof(h->non_zero_count_cache));
+    memset(sl->non_zero_count_cache, 0, sizeof(sl->non_zero_count_cache));
     assert(ref >= 0);
     /* FIXME: It is possible albeit uncommon that slice references
      * differ between slices. We take the easy approach and ignore
@@ -70,11 +71,11 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
         ref = 0;
     fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy],
                    2, 2, 2, ref, 1);
-    fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
-    fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
+    fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
+    fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8,
                    pack16to32((*mv)[0][0][0], (*mv)[0][0][1]), 4);
     assert(!FRAME_MBAFF(h));
-    ff_h264_hl_decode_mb(h);
+    ff_h264_hl_decode_mb(h, &h->slice_ctx[0]);
 }
 
 void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
@@ -125,7 +126,7 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
  */
-int ff_h264_check_intra4x4_pred_mode(H264Context *h)
+int ff_h264_check_intra4x4_pred_mode(H264Context *h, H264SliceContext *sl)
 {
     static const int8_t top[12] = {
         -1, 0, LEFT_DC_PRED, -1, -1, -1, -1, -1, 0
@@ -135,32 +136,32 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
     };
     int i;
 
-    if (!(h->top_samples_available & 0x8000)) {
+    if (!(sl->top_samples_available & 0x8000)) {
         for (i = 0; i < 4; i++) {
-            int status = top[h->intra4x4_pred_mode_cache[scan8[0] + i]];
+            int status = top[sl->intra4x4_pred_mode_cache[scan8[0] + i]];
             if (status < 0) {
                 av_log(h->avctx, AV_LOG_ERROR,
                        "top block unavailable for requested intra4x4 mode %d at %d %d\n",
                        status, h->mb_x, h->mb_y);
                 return AVERROR_INVALIDDATA;
             } else if (status) {
-                h->intra4x4_pred_mode_cache[scan8[0] + i] = status;
+                sl->intra4x4_pred_mode_cache[scan8[0] + i] = status;
             }
         }
     }
 
-    if ((h->left_samples_available & 0x8888) != 0x8888) {
+    if ((sl->left_samples_available & 0x8888) != 0x8888) {
         static const int mask[4] = { 0x8000, 0x2000, 0x80, 0x20 };
         for (i = 0; i < 4; i++)
-            if (!(h->left_samples_available & mask[i])) {
-                int status = left[h->intra4x4_pred_mode_cache[scan8[0] + 8 * i]];
+            if (!(sl->left_samples_available & mask[i])) {
+                int status = left[sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i]];
                 if (status < 0) {
                     av_log(h->avctx, AV_LOG_ERROR,
                            "left block unavailable for requested intra4x4 mode %d at %d %d\n",
                            status, h->mb_x, h->mb_y);
                     return AVERROR_INVALIDDATA;
                 } else if (status) {
-                    h->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
+                    sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i] = status;
                 }
             }
     }
@@ -172,7 +173,8 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h)
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
  */
-int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
+int ff_h264_check_intra_pred_mode(H264Context *h, H264SliceContext *sl,
+                                  int mode, int is_chroma)
 {
     static const int8_t top[4]  = { LEFT_DC_PRED8x8, 1, -1, -1 };
     static const int8_t left[5] = { TOP_DC_PRED8x8, -1,  2, -1, DC_128_PRED8x8 };
@@ -184,7 +186,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
         return AVERROR_INVALIDDATA;
     }
 
-    if (!(h->top_samples_available & 0x8000)) {
+    if (!(sl->top_samples_available & 0x8000)) {
         mode = top[mode];
         if (mode < 0) {
             av_log(h->avctx, AV_LOG_ERROR,
@@ -194,12 +196,12 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma)
         }
     }
 
-    if ((h->left_samples_available & 0x8080) != 0x8080) {
+    if ((sl->left_samples_available & 0x8080) != 0x8080) {
         mode = left[mode];
-        if (is_chroma && (h->left_samples_available & 0x8080)) {
+        if (is_chroma && (sl->left_samples_available & 0x8080)) {
             // mad cow disease mode, aka MBAFF + constrained_intra_pred
             mode = ALZHEIMER_DC_L0T_PRED8x8 +
-                   (!(h->left_samples_available & 0x8000)) +
+                   (!(sl->left_samples_available & 0x8000)) +
                    2 * (mode == DC_128_PRED8x8);
         }
         if (mode < 0) {
@@ -409,6 +411,8 @@ int ff_h264_alloc_tables(H264Context *h)
 
     FF_ALLOCZ_OR_GOTO(h->avctx, h->intra4x4_pred_mode,
                       row_mb_num * 8 * sizeof(uint8_t), fail)
+    h->slice_ctx[0].intra4x4_pred_mode = h->intra4x4_pred_mode;
+
     FF_ALLOCZ_OR_GOTO(h->avctx, h->non_zero_count,
                       big_mb_num * 48 * sizeof(uint8_t), fail)
     FF_ALLOCZ_OR_GOTO(h->avctx, h->slice_table_base,
@@ -480,17 +484,18 @@ int ff_h264_context_init(H264Context *h)
     FF_ALLOCZ_OR_GOTO(h->avctx, h->top_borders[1],
                       h->mb_width * 16 * 3 * sizeof(uint8_t) * 2, fail)
 
-    h->ref_cache[0][scan8[5]  + 1] =
-    h->ref_cache[0][scan8[7]  + 1] =
-    h->ref_cache[0][scan8[13] + 1] =
-    h->ref_cache[1][scan8[5]  + 1] =
-    h->ref_cache[1][scan8[7]  + 1] =
-    h->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
+    for (i = 0; i < h->nb_slice_ctx; i++) {
+        h->slice_ctx[i].ref_cache[0][scan8[5]  + 1] =
+        h->slice_ctx[i].ref_cache[0][scan8[7]  + 1] =
+        h->slice_ctx[i].ref_cache[0][scan8[13] + 1] =
+        h->slice_ctx[i].ref_cache[1][scan8[5]  + 1] =
+        h->slice_ctx[i].ref_cache[1][scan8[7]  + 1] =
+        h->slice_ctx[i].ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE;
+    }
 
     if (CONFIG_ERROR_RESILIENCE) {
         /* init ER */
         er->avctx          = h->avctx;
-        er->mecc           = &h->mecc;
         er->decode_mb      = h264_er_decode_mb;
         er->opaque         = h;
         er->quarter_sample = 1;
@@ -619,8 +624,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     h->dequant_coeff_pps = -1;
 
     /* needed so that IDCT permutation is known early */
-    if (CONFIG_ERROR_RESILIENCE)
-        ff_me_cmp_init(&h->mecc, h->avctx);
     ff_videodsp_init(&h->vdsp, 8);
 
     memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
@@ -645,7 +648,17 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     h->pixel_shift        = 0;
     h->sps.bit_depth_luma = avctx->bits_per_raw_sample = 8;
 
+    h->nb_slice_ctx = (avctx->active_thread_type & FF_THREAD_SLICE) ?  H264_MAX_THREADS : 1;
+    h->slice_ctx = av_mallocz_array(h->nb_slice_ctx, sizeof(*h->slice_ctx));
+    if (!h->slice_ctx) {
+        h->nb_slice_ctx = 0;
+        return AVERROR(ENOMEM);
+    }
+
     h->thread_context[0] = h;
+    for (i = 0; i < h->nb_slice_ctx; i++)
+        h->slice_ctx[i].h264 = h->thread_context[0];
+
     h->outputed_poc      = h->next_outputed_poc = INT_MIN;
     for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
         h->last_pocs[i] = INT_MIN;
@@ -682,12 +695,28 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
 static int decode_init_thread_copy(AVCodecContext *avctx)
 {
     H264Context *h = avctx->priv_data;
+    int i;
 
     if (!avctx->internal->is_copy)
         return 0;
     memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
     memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
 
+    h->nb_slice_ctx = (avctx->active_thread_type & FF_THREAD_SLICE) ?  H264_MAX_THREADS : 1;
+    h->slice_ctx = av_mallocz_array(h->nb_slice_ctx, sizeof(*h->slice_ctx));
+    if (!h->slice_ctx) {
+        h->nb_slice_ctx = 0;
+        return AVERROR(ENOMEM);
+    }
+
+    for (i = 0; i < h->nb_slice_ctx; i++)
+        h->slice_ctx[i].h264 = h;
+
+    h->avctx               = avctx;
+    h->rbsp_buffer[0]      = NULL;
+    h->rbsp_buffer[1]      = NULL;
+    h->rbsp_buffer_size[0] = 0;
+    h->rbsp_buffer_size[1] = 0;
     h->context_initialized = 0;
 
     return 0;
@@ -974,37 +1003,37 @@ static void decode_postinit(H264Context *h, int setup_finished)
         ff_thread_finish_setup(h->avctx);
 }
 
-int ff_pred_weight_table(H264Context *h)
+int ff_pred_weight_table(H264Context *h, H264SliceContext *sl)
 {
     int list, i;
     int luma_def, chroma_def;
 
-    h->use_weight             = 0;
-    h->use_weight_chroma      = 0;
-    h->luma_log2_weight_denom = get_ue_golomb(&h->gb);
+    sl->use_weight             = 0;
+    sl->use_weight_chroma      = 0;
+    sl->luma_log2_weight_denom = get_ue_golomb(&h->gb);
     if (h->sps.chroma_format_idc)
-        h->chroma_log2_weight_denom = get_ue_golomb(&h->gb);
-    luma_def   = 1 << h->luma_log2_weight_denom;
-    chroma_def = 1 << h->chroma_log2_weight_denom;
+        sl->chroma_log2_weight_denom = get_ue_golomb(&h->gb);
+    luma_def   = 1 << sl->luma_log2_weight_denom;
+    chroma_def = 1 << sl->chroma_log2_weight_denom;
 
     for (list = 0; list < 2; list++) {
-        h->luma_weight_flag[list]   = 0;
-        h->chroma_weight_flag[list] = 0;
+        sl->luma_weight_flag[list]   = 0;
+        sl->chroma_weight_flag[list] = 0;
         for (i = 0; i < h->ref_count[list]; i++) {
             int luma_weight_flag, chroma_weight_flag;
 
             luma_weight_flag = get_bits1(&h->gb);
             if (luma_weight_flag) {
-                h->luma_weight[i][list][0] = get_se_golomb(&h->gb);
-                h->luma_weight[i][list][1] = get_se_golomb(&h->gb);
-                if (h->luma_weight[i][list][0] != luma_def ||
-                    h->luma_weight[i][list][1] != 0) {
-                    h->use_weight             = 1;
-                    h->luma_weight_flag[list] = 1;
+                sl->luma_weight[i][list][0] = get_se_golomb(&h->gb);
+                sl->luma_weight[i][list][1] = get_se_golomb(&h->gb);
+                if (sl->luma_weight[i][list][0] != luma_def ||
+                    sl->luma_weight[i][list][1] != 0) {
+                    sl->use_weight             = 1;
+                    sl->luma_weight_flag[list] = 1;
                 }
             } else {
-                h->luma_weight[i][list][0] = luma_def;
-                h->luma_weight[i][list][1] = 0;
+                sl->luma_weight[i][list][0] = luma_def;
+                sl->luma_weight[i][list][1] = 0;
             }
 
             if (h->sps.chroma_format_idc) {
@@ -1012,19 +1041,19 @@ int ff_pred_weight_table(H264Context *h)
                 if (chroma_weight_flag) {
                     int j;
                     for (j = 0; j < 2; j++) {
-                        h->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);
-                        h->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);
-                        if (h->chroma_weight[i][list][j][0] != chroma_def ||
-                            h->chroma_weight[i][list][j][1] != 0) {
-                            h->use_weight_chroma        = 1;
-                            h->chroma_weight_flag[list] = 1;
+                        sl->chroma_weight[i][list][j][0] = get_se_golomb(&h->gb);
+                        sl->chroma_weight[i][list][j][1] = get_se_golomb(&h->gb);
+                        if (sl->chroma_weight[i][list][j][0] != chroma_def ||
+                            sl->chroma_weight[i][list][j][1] != 0) {
+                            sl->use_weight_chroma        = 1;
+                            sl->chroma_weight_flag[list] = 1;
                         }
                     }
                 } else {
                     int j;
                     for (j = 0; j < 2; j++) {
-                        h->chroma_weight[i][list][j][0] = chroma_def;
-                        h->chroma_weight[i][list][j][1] = 0;
+                        sl->chroma_weight[i][list][j][0] = chroma_def;
+                        sl->chroma_weight[i][list][j][1] = 0;
                     }
                 }
             }
@@ -1032,7 +1061,7 @@ int ff_pred_weight_table(H264Context *h)
         if (h->slice_type_nos != AV_PICTURE_TYPE_B)
             break;
     }
-    h->use_weight = h->use_weight || h->use_weight_chroma;
+    sl->use_weight = sl->use_weight || sl->use_weight_chroma;
     return 0;
 }
 
@@ -1060,10 +1089,6 @@ void ff_h264_flush_change(H264Context *h)
     if (h->cur_pic_ptr)
         h->cur_pic_ptr->reference = 0;
     h->first_field = 0;
-    memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
-    memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
-    memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));
-    memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));
     ff_h264_reset_sei(h);
     h->recovery_frame = -1;
     h->frame_recovered = 0;
@@ -1087,13 +1112,6 @@ static void flush_dpb(AVCodecContext *avctx)
 
     h->mb_x = h->mb_y = 0;
 
-    h->parse_context.state             = -1;
-    h->parse_context.frame_start_found = 0;
-    h->parse_context.overread          = 0;
-    h->parse_context.overread_index    = 0;
-    h->parse_context.index             = 0;
-    h->parse_context.last_index        = 0;
-
     ff_h264_free_tables(h, 1);
     h->context_initialized = 0;
 }
@@ -1231,8 +1249,6 @@ int ff_h264_set_parameter_from_sps(H264Context *h)
             ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma);
             ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma,
                               h->sps.chroma_format_idc);
-            if (CONFIG_ERROR_RESILIENCE)
-                ff_me_cmp_init(&h->mecc, h->avctx);
             ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
         } else {
             av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth %d\n",
@@ -1412,6 +1428,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
 {
     AVCodecContext *const avctx = h->avctx;
     H264Context *hx; ///< thread context
+    H264SliceContext *sl;
     int buf_index;
     unsigned context_count;
     int next_avc;
@@ -1457,6 +1474,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size,
             }
 
             hx = h->thread_context[context_count];
+            sl = &h->slice_ctx[context_count];
 
             ptr = ff_h264_decode_nal(hx, buf + buf_index, &dst_length,
                                      &consumed, next_avc - buf_index);
@@ -1515,9 +1533,8 @@ again:
                 init_get_bits(&hx->gb, ptr, bit_length);
                 hx->intra_gb_ptr      =
                 hx->inter_gb_ptr      = &hx->gb;
-                hx->data_partitioning = 0;
 
-                if ((err = ff_h264_decode_slice_header(hx, h)))
+                if ((err = ff_h264_decode_slice_header(hx, sl, h)))
                     break;
 
                 if (h->sei_recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
@@ -1568,46 +1585,11 @@ again:
                 }
                 break;
             case NAL_DPA:
-                if (h->avctx->flags & CODEC_FLAG2_CHUNKS) {
-                    av_log(h->avctx, AV_LOG_ERROR,
-                           "Decoding in chunks is not supported for "
-                           "partitioned slices.\n");
-                    return AVERROR(ENOSYS);
-                }
-
-                init_get_bits(&hx->gb, ptr, bit_length);
-                hx->intra_gb_ptr =
-                hx->inter_gb_ptr = NULL;
-
-                if ((err = ff_h264_decode_slice_header(hx, h)) < 0) {
-                    /* make sure data_partitioning is cleared if it was set
-                     * before, so we don't try decoding a slice without a valid
-                     * slice header later */
-                    h->data_partitioning = 0;
-                    break;
-                }
-
-                hx->data_partitioning = 1;
-                break;
             case NAL_DPB:
-                init_get_bits(&hx->intra_gb, ptr, bit_length);
-                hx->intra_gb_ptr = &hx->intra_gb;
-                break;
             case NAL_DPC:
-                init_get_bits(&hx->inter_gb, ptr, bit_length);
-                hx->inter_gb_ptr = &hx->inter_gb;
-
-                if (hx->redundant_pic_count == 0 &&
-                    hx->intra_gb_ptr &&
-                    hx->data_partitioning &&
-                    h->cur_pic_ptr && h->context_initialized &&
-                    (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) &&
-                    (avctx->skip_frame < AVDISCARD_BIDIR  ||
-                     hx->slice_type_nos != AV_PICTURE_TYPE_B) &&
-                    (avctx->skip_frame < AVDISCARD_NONKEY ||
-                     hx->slice_type_nos == AV_PICTURE_TYPE_I) &&
-                    avctx->skip_frame < AVDISCARD_ALL)
-                    context_count++;
+                avpriv_request_sample(avctx, "data partitioning");
+                ret = AVERROR(ENOSYS);
+                goto end;
                 break;
             case NAL_SEI:
                 init_get_bits(&h->gb, ptr, bit_length);
@@ -1669,6 +1651,7 @@ again:
                 h->nal_unit_type = hx->nal_unit_type;
                 h->nal_ref_idc   = hx->nal_ref_idc;
                 hx               = h;
+                sl               = &h->slice_ctx[0];
                 goto again;
             }
         }
@@ -1734,9 +1717,6 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data,
     int ret;
 
     h->flags = avctx->flags;
-    /* reset data partitioning here, to ensure GetBitContexts from previous
-     * packets do not get used. */
-    h->data_partitioning = 0;
 
     /* end of stream, output what is still in the buffers */
 out:
@@ -1819,6 +1799,9 @@ av_cold void ff_h264_free_context(H264Context *h)
 
     ff_h264_free_tables(h, 1); // FIXME cleanup init stuff perhaps
 
+    av_freep(&h->slice_ctx);
+    h->nb_slice_ctx = 0;
+
     for (i = 0; i < MAX_SPS_COUNT; i++)
         av_freep(h->sps_buffers + i);