summaryrefslogtreecommitdiff
path: root/vp8/encoder/rdopt.c
diff options
context:
space:
mode:
authorYunqing Wang <yunqingwang@google.com>2011-05-10 06:59:38 -0700
committerCode Review <code-review@webmproject.org>2011-05-10 06:59:38 -0700
commitc7a56f677d4c5336fa6b0f07b10d3cdccc14f9b3 (patch)
tree94214cd19177edfe50ce3a5b41ff27bea767b53b /vp8/encoder/rdopt.c
parenta7d4d3c550b1b98b98fb37fbe409142f45e2ca02 (diff)
parentcb7b1fb1445331fd28210fbb7e8a0f7f672c4080 (diff)
downloadlibvpx-c7a56f677d4c5336fa6b0f07b10d3cdccc14f9b3.tar
libvpx-c7a56f677d4c5336fa6b0f07b10d3cdccc14f9b3.tar.gz
libvpx-c7a56f677d4c5336fa6b0f07b10d3cdccc14f9b3.tar.bz2
libvpx-c7a56f677d4c5336fa6b0f07b10d3cdccc14f9b3.zip
Merge "Use diamond search to replace full search in full-pixel refining search"
Diffstat (limited to 'vp8/encoder/rdopt.c')
-rw-r--r--vp8/encoder/rdopt.c253
1 files changed, 106 insertions, 147 deletions
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 5aa17ca8d..880153fef 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -2004,168 +2004,138 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
break;
case NEWMV:
+ {
+ int thissme;
+ int bestsme = INT_MAX;
+ int step_param = cpi->sf.first_step;
+ int further_steps;
+ int n;
+ int do_refine=1; /* If last step (1-away) of n-step search doesn't pick the center point as the best match,
+ we will do a final 1-away diamond refining search */
- // Decrement full search counter
- if (cpi->check_freq[lf_or_gf] > 0)
- cpi->check_freq[lf_or_gf] --;
+ int sadpb = x->sadperbit16;
- {
- int thissme;
- int bestsme = INT_MAX;
- int step_param = cpi->sf.first_step;
- int search_range;
- int further_steps;
- int n;
+ int col_min = (best_ref_mv.col - MAX_FULL_PEL_VAL) >>3;
+ int col_max = (best_ref_mv.col + MAX_FULL_PEL_VAL) >>3;
+ int row_min = (best_ref_mv.row - MAX_FULL_PEL_VAL) >>3;
+ int row_max = (best_ref_mv.row + MAX_FULL_PEL_VAL) >>3;
- int col_min = (best_ref_mv.col - MAX_FULL_PEL_VAL) >>3;
- int col_max = (best_ref_mv.col + MAX_FULL_PEL_VAL) >>3;
- int row_min = (best_ref_mv.row - MAX_FULL_PEL_VAL) >>3;
- int row_max = (best_ref_mv.row + MAX_FULL_PEL_VAL) >>3;
-
- int tmp_col_min = x->mv_col_min;
- int tmp_col_max = x->mv_col_max;
- int tmp_row_min = x->mv_row_min;
- int tmp_row_max = x->mv_row_max;
-
- // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
- if (x->mv_col_min < col_min )
- x->mv_col_min = col_min;
- if (x->mv_col_max > col_max )
- x->mv_col_max = col_max;
- if (x->mv_row_min < row_min )
- x->mv_row_min = row_min;
- if (x->mv_row_max > row_max )
- x->mv_row_max = row_max;
-
- //adjust search range according to sr from mv prediction
- if(sr > step_param)
- step_param = sr;
-
- // Work out how long a search we should do
- search_range = MAXF(abs(best_ref_mv.col), abs(best_ref_mv.row)) >> 3;
-
- if (search_range >= x->vector_range)
- x->vector_range = search_range;
- else if (x->vector_range > cpi->sf.min_fs_radius)
- x->vector_range--;
-
- // Initial step/diamond search
- {
- int sadpb = x->sadperbit16;
-
- if (cpi->sf.search_method == HEX)
- {
- bestsme = vp8_hex_search(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvsadcost, x->mvcost, &best_ref_mv);
- mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
- mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
- }
- else
- {
- bestsme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv.as_mv, step_param, sadpb / 2/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); //sadpb < 9
- mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
- mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+ int tmp_col_min = x->mv_col_min;
+ int tmp_col_max = x->mv_col_max;
+ int tmp_row_min = x->mv_row_min;
+ int tmp_row_max = x->mv_row_max;
- // Further step/diamond searches as necessary
- n = 0;
- further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+ // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
+ if (x->mv_col_min < col_min )
+ x->mv_col_min = col_min;
+ if (x->mv_col_max > col_max )
+ x->mv_col_max = col_max;
+ if (x->mv_row_min < row_min )
+ x->mv_row_min = row_min;
+ if (x->mv_row_max > row_max )
+ x->mv_row_max = row_max;
- n = num00;
- num00 = 0;
+ //adjust search range according to sr from mv prediction
+ if(sr > step_param)
+ step_param = sr;
- while (n < further_steps)
- {
- n++;
+ // Initial step/diamond search
+ if (cpi->sf.search_method == HEX)
+ {
+ bestsme = vp8_hex_search(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvsadcost, x->mvcost, &best_ref_mv);
+ mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+ mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+ }
+ else
+ {
+ bestsme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv.as_mv, step_param, sadpb / 2/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); //sadpb < 9
+ mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+ mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
- if (num00)
- num00--;
- else
- {
- thissme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv.as_mv, step_param + n, sadpb / 4/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); //sadpb = 9
+ // Further step/diamond searches as necessary
+ n = 0;
+ further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
- if (thissme < bestsme)
- {
- bestsme = thissme;
- mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
- mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
- }
- else
- {
- d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
- d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
- }
- }
- }
- }
+ n = num00;
+ num00 = 0;
- }
+ /* If there won't be more n-step search, check to see if refining search is needed. */
+ if (n > further_steps)
+ do_refine = 0;
- // Should we do a full search
- if (!cpi->check_freq[lf_or_gf] || cpi->do_full[lf_or_gf])
+ while (n < further_steps)
{
- int thissme;
- int full_flag_thresh = 0;
+ n++;
- // Update x->vector_range based on best vector found in step search
- search_range = MAXF(abs((mvp.row>>3) - d->bmi.mv.as_mv.row), abs((mvp.col>>3) - d->bmi.mv.as_mv.col));
- //search_range *= 1.4; //didn't improve PSNR
-
- if (search_range > x->vector_range)
- x->vector_range = search_range;
+ if (num00)
+ num00--;
else
- search_range = x->vector_range;
-
- // Apply limits
- search_range = (search_range > cpi->sf.max_fs_radius) ? cpi->sf.max_fs_radius : search_range;
-
- //add this to reduce full search range.
- if(sr<=3 && search_range > 8) search_range = 8;
-
{
- int sadpb = x->sadperbit16 >> 2;
- /* use diamond search result as full search staring point */
- thissme = cpi->full_search_sad(x, b, d, &d->bmi.mv.as_mv, sadpb, search_range, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
- }
+ thissme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv.as_mv, step_param + n, sadpb / 4/*x->errorperbit*/, &num00, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv); //sadpb = 9
- // Barrier threshold to initiating full search
- // full_flag_thresh = 10 + (thissme >> 7);
- if ((thissme + full_flag_thresh) < bestsme)
- {
- cpi->do_full[lf_or_gf] ++;
- bestsme = thissme;
- }
- else if (thissme < bestsme)
- bestsme = thissme;
- else
- {
- cpi->do_full[lf_or_gf] = cpi->do_full[lf_or_gf] >> 1;
- cpi->check_freq[lf_or_gf] = cpi->sf.full_freq[lf_or_gf];
+ /* check to see if refining search is needed. */
+ if (num00 > (further_steps-n))
+ do_refine = 0;
- // The full search result is actually worse so re-instate the previous best vector
- d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
- d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+ if (thissme < bestsme)
+ {
+ bestsme = thissme;
+ mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+ mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+ }
+ else
+ {
+ d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+ d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+ }
}
}
+ }
+
+ /* final 1-away diamond refining search */
+ if (do_refine == 1)
+ {
+ int search_range;
- x->mv_col_min = tmp_col_min;
- x->mv_col_max = tmp_col_max;
- x->mv_row_min = tmp_row_min;
- x->mv_row_max = tmp_row_max;
+ //It seems not a good way to set search_range. Need further investigation.
+ //search_range = MAXF(abs((mvp.row>>3) - d->bmi.mv.as_mv.row), abs((mvp.col>>3) - d->bmi.mv.as_mv.col));
+ search_range = 8;
- if (bestsme < INT_MAX)
+ //thissme = cpi->full_search_sad(x, b, d, &d->bmi.mv.as_mv, sadpb, search_range, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
+ thissme = cpi->refining_search_sad(x, b, d, &d->bmi.mv.as_mv, sadpb/4, search_range, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &best_ref_mv);
+
+ if (thissme < bestsme)
{
- int dis; /* TODO: use dis in distortion calculation later. */
- unsigned int sse;
- cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &dis, &sse);
+ bestsme = thissme;
+ mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+ mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
}
+ else
+ {
+ d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
+ d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
+ }
+ }
- mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
- mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
-
- // Add the new motion vector cost to our rolling cost variable
- rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);
+ x->mv_col_min = tmp_col_min;
+ x->mv_col_max = tmp_col_max;
+ x->mv_row_min = tmp_row_min;
+ x->mv_row_max = tmp_row_max;
+ if (bestsme < INT_MAX)
+ {
+ int dis; /* TODO: use dis in distortion calculation later. */
+ unsigned int sse;
+ cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, &cpi->fn_ptr[BLOCK_16X16], x->mvcost, &dis, &sse);
}
+ mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
+ mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
+
+ // Add the new motion vector cost to our rolling cost variable
+ rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);
+ }
+
case NEARESTMV:
case NEARMV:
@@ -2401,17 +2371,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
}
- // If we have chosen new mv or split then decay the full search check count more quickly.
- if ((vp8_mode_order[best_mode_index] == NEWMV) || (vp8_mode_order[best_mode_index] == SPLITMV))
- {
- int lf_or_gf = (vp8_ref_frame_order[best_mode_index] == LAST_FRAME) ? 0 : 1;
-
- if (cpi->check_freq[lf_or_gf] && !cpi->do_full[lf_or_gf])
- {
- cpi->check_freq[lf_or_gf] --;
- }
- }
-
// Keep a record of best mode index that we chose
cpi->last_best_mode_index = best_mode_index;