You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	avcodec/h264dec: Move ERContext to H264Context
Since 7be2d2a70c only one context
is used. Moving it to H264Context from H264SliceContext is natural.
One could access the ERContext from H264SliceContext
via H264SliceContext.h264->er; yet H264SliceContext.h264 should
naturally be const-qualified, because slice threads should not
modify the main context. The ERContext is an exception
to this, as ff_er_add_slice() is intended to be called simultaneously
by multiple threads. And for this one needs a pointer whose
pointed-to-type is not const-qualified.
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
			
			
This commit is contained in:
		| @@ -537,7 +537,7 @@ static int h264_frame_start(H264Context *h) | ||||
|     h->cur_pic_ptr = pic; | ||||
|     ff_h264_unref_picture(h, &h->cur_pic); | ||||
|     if (CONFIG_ERROR_RESILIENCE) { | ||||
|         ff_h264_set_erpic(&h->slice_ctx[0].er.cur_pic, NULL); | ||||
|         ff_h264_set_erpic(&h->er.cur_pic, NULL); | ||||
|     } | ||||
|  | ||||
|     if ((ret = ff_h264_ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0) | ||||
| @@ -549,9 +549,9 @@ static int h264_frame_start(H264Context *h) | ||||
|     } | ||||
|  | ||||
|     if (CONFIG_ERROR_RESILIENCE && h->enable_er) { | ||||
|         ff_er_frame_start(&h->slice_ctx[0].er); | ||||
|         ff_h264_set_erpic(&h->slice_ctx[0].er.last_pic, NULL); | ||||
|         ff_h264_set_erpic(&h->slice_ctx[0].er.next_pic, NULL); | ||||
|         ff_er_frame_start(&h->er); | ||||
|         ff_h264_set_erpic(&h->er.last_pic, NULL); | ||||
|         ff_h264_set_erpic(&h->er.next_pic, NULL); | ||||
|     } | ||||
|  | ||||
|     for (i = 0; i < 16; i++) { | ||||
| @@ -1004,11 +1004,7 @@ static int h264_slice_header_init(H264Context *h) | ||||
|     ff_videodsp_init(&h->vdsp, sps->bit_depth_luma); | ||||
|  | ||||
|     if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) { | ||||
|         ret = ff_h264_slice_context_init(h, &h->slice_ctx[0]); | ||||
|         if (ret < 0) { | ||||
|             av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); | ||||
|             goto fail; | ||||
|         } | ||||
|         ff_h264_slice_context_init(h, &h->slice_ctx[0]); | ||||
|     } else { | ||||
|         for (i = 0; i < h->nb_slice_ctx; i++) { | ||||
|             H264SliceContext *sl = &h->slice_ctx[i]; | ||||
| @@ -1018,10 +1014,7 @@ static int h264_slice_header_init(H264Context *h) | ||||
|             sl->mvd_table[0]       = h->mvd_table[0]       + i * 8 * 2 * h->mb_stride; | ||||
|             sl->mvd_table[1]       = h->mvd_table[1]       + i * 8 * 2 * h->mb_stride; | ||||
|  | ||||
|             if ((ret = ff_h264_slice_context_init(h, sl)) < 0) { | ||||
|                 av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); | ||||
|                 goto fail; | ||||
|             } | ||||
|             ff_h264_slice_context_init(h, sl); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -2667,7 +2660,7 @@ static void decode_finish_row(const H264Context *h, H264SliceContext *sl) | ||||
|  | ||||
|     ff_h264_draw_horiz_band(h, sl, top, height); | ||||
|  | ||||
|     if (h->droppable || sl->h264->slice_ctx[0].er.error_occurred) | ||||
|     if (h->droppable || h->er.error_occurred) | ||||
|         return; | ||||
|  | ||||
|     ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1, | ||||
| @@ -2682,9 +2675,7 @@ static void er_add_slice(H264SliceContext *sl, | ||||
|         return; | ||||
|  | ||||
|     if (CONFIG_ERROR_RESILIENCE) { | ||||
|         ERContext *er = &sl->h264->slice_ctx[0].er; | ||||
|  | ||||
|         ff_er_add_slice(er, startx, starty, endx, endy, status); | ||||
|         ff_er_add_slice(sl->er, startx, starty, endx, endy, status); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -2713,13 +2704,13 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) | ||||
|     sl->is_complex = FRAME_MBAFF(h) || h->picture_structure != PICT_FRAME || | ||||
|                      (CONFIG_GRAY && (h->flags & AV_CODEC_FLAG_GRAY)); | ||||
|  | ||||
|     if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && h->slice_ctx[0].er.error_status_table) { | ||||
|     if (!(h->avctx->active_thread_type & FF_THREAD_SLICE) && h->picture_structure == PICT_FRAME && sl->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 = h->slice_ctx[0].er.error_status_table[h->slice_ctx[0].er.mb_index2xy[start_i - 1]]; | ||||
|             int prev_status = sl->er->error_status_table[sl->er->mb_index2xy[start_i - 1]]; | ||||
|             prev_status &= ~ VP_START; | ||||
|             if (prev_status != (ER_MV_END | ER_DC_END | ER_AC_END)) | ||||
|                 h->slice_ctx[0].er.error_occurred = 1; | ||||
|                 sl->er->error_occurred = 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -154,14 +154,16 @@ void ff_h264_free_tables(H264Context *h) | ||||
|     av_buffer_pool_uninit(&h->motion_val_pool); | ||||
|     av_buffer_pool_uninit(&h->ref_index_pool); | ||||
|  | ||||
| #if CONFIG_ERROR_RESILIENCE | ||||
|     av_freep(&h->er.mb_index2xy); | ||||
|     av_freep(&h->er.error_status_table); | ||||
|     av_freep(&h->er.er_temp_buffer); | ||||
|     av_freep(&h->dc_val_base); | ||||
| #endif | ||||
|  | ||||
|     for (i = 0; i < h->nb_slice_ctx; i++) { | ||||
|         H264SliceContext *sl = &h->slice_ctx[i]; | ||||
|  | ||||
|         av_freep(&sl->dc_val_base); | ||||
|         av_freep(&sl->er.mb_index2xy); | ||||
|         av_freep(&sl->er.error_status_table); | ||||
|         av_freep(&sl->er.er_temp_buffer); | ||||
|  | ||||
|         av_freep(&sl->bipred_scratchpad); | ||||
|         av_freep(&sl->edge_emu_buffer); | ||||
|         av_freep(&sl->top_borders[0]); | ||||
| @@ -176,6 +178,7 @@ void ff_h264_free_tables(H264Context *h) | ||||
|  | ||||
| int ff_h264_alloc_tables(H264Context *h) | ||||
| { | ||||
|     ERContext *const er = &h->er; | ||||
|     const int big_mb_num = h->mb_stride * (h->mb_height + 1); | ||||
|     const int row_mb_num = 2*h->mb_stride*FFMAX(h->nb_slice_ctx, 1); | ||||
|     const int st_size = big_mb_num + h->mb_stride; | ||||
| @@ -208,33 +211,11 @@ int ff_h264_alloc_tables(H264Context *h) | ||||
|             h->mb2br_xy[mb_xy] = 8 * (FMO ? mb_xy : (mb_xy % (2 * h->mb_stride))); | ||||
|         } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Init context | ||||
|  * Allocate buffers which are not shared amongst multiple threads. | ||||
|  */ | ||||
| int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) | ||||
| { | ||||
|     ERContext *er = &sl->er; | ||||
|     int mb_array_size = h->mb_height * h->mb_stride; | ||||
|     int y_size  = (2 * h->mb_width + 1) * (2 * h->mb_height + 1); | ||||
|     int c_size  = h->mb_stride * (h->mb_height + 1); | ||||
|     int yc_size = y_size + 2   * c_size; | ||||
|     int x, y, i; | ||||
|  | ||||
|     sl->ref_cache[0][scan8[5]  + 1] = | ||||
|     sl->ref_cache[0][scan8[7]  + 1] = | ||||
|     sl->ref_cache[0][scan8[13] + 1] = | ||||
|     sl->ref_cache[1][scan8[5]  + 1] = | ||||
|     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) { | ||||
|     if (CONFIG_ERROR_RESILIENCE) { | ||||
|         const int er_size = h->mb_height * h->mb_stride * (4*sizeof(int) + 1); | ||||
|         int mb_array_size = h->mb_height * h->mb_stride; | ||||
|         int y_size  = (2 * h->mb_width + 1) * (2 * h->mb_height + 1); | ||||
|         int yc_size = y_size + 2 * big_mb_num; | ||||
|  | ||||
|         /* init ER */ | ||||
|         er->avctx          = h->avctx; | ||||
| @@ -252,7 +233,7 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) | ||||
|         if (!FF_ALLOCZ_TYPED_ARRAY(er->mb_index2xy,        h->mb_num + 1) || | ||||
|             !FF_ALLOCZ_TYPED_ARRAY(er->error_status_table, mb_array_size) || | ||||
|             !FF_ALLOCZ_TYPED_ARRAY(er->er_temp_buffer,     er_size)       || | ||||
|             !FF_ALLOCZ_TYPED_ARRAY(sl->dc_val_base,        yc_size)) | ||||
|             !FF_ALLOCZ_TYPED_ARRAY(h->dc_val_base,         yc_size)) | ||||
|             return AVERROR(ENOMEM); // ff_h264_free_tables will clean up for us | ||||
|  | ||||
|         for (y = 0; y < h->mb_height; y++) | ||||
| @@ -261,16 +242,31 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) | ||||
|  | ||||
|         er->mb_index2xy[h->mb_height * h->mb_width] = (h->mb_height - 1) * | ||||
|                                                       h->mb_stride + h->mb_width; | ||||
|         er->dc_val[0] = sl->dc_val_base + h->mb_width * 2 + 2; | ||||
|         er->dc_val[1] = sl->dc_val_base + y_size + h->mb_stride + 1; | ||||
|         er->dc_val[2] = er->dc_val[1] + c_size; | ||||
|         for (i = 0; i < yc_size; i++) | ||||
|             sl->dc_val_base[i] = 1024; | ||||
|         er->dc_val[0] = h->dc_val_base + h->mb_width * 2 + 2; | ||||
|         er->dc_val[1] = h->dc_val_base + y_size + h->mb_stride + 1; | ||||
|         er->dc_val[2] = er->dc_val[1] + big_mb_num; | ||||
|         for (int i = 0; i < yc_size; i++) | ||||
|             h->dc_val_base[i] = 1024; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Init slice context | ||||
|  */ | ||||
| void ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl) | ||||
| { | ||||
|     sl->ref_cache[0][scan8[5]  + 1] = | ||||
|     sl->ref_cache[0][scan8[7]  + 1] = | ||||
|     sl->ref_cache[0][scan8[13] + 1] = | ||||
|     sl->ref_cache[1][scan8[5]  + 1] = | ||||
|     sl->ref_cache[1][scan8[7]  + 1] = | ||||
|     sl->ref_cache[1][scan8[13] + 1] = PART_NOT_AVAILABLE; | ||||
|  | ||||
|     sl->er = &h->er; | ||||
| } | ||||
|  | ||||
| static int h264_init_pic(H264Picture *pic) | ||||
| { | ||||
|     pic->f = av_frame_alloc(); | ||||
| @@ -739,7 +735,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) | ||||
|         goto end; | ||||
|  | ||||
|     // set decode_error_flags to allow users to detect concealed decoding errors | ||||
|     if ((ret < 0 || h->slice_ctx->er.error_occurred) && h->cur_pic_ptr) { | ||||
|     if ((ret < 0 || h->er.error_occurred) && h->cur_pic_ptr) { | ||||
|         h->cur_pic_ptr->f->decode_error_flags |= FF_DECODE_ERROR_DECODE_SLICES; | ||||
|     } | ||||
|  | ||||
| @@ -764,25 +760,25 @@ end: | ||||
|         H264SliceContext *sl = h->slice_ctx; | ||||
|         int use_last_pic = h->last_pic_for_ec.f->buf[0] && !sl->ref_count[0]; | ||||
|  | ||||
|         ff_h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr); | ||||
|         ff_h264_set_erpic(&h->er.cur_pic, h->cur_pic_ptr); | ||||
|  | ||||
|         if (use_last_pic) { | ||||
|             ff_h264_set_erpic(&sl->er.last_pic, &h->last_pic_for_ec); | ||||
|             ff_h264_set_erpic(&h->er.last_pic, &h->last_pic_for_ec); | ||||
|             sl->ref_list[0][0].parent = &h->last_pic_for_ec; | ||||
|             memcpy(sl->ref_list[0][0].data, h->last_pic_for_ec.f->data, sizeof(sl->ref_list[0][0].data)); | ||||
|             memcpy(sl->ref_list[0][0].linesize, h->last_pic_for_ec.f->linesize, sizeof(sl->ref_list[0][0].linesize)); | ||||
|             sl->ref_list[0][0].reference = h->last_pic_for_ec.reference; | ||||
|         } else if (sl->ref_count[0]) { | ||||
|             ff_h264_set_erpic(&sl->er.last_pic, sl->ref_list[0][0].parent); | ||||
|             ff_h264_set_erpic(&h->er.last_pic, sl->ref_list[0][0].parent); | ||||
|         } else | ||||
|             ff_h264_set_erpic(&sl->er.last_pic, NULL); | ||||
|             ff_h264_set_erpic(&h->er.last_pic, NULL); | ||||
|  | ||||
|         if (sl->ref_count[1]) | ||||
|             ff_h264_set_erpic(&sl->er.next_pic, sl->ref_list[1][0].parent); | ||||
|             ff_h264_set_erpic(&h->er.next_pic, sl->ref_list[1][0].parent); | ||||
|  | ||||
|         sl->er.ref_count = sl->ref_count[0]; | ||||
|         h->er.ref_count = sl->ref_count[0]; | ||||
|  | ||||
|         ff_er_frame_end(&sl->er); | ||||
|         ff_er_frame_end(&h->er); | ||||
|         if (use_last_pic) | ||||
|             memset(&sl->ref_list[0][0], 0, sizeof(sl->ref_list[0][0])); | ||||
|     } | ||||
|   | ||||
| @@ -170,7 +170,7 @@ typedef struct H264Ref { | ||||
| typedef struct H264SliceContext { | ||||
|     struct H264Context *h264; | ||||
|     GetBitContext gb; | ||||
|     ERContext er; | ||||
|     ERContext *er; | ||||
|  | ||||
|     int slice_num; | ||||
|     int slice_type; | ||||
| @@ -271,7 +271,6 @@ typedef struct H264SliceContext { | ||||
|     unsigned int pps_id; | ||||
|  | ||||
|     const uint8_t *intra_pcm_ptr; | ||||
|     int16_t *dc_val_base; | ||||
|  | ||||
|     uint8_t *bipred_scratchpad; | ||||
|     uint8_t *edge_emu_buffer; | ||||
| @@ -543,6 +542,8 @@ typedef struct H264Context { | ||||
|     int height_from_caller; | ||||
|  | ||||
|     int enable_er; | ||||
|     ERContext er; | ||||
|     int16_t *dc_val_base; | ||||
|  | ||||
|     H264SEIContext sei; | ||||
|  | ||||
| @@ -784,7 +785,7 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src); | ||||
| int ff_h264_replace_picture(H264Context *h, H264Picture *dst, const H264Picture *src); | ||||
| void ff_h264_unref_picture(H264Context *h, H264Picture *pic); | ||||
|  | ||||
| int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl); | ||||
| void ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl); | ||||
|  | ||||
| void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user