diff options
author | Anton Khirnov <anton@khirnov.net> | 2015-01-17 22:28:46 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2015-03-21 11:27:14 +0100 |
commit | d4d9068cdf8f4b2b87ae87a2ef880d243f77b977 (patch) | |
tree | 2ede3f693c54ca02c41d90549295fe5868f55b54 /libavcodec/h264_slice.c | |
parent | 0edbe6faa7ef80daf0e84353cbe733389bf1a522 (diff) | |
download | ffmpeg-streaming-d4d9068cdf8f4b2b87ae87a2ef880d243f77b977.zip ffmpeg-streaming-d4d9068cdf8f4b2b87ae87a2ef880d243f77b977.tar.gz |
h264: move mb_{x,y} into the per-slice context
Diffstat (limited to 'libavcodec/h264_slice.c')
-rw-r--r-- | libavcodec/h264_slice.c | 130 |
1 files changed, 67 insertions, 63 deletions
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 64dae07..cea213e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -719,7 +719,8 @@ static int h264_frame_start(H264Context *h) return 0; } -static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y, +static av_always_inline void backup_mb_border(H264Context *h, H264SliceContext *sl, + uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int simple) @@ -735,9 +736,9 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y, src_cr -= uvlinesize; if (!simple && FRAME_MBAFF(h)) { - if (h->mb_y & 1) { + if (sl->mb_y & 1) { if (!MB_MBAFF(h)) { - top_border = h->top_borders[0][h->mb_x]; + top_border = h->top_borders[0][sl->mb_x]; AV_COPY128(top_border, src_y + 15 * linesize); if (pixel_shift) AV_COPY128(top_border + 16, src_y + 15 * linesize + 16); @@ -777,7 +778,7 @@ static av_always_inline void backup_mb_border(H264Context *h, uint8_t *src_y, return; } - top_border = h->top_borders[top_idx][h->mb_x]; + top_border = h->top_borders[top_idx][sl->mb_x]; /* There are two lines saved, the line above the top macroblock * of a pair, and the line above the bottom macroblock. */ AV_COPY128(top_border, src_y + 16 * linesize); @@ -1207,8 +1208,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex slice_type = get_ue_golomb_31(&h->gb); if (slice_type > 9) { av_log(h->avctx, AV_LOG_ERROR, - "slice type %d too large at %d %d\n", - slice_type, h->mb_x, h->mb_y); + "slice type %d too large at %d\n", + slice_type, first_mb_in_slice); return AVERROR_INVALIDDATA; } if (slice_type > 4) { @@ -1556,12 +1557,12 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Contex av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n"); return AVERROR_INVALIDDATA; } - h->resync_mb_x = h->mb_x = first_mb_in_slice % h->mb_width; - h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) << + h->resync_mb_x = sl->mb_x = first_mb_in_slice % h->mb_width; + h->resync_mb_y = sl->mb_y = (first_mb_in_slice / h->mb_width) << FIELD_OR_MBAFF_PICTURE(h); if (h->picture_structure == PICT_BOTTOM_FIELD) - h->resync_mb_y = h->mb_y = h->mb_y + 1; - assert(h->mb_y < h->mb_height); + h->resync_mb_y = sl->mb_y = sl->mb_y + 1; + assert(sl->mb_y < h->mb_height); if (h->picture_structure == PICT_FRAME) { h->curr_pic_num = h->frame_num; @@ -1895,7 +1896,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h, } { - int16_t(*mv_src)[2] = &h->cur_pic.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride]; + int16_t(*mv_src)[2] = &h->cur_pic.motion_val[list][4 * sl->mb_x + 4 * sl->mb_y * b_stride]; AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride); AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride); AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride); @@ -1924,7 +1925,7 @@ static int fill_filter_caches(H264Context *h, H264SliceContext *sl, int mb_type) if (FRAME_MBAFF(h)) { const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]); const int curr_mb_field_flag = IS_INTERLACED(mb_type); - if (h->mb_y & 1) { + if (sl->mb_y & 1) { if (left_mb_field_flag != curr_mb_field_flag) left_xy[LTOP] -= h->mb_stride; } else { @@ -2056,7 +2057,7 @@ static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int e { uint8_t *dest_y, *dest_cb, *dest_cr; int linesize, uvlinesize, mb_x, mb_y; - const int end_mb_y = h->mb_y + FRAME_MBAFF(h); + const int end_mb_y = sl->mb_y + FRAME_MBAFF(h); const int old_slice_type = sl->slice_type; const int pixel_shift = h->pixel_shift; const int block_h = 16 >> h->chroma_y_shift; @@ -2074,8 +2075,8 @@ static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int e h->mb_mbaff = h->mb_field_decoding_flag = !!IS_INTERLACED(mb_type); - h->mb_x = mb_x; - h->mb_y = mb_y; + sl->mb_x = mb_x; + sl->mb_y = mb_y; dest_y = h->cur_pic.f.data[0] + ((mb_x << pixel_shift) + mb_y * h->linesize) * 16; dest_cb = h->cur_pic.f.data[1] + @@ -2098,7 +2099,7 @@ static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int e linesize = sl->mb_linesize = h->linesize; uvlinesize = sl->mb_uvlinesize = h->uvlinesize; } - backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, + backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); if (fill_filter_caches(h, sl, mb_type)) continue; @@ -2115,15 +2116,15 @@ static void loop_filter(H264Context *h, H264SliceContext *sl, int start_x, int e } } sl->slice_type = old_slice_type; - h->mb_x = end_x; - h->mb_y = end_mb_y - FRAME_MBAFF(h); + sl->mb_x = end_x; + sl->mb_y = end_mb_y - FRAME_MBAFF(h); 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, H264SliceContext *sl) { - const int mb_xy = h->mb_x + h->mb_y * h->mb_stride; + const int mb_xy = sl->mb_x + sl->mb_y * h->mb_stride; int mb_type = (h->slice_table[mb_xy - 1] == sl->slice_num) ? h->cur_pic.mb_type[mb_xy - 1] : (h->slice_table[mb_xy - h->mb_stride] == sl->slice_num) ? @@ -2136,7 +2137,7 @@ static void predict_field_decoding_flag(H264Context *h, H264SliceContext *sl) */ static void decode_finish_row(H264Context *h, H264SliceContext *sl) { - int top = 16 * (h->mb_y >> FIELD_PICTURE(h)); + int top = 16 * (sl->mb_y >> FIELD_PICTURE(h)); int pic_height = 16 * h->mb_height >> FIELD_PICTURE(h); int height = 16 << FRAME_MBAFF(h); int deblock_border = (16 + 4) << FRAME_MBAFF(h); @@ -2181,7 +2182,7 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) { H264SliceContext *sl = arg; H264Context *h = sl->h264; - int lf_x_start = h->mb_x; + int lf_x_start = sl->mb_x; sl->mb_skip_run = -1; @@ -2211,53 +2212,53 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) // FIXME optimal? or let mb_decode decode 16x32 ? if (ret >= 0 && FRAME_MBAFF(h)) { - h->mb_y++; + sl->mb_y++; ret = ff_h264_decode_mb_cabac(h, sl); if (ret >= 0) ff_h264_hl_decode_mb(h, sl); - h->mb_y--; + sl->mb_y--; } eos = get_cabac_terminate(&sl->cabac); if ((h->workaround_bugs & FF_BUG_TRUNCATED) && sl->cabac.bytestream > sl->cabac.bytestream_end + 2) { - er_add_slice(h, sl, 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, sl, lf_x_start, h->mb_x + 1); + er_add_slice(h, sl, h->resync_mb_x, h->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); return 0; } if (ret < 0 || sl->cabac.bytestream > sl->cabac.bytestream_end + 2) { av_log(h->avctx, AV_LOG_ERROR, "error while decoding MB %d %d, bytestream %td\n", - h->mb_x, h->mb_y, + sl->mb_x, sl->mb_y, sl->cabac.bytestream_end - sl->cabac.bytestream); - er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); + er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, sl->mb_x, + sl->mb_y, ER_MB_ERROR); return AVERROR_INVALIDDATA; } - if (++h->mb_x >= h->mb_width) { - loop_filter(h, sl, lf_x_start, h->mb_x); - h->mb_x = lf_x_start = 0; + if (++sl->mb_x >= h->mb_width) { + loop_filter(h, sl, lf_x_start, sl->mb_x); + sl->mb_x = lf_x_start = 0; decode_finish_row(h, sl); - ++h->mb_y; + ++sl->mb_y; if (FIELD_OR_MBAFF_PICTURE(h)) { - ++h->mb_y; - if (FRAME_MBAFF(h) && h->mb_y < h->mb_height) + ++sl->mb_y; + if (FRAME_MBAFF(h) && sl->mb_y < h->mb_height) predict_field_decoding_flag(h, sl); } } - if (eos || h->mb_y >= h->mb_height) { + if (eos || sl->mb_y >= h->mb_height) { tprintf(h->avctx, "slice end %d %d\n", get_bits_count(&h->gb), h->gb.size_in_bits); - er_add_slice(h, sl, 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, sl, lf_x_start, h->mb_x); + er_add_slice(h, sl, h->resync_mb_x, h->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; } } @@ -2270,44 +2271,44 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) // FIXME optimal? or let mb_decode decode 16x32 ? if (ret >= 0 && FRAME_MBAFF(h)) { - h->mb_y++; + sl->mb_y++; ret = ff_h264_decode_mb_cavlc(h, sl); if (ret >= 0) ff_h264_hl_decode_mb(h, sl); - h->mb_y--; + sl->mb_y--; } if (ret < 0) { av_log(h->avctx, AV_LOG_ERROR, - "error while decoding MB %d %d\n", h->mb_x, h->mb_y); - er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); + "error while decoding MB %d %d\n", sl->mb_x, sl->mb_y); + er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, sl->mb_x, + sl->mb_y, ER_MB_ERROR); return ret; } - if (++h->mb_x >= h->mb_width) { - loop_filter(h, sl, lf_x_start, h->mb_x); - h->mb_x = lf_x_start = 0; + if (++sl->mb_x >= h->mb_width) { + loop_filter(h, sl, lf_x_start, sl->mb_x); + sl->mb_x = lf_x_start = 0; decode_finish_row(h, sl); - ++h->mb_y; + ++sl->mb_y; if (FIELD_OR_MBAFF_PICTURE(h)) { - ++h->mb_y; - if (FRAME_MBAFF(h) && h->mb_y < h->mb_height) + ++sl->mb_y; + if (FRAME_MBAFF(h) && sl->mb_y < h->mb_height) predict_field_decoding_flag(h, sl); } - if (h->mb_y >= h->mb_height) { + if (sl->mb_y >= h->mb_height) { tprintf(h->avctx, "slice end %d %d\n", get_bits_count(&h->gb), h->gb.size_in_bits); if (get_bits_left(&h->gb) == 0) { er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, - h->mb_x - 1, h->mb_y, ER_MB_END); + sl->mb_x - 1, sl->mb_y, ER_MB_END); return 0; } else { er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, - h->mb_x - 1, h->mb_y, ER_MB_END); + sl->mb_x - 1, sl->mb_y, ER_MB_END); return AVERROR_INVALIDDATA; } @@ -2320,14 +2321,14 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) if (get_bits_left(&h->gb) == 0) { er_add_slice(h, sl, 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, sl, lf_x_start, h->mb_x); + 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, h->resync_mb_x, h->resync_mb_y, h->mb_x, - h->mb_y, ER_MB_ERROR); + er_add_slice(h, sl, h->resync_mb_x, h->resync_mb_y, sl->mb_x, + sl->mb_y, ER_MB_ERROR); return AVERROR_INVALIDDATA; } @@ -2346,12 +2347,15 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count) { AVCodecContext *const avctx = h->avctx; H264Context *hx; + H264SliceContext *sl; int i; if (h->avctx->hwaccel) return 0; if (context_count == 1) { - return decode_slice(avctx, &h->slice_ctx[0]); + int ret = decode_slice(avctx, &h->slice_ctx[0]); + h->mb_y = h->slice_ctx[0].mb_y; + return ret; } else { for (i = 1; i < context_count; i++) { hx = h->thread_context[i]; @@ -2363,8 +2367,8 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count) /* pull back stuff from slices to master context */ hx = h->thread_context[context_count - 1]; - h->mb_x = hx->mb_x; - h->mb_y = hx->mb_y; + sl = &h->slice_ctx[context_count - 1]; + h->mb_y = sl->mb_y; h->droppable = hx->droppable; h->picture_structure = hx->picture_structure; for (i = 1; i < context_count; i++) |