From 3275ad701a5c37041ab90b743cc6fec6a8340f80 Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Wed, 14 Aug 2013 16:50:45 -0700 Subject: Enable early termination in uv rd loop This commit enables early termination in the rate-distortion optimization search loop for chroma components. When the cumulative rd cost is above the current best value, skip the rest per-block transform/quantization/coeff_cost and continue to the next prediction mode. For bus_cif at 2000 kbps, the average run-time goes down from 168546ms -> 164678ms, (2% speed-up) at speed 0 36197ms -> 34465ms, (4% speed-up) at speed 1 Change-Id: I9d3043864126e62bd0166250d66b3170d520b3c0 --- vp9/encoder/vp9_rdopt.c | 58 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 6482615a3..36a772200 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -1282,7 +1282,8 @@ static int64_t rd_pick_intra_sby_mode(VP9_COMP *cpi, MACROBLOCK *x, static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x, int *rate, int64_t *distortion, int *skippable, - int64_t *sse, BLOCK_SIZE_TYPE bsize) { + int64_t *sse, BLOCK_SIZE_TYPE bsize, + int64_t ref_best_rd) { MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi; TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi); @@ -1290,6 +1291,9 @@ static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x, int pnrate = 0, pnskip = 1; int64_t pndist = 0, pnsse = 0; + if (ref_best_rd < 0) + goto term; + if (is_inter_block(mbmi)) vp9_subtract_sbuv(x, bsize); @@ -1300,12 +1304,22 @@ static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x, for (plane = 1; plane < MAX_MB_PLANE; ++plane) { txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse, - INT64_MAX, plane, bsize, uv_txfm_size); + ref_best_rd, plane, bsize, uv_txfm_size); + if (pnrate == INT_MAX) + goto term; *rate += pnrate; *distortion += pndist; *sse += pnsse; *skippable &= pnskip; } + return; + + term: + *rate = INT_MAX; + *distortion = INT64_MAX; + *sse = INT64_MAX; + *skippable = 0; + return; } static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, @@ -1324,7 +1338,9 @@ static int64_t rd_pick_intra_sbuv_mode(VP9_COMP *cpi, MACROBLOCK *x, for (mode = DC_PRED; mode <= last_mode; mode++) { x->e_mbd.mode_info_context->mbmi.uv_mode = mode; super_block_uvrd(&cpi->common, x, &this_rate_tokenonly, - &this_distortion, &s, &this_sse, bsize); + &this_distortion, &s, &this_sse, bsize, best_rd); + if (this_rate_tokenonly == INT_MAX) + continue; this_rate = this_rate_tokenonly + x->intra_uv_mode_cost[cpi->common.frame_type][mode]; this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); @@ -1353,7 +1369,7 @@ static int64_t rd_sbuv_dcpred(VP9_COMP *cpi, MACROBLOCK *x, x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; super_block_uvrd(&cpi->common, x, rate_tokenonly, - distortion, skippable, &this_sse, bsize); + distortion, skippable, &this_sse, bsize, INT64_MAX); *rate = *rate_tokenonly + x->intra_uv_mode_cost[cpi->common.frame_type][DC_PRED]; this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *distortion); @@ -2593,7 +2609,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, int_mv (*mode_mv)[MAX_REF_FRAMES], int mi_row, int mi_col, int_mv single_newmv[MAX_REF_FRAMES], - int64_t *psse, int64_t ref_best_rd) { + int64_t *psse, + const int64_t ref_best_rd) { VP9_COMMON *cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi; @@ -2944,7 +2961,8 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (!x->skip) { int skippable_y, skippable_uv; - int64_t sseuv = INT_MAX; + int64_t sseuv = INT64_MAX; + int64_t rdcosty = INT64_MAX; // Y cost and distortion super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse, @@ -2963,8 +2981,20 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, *rate2 += *rate_y; *distortion += *distortion_y; - super_block_uvrd(cm, x, rate_uv, distortion_uv, - &skippable_uv, &sseuv, bsize); + rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion); + rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse)); + + super_block_uvrd(cm, x, rate_uv, distortion_uv, &skippable_uv, &sseuv, + bsize, ref_best_rd - rdcosty); + if (*rate_uv == INT_MAX) { + *rate2 = INT_MAX; + *distortion = INT64_MAX; + for (i = 0; i < MAX_MB_PLANE; i++) { + xd->plane[i].dst.buf = orig_dst[i]; + xd->plane[i].dst.stride = orig_dst_stride[i]; + } + return INT64_MAX; + } *psse += sseuv; *rate2 += *rate_uv; @@ -3473,9 +3503,9 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, (int)this_rd_thresh, seg_mvs, bsi, switchable_filter_index, mi_row, mi_col); - if (tmp_rd == INT64_MAX) continue; + cpi->rd_filter_cache[switchable_filter_index] = tmp_rd; rs = get_switchable_rate(x); rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0); @@ -3568,15 +3598,17 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } compmode_cost = vp9_cost_bit(comp_mode_p, is_comp_pred); - if (RDCOST(x->rdmult, x->rddiv, rate2, distortion2) < - best_rd) { + tmp_best_rdu = best_rd - RDCOST(x->rdmult, x->rddiv, rate2, distortion2); + + if (tmp_best_rdu > 0) { // If even the 'Y' rd value of split is higher than best so far // then dont bother looking at UV vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col, BLOCK_8X8); - super_block_uvrd(cm, x, &rate_uv, &distortion_uv, &uv_skippable, - &uv_sse, BLOCK_8X8); + &uv_sse, BLOCK_8X8, tmp_best_rdu); + if (rate_uv == INT_MAX) + continue; rate2 += rate_uv; distortion2 += distortion_uv; skippable = skippable && uv_skippable; -- cgit v1.2.3