From c28ed1d743443e783537d279ae721be3bbdf7646 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 29 Jan 2015 13:06:25 +0100 Subject: [PATCH] h264: move [uv]linesize to the per-slice context While it is a per-frame variable, it is only really used in the low-level decoding code, so it is more efficient to store it in the slice context. --- libavcodec/h264.h | 2 +- libavcodec/h264_mb.c | 8 +++---- libavcodec/h264_mb_template.c | 36 ++++++++++++++--------------- libavcodec/h264_slice.c | 43 +++++++++++++++-------------------- libavcodec/svq3.c | 32 +++++++++++++------------- 5 files changed, 57 insertions(+), 64 deletions(-) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 9fc5c12fee..6f46af48a4 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -366,6 +366,7 @@ typedef struct H264SliceContext { unsigned int topright_samples_available; unsigned int left_samples_available; + ptrdiff_t linesize, uvlinesize; ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff ptrdiff_t mb_uvlinesize; @@ -478,7 +479,6 @@ typedef struct H264Context { /* coded dimensions -- 16 * mb w/h */ int width, height; - ptrdiff_t linesize, uvlinesize; int chroma_x_shift, chroma_y_shift; int droppable; diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index 57d429ab02..fea733a9c3 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -487,13 +487,13 @@ static av_always_inline void prefetch_motion(const H264Context *h, H264SliceCont int off = (mx << pixel_shift) + (my + (sl->mb_x & 3) * 4) * sl->mb_linesize + (64 << pixel_shift); - h->vdsp.prefetch(src[0] + off, h->linesize, 4); + h->vdsp.prefetch(src[0] + off, sl->linesize, 4); if (chroma_idc == 3 /* yuv444 */) { - h->vdsp.prefetch(src[1] + off, h->linesize, 4); - h->vdsp.prefetch(src[2] + off, h->linesize, 4); + h->vdsp.prefetch(src[1] + off, sl->linesize, 4); + h->vdsp.prefetch(src[2] + off, sl->linesize, 4); } else { off = ((mx >> 1) << pixel_shift) + - ((my >> 1) + (sl->mb_x & 7)) * h->uvlinesize + + ((my >> 1) + (sl->mb_x & 7)) * sl->uvlinesize + (64 << pixel_shift); h->vdsp.prefetch(src[1] + off, src[2] - src[1], 2); } diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c index 94de31634c..75757a66a5 100644 --- a/libavcodec/h264_mb_template.c +++ b/libavcodec/h264_mb_template.c @@ -57,23 +57,23 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex const int block_h = 16 >> h->chroma_y_shift; const int chroma422 = CHROMA422(h); - 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] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h; - dest_cr = h->cur_pic.f.data[2] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * h->uvlinesize * block_h; + dest_y = h->cur_pic.f.data[0] + ((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16; + dest_cb = h->cur_pic.f.data[1] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h; + dest_cr = h->cur_pic.f.data[2] + (mb_x << PIXEL_SHIFT) * 8 + mb_y * sl->uvlinesize * block_h; - h->vdsp.prefetch(dest_y + (sl->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT), h->linesize, 4); - h->vdsp.prefetch(dest_cb + (sl->mb_x & 7) * h->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2); + h->vdsp.prefetch(dest_y + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT), sl->linesize, 4); + h->vdsp.prefetch(dest_cb + (sl->mb_x & 7) * sl->uvlinesize + (64 << PIXEL_SHIFT), dest_cr - dest_cb, 2); h->list_counts[mb_xy] = sl->list_count; if (!SIMPLE && MB_FIELD(sl)) { - linesize = sl->mb_linesize = h->linesize * 2; - uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2; + linesize = sl->mb_linesize = sl->linesize * 2; + uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2; block_offset = &h->block_offset[48]; if (mb_y & 1) { // FIXME move out of this function? - dest_y -= h->linesize * 15; - dest_cb -= h->uvlinesize * (block_h - 1); - dest_cr -= h->uvlinesize * (block_h - 1); + dest_y -= sl->linesize * 15; + dest_cb -= sl->uvlinesize * (block_h - 1); + dest_cr -= sl->uvlinesize * (block_h - 1); } if (FRAME_MBAFF(h)) { int list; @@ -94,8 +94,8 @@ static av_noinline void FUNC(hl_decode_mb)(const H264Context *h, H264SliceContex } } } else { - linesize = sl->mb_linesize = h->linesize; - uvlinesize = sl->mb_uvlinesize = h->uvlinesize; + linesize = sl->mb_linesize = sl->linesize; + uvlinesize = sl->mb_uvlinesize = sl->uvlinesize; // dct_offset = s->linesize * 16; } @@ -287,19 +287,19 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo for (p = 0; p < plane_count; p++) { dest[p] = h->cur_pic.f.data[p] + - ((mb_x << PIXEL_SHIFT) + mb_y * h->linesize) * 16; - h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * h->linesize + (64 << PIXEL_SHIFT), - h->linesize, 4); + ((mb_x << PIXEL_SHIFT) + mb_y * sl->linesize) * 16; + h->vdsp.prefetch(dest[p] + (sl->mb_x & 3) * 4 * sl->linesize + (64 << PIXEL_SHIFT), + sl->linesize, 4); } h->list_counts[mb_xy] = sl->list_count; if (!SIMPLE && MB_FIELD(sl)) { - linesize = sl->mb_linesize = sl->mb_uvlinesize = h->linesize * 2; + linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize * 2; block_offset = &h->block_offset[48]; if (mb_y & 1) // FIXME move out of this function? for (p = 0; p < 3; p++) - dest[p] -= h->linesize * 15; + dest[p] -= sl->linesize * 15; if (FRAME_MBAFF(h)) { int list; for (list = 0; list < sl->list_count; list++) { @@ -319,7 +319,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(const H264Context *h, H264SliceCo } } } else { - linesize = sl->mb_linesize = sl->mb_uvlinesize = h->linesize; + linesize = sl->mb_linesize = sl->mb_uvlinesize = sl->linesize; } if (!SIMPLE && IS_INTRA_PCM(mb_type)) { diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index d0438fd00c..047dbaef0a 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -228,9 +228,6 @@ static int alloc_picture(H264Context *h, H264Picture *pic) if (ret < 0) goto fail; - h->linesize = pic->f.linesize[0]; - h->uvlinesize = pic->f.linesize[1]; - if (h->avctx->hwaccel) { const AVHWAccel *hwaccel = h->avctx->hwaccel; av_assert0(!pic->hwaccel_picture_private); @@ -458,11 +455,6 @@ int ff_h264_update_thread_context(AVCodecContext *dst, } context_reinitialized = 1; - /* update linesize on resize. The decoder doesn't - * necessarily call h264_frame_start in the new thread */ - h->linesize = h1->linesize; - h->uvlinesize = h1->uvlinesize; - /* copy block_offset since frame_start may not be called */ memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset)); } @@ -644,17 +636,15 @@ static int h264_frame_start(H264Context *h) if (CONFIG_ERROR_RESILIENCE) ff_er_frame_start(&h->slice_ctx[0].er); - assert(h->linesize && h->uvlinesize); - for (i = 0; i < 16; i++) { - h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3); - h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[0] * ((scan8[i] - scan8[0]) >> 3); } for (i = 0; i < 16; i++) { h->block_offset[16 + i] = - h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 4 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3); h->block_offset[48 + 16 + i] = - h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7) << pixel_shift) + 8 * pic->f.linesize[1] * ((scan8[i] - scan8[0]) >> 3); } /* Some macroblocks can be accessed before they're available in case @@ -1976,26 +1966,26 @@ static void loop_filter(const H264Context *h, H264SliceContext *sl, int start_x, 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; + ((mb_x << pixel_shift) + mb_y * sl->linesize) * 16; dest_cb = h->cur_pic.f.data[1] + (mb_x << pixel_shift) * (8 << CHROMA444(h)) + - mb_y * h->uvlinesize * block_h; + mb_y * sl->uvlinesize * block_h; dest_cr = h->cur_pic.f.data[2] + (mb_x << pixel_shift) * (8 << CHROMA444(h)) + - mb_y * h->uvlinesize * block_h; + mb_y * sl->uvlinesize * block_h; // FIXME simplify above if (MB_FIELD(sl)) { - linesize = sl->mb_linesize = h->linesize * 2; - uvlinesize = sl->mb_uvlinesize = h->uvlinesize * 2; + linesize = sl->mb_linesize = sl->linesize * 2; + uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2; if (mb_y & 1) { // FIXME move out of this function? - dest_y -= h->linesize * 15; - dest_cb -= h->uvlinesize * (block_h - 1); - dest_cr -= h->uvlinesize * (block_h - 1); + dest_y -= sl->linesize * 15; + dest_cb -= sl->uvlinesize * (block_h - 1); + dest_cr -= sl->uvlinesize * (block_h - 1); } } else { - linesize = sl->mb_linesize = h->linesize; - uvlinesize = sl->mb_uvlinesize = h->uvlinesize; + linesize = sl->mb_linesize = sl->linesize; + uvlinesize = sl->mb_uvlinesize = sl->uvlinesize; } backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0); @@ -2083,7 +2073,10 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) int lf_x_start = sl->mb_x; int ret; - ret = alloc_scratch_buffers(sl, h->linesize); + sl->linesize = h->cur_pic_ptr->f.linesize[0]; + sl->uvlinesize = h->cur_pic_ptr->f.linesize[1]; + + ret = alloc_scratch_buffers(sl, sl->linesize); if (ret < 0) return ret; diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index d28b2d2f19..00e7c89e8f 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -313,23 +313,23 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, } /* form component predictions */ - dest = h->cur_pic.f.data[0] + x + y * h->linesize; - src = pic->f.data[0] + mx + my * h->linesize; + dest = h->cur_pic.f.data[0] + x + y * sl->linesize; + src = pic->f.data[0] + mx + my * sl->linesize; if (emu) { h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, - h->linesize, h->linesize, + sl->linesize, sl->linesize, width + 1, height + 1, mx, my, s->h_edge_pos, s->v_edge_pos); src = sl->edge_emu_buffer; } if (thirdpel) (avg ? s->tdsp.avg_tpel_pixels_tab - : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, h->linesize, + : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, sl->linesize, width, height); else (avg ? s->hdsp.avg_pixels_tab - : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, h->linesize, + : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, sl->linesize, height); if (!(h->flags & CODEC_FLAG_GRAY)) { @@ -340,12 +340,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, blocksize++; for (i = 1; i < 3; i++) { - dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * h->uvlinesize; - src = pic->f.data[i] + mx + my * h->uvlinesize; + dest = h->cur_pic.f.data[i] + (x >> 1) + (y >> 1) * sl->uvlinesize; + src = pic->f.data[i] + mx + my * sl->uvlinesize; if (emu) { h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src, - h->uvlinesize, h->uvlinesize, + sl->uvlinesize, sl->uvlinesize, width + 1, height + 1, mx, my, (s->h_edge_pos >> 1), s->v_edge_pos >> 1); @@ -354,12 +354,12 @@ static inline void svq3_mc_dir_part(SVQ3Context *s, if (thirdpel) (avg ? s->tdsp.avg_tpel_pixels_tab : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, - h->uvlinesize, + sl->uvlinesize, width, height); else (avg ? s->hdsp.avg_pixels_tab : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, - h->uvlinesize, + sl->uvlinesize, height); } } @@ -1101,8 +1101,8 @@ static int get_buffer(AVCodecContext *avctx, H264Picture *pic) return AVERROR(ENOMEM); } - h->linesize = pic->f.linesize[0]; - h->uvlinesize = pic->f.linesize[1]; + sl->linesize = pic->f.linesize[0]; + sl->uvlinesize = pic->f.linesize[1]; return 0; fail: @@ -1162,14 +1162,14 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, return ret; for (i = 0; i < 16; i++) { - h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3); - h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->linesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->linesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->linesize * ((scan8[i] - scan8[0]) >> 3); } for (i = 0; i < 16; i++) { h->block_offset[16 + i] = - h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3); h->block_offset[48 + 16 + i] = - h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * h->uvlinesize * ((scan8[i] - scan8[0]) >> 3); + h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3); } if (h->pict_type != AV_PICTURE_TYPE_I) {