| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 | 12 |
| 13 #include "vpx_mem/vpx_mem.h" | 13 #include "vpx_mem/vpx_mem.h" |
| 14 #include "vp9/encoder/vp9_rdopt.h" | 14 #include "vp9/encoder/vp9_rdopt.h" |
| 15 #include "vp9/encoder/vp9_segmentation.h" | 15 #include "vp9/encoder/vp9_segmentation.h" |
| 16 #include "vp9/encoder/vp9_mcomp.h" | 16 #include "vp9/encoder/vp9_mcomp.h" |
| 17 #include "vp9/common/vp9_blockd.h" | 17 #include "vp9/common/vp9_blockd.h" |
| 18 #include "vp9/common/vp9_reconinter.h" | 18 #include "vp9/common/vp9_reconinter.h" |
| 19 #include "vp9/common/vp9_reconintra.h" | 19 #include "vp9/common/vp9_reconintra.h" |
| 20 #include "vp9/common/vp9_systemdependent.h" | 20 #include "vp9/common/vp9_systemdependent.h" |
| 21 | 21 |
| 22 | 22 |
| 23 static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, | 23 static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, |
| 24 const MV *ref_mv, | 24 const MV *ref_mv, |
| 25 MV *dst_mv, | 25 MV *dst_mv, |
| 26 int mb_row, | 26 int mb_row, |
| 27 int mb_col) { | 27 int mb_col) { |
| 28 MACROBLOCK *const x = &cpi->mb; | 28 MACROBLOCK *const x = &cpi->mb; |
| 29 MACROBLOCKD *const xd = &x->e_mbd; | 29 MACROBLOCKD *const xd = &x->e_mbd; |
| 30 vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; | 30 const MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; |
| 31 const vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16]; |
| 31 | 32 |
| 32 const int tmp_col_min = x->mv_col_min; | 33 const int tmp_col_min = x->mv_col_min; |
| 33 const int tmp_col_max = x->mv_col_max; | 34 const int tmp_col_max = x->mv_col_max; |
| 34 const int tmp_row_min = x->mv_row_min; | 35 const int tmp_row_min = x->mv_row_min; |
| 35 const int tmp_row_max = x->mv_row_max; | 36 const int tmp_row_max = x->mv_row_max; |
| 36 MV ref_full; | 37 MV ref_full; |
| 37 | 38 |
| 38 // Further step/diamond searches as necessary | 39 // Further step/diamond searches as necessary |
| 39 int step_param = cpi->sf.reduce_first_step_size + | 40 int step_param = mv_sf->reduce_first_step_size + |
| 40 (cpi->oxcf.speed > 5 ? 1 : 0); | 41 (cpi->oxcf.speed > 5 ? 1 : 0); |
| 41 step_param = MIN(step_param, cpi->sf.max_step_search_steps - 2); | 42 step_param = MIN(step_param, mv_sf->max_step_search_steps - 2); |
| 42 | 43 |
| 43 vp9_set_mv_search_range(x, ref_mv); | 44 vp9_set_mv_search_range(x, ref_mv); |
| 44 | 45 |
| 45 ref_full.col = ref_mv->col >> 3; | 46 ref_full.col = ref_mv->col >> 3; |
| 46 ref_full.row = ref_mv->row >> 3; | 47 ref_full.row = ref_mv->row >> 3; |
| 47 | 48 |
| 48 /*cpi->sf.search_method == HEX*/ | 49 /*cpi->sf.search_method == HEX*/ |
| 49 vp9_hex_search(x, &ref_full, step_param, x->errorperbit, 0, &v_fn_ptr, 0, | 50 vp9_hex_search(x, &ref_full, step_param, x->errorperbit, 0, &v_fn_ptr, 0, |
| 50 ref_mv, dst_mv); | 51 ref_mv, dst_mv); |
| 51 | 52 |
| 52 // Try sub-pixel MC | 53 // Try sub-pixel MC |
| 53 // if (bestsme > error_thresh && bestsme < INT_MAX) | 54 // if (bestsme > error_thresh && bestsme < INT_MAX) |
| 54 { | 55 { |
| 55 int distortion; | 56 int distortion; |
| 56 unsigned int sse; | 57 unsigned int sse; |
| 57 cpi->find_fractional_mv_step( | 58 cpi->find_fractional_mv_step( |
| 58 x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit, | 59 x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit, |
| 59 &v_fn_ptr, 0, cpi->sf.subpel_iters_per_step, NULL, NULL, &distortion, | 60 &v_fn_ptr, 0, mv_sf->subpel_iters_per_step, NULL, NULL, &distortion, |
| 60 &sse); | 61 &sse); |
| 61 } | 62 } |
| 62 | 63 |
| 63 xd->mi[0]->mbmi.mode = NEWMV; | 64 xd->mi[0]->mbmi.mode = NEWMV; |
| 64 xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv; | 65 xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv; |
| 65 | 66 |
| 66 vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16); | 67 vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16); |
| 67 | 68 |
| 68 /* restore UMV window */ | 69 /* restore UMV window */ |
| 69 x->mv_col_min = tmp_col_min; | 70 x->mv_col_min = tmp_col_min; |
| 70 x->mv_col_max = tmp_col_max; | 71 x->mv_col_max = tmp_col_max; |
| 71 x->mv_row_min = tmp_row_min; | 72 x->mv_row_min = tmp_row_min; |
| 72 x->mv_row_max = tmp_row_max; | 73 x->mv_row_max = tmp_row_max; |
| 73 | 74 |
| 74 return vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, | 75 return vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
| 75 xd->plane[0].dst.buf, xd->plane[0].dst.stride, | 76 xd->plane[0].dst.buf, xd->plane[0].dst.stride); |
| 76 INT_MAX); | |
| 77 } | 77 } |
| 78 | 78 |
| 79 static int do_16x16_motion_search(VP9_COMP *cpi, const MV *ref_mv, | 79 static int do_16x16_motion_search(VP9_COMP *cpi, const MV *ref_mv, |
| 80 int_mv *dst_mv, int mb_row, int mb_col) { | 80 int_mv *dst_mv, int mb_row, int mb_col) { |
| 81 MACROBLOCK *const x = &cpi->mb; | 81 MACROBLOCK *const x = &cpi->mb; |
| 82 MACROBLOCKD *const xd = &x->e_mbd; | 82 MACROBLOCKD *const xd = &x->e_mbd; |
| 83 unsigned int err, tmp_err; | 83 unsigned int err, tmp_err; |
| 84 MV tmp_mv; | 84 MV tmp_mv; |
| 85 | 85 |
| 86 // Try zero MV first | 86 // Try zero MV first |
| 87 // FIXME should really use something like near/nearest MV and/or MV prediction | 87 // FIXME should really use something like near/nearest MV and/or MV prediction |
| 88 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, | 88 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
| 89 xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, | 89 xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); |
| 90 INT_MAX); | |
| 91 dst_mv->as_int = 0; | 90 dst_mv->as_int = 0; |
| 92 | 91 |
| 93 // Test last reference frame using the previous best mv as the | 92 // Test last reference frame using the previous best mv as the |
| 94 // starting point (best reference) for the search | 93 // starting point (best reference) for the search |
| 95 tmp_err = do_16x16_motion_iteration(cpi, ref_mv, &tmp_mv, mb_row, mb_col); | 94 tmp_err = do_16x16_motion_iteration(cpi, ref_mv, &tmp_mv, mb_row, mb_col); |
| 96 if (tmp_err < err) { | 95 if (tmp_err < err) { |
| 97 err = tmp_err; | 96 err = tmp_err; |
| 98 dst_mv->as_mv = tmp_mv; | 97 dst_mv->as_mv = tmp_mv; |
| 99 } | 98 } |
| 100 | 99 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 116 } | 115 } |
| 117 | 116 |
| 118 static int do_16x16_zerozero_search(VP9_COMP *cpi, int_mv *dst_mv) { | 117 static int do_16x16_zerozero_search(VP9_COMP *cpi, int_mv *dst_mv) { |
| 119 MACROBLOCK *const x = &cpi->mb; | 118 MACROBLOCK *const x = &cpi->mb; |
| 120 MACROBLOCKD *const xd = &x->e_mbd; | 119 MACROBLOCKD *const xd = &x->e_mbd; |
| 121 unsigned int err; | 120 unsigned int err; |
| 122 | 121 |
| 123 // Try zero MV first | 122 // Try zero MV first |
| 124 // FIXME should really use something like near/nearest MV and/or MV prediction | 123 // FIXME should really use something like near/nearest MV and/or MV prediction |
| 125 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, | 124 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
| 126 xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride, | 125 xd->plane[0].pre[0].buf, xd->plane[0].pre[0].stride); |
| 127 INT_MAX); | |
| 128 | 126 |
| 129 dst_mv->as_int = 0; | 127 dst_mv->as_int = 0; |
| 130 | 128 |
| 131 return err; | 129 return err; |
| 132 } | 130 } |
| 133 static int find_best_16x16_intra(VP9_COMP *cpi, PREDICTION_MODE *pbest_mode) { | 131 static int find_best_16x16_intra(VP9_COMP *cpi, PREDICTION_MODE *pbest_mode) { |
| 134 MACROBLOCK *const x = &cpi->mb; | 132 MACROBLOCK *const x = &cpi->mb; |
| 135 MACROBLOCKD *const xd = &x->e_mbd; | 133 MACROBLOCKD *const xd = &x->e_mbd; |
| 136 PREDICTION_MODE best_mode = -1, mode; | 134 PREDICTION_MODE best_mode = -1, mode; |
| 137 unsigned int best_err = INT_MAX; | 135 unsigned int best_err = INT_MAX; |
| 138 | 136 |
| 139 // calculate SATD for each intra prediction mode; | 137 // calculate SATD for each intra prediction mode; |
| 140 // we're intentionally not doing 4x4, we just want a rough estimate | 138 // we're intentionally not doing 4x4, we just want a rough estimate |
| 141 for (mode = DC_PRED; mode <= TM_PRED; mode++) { | 139 for (mode = DC_PRED; mode <= TM_PRED; mode++) { |
| 142 unsigned int err; | 140 unsigned int err; |
| 143 | 141 |
| 144 xd->mi[0]->mbmi.mode = mode; | 142 xd->mi[0]->mbmi.mode = mode; |
| 145 vp9_predict_intra_block(xd, 0, 2, TX_16X16, mode, | 143 vp9_predict_intra_block(xd, 0, 2, TX_16X16, mode, |
| 146 x->plane[0].src.buf, x->plane[0].src.stride, | 144 x->plane[0].src.buf, x->plane[0].src.stride, |
| 147 xd->plane[0].dst.buf, xd->plane[0].dst.stride, | 145 xd->plane[0].dst.buf, xd->plane[0].dst.stride, |
| 148 0, 0, 0); | 146 0, 0, 0); |
| 149 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, | 147 err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, |
| 150 xd->plane[0].dst.buf, xd->plane[0].dst.stride, best_err); | 148 xd->plane[0].dst.buf, xd->plane[0].dst.stride); |
| 151 | 149 |
| 152 // find best | 150 // find best |
| 153 if (err < best_err) { | 151 if (err < best_err) { |
| 154 best_err = err; | 152 best_err = err; |
| 155 best_mode = mode; | 153 best_mode = mode; |
| 156 } | 154 } |
| 157 } | 155 } |
| 158 | 156 |
| 159 if (pbest_mode) | 157 if (pbest_mode) |
| 160 *pbest_mode = best_mode; | 158 *pbest_mode = best_mode; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 MBGRAPH_FRAME_STATS *stats, | 226 MBGRAPH_FRAME_STATS *stats, |
| 229 YV12_BUFFER_CONFIG *buf, | 227 YV12_BUFFER_CONFIG *buf, |
| 230 YV12_BUFFER_CONFIG *golden_ref, | 228 YV12_BUFFER_CONFIG *golden_ref, |
| 231 YV12_BUFFER_CONFIG *alt_ref) { | 229 YV12_BUFFER_CONFIG *alt_ref) { |
| 232 MACROBLOCK *const x = &cpi->mb; | 230 MACROBLOCK *const x = &cpi->mb; |
| 233 MACROBLOCKD *const xd = &x->e_mbd; | 231 MACROBLOCKD *const xd = &x->e_mbd; |
| 234 VP9_COMMON *const cm = &cpi->common; | 232 VP9_COMMON *const cm = &cpi->common; |
| 235 | 233 |
| 236 int mb_col, mb_row, offset = 0; | 234 int mb_col, mb_row, offset = 0; |
| 237 int mb_y_offset = 0, arf_y_offset = 0, gld_y_offset = 0; | 235 int mb_y_offset = 0, arf_y_offset = 0, gld_y_offset = 0; |
| 238 MV arf_top_mv = {0, 0}, gld_top_mv = {0, 0}; | 236 MV gld_top_mv = {0, 0}; |
| 239 MODE_INFO mi_local; | 237 MODE_INFO mi_local; |
| 240 | 238 |
| 241 vp9_zero(mi_local); | 239 vp9_zero(mi_local); |
| 242 // Set up limit values for motion vectors to prevent them extending outside | 240 // Set up limit values for motion vectors to prevent them extending outside |
| 243 // the UMV borders. | 241 // the UMV borders. |
| 244 x->mv_row_min = -BORDER_MV_PIXELS_B16; | 242 x->mv_row_min = -BORDER_MV_PIXELS_B16; |
| 245 x->mv_row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16; | 243 x->mv_row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16; |
| 246 xd->up_available = 0; | 244 xd->up_available = 0; |
| 247 xd->plane[0].dst.stride = buf->y_stride; | 245 xd->plane[0].dst.stride = buf->y_stride; |
| 248 xd->plane[0].pre[0].stride = buf->y_stride; | 246 xd->plane[0].pre[0].stride = buf->y_stride; |
| 249 xd->plane[1].dst.stride = buf->uv_stride; | 247 xd->plane[1].dst.stride = buf->uv_stride; |
| 250 xd->mi[0] = &mi_local; | 248 xd->mi[0] = &mi_local; |
| 251 mi_local.mbmi.sb_type = BLOCK_16X16; | 249 mi_local.mbmi.sb_type = BLOCK_16X16; |
| 252 mi_local.mbmi.ref_frame[0] = LAST_FRAME; | 250 mi_local.mbmi.ref_frame[0] = LAST_FRAME; |
| 253 mi_local.mbmi.ref_frame[1] = NONE; | 251 mi_local.mbmi.ref_frame[1] = NONE; |
| 254 | 252 |
| 255 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { | 253 for (mb_row = 0; mb_row < cm->mb_rows; mb_row++) { |
| 256 MV arf_left_mv = arf_top_mv, gld_left_mv = gld_top_mv; | 254 MV gld_left_mv = gld_top_mv; |
| 257 int mb_y_in_offset = mb_y_offset; | 255 int mb_y_in_offset = mb_y_offset; |
| 258 int arf_y_in_offset = arf_y_offset; | 256 int arf_y_in_offset = arf_y_offset; |
| 259 int gld_y_in_offset = gld_y_offset; | 257 int gld_y_in_offset = gld_y_offset; |
| 260 | 258 |
| 261 // Set up limit values for motion vectors to prevent them extending outside | 259 // Set up limit values for motion vectors to prevent them extending outside |
| 262 // the UMV borders. | 260 // the UMV borders. |
| 263 x->mv_col_min = -BORDER_MV_PIXELS_B16; | 261 x->mv_col_min = -BORDER_MV_PIXELS_B16; |
| 264 x->mv_col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16; | 262 x->mv_col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16; |
| 265 xd->left_available = 0; | 263 xd->left_available = 0; |
| 266 | 264 |
| 267 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { | 265 for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { |
| 268 MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col]; | 266 MBGRAPH_MB_STATS *mb_stats = &stats->mb_stats[offset + mb_col]; |
| 269 | 267 |
| 270 update_mbgraph_mb_stats(cpi, mb_stats, buf, mb_y_in_offset, | 268 update_mbgraph_mb_stats(cpi, mb_stats, buf, mb_y_in_offset, |
| 271 golden_ref, &gld_left_mv, alt_ref, | 269 golden_ref, &gld_left_mv, alt_ref, |
| 272 mb_row, mb_col); | 270 mb_row, mb_col); |
| 273 arf_left_mv = mb_stats->ref[ALTREF_FRAME].m.mv.as_mv; | |
| 274 gld_left_mv = mb_stats->ref[GOLDEN_FRAME].m.mv.as_mv; | 271 gld_left_mv = mb_stats->ref[GOLDEN_FRAME].m.mv.as_mv; |
| 275 if (mb_col == 0) { | 272 if (mb_col == 0) { |
| 276 arf_top_mv = arf_left_mv; | |
| 277 gld_top_mv = gld_left_mv; | 273 gld_top_mv = gld_left_mv; |
| 278 } | 274 } |
| 279 xd->left_available = 1; | 275 xd->left_available = 1; |
| 280 mb_y_in_offset += 16; | 276 mb_y_in_offset += 16; |
| 281 gld_y_in_offset += 16; | 277 gld_y_in_offset += 16; |
| 282 arf_y_in_offset += 16; | 278 arf_y_in_offset += 16; |
| 283 x->mv_col_min -= 16; | 279 x->mv_col_min -= 16; |
| 284 x->mv_col_max -= 16; | 280 x->mv_col_max -= 16; |
| 285 } | 281 } |
| 286 xd->up_available = 1; | 282 xd->up_available = 1; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 assert(q_cur != NULL); | 401 assert(q_cur != NULL); |
| 406 | 402 |
| 407 update_mbgraph_frame_stats(cpi, frame_stats, &q_cur->img, | 403 update_mbgraph_frame_stats(cpi, frame_stats, &q_cur->img, |
| 408 golden_ref, cpi->Source); | 404 golden_ref, cpi->Source); |
| 409 } | 405 } |
| 410 | 406 |
| 411 vp9_clear_system_state(); | 407 vp9_clear_system_state(); |
| 412 | 408 |
| 413 separate_arf_mbs(cpi); | 409 separate_arf_mbs(cpi); |
| 414 } | 410 } |
| OLD | NEW |