ref: 1f7e4856f8f5a487d9ed36d27e84b51d0899b0bc
parent: 1ff4a5b3a255515e61ef0be19ece7307c9e9354b
author: hkuang <[email protected]>
date: Fri Mar 14 11:31:49 EDT 2014
Fix the md5 mismatch for some scale cases. Fixes issue #731 Change-Id: Id313e84b8fb4ff20f6a4e1ed11cb601927888318
--- a/vp9/common/vp9_reconinter.c
+++ b/vp9/common/vp9_reconinter.c
@@ -293,24 +293,40 @@
ref_frame = plane == 1 ? ref_buf->u_buffer : ref_buf->v_buffer;
}
- // Get block position in current frame.
- x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
- y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
+ if (vp9_is_scaled(sf)) {
+ // Co-ordinate of containing block to pixel precision.
+ int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x));
+ int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y));
- // Precision of x0_16 and y0_16 is 1/16th pixel.
- x0_16 = x0 << SUBPEL_BITS;
- y0_16 = y0 << SUBPEL_BITS;
+ // Co-ordinate of the block to 1/16th pixel precision.
+ x0_16 = (x_start + x) << SUBPEL_BITS;
+ y0_16 = (y_start + y) << SUBPEL_BITS;
- if (vp9_is_scaled(sf)) {
+ // Co-ordinate of current block in reference frame
+ // to 1/16th pixel precision.
+ x0_16 = sf->scale_value_x(x0_16, sf);
+ y0_16 = sf->scale_value_y(y0_16, sf);
+
+ // Map the top left corner of the block into the reference frame.
+ // NOTE: This must be done in this way instead of
+ // sf->scale_value_x(x_start + x, sf).
+ x0 = sf->scale_value_x(x_start, sf) + sf->scale_value_x(x, sf);
+ y0 = sf->scale_value_y(y_start, sf) + sf->scale_value_y(y, sf);
+
+ // Scale the MV and incorporate the sub-pixel offset of the block
+ // in the reference frame.
scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
xs = sf->x_step_q4;
ys = sf->y_step_q4;
- // Map the top left corner of the block into the reference frame.
- x0 = sf->scale_value_x(x0, sf);
- y0 = sf->scale_value_y(y0, sf);
- x0_16 = sf->scale_value_x(x0_16, sf);
- y0_16 = sf->scale_value_y(y0_16, sf);
} else {
+ // Co-ordinate of containing block to pixel precision.
+ x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
+ y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
+
+ // Co-ordinate of the block to 1/16th pixel precision.
+ x0_16 = x0 << SUBPEL_BITS;
+ y0_16 = y0 << SUBPEL_BITS;
+
scaled_mv.row = mv_q4.row;
scaled_mv.col = mv_q4.col;
xs = ys = 16;
@@ -354,9 +370,10 @@
y0 < 0 || y0 > frame_height - 1 || y1 < 0 || y1 > frame_height - 1) {
uint8_t *buf_ptr1 = ref_frame + y0 * pre_buf->stride + x0;
// Extend the border.
- build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0,
- x0, y0, x1 - x0, y1 - y0, frame_width, frame_height);
- buf_stride = x1 - x0;
+ build_mc_border(buf_ptr1, pre_buf->stride, xd->mc_buf, x1 - x0 + 1,
+ x0, y0, x1 - x0 + 1, y1 - y0 + 1, frame_width,
+ frame_height);
+ buf_stride = x1 - x0 + 1;
buf_ptr = xd->mc_buf + y_pad * 3 * buf_stride + x_pad * 3;
}
}