From fc49a377d79793b65f7d4db528b38af5fb9e7f6a Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Tue, 16 Apr 2013 16:26:26 -0700 Subject: [PATCH] make buid_inter_predictors block size agnostic (chroma) Updates to make non-SPLITMV inter predictors work for all plane types. Change-Id: I25dbef40b7ffcac30254b43eed1e22fc732378ae --- vp9/common/vp9_blockd.h | 2 +- vp9/common/vp9_reconinter.c | 202 ++++++++++++-------------------------------- vp9/common/vp9_reconinter.h | 7 -- 3 files changed, 54 insertions(+), 157 deletions(-) diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index dd95761..e124489 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -907,7 +907,7 @@ static INLINE void foreach_predicted_block_in_plane( int i; assert(pred_b <= block_size_b); - assert(pred_b == ss_block_size); + assert(pred_b == (mode == SPLITMV ? 0 : ss_block_size)); for (i = 0; i < (1 << ss_block_size); i += step) { visit(plane, i, bsize, pred_w, pred_h, arg); } diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 64929c1..ea7702a 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -358,9 +358,6 @@ void vp9_build_inter_predictor(const uint8_t *src, int src_stride, w, h); } -/* Like vp9_build_inter_predictor, but takes the full-pel part of the - * mv separately, and the fractional part as a q4. - */ void vp9_build_inter_predictor_q4(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, const int_mv *mv_q4, @@ -527,33 +524,38 @@ static void clamp_uvmv_to_umv_border(MV *mv, const MACROBLOCKD *xd) { #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 bwl, int bhl, int ss_x, int ss_y, 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); + const int spel_left = (VP9_INTERP_EXTEND + (4 << bwl)) << 4; + const int spel_right = spel_left - (1 << 4); + const int spel_top = (VP9_INTERP_EXTEND + (4 << bhl)) << 4; + const int spel_bottom = spel_top - (1 << 4); 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); + + assert(ss_x <= 1); + assert(ss_y <= 1); + clamped_mv.col = clamp(src_mv->col << (1 - ss_x), + (mb_to_left_edge << (1 - ss_x)) - spel_left, + (mb_to_right_edge << (1 - ss_x)) + spel_right); + clamped_mv.row = clamp(src_mv->row << (1 - ss_y), + (mb_to_top_edge << (1 - ss_y)) - spel_top, + (mb_to_bottom_edge << (1 - ss_y)) + spel_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; + uint8_t* dst[MAX_MB_PLANE]; + int dst_stride[MAX_MB_PLANE]; + uint8_t* pre[2][MAX_MB_PLANE]; + int pre_stride[2][MAX_MB_PLANE]; }; static void build_inter_predictors(int plane, int block, BLOCK_SIZE_TYPE bsize, @@ -572,18 +574,23 @@ static void build_inter_predictors(int plane, int block, 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 base_pre = arg->pre[which_mv][plane]; + const int pre_stride = arg->pre_stride[which_mv][plane]; 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; + + /* TODO(jkoleszar): This clamping is done in the incorrect place for the + * scaling case. It needs to be done on the scaled MV, not the pre-scaling + * MV. Note however that it performs the subsampling aware scaling so + * that the result is always q4. + */ clamped_mv.as_mv = clamp_mv_to_umv_border_sb(mv, bwl, bhl, + xd->plane[plane].subsampling_x, + xd->plane[plane].subsampling_y, xd->mb_to_left_edge, xd->mb_to_top_edge, xd->mb_to_right_edge, @@ -591,10 +598,10 @@ static void build_inter_predictors(int plane, int block, 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); + vp9_build_inter_predictor_q4(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, @@ -604,10 +611,30 @@ void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, 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 + xd, mb_col * 16, mb_row * 16, + {dst_y, NULL, NULL}, {dst_ystride, 0, 0}, + {{xd->pre.y_buffer, NULL, NULL}, {xd->second_pre.y_buffer, NULL, NULL}}, + {{xd->pre.y_stride, 0, 0}, {xd->second_pre.y_stride, 0, 0}}, }; foreach_predicted_block_in_plane(xd, bsize, 0, build_inter_predictors, &args); } +void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, + uint8_t *dst_u, + uint8_t *dst_v, + int dst_uvstride, + int mb_row, + int mb_col, + BLOCK_SIZE_TYPE bsize) { + struct build_inter_predictors_args args = { + xd, mb_col * 16, mb_row * 16, + {NULL, dst_u, dst_v}, {0, dst_uvstride, dst_uvstride}, + {{NULL, xd->pre.u_buffer, xd->pre.v_buffer}, + {NULL, xd->second_pre.u_buffer, xd->second_pre.v_buffer}}, + {{0, xd->pre.uv_stride, xd->pre.uv_stride}, + {0, xd->second_pre.uv_stride, xd->second_pre.uv_stride}}, + }; + foreach_predicted_block_uv(xd, bsize, build_inter_predictors, &args); +} #endif #define AVERAGE_WEIGHT (1 << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT)) @@ -993,65 +1020,6 @@ static void build_inter16x16_predictors_mbuv_w(MACROBLOCKD *xd, scale, 8, 8, which_mv ? weight : 0, &xd->subpix); } } - -void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, - uint8_t *dst_u, - uint8_t *dst_v, - int dst_uvstride, - int mb_row, - int mb_col) { -#ifdef USE_IMPLICIT_WEIGHT_UV - int weight = get_implicit_compoundinter_weight(xd, mb_row, mb_col); -#else - int weight = AVERAGE_WEIGHT; -#endif - build_inter16x16_predictors_mbuv_w(xd, dst_u, dst_v, dst_uvstride, - weight, mb_row, mb_col); -} - -#else - -void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, - uint8_t *dst_u, - uint8_t *dst_v, - int dst_uvstride, - 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 *uptr, *vptr; - int pre_stride = which_mv ? xd->second_pre.uv_stride - : xd->pre.uv_stride; - 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; - - - if (clamp_mvs) - 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); - - scale->set_scaled_offsets(scale, mb_row * 16, mb_col * 16); - - vp9_build_inter_predictor_q4( - 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, &mv, - scale, 8, 8, - which_mv << (2 * CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT), &xd->subpix); - } -} #endif #if CONFIG_IMPLICIT_COMPOUNDINTER_WEIGHT @@ -1198,70 +1166,6 @@ void vp9_build_inter_predictors_sbuv(MACROBLOCKD *xd, build_inter_predictors_sbuv_w(xd, dst_u, dst_v, dst_uvstride, weight, mb_row, mb_col, bsize); } - -#else - -void vp9_build_inter_predictors_sbuv(MACROBLOCKD *x, - uint8_t *dst_u, - uint8_t *dst_v, - int dst_uvstride, - 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 *u1 = x->pre.u_buffer, *v1 = x->pre.v_buffer; - uint8_t *u2 = x->second_pre.u_buffer, *v2 = x->second_pre.v_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++) { - int scaled_uv_offset; - 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); - - scaled_uv_offset = scaled_buffer_offset(x_idx * 8, - y_idx * 8, - x->pre.uv_stride, - &x->scale_factor_uv[0]); - x->pre.u_buffer = u1 + scaled_uv_offset; - x->pre.v_buffer = v1 + scaled_uv_offset; - - if (x->mode_info_context->mbmi.second_ref_frame > 0) { - scaled_uv_offset = scaled_buffer_offset(x_idx * 8, - y_idx * 8, - x->second_pre.uv_stride, - &x->scale_factor_uv[1]); - x->second_pre.u_buffer = u2 + scaled_uv_offset; - x->second_pre.v_buffer = v2 + scaled_uv_offset; - } - - vp9_build_inter16x16_predictors_mbuv(x, - dst_u + y_idx * 8 * dst_uvstride + x_idx * 8, - dst_v + y_idx * 8 * dst_uvstride + x_idx * 8, - dst_uvstride, 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.u_buffer = u1; - x->pre.v_buffer = v1; - - if (x->mode_info_context->mbmi.second_ref_frame > 0) { - x->second_pre.u_buffer = u2; - x->second_pre.v_buffer = v2; - } -} #endif void vp9_build_inter_predictors_sb(MACROBLOCKD *mb, diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h index 38981e9..601f95c 100644 --- a/vp9/common/vp9_reconinter.h +++ b/vp9/common/vp9_reconinter.h @@ -16,13 +16,6 @@ struct subpix_fn_table; -void vp9_build_inter16x16_predictors_mbuv(MACROBLOCKD *xd, - uint8_t *dst_u, - uint8_t *dst_v, - int dst_uvstride, - int mb_row, - int mb_col); - void vp9_build_inter_predictors_sby(MACROBLOCKD *x, uint8_t *dst_y, int dst_ystride, -- 2.7.4