From e588615d938f8581f0d6f3771662d08cadfc00de Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Fri, 3 Jan 2014 09:10:38 +0100 Subject: [PATCH] hevc: fix decoding of one PU wide files For those the block size may be larger than the source linesize (if the edges are not allocated). Signed-off-by: Anton Khirnov --- libavcodec/hevc.c | 33 ++++++++++++++++++--------------- libavcodec/hevc.h | 6 ++++-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 7481023cc3..438794ded7 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -1497,15 +1497,19 @@ static void luma_mc(HEVCContext *s, int16_t *dst, ptrdiff_t dststride, if (x_off < extra_left || y_off < extra_top || x_off >= pic_width - block_w - ff_hevc_qpel_extra_after[mx] || y_off >= pic_height - block_h - ff_hevc_qpel_extra_after[my]) { + const int edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->sps->pixel_shift; int offset = extra_top * srcstride + (extra_left << s->sps->pixel_shift); + int buf_offset = extra_top * + edge_emu_stride + (extra_left << s->sps->pixel_shift); s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src - offset, - srcstride, srcstride, + edge_emu_stride, srcstride, block_w + ff_hevc_qpel_extra[mx], block_h + ff_hevc_qpel_extra[my], x_off - extra_left, y_off - extra_top, pic_width, pic_height); - src = lc->edge_emu_buffer + offset; + src = lc->edge_emu_buffer + buf_offset; + srcstride = edge_emu_stride; } s->hevcdsp.put_hevc_qpel[my][mx](dst, dststride, src, srcstride, block_w, block_h, lc->mc_buffer); @@ -1548,27 +1552,35 @@ static void chroma_mc(HEVCContext *s, int16_t *dst1, int16_t *dst2, if (x_off < EPEL_EXTRA_BEFORE || y_off < EPEL_EXTRA_AFTER || x_off >= pic_width - block_w - EPEL_EXTRA_AFTER || y_off >= pic_height - block_h - EPEL_EXTRA_AFTER) { + const int edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->sps->pixel_shift; int offset1 = EPEL_EXTRA_BEFORE * (src1stride + (1 << s->sps->pixel_shift)); + int buf_offset1 = EPEL_EXTRA_BEFORE * + (edge_emu_stride + (1 << s->sps->pixel_shift)); int offset2 = EPEL_EXTRA_BEFORE * (src2stride + (1 << s->sps->pixel_shift)); + int buf_offset2 = EPEL_EXTRA_BEFORE * + (edge_emu_stride + (1 << s->sps->pixel_shift)); s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src1 - offset1, - src1stride, src1stride, + edge_emu_stride, src1stride, block_w + EPEL_EXTRA, block_h + EPEL_EXTRA, x_off - EPEL_EXTRA_BEFORE, y_off - EPEL_EXTRA_BEFORE, pic_width, pic_height); - src1 = lc->edge_emu_buffer + offset1; + src1 = lc->edge_emu_buffer + buf_offset1; + src1stride = edge_emu_stride; s->hevcdsp.put_hevc_epel[!!my][!!mx](dst1, dststride, src1, src1stride, block_w, block_h, mx, my, lc->mc_buffer); s->vdsp.emulated_edge_mc(lc->edge_emu_buffer, src2 - offset2, - src2stride, src2stride, + edge_emu_stride, src2stride, block_w + EPEL_EXTRA, block_h + EPEL_EXTRA, x_off - EPEL_EXTRA_BEFORE, y_off - EPEL_EXTRA_BEFORE, pic_width, pic_height); - src2 = lc->edge_emu_buffer + offset2; + src2 = lc->edge_emu_buffer + buf_offset2; + src2stride = edge_emu_stride; + s->hevcdsp.put_hevc_epel[!!my][!!mx](dst2, dststride, src2, src2stride, block_w, block_h, mx, my, lc->mc_buffer); @@ -2421,13 +2433,6 @@ static int hevc_frame_start(HEVCContext *s) if (ret < 0) goto fail; - av_fast_malloc(&lc->edge_emu_buffer, &lc->edge_emu_buffer_size, - (MAX_PB_SIZE + 7) * s->ref->frame->linesize[0]); - if (!lc->edge_emu_buffer) { - ret = AVERROR(ENOMEM); - goto fail; - } - ret = ff_hevc_frame_rps(s); if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "Error constructing the frame RPS.\n"); @@ -2924,12 +2929,10 @@ fail: static av_cold int hevc_decode_free(AVCodecContext *avctx) { HEVCContext *s = avctx->priv_data; - HEVCLocalContext *lc = &s->HEVClc; int i; pic_arrays_free(s); - av_freep(&lc->edge_emu_buffer); av_freep(&s->md5_ctx); av_frame_free(&s->tmp_frame); diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 014219795d..07d70739de 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -71,6 +71,8 @@ #define EPEL_EXTRA_AFTER 2 #define EPEL_EXTRA 3 +#define EDGE_EMU_BUFFER_STRIDE 80 + /** * Value of the luma sample at position (x, y) in the 2D array tab. */ @@ -741,8 +743,8 @@ typedef struct HEVCLocalContext { int start_of_tiles_x; int end_of_tiles_x; int end_of_tiles_y; - uint8_t *edge_emu_buffer; - int edge_emu_buffer_size; + /* +7 is for subpixel interpolation, *2 for high bit depths */ + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[(MAX_PB_SIZE + 7) * EDGE_EMU_BUFFER_STRIDE * 2]; CodingTree ct; CodingUnit cu; PredictionUnit pu; -- GitLab