diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2014-01-03 09:10:38 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2014-01-09 09:46:13 +0100 |
commit | e588615d938f8581f0d6f3771662d08cadfc00de (patch) | |
tree | 71ad5db7d18a025cc455749d49523a6b3693dd4d /libavcodec | |
parent | a246af86e47044dec243db2f708cc125d608ea78 (diff) | |
download | ffmpeg-e588615d938f8581f0d6f3771662d08cadfc00de.tar.gz |
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 <anton@khirnov.net>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/hevc.c | 33 | ||||
-rw-r--r-- | 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; |