From 900e3af857871f1075d9f095ea22bfee1484c086 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 16 May 2015 11:59:01 -0400 Subject: [PATCH] vp9: match another find_ref_mvs() bug in libvpx. If we find a second non-sub8x8 motion vector for a non-first sub8x8 block, and the clamped value is identical to the first non-sub8x8 motion vector, then the resulting nearmv motion vector is forced to zero. --- libavcodec/vp9.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 09c96f162a..7f28b2689e 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1111,7 +1111,7 @@ static void find_ref_mvs(VP9Context *s, int row = s->row, col = s->col, row7 = s->row7; const int8_t (*p)[2] = mv_ref_blk_off[b->bs]; #define INVALID_MV 0x80008000U - uint32_t mem = INVALID_MV; + uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV; int i; #define RETURN_DIRECT_MV(mv) \ @@ -1142,15 +1142,25 @@ static void find_ref_mvs(VP9Context *s, if (sb > 0) { \ VP56mv tmp; \ uint32_t m; \ - clamp_mv(&tmp, &mv, s); \ - m = AV_RN32A(&tmp); \ - if (!idx) { \ - AV_WN32A(pmv, m); \ - return; \ - } else if (mem == INVALID_MV) { \ - mem = m; \ - } else if (m != mem) { \ - AV_WN32A(pmv, m); \ + av_assert2(idx == 1); \ + av_assert2(mem != INVALID_MV); \ + if (mem_sub8x8 == INVALID_MV) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + return; \ + } \ + mem_sub8x8 = AV_RN32A(&mv); \ + } else if (mem_sub8x8 != AV_RN32A(&mv)) { \ + clamp_mv(&tmp, &mv, s); \ + m = AV_RN32A(&tmp); \ + if (m != mem) { \ + AV_WN32A(pmv, m); \ + } else { \ + /* BUG I'm pretty sure this isn't the intention */ \ + AV_WN32A(pmv, 0); \ + } \ return; \ } \ } else { \