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);
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]);
* 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 */
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;
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));
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));
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;
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);
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;
}
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;
}
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);
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);
"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;
}
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);
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;
}
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;
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;
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,
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;