mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-23 04:24:35 +02:00
h264: move remaining ER stuff into the per-slice context
This commit is contained in:
parent
5bc69f38c1
commit
582683b6ac
@ -379,10 +379,6 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp)
|
||||
hx = h->thread_context[i];
|
||||
if (!hx)
|
||||
continue;
|
||||
av_freep(&hx->dc_val_base);
|
||||
av_freep(&hx->er.mb_index2xy);
|
||||
av_freep(&hx->er.error_status_table);
|
||||
av_freep(&hx->er.er_temp_buffer);
|
||||
|
||||
if (free_rbsp) {
|
||||
av_freep(&hx->rbsp_buffer);
|
||||
@ -395,6 +391,11 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp)
|
||||
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]);
|
||||
@ -477,23 +478,21 @@ fail:
|
||||
* Init context
|
||||
* Allocate buffers which are not shared amongst multiple threads.
|
||||
*/
|
||||
int ff_h264_context_init(H264Context *h)
|
||||
int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl)
|
||||
{
|
||||
ERContext *er = &h->er;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
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 (CONFIG_ERROR_RESILIENCE) {
|
||||
/* init ER */
|
||||
@ -525,13 +524,13 @@ int ff_h264_context_init(H264Context *h)
|
||||
FF_ALLOC_OR_GOTO(h->avctx, er->er_temp_buffer,
|
||||
h->mb_height * h->mb_stride, fail);
|
||||
|
||||
FF_ALLOCZ_OR_GOTO(h->avctx, h->dc_val_base,
|
||||
FF_ALLOCZ_OR_GOTO(h->avctx, sl->dc_val_base,
|
||||
yc_size * sizeof(int16_t), fail);
|
||||
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[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++)
|
||||
h->dc_val_base[i] = 1024;
|
||||
sl->dc_val_base[i] = 1024;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -299,6 +299,7 @@ typedef struct H264Picture {
|
||||
typedef struct H264SliceContext {
|
||||
struct H264Context *h264;
|
||||
GetBitContext gb;
|
||||
ERContext er;
|
||||
|
||||
int slice_num;
|
||||
int slice_type;
|
||||
@ -398,6 +399,7 @@ typedef struct H264SliceContext {
|
||||
int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1
|
||||
|
||||
const uint8_t *intra_pcm_ptr;
|
||||
int16_t *dc_val_base;
|
||||
|
||||
uint8_t *bipred_scratchpad;
|
||||
uint8_t *edge_emu_buffer;
|
||||
@ -449,7 +451,6 @@ typedef struct H264Context {
|
||||
H264ChromaContext h264chroma;
|
||||
H264QpelContext h264qpel;
|
||||
GetBitContext gb;
|
||||
ERContext er;
|
||||
|
||||
H264Picture *DPB;
|
||||
H264Picture *cur_pic_ptr;
|
||||
@ -714,7 +715,6 @@ typedef struct H264Context {
|
||||
int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs
|
||||
|
||||
int cur_chroma_format_idc;
|
||||
int16_t *dc_val_base;
|
||||
|
||||
AVBufferPool *qscale_table_pool;
|
||||
AVBufferPool *mb_type_pool;
|
||||
@ -1060,7 +1060,7 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup);
|
||||
int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src);
|
||||
void ff_h264_unref_picture(H264Context *h, H264Picture *pic);
|
||||
|
||||
int ff_h264_context_init(H264Context *h);
|
||||
int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl);
|
||||
int ff_h264_set_parameter_from_sps(H264Context *h);
|
||||
|
||||
void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height);
|
||||
|
@ -185,12 +185,12 @@ int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)
|
||||
* causes problems for the first MB line, too.
|
||||
*/
|
||||
if (!FIELD_PICTURE(h)) {
|
||||
h264_set_erpic(&h->er.cur_pic, h->cur_pic_ptr);
|
||||
h264_set_erpic(&h->er.last_pic,
|
||||
h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr);
|
||||
h264_set_erpic(&sl->er.last_pic,
|
||||
sl->ref_count[0] ? &sl->ref_list[0][0] : NULL);
|
||||
h264_set_erpic(&h->er.next_pic,
|
||||
h264_set_erpic(&sl->er.next_pic,
|
||||
sl->ref_count[1] ? &sl->ref_list[1][0] : NULL);
|
||||
ff_er_frame_end(&h->er);
|
||||
ff_er_frame_end(&sl->er);
|
||||
}
|
||||
#endif /* CONFIG_ERROR_RESILIENCE */
|
||||
|
||||
|
@ -504,7 +504,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
|
||||
memcpy(h, h1, sizeof(*h1));
|
||||
memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
|
||||
memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
|
||||
memset(&h->er, 0, sizeof(h->er));
|
||||
h->context_initialized = 0;
|
||||
|
||||
memset(&h->cur_pic, 0, sizeof(h->cur_pic));
|
||||
@ -513,6 +512,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
|
||||
|
||||
h->slice_ctx = orig_slice_ctx;
|
||||
|
||||
memset(&h->slice_ctx[0].er, 0, sizeof(h->slice_ctx[0].er));
|
||||
memset(&h->slice_ctx[0].mb, 0, sizeof(h->slice_ctx[0].mb));
|
||||
memset(&h->slice_ctx[0].mb_luma_dc, 0, sizeof(h->slice_ctx[0].mb_luma_dc));
|
||||
memset(&h->slice_ctx[0].mb_padding, 0, sizeof(h->slice_ctx[0].mb_padding));
|
||||
@ -529,7 +529,7 @@ int ff_h264_update_thread_context(AVCodecContext *dst,
|
||||
av_log(dst, AV_LOG_ERROR, "Could not allocate memory\n");
|
||||
return ret;
|
||||
}
|
||||
ret = ff_h264_context_init(h);
|
||||
ret = ff_h264_slice_context_init(h, &h->slice_ctx[0]);
|
||||
if (ret < 0) {
|
||||
av_log(dst, AV_LOG_ERROR, "context_init() failed.\n");
|
||||
return ret;
|
||||
@ -672,7 +672,7 @@ static int h264_frame_start(H264Context *h)
|
||||
return ret;
|
||||
|
||||
if (CONFIG_ERROR_RESILIENCE)
|
||||
ff_er_frame_start(&h->er);
|
||||
ff_er_frame_start(&h->slice_ctx[0].er);
|
||||
|
||||
assert(h->linesize && h->uvlinesize);
|
||||
|
||||
@ -1098,7 +1098,7 @@ static int h264_slice_header_init(H264Context *h, int reinit)
|
||||
h->slice_context_count = nb_slices;
|
||||
|
||||
if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) {
|
||||
ret = ff_h264_context_init(h);
|
||||
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");
|
||||
return ret;
|
||||
@ -1141,7 +1141,7 @@ static int h264_slice_header_init(H264Context *h, int reinit)
|
||||
}
|
||||
|
||||
for (i = 0; i < h->slice_context_count; i++)
|
||||
if ((ret = ff_h264_context_init(h->thread_context[i])) < 0) {
|
||||
if ((ret = ff_h264_slice_context_init(h, &h->slice_ctx[i])) < 0) {
|
||||
av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n");
|
||||
return ret;
|
||||
}
|
||||
@ -2154,12 +2154,12 @@ static void decode_finish_row(H264Context *h, H264SliceContext *sl)
|
||||
h->picture_structure == PICT_BOTTOM_FIELD);
|
||||
}
|
||||
|
||||
static void er_add_slice(H264Context *h, H264SliceContext *sl,
|
||||
static void er_add_slice(H264SliceContext *sl,
|
||||
int startx, int starty,
|
||||
int endx, int endy, int status)
|
||||
{
|
||||
#if CONFIG_ERROR_RESILIENCE
|
||||
ERContext *er = &h->er;
|
||||
ERContext *er = &sl->er;
|
||||
|
||||
er->ref_count = sl->ref_count[0];
|
||||
ff_er_add_slice(er, startx, starty, endx, endy, status);
|
||||
@ -2217,7 +2217,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
|
||||
if ((h->workaround_bugs & FF_BUG_TRUNCATED) &&
|
||||
sl->cabac.bytestream > sl->cabac.bytestream_end + 2) {
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x - 1,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x - 1,
|
||||
sl->mb_y, ER_MB_END);
|
||||
if (sl->mb_x >= lf_x_start)
|
||||
loop_filter(h, sl, lf_x_start, sl->mb_x + 1);
|
||||
@ -2228,7 +2228,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
"error while decoding MB %d %d, bytestream %td\n",
|
||||
sl->mb_x, sl->mb_y,
|
||||
sl->cabac.bytestream_end - sl->cabac.bytestream);
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
sl->mb_y, ER_MB_ERROR);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
@ -2248,7 +2248,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
if (eos || sl->mb_y >= h->mb_height) {
|
||||
tprintf(h->avctx, "slice end %d %d\n",
|
||||
get_bits_count(&sl->gb), sl->gb.size_in_bits);
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x - 1,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x - 1,
|
||||
sl->mb_y, ER_MB_END);
|
||||
if (sl->mb_x > lf_x_start)
|
||||
loop_filter(h, sl, lf_x_start, sl->mb_x);
|
||||
@ -2275,7 +2275,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
if (ret < 0) {
|
||||
av_log(h->avctx, AV_LOG_ERROR,
|
||||
"error while decoding MB %d %d\n", sl->mb_x, sl->mb_y);
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
sl->mb_y, ER_MB_ERROR);
|
||||
return ret;
|
||||
}
|
||||
@ -2295,12 +2295,12 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
get_bits_count(&sl->gb), sl->gb.size_in_bits);
|
||||
|
||||
if (get_bits_left(&sl->gb) == 0) {
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
sl->mb_x - 1, sl->mb_y, ER_MB_END);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
sl->mb_x - 1, sl->mb_y, ER_MB_END);
|
||||
|
||||
return AVERROR_INVALIDDATA;
|
||||
@ -2313,14 +2313,14 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
|
||||
get_bits_count(&sl->gb), sl->gb.size_in_bits);
|
||||
|
||||
if (get_bits_left(&sl->gb) == 0) {
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y,
|
||||
sl->mb_x - 1, sl->mb_y, ER_MB_END);
|
||||
if (sl->mb_x > lf_x_start)
|
||||
loop_filter(h, sl, lf_x_start, sl->mb_x);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
er_add_slice(h, sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
er_add_slice(sl, sl->resync_mb_x, sl->resync_mb_y, sl->mb_x,
|
||||
sl->mb_y, ER_MB_ERROR);
|
||||
|
||||
return AVERROR_INVALIDDATA;
|
||||
@ -2351,8 +2351,8 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
|
||||
return ret;
|
||||
} else {
|
||||
for (i = 1; i < context_count; i++) {
|
||||
hx = h->thread_context[i];
|
||||
hx->er.error_count = 0;
|
||||
sl = &h->slice_ctx[i];
|
||||
sl->er.error_count = 0;
|
||||
}
|
||||
|
||||
avctx->execute(avctx, decode_slice, h->slice_ctx,
|
||||
@ -2365,7 +2365,7 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count)
|
||||
h->droppable = hx->droppable;
|
||||
h->picture_structure = hx->picture_structure;
|
||||
for (i = 1; i < context_count; i++)
|
||||
h->er.error_count += h->thread_context[i]->er.error_count;
|
||||
h->slice_ctx[0].er.error_count += h->slice_ctx[i].er.error_count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user