ref: f451b404ea915cff2602ba130e6b36d66b9277ef
parent: adbad6092fff13ef5fe2ff308908e9cdd7936eaa
author: Marco <marpan@google.com>
date: Wed Jun 29 06:38:23 EDT 2016
vp9: Adjustment to mv bias for non-rd pickmode. Replace the existing mv bias with a bias only for NEWMV, and based on the motion vector difference of its top/left neighbors. For cbr non-screen-content mode. Change-Id: I8a8cf56347cfa23e9ffd8ead69eec8746c8f9e09
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1185,16 +1185,52 @@
}
}
-static void vp9_large_block_mv_bias(const NOISE_ESTIMATE *ne, RD_COST *this_rdc,
- BLOCK_SIZE bsize, int mv_row, int mv_col,
- int is_last_frame) {
- // Bias against non-zero (above some threshold) motion for large blocks.
- // This is temporary fix to avoid selection of large mv for big blocks.
- if (mv_row > 64 || mv_row < -64 || mv_col > 64 || mv_col < -64) {
- if (bsize == BLOCK_64X64)
- this_rdc->rdcost = this_rdc->rdcost << 1;
- else if (bsize >= BLOCK_32X32)
- this_rdc->rdcost = 3 * this_rdc->rdcost >> 1;
+static void vp9_NEWMV_diff_bias(const NOISE_ESTIMATE *ne, MACROBLOCKD *xd,
+ PREDICTION_MODE this_mode, RD_COST *this_rdc,
+ BLOCK_SIZE bsize, int mv_row, int mv_col,
+ int is_last_frame) {
+ // Bias against MVs associated with NEWMV mode that are very different from
+ // top/left neighbors.
+ if (this_mode == NEWMV) {
+ int al_mv_average_row;
+ int al_mv_average_col;
+ int left_row, left_col;
+ int row_diff, col_diff;
+ int above_mv_valid = 0;
+ int left_mv_valid = 0;
+ int above_row = 0;
+ int above_col = 0;
+
+ if (xd->above_mi) {
+ above_mv_valid = xd->above_mi->mv[0].as_int != INVALID_MV;
+ above_row = xd->above_mi->mv[0].as_mv.row;
+ above_col = xd->above_mi->mv[0].as_mv.col;
+ }
+ if (xd->left_mi) {
+ left_mv_valid = xd->left_mi->mv[0].as_int != INVALID_MV;
+ left_row = xd->left_mi->mv[0].as_mv.row;
+ left_col = xd->left_mi->mv[0].as_mv.col;
+ }
+ if (above_mv_valid && left_mv_valid) {
+ al_mv_average_row = (above_row + left_row + 1) >> 1;
+ al_mv_average_col = (above_col + left_col + 1) >> 1;
+ } else if (above_mv_valid) {
+ al_mv_average_row = above_row;
+ al_mv_average_col = above_col;
+ } else if (left_mv_valid) {
+ al_mv_average_row = left_row;
+ al_mv_average_col = left_col;
+ } else {
+ al_mv_average_row = al_mv_average_col = 0;
+ }
+ row_diff = (al_mv_average_row - mv_row);
+ col_diff = (al_mv_average_col - mv_col);
+ if (row_diff > 48 || row_diff < -48 || col_diff > 48 || col_diff < -48) {
+ if (bsize > BLOCK_32X32)
+ this_rdc->rdcost = this_rdc->rdcost << 1;
+ else
+ this_rdc->rdcost = 3 * this_rdc->rdcost >> 1;
+ }
}
// If noise estimation is enabled, and estimated level is above threshold,
// add a bias to LAST reference with small motion, for large blocks.
@@ -1810,15 +1846,15 @@
this_rdc.rate += ref_frame_cost[ref_frame];
this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
- // Bias against non-zero motion
+ // Bias against NEWMV that is very different from its neighbors, and bias
+ // to small motion-lastref for noisy input.
if (cpi->oxcf.rc_mode == VPX_CBR &&
cpi->oxcf.speed >= 5 &&
- cpi->oxcf.content != VP9E_CONTENT_SCREEN &&
- !x->sb_is_skin) {
- vp9_large_block_mv_bias(&cpi->noise_estimate, &this_rdc, bsize,
- frame_mv[this_mode][ref_frame].as_mv.row,
- frame_mv[this_mode][ref_frame].as_mv.col,
- ref_frame == LAST_FRAME);
+ cpi->oxcf.content != VP9E_CONTENT_SCREEN) {
+ vp9_NEWMV_diff_bias(&cpi->noise_estimate, xd, this_mode, &this_rdc, bsize,
+ frame_mv[this_mode][ref_frame].as_mv.row,
+ frame_mv[this_mode][ref_frame].as_mv.col,
+ ref_frame == LAST_FRAME);
}
// Skipping checking: test to see if this block can be reconstructed by