From 4924934d2bf860a13ebd8b3f28fe78ea7d9ccb25 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Fri, 12 Apr 2013 17:19:57 -0700 Subject: make buid_inter_predictors block size agnostic (luma) This commit converts the luma versions of vp9_build_inter_predictors_sb to use a common function. Update the convolution functions to support block sizes larger than 16x16, and add a foreach_predicted_block walker. Next step will be to calculate the UV motion vector and implement SBUV, then fold in vp9_build_inter16x16_predictors_mb and SPLITMV. At the 16x16, 32x32, and 64x64 levels implemented in this commit, each plane is predicted with only a single call to vp9_build_inter_predictor. This is not yet called for SPLITMV. If the notion of SPLITMV/I8X8/I4X4 goes away, then the prediction block walker can go away, since we'll always predict the whole bsize in a single step. Implemented using a block walker at this stage for SPLITMV, as a 4x4 "prediction block size" within the BLOCK_SIZE_MB16X16 macroblock. It would also support other rectangular sizes too, if the blocks smaller than 16x16 remain implemented as a SPLITMV-like thing. Just using 4x4 for now. There's also a potential to combine with the foreach_transformed_block walker if the logic for calculating the size of the subsampled transform is made more straightforward, perhaps as a consequence of supporing smaller macroblocks than 16x16. Will watch what happens there. Change-Id: Iddd9973398542216601b630c628b9b7fdee33fe2 --- vp9/common/vp9_blockd.h | 58 ++++++++++++++ vp9/common/vp9_reconinter.c | 187 ++++++++++++++++++++------------------------ vp9/common/vp9_reconinter.h | 6 -- vp9/encoder/vp9_firstpass.c | 2 + 4 files changed, 146 insertions(+), 107 deletions(-) (limited to 'vp9') diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 7eb9f8e86..dd957618c 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -875,4 +875,62 @@ static INLINE void foreach_transformed_block_uv( } } +// TODO(jkoleszar): In principle, pred_w, pred_h are unnecessary, as we could +// calculate the subsampled BLOCK_SIZE_TYPE, but that type isn't defined for +// sizes smaller than 16x16 yet. +typedef void (*foreach_predicted_block_visitor)(int plane, int block, + BLOCK_SIZE_TYPE bsize, + int pred_w, int pred_h, + void *arg); +static INLINE void foreach_predicted_block_in_plane( + const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, int plane, + foreach_predicted_block_visitor visit, void *arg) { + const int bw = b_width_log2(bsize), bh = b_height_log2(bsize); + + // block sizes in number of 4x4 blocks log 2 ("*_b") + // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8 + const MB_PREDICTION_MODE mode = xd->mode_info_context->mbmi.mode; + const int block_size_b = bw + bh; + + // subsampled size of the block + const int ss_sum = xd->plane[plane].subsampling_x + + xd->plane[plane].subsampling_y; + const int ss_block_size = block_size_b - ss_sum; + + // size of the predictor to use. + // TODO(jkoleszar): support I8X8, I4X4 + const int pred_w = bw - xd->plane[plane].subsampling_x; + const int pred_h = bh - xd->plane[plane].subsampling_y; + const int pred_b = mode == SPLITMV ? 0 : pred_w + pred_h; + const int step = 1 << pred_b; + + int i; + + assert(pred_b <= block_size_b); + assert(pred_b == ss_block_size); + for (i = 0; i < (1 << ss_block_size); i += step) { + visit(plane, i, bsize, pred_w, pred_h, arg); + } +} +static INLINE void foreach_predicted_block( + const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, + foreach_predicted_block_visitor visit, void *arg) { + int plane; + + for (plane = 0; plane < MAX_MB_PLANE; plane++) { + foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); + } +} +static INLINE void foreach_predicted_block_uv( + const MACROBLOCKD* const xd, BLOCK_SIZE_TYPE bsize, + foreach_predicted_block_visitor visit, void *arg) { + int plane; + + for (plane = 1; plane < MAX_MB_PLANE; plane++) { + foreach_predicted_block_in_plane(xd, bsize, plane, visit, arg); + } +} + + + #endif // VP9_COMMON_VP9_BLOCKD_H_ diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 71be77df1..002e6eb05 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -527,6 +527,92 @@ static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { (xd->mb_to_bottom_edge + (16 << 3)) >> 1 : mv->row; } +#if !CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT +// TODO(jkoleszar): yet another mv clamping function :-( +MV clamp_mv_to_umv_border_sb(const MV *src_mv, + int bwl, int bhl, + int mb_to_left_edge, int mb_to_top_edge, + int mb_to_right_edge, int mb_to_bottom_edge) { + /* If the MV points so far into the UMV border that no visible pixels + * are used for reconstruction, the subpel part of the MV can be + * discarded and the MV limited to 16 pixels with equivalent results. + */ + const int epel_left = (VP9_INTERP_EXTEND + (4 << bwl)) << 3; + const int epel_right = epel_left - (1 << 3); + const int epel_top = (VP9_INTERP_EXTEND + (4 << bhl)) << 3; + const int epel_bottom = epel_top - (1 << 3); + MV clamped_mv; + clamped_mv.col = clamp(src_mv->col, + mb_to_left_edge - epel_left, + mb_to_right_edge + epel_right); + clamped_mv.row = clamp(src_mv->row, + mb_to_top_edge - epel_top, + mb_to_bottom_edge + epel_bottom); + return clamped_mv; +} + +struct build_inter_predictors_args { + MACROBLOCKD *xd; + uint8_t* dst[MAX_MB_PLANE]; + int dst_stride[MAX_MB_PLANE]; + int x; + int y; +}; +static void build_inter_predictors(int plane, int block, + BLOCK_SIZE_TYPE bsize, + int pred_w, int pred_h, + void *argv) { + const struct build_inter_predictors_args* const arg = argv; + const int bwl = pred_w, bw = 4 << bwl; + const int bhl = pred_h, bh = 4 << bhl; + const int x_idx = block & ((1 << bwl) - 1), y_idx = block >> bwl; + const int x = x_idx * 4, y = y_idx * 4; + MACROBLOCKD * const xd = arg->xd; + const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0; + int which_mv; + + for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) { + const MV* const mv = (xd->mode_info_context->mbmi.mode == SPLITMV) + ? &xd->block[block].bmi.as_mv[which_mv].as_mv + : &xd->mode_info_context->mbmi.mv[which_mv].as_mv; + + const uint8_t * const base_pre = which_mv ? xd->second_pre.y_buffer + : xd->pre.y_buffer; + const int pre_stride = which_mv ? xd->second_pre.y_stride + : xd->pre.y_stride; + const uint8_t *const pre = base_pre + + scaled_buffer_offset(x, y, pre_stride, &xd->scale_factor[which_mv]); + struct scale_factors * const scale = + plane == 0 ? &xd->scale_factor[which_mv] : &xd->scale_factor_uv[which_mv]; + + int_mv clamped_mv; + clamped_mv.as_mv = clamp_mv_to_umv_border_sb(mv, bwl, bhl, + xd->mb_to_left_edge, + xd->mb_to_top_edge, + xd->mb_to_right_edge, + xd->mb_to_bottom_edge); + + scale->set_scaled_offsets(scale, arg->y + y, arg->x + x); + + vp9_build_inter_predictor(pre, pre_stride, + arg->dst[plane], arg->dst_stride[plane], + &clamped_mv, &xd->scale_factor[which_mv], + bw, bh, which_mv, &xd->subpix); + } +} +void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, + uint8_t *dst_y, + int dst_ystride, + int mb_row, + int mb_col, + BLOCK_SIZE_TYPE bsize) { + struct build_inter_predictors_args args = { + xd, {dst_y, NULL, NULL}, {dst_ystride, 0, 0}, mb_col * 16, mb_row * 16 + }; + foreach_predicted_block_in_plane(xd, bsize, 0, build_inter_predictors, &args); +} +#endif + #define AVERAGE_WEIGHT (1 << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT)) #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT @@ -867,49 +953,6 @@ static void build_inter16x16_predictors_mby_w(MACROBLOCKD *xd, which_mv ? weight : 0, &xd->subpix); } } - -void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd, - uint8_t *dst_y, - int dst_ystride, - int mb_row, - int mb_col) { - int weight = get_implicit_compoundinter_weight(xd, mb_row, mb_col); - - build_inter16x16_predictors_mby_w(xd, dst_y, dst_ystride, weight, - mb_row, mb_col); -} - -#else - -void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd, - uint8_t *dst_y, - int dst_ystride, - int mb_row, - int mb_col) { - const int use_second_ref = xd->mode_info_context->mbmi.second_ref_frame > 0; - int which_mv; - - for (which_mv = 0; which_mv < 1 + use_second_ref; ++which_mv) { - const int clamp_mvs = which_mv ? - xd->mode_info_context->mbmi.need_to_clamp_secondmv : - xd->mode_info_context->mbmi.need_to_clamp_mvs; - - uint8_t *base_pre = which_mv ? xd->second_pre.y_buffer : xd->pre.y_buffer; - int pre_stride = which_mv ? xd->second_pre.y_stride : xd->pre.y_stride; - int_mv ymv; - struct scale_factors *scale = &xd->scale_factor[which_mv]; - - ymv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int; - - if (clamp_mvs) - clamp_mv_to_umv_border(&ymv.as_mv, xd); - - scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16); - - vp9_build_inter_predictor(base_pre, pre_stride, dst_y, dst_ystride, - &ymv, scale, 16, 16, which_mv, &xd->subpix); - } -} #endif #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT @@ -1109,64 +1152,6 @@ void vp9_build_inter_predictors_sby(MACROBLOCKD *x, build_inter_predictors_sby_w(x, dst_y, dst_ystride, weight, mb_row, mb_col, bsize); } - -#else - -// TODO(jingning): vp9_convolve8_ssse3_ limits the dimension up to 16. Currently -// handle inter prediction of block sizes above 16x16 separately from those -// smaller ones. Need to combine them all in to a unified inter prediction -// function. -void vp9_build_inter_predictors_sby(MACROBLOCKD *x, - uint8_t *dst_y, - int dst_ystride, - int mb_row, - int mb_col, - BLOCK_SIZE_TYPE bsize) { - const int bwl = mb_width_log2(bsize), bw = 1 << bwl; - const int bhl = mb_height_log2(bsize), bh = 1 << bhl; - uint8_t *y1 = x->pre.y_buffer; - uint8_t *y2 = x->second_pre.y_buffer; - int edge[4], n; - - edge[0] = x->mb_to_top_edge; - edge[1] = x->mb_to_bottom_edge; - edge[2] = x->mb_to_left_edge; - edge[3] = x->mb_to_right_edge; - - for (n = 0; n < bw * bh; n++) { - const int x_idx = n & (bw - 1), y_idx = n >> bwl; - - x->mb_to_top_edge = edge[0] - ((y_idx * 16) << 3); - x->mb_to_bottom_edge = edge[1] + (((bh - 1 - y_idx) * 16) << 3); - x->mb_to_left_edge = edge[2] - ((x_idx * 16) << 3); - x->mb_to_right_edge = edge[3] + (((bw - 1 - x_idx) * 16) << 3); - - x->pre.y_buffer = y1 + scaled_buffer_offset(x_idx * 16, - y_idx * 16, - x->pre.y_stride, - &x->scale_factor[0]); - if (x->mode_info_context->mbmi.second_ref_frame > 0) { - x->second_pre.y_buffer = y2 + - scaled_buffer_offset(x_idx * 16, - y_idx * 16, - x->second_pre.y_stride, - &x->scale_factor[1]); - } - vp9_build_inter16x16_predictors_mby(x, - dst_y + y_idx * 16 * dst_ystride + x_idx * 16, - dst_ystride, mb_row + y_idx, mb_col + x_idx); - } - x->mb_to_top_edge = edge[0]; - x->mb_to_bottom_edge = edge[1]; - x->mb_to_left_edge = edge[2]; - x->mb_to_right_edge = edge[3]; - - x->pre.y_buffer = y1; - if (x->mode_info_context->mbmi.second_ref_frame > 0) { - x->second_pre.y_buffer = y2; - } -} - #endif #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h index 533d30466..77fa9ab3f 100644 --- a/vp9/common/vp9_reconinter.h +++ b/vp9/common/vp9_reconinter.h @@ -16,12 +16,6 @@ struct subpix_fn_table; -void vp9_build_inter16x16_predictors_mby(MACROBLOCKD *xd, - uint8_t *dst_y, - int dst_ystride, - int mb_row, - int mb_col); - void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, uint8_t *dst_u, uint8_t *dst_v, diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index bb6ba7056..ae263caf7 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -524,6 +524,7 @@ void vp9_first_pass(VP9_COMP *cpi) { x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP9BORDERINPIXELS - 16); + set_mb_row(cm, xd, mb_row, 1 << mb_height_log2(BLOCK_SIZE_MB16X16)); // for each macroblock col in image for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { @@ -531,6 +532,7 @@ void vp9_first_pass(VP9_COMP *cpi) { int gf_motion_error = INT_MAX; int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); + set_mb_col(cm, xd, mb_col, 1 << mb_height_log2(BLOCK_SIZE_MB16X16)); xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset; xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset; xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset; -- cgit v1.2.3 From 2987fa1dc130256562e661bafb0136ac9b704abf Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Mon, 15 Apr 2013 13:18:24 -0700 Subject: Removing rounding from UV MV calculation Consider the previous behavior for the MV 1 3/8 (11/8 pel). In the existing code, the fractional part of the MV is considered separately, and rounded is applied, giving a result of 6/8. Rounding is not required in this case, as we're increasing the precision from a q3 to a q4, and the correct value 11/16 can be represented exactly. Slight gain observed (+.033 average on derf) Change-Id: I320e160e8b12f1dd66aa0ce7966b5088870fe9f8 --- vp9/common/vp9_reconinter.c | 69 ++++++++++----------------------------- vp9/common/vp9_reconinter.h | 3 +- vp9/encoder/vp9_temporal_filter.c | 16 ++++----- 3 files changed, 24 insertions(+), 64 deletions(-) (limited to 'vp9') diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 002e6eb05..64929c1bc 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -363,21 +363,18 @@ void vp9_build_inter_predictor(const uint8_t *src, int src_stride, */ void vp9_build_inter_predictor_q4(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, - const int_mv *fullpel_mv_q3, - const int_mv *frac_mv_q4, + const int_mv *mv_q4, const struct scale_factors *scale, int w, int h, int weight, const struct subpix_fn_table *subpix) { - const int mv_row_q4 = ((fullpel_mv_q3->as_mv.row >> 3) << 4) - + (frac_mv_q4->as_mv.row & 0xf); - const int mv_col_q4 = ((fullpel_mv_q3->as_mv.col >> 3) << 4) - + (frac_mv_q4->as_mv.col & 0xf); const int scaled_mv_row_q4 = - scale->scale_motion_vector_component_q4(mv_row_q4, scale->y_num, - scale->y_den, scale->y_offset_q4); + scale->scale_motion_vector_component_q4(mv_q4->as_mv.row, + scale->y_num, scale->y_den, + scale->y_offset_q4); const int scaled_mv_col_q4 = - scale->scale_motion_vector_component_q4(mv_col_q4, scale->x_num, - scale->x_den, scale->x_offset_q4); + scale->scale_motion_vector_component_q4(mv_q4->as_mv.col, + scale->x_num, scale->x_den, + scale->x_offset_q4); const int subpel_x = scaled_mv_col_q4 & 15; const int subpel_y = scaled_mv_row_q4 & 15; @@ -973,30 +970,14 @@ static void build_inter16x16_predictors_mbuv_w(MACROBLOCKD *xd, uint8_t *uptr, *vptr; int pre_stride = which_mv ? xd->second_pre.uv_stride : xd->pre.uv_stride; - int_mv _o16x16mv; - int_mv _16x16mv; + int_mv mv; struct scale_factors *scale = &xd->scale_factor_uv[which_mv]; + mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int; - _16x16mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int; if (clamp_mvs) - clamp_mv_to_umv_border(&_16x16mv.as_mv, xd); - - _o16x16mv = _16x16mv; - /* calc uv motion vectors */ - if (_16x16mv.as_mv.row < 0) - _16x16mv.as_mv.row -= 1; - else - _16x16mv.as_mv.row += 1; - - if (_16x16mv.as_mv.col < 0) - _16x16mv.as_mv.col -= 1; - else - _16x16mv.as_mv.col += 1; - - _16x16mv.as_mv.row /= 2; - _16x16mv.as_mv.col /= 2; + clamp_mv_to_umv_border(&mv.as_mv, xd); uptr = (which_mv ? xd->second_pre.u_buffer : xd->pre.u_buffer); vptr = (which_mv ? xd->second_pre.v_buffer : xd->pre.v_buffer); @@ -1004,11 +985,11 @@ static void build_inter16x16_predictors_mbuv_w(MACROBLOCKD *xd, scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16); vp9_build_inter_predictor_q4( - uptr, pre_stride, dst_u, dst_uvstride, &_16x16mv, &_o16x16mv, + uptr, pre_stride, dst_u, dst_uvstride, &mv, scale, 8, 8, which_mv ? weight : 0, &xd->subpix); vp9_build_inter_predictor_q4( - vptr, pre_stride, dst_v, dst_uvstride, &_16x16mv, &_o16x16mv, + vptr, pre_stride, dst_v, dst_uvstride, &mv, scale, 8, 8, which_mv ? weight : 0, &xd->subpix); } } @@ -1046,30 +1027,14 @@ void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, uint8_t *uptr, *vptr; int pre_stride = which_mv ? xd->second_pre.uv_stride : xd->pre.uv_stride; - int_mv _o16x16mv; - int_mv _16x16mv; + int_mv mv; struct scale_factors *scale = &xd->scale_factor_uv[which_mv]; + mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int; - _16x16mv.as_int = xd->mode_info_context->mbmi.mv[which_mv].as_int; if (clamp_mvs) - clamp_mv_to_umv_border(&_16x16mv.as_mv, xd); - - _o16x16mv = _16x16mv; - /* calc uv motion vectors */ - if (_16x16mv.as_mv.row < 0) - _16x16mv.as_mv.row -= 1; - else - _16x16mv.as_mv.row += 1; - - if (_16x16mv.as_mv.col < 0) - _16x16mv.as_mv.col -= 1; - else - _16x16mv.as_mv.col += 1; - - _16x16mv.as_mv.row /= 2; - _16x16mv.as_mv.col /= 2; + clamp_mv_to_umv_border(&mv.as_mv, xd); uptr = (which_mv ? xd->second_pre.u_buffer : xd->pre.u_buffer); vptr = (which_mv ? xd->second_pre.v_buffer : xd->pre.v_buffer); @@ -1077,12 +1042,12 @@ void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16); vp9_build_inter_predictor_q4( - uptr, pre_stride, dst_u, dst_uvstride, &_16x16mv, &_o16x16mv, + uptr, pre_stride, dst_u, dst_uvstride, &mv, scale, 8, 8, which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT), &xd->subpix); vp9_build_inter_predictor_q4( - vptr, pre_stride, dst_v, dst_uvstride, &_16x16mv, &_o16x16mv, + vptr, pre_stride, dst_v, dst_uvstride, &mv, scale, 8, 8, which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT), &xd->subpix); } diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h index 77fa9ab3f..38981e9c1 100644 --- a/vp9/common/vp9_reconinter.h +++ b/vp9/common/vp9_reconinter.h @@ -67,8 +67,7 @@ void vp9_build_inter_predictor(const uint8_t *src, int src_stride, void vp9_build_inter_predictor_q4(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, - const int_mv *fullpel_mv_q3, - const int_mv *frac_mv_q4, + const int_mv *mv_q4, const struct scale_factors *scale, int w, int h, int do_avg, const struct subpix_fn_table *subpix); diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c index cf84fa1e5..6149518ca 100644 --- a/vp9/encoder/vp9_temporal_filter.c +++ b/vp9/encoder/vp9_temporal_filter.c @@ -41,18 +41,14 @@ static void temporal_filter_predictors_mb_c(MACROBLOCKD *xd, int mv_col, uint8_t *pred) { const int which_mv = 0; - int_mv subpel_mv; - int_mv fullpel_mv; + int_mv mv; - subpel_mv.as_mv.row = mv_row; - subpel_mv.as_mv.col = mv_col; - // TODO(jkoleszar): Make this rounding consistent with the rest of the code - fullpel_mv.as_mv.row = (mv_row >> 1) & ~7; - fullpel_mv.as_mv.col = (mv_col >> 1) & ~7; + mv.as_mv.row = mv_row; + mv.as_mv.col = mv_col; vp9_build_inter_predictor(y_mb_ptr, stride, &pred[0], 16, - &subpel_mv, + &mv, &xd->scale_factor[which_mv], 16, 16, which_mv << @@ -63,7 +59,7 @@ static void temporal_filter_predictors_mb_c(MACROBLOCKD *xd, vp9_build_inter_predictor_q4(u_mb_ptr, stride, &pred[256], 8, - &fullpel_mv, &subpel_mv, + &mv, &xd->scale_factor_uv[which_mv], 8, 8, which_mv << @@ -72,7 +68,7 @@ static void temporal_filter_predictors_mb_c(MACROBLOCKD *xd, vp9_build_inter_predictor_q4(v_mb_ptr, stride, &pred[320], 8, - &fullpel_mv, &subpel_mv, + &mv, &xd->scale_factor_uv[which_mv], 8, 8, which_mv << -- cgit v1.2.3