diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 1b4fbd2cf3..bc2dc0d412 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -2740,18 +2740,23 @@ static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func sm uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { #define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14) + int mx, my; + int refbw_m1, refbh_m1; + int th; + VP56mv mv; + + mv.x = av_clip(in_mv->x, -(x + bw + 4) << 3, (s->cols * 8 - x + 3) << 3); + mv.y = av_clip(in_mv->y, -(y + bh + 4) << 3, (s->rows * 8 - y + 3) << 3); // BUG libvpx seems to scale the two components separately. This introduces // rounding errors but we have to reproduce them to be exactly compatible // with the output from libvpx... - int mx = scale_mv(mv->x * 2, 0) + scale_mv(x * 16, 0); - int my = scale_mv(mv->y * 2, 1) + scale_mv(y * 16, 1); - int refbw_m1, refbh_m1; - int th; + mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0); + my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1); y = my >> 4; x = mx >> 4; @@ -2783,25 +2788,30 @@ static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func const uint8_t *ref_u, ptrdiff_t src_stride_u, const uint8_t *ref_v, ptrdiff_t src_stride_v, ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv, int bw, int bh, int w, int h, int bytesperpixel, const uint16_t *scale, const uint8_t *step) { int mx, my; int refbw_m1, refbh_m1; int th; + VP56mv mv; if (s->ss_h) { // BUG https://code.google.com/p/webm/issues/detail?id=820 - mx = scale_mv(mv->x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); + mv.x = av_clip(in_mv->x, -(x + bw + 4) << 4, (s->cols * 4 - x + 3) << 4); + mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); } else { - mx = scale_mv(mv->x << 1, 0) + scale_mv(x * 16, 0); + mv.x = av_clip(in_mv->x, -(x + bw + 4) << 3, (s->cols * 8 - x + 3) << 3); + mx = scale_mv(mv.x << 1, 0) + scale_mv(x * 16, 0); } if (s->ss_v) { // BUG https://code.google.com/p/webm/issues/detail?id=820 - my = scale_mv(mv->y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); + mv.y = av_clip(in_mv->y, -(y + bh + 4) << 4, (s->rows * 4 - y + 3) << 4); + my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); } else { - my = scale_mv(mv->y << 1, 1) + scale_mv(y * 16, 1); + mv.y = av_clip(in_mv->y, -(y + bh + 4) << 3, (s->rows * 8 - y + 3) << 3); + my = scale_mv(mv.y << 1, 1) + scale_mv(y * 16, 1); } #undef scale_mv y = my >> 4;