In vp9_dec_build_inter_predictors_sb(), this code will be triggered for 4:2:2
chroma blocks with num_4x4_w=1 and num_4x4_h=2:
if (xd->mi[0].src_mi->mbmi.sb_type < BLOCK_8X8) {
int i = 0, x, y;
assert(bsize == BLOCK_8X8);
for (y = 0; y < num_4x4_h; ++y)
for (x = 0; x < num_4x4_w; ++x)
dec_build_inter_predictors(xd, plane, i++, bw, bh,
4 * x, 4 * y, 4, 4, mi_x, mi_y);
} else {
i++ is only incremented within the loop iterations, so the values in
dec_build_inter_predictors for the top 4x4 chroma block is 0, and bottom is 1.
This value is then used to get the final motion vector:
static void dec_build_inter_predictors(MACROBLOCKD *xd, int plane, int block,
int bw, int bh,
int x, int y, int w, int h,
int mi_x, int mi_y) {
[..]
const MV mv = mi->mbmi.sb_type < BLOCK_8X8
? average_split_mvs(pd, mi, ref, block)
: mi->mbmi.mv[ref].as_mv;
which is:
static MV average_split_mvs(const struct macroblockd_plane *pd,
const MODE_INFO *mi, int ref, int block) {
const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
MV res = {0, 0};
switch (ss_idx) {
case 0:
res = mi->bmi[block].as_mv[ref].as_mv;
break;
case 1:
res = mi_mv_pred_q2(mi, ref, block, block + 2);
break;
case 2:
res = mi_mv_pred_q2(mi, ref, block, block + 1);
break;
case 3:
res = mi_mv_pred_q4(mi, ref);
break;
default:
assert(ss_idx <= 3 && ss_idx >= 0);
}
return res;
}
The result of all this is that for the bottom 4x4 block in chroma blocks with
lumasize=8x4 or 4x4, the indices for the luma motion vectors averaged into the
final motion vector are 0 and 1 for the top block (which is correct), and 1 and
2 for the bottom block (instead of 2 and 3), thus resulting in wacky chroma
inter prediction.
I realize that you can't fix this in vp9, but it'd be nice to fix it in vp10. I
found the bug while implementing ffvp9.
Original issue reported on code.google.com by rsbul...@gmail.com on 30 Apr 2015 at 3:57
Original issue reported on code.google.com by
rsbul...@gmail.com
on 30 Apr 2015 at 3:57