ref: 811cef97c979d10d08a82c580cfbfb82484bc55d
parent: 29771770c1298fdd2b54c1ad6eb0af98aaf7c22a
author: Jingning Han <[email protected]>
date: Thu Oct 9 08:32:56 EDT 2014
Refactor rate distortion cost structure This commit makes a struct that contains rate value, distortion value, and the rate-distortion cost. The goal is to provide a better interface for rate-distortion related operation. It is first used in rd_pick_partition and saves a few RDCOST calculations. Change-Id: I1a6ab7b35282d3c80195af59b6810e577544691f
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -770,8 +770,7 @@
}
static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
- int mi_row, int mi_col,
- int *totalrate, int64_t *totaldist,
+ int mi_row, int mi_col, RD_COST *rd_cost,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
int64_t best_rd) {
VP9_COMMON *const cm = &cpi->common;
@@ -857,28 +856,33 @@
// Find best coding mode & reconstruct the MB so it is available
// as a predictor for MBs that follow in the SB
if (frame_is_intra_only(cm)) {
- vp9_rd_pick_intra_mode_sb(cpi, x, totalrate, totaldist, bsize, ctx,
- best_rd);
+ vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, best_rd);
} else {
if (bsize >= BLOCK_8X8) {
if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
- vp9_rd_pick_inter_mode_sb_seg_skip(cpi, x, totalrate, totaldist, bsize,
+ vp9_rd_pick_inter_mode_sb_seg_skip(cpi, x, rd_cost, bsize,
ctx, best_rd);
else
vp9_rd_pick_inter_mode_sb(cpi, x, tile, mi_row, mi_col,
- totalrate, totaldist, bsize, ctx, best_rd);
+ rd_cost, bsize, ctx, best_rd);
} else {
- vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, totalrate,
- totaldist, bsize, ctx, best_rd);
+ vp9_rd_pick_inter_mode_sub8x8(cpi, x, tile, mi_row, mi_col, rd_cost,
+ bsize, ctx, best_rd);
}
}
- x->rdmult = orig_rdmult;
-
- if (aq_mode == VARIANCE_AQ && *totalrate != INT_MAX) {
+ if (aq_mode == VARIANCE_AQ && rd_cost->rate != INT_MAX) {
vp9_clear_system_state();
- *totalrate = (int)round(*totalrate * rdmult_ratio);
+ rd_cost->rate = (int)round(rd_cost->rate * rdmult_ratio);
+ rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
}
+
+ x->rdmult = orig_rdmult;
+
+ // TODO(jingning) The rate-distortion optimization flow needs to be
+ // refactored to provide proper exit/return handle.
+ if (rd_cost->rate == INT_MAX)
+ rd_cost->rdcost = INT64_MAX;
}
static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
@@ -1500,10 +1504,9 @@
update_partition_context(xd, mi_row, mi_col, subsize, bsize);
}
-static void rd_use_partition(VP9_COMP *cpi,
- const TileInfo *const tile,
- MODE_INFO *mi_8x8,
- TOKENEXTRA **tp, int mi_row, int mi_col,
+static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
+ MODE_INFO *mi_8x8, TOKENEXTRA **tp,
+ int mi_row, int mi_col,
BLOCK_SIZE bsize, int *rate, int64_t *dist,
int do_recon, PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
@@ -1518,15 +1521,9 @@
BLOCK_SIZE subsize;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
- int last_part_rate = INT_MAX;
- int64_t last_part_dist = INT64_MAX;
- int64_t last_part_rd = INT64_MAX;
- int none_rate = INT_MAX;
- int64_t none_dist = INT64_MAX;
- int64_t none_rd = INT64_MAX;
- int chosen_rate = INT_MAX;
- int64_t chosen_dist = INT64_MAX;
- int64_t chosen_rd = INT64_MAX;
+ RD_COST last_part_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
+ RD_COST none_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
+ RD_COST chosen_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
BLOCK_SIZE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0].src_mi->mbmi.sb_type;
@@ -1572,14 +1569,15 @@
mi_row + (mi_step >> 1) < cm->mi_rows &&
mi_col + (mi_step >> 1) < cm->mi_cols) {
pc_tree->partitioning = PARTITION_NONE;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rate, &none_dist, bsize,
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &none_rdc, bsize,
ctx, INT64_MAX);
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- if (none_rate < INT_MAX) {
- none_rate += cpi->partition_cost[pl][PARTITION_NONE];
- none_rd = RDCOST(x->rdmult, x->rddiv, none_rate, none_dist);
+ if (none_rdc.rate < INT_MAX) {
+ none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ none_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, none_rdc.rate,
+ none_rdc.dist);
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -1590,84 +1588,85 @@
switch (partition) {
case PARTITION_NONE:
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, bsize, ctx, INT64_MAX);
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
+ bsize, ctx, INT64_MAX);
break;
case PARTITION_HORZ:
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, subsize, &pc_tree->horizontal[0],
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
+ subsize, &pc_tree->horizontal[0],
INT64_MAX);
- if (last_part_rate != INT_MAX &&
+ if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
- int rt = 0;
- int64_t dt = 0;
+ RD_COST tmp_rdc = {0, 0, 0};
PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
- rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &rt, &dt,
+ rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
subsize, &pc_tree->horizontal[1], INT64_MAX);
- if (rt == INT_MAX || dt == INT64_MAX) {
- last_part_rate = INT_MAX;
- last_part_dist = INT64_MAX;
+ if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
+ last_part_rdc.rate = INT_MAX;
+ last_part_rdc.dist = INT64_MAX;
+ last_part_rdc.rdcost = INT64_MAX;
break;
}
-
- last_part_rate += rt;
- last_part_dist += dt;
+ last_part_rdc.rate += tmp_rdc.rate;
+ last_part_rdc.dist += tmp_rdc.dist;
+ last_part_rdc.rdcost += tmp_rdc.rdcost;
}
break;
case PARTITION_VERT:
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, subsize, &pc_tree->vertical[0],
- INT64_MAX);
- if (last_part_rate != INT_MAX &&
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
+ subsize, &pc_tree->vertical[0], INT64_MAX);
+ if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
- int rt = 0;
- int64_t dt = 0;
+ RD_COST tmp_rdc = {0, 0, 0};
PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &rt, &dt,
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
INT64_MAX);
- if (rt == INT_MAX || dt == INT64_MAX) {
- last_part_rate = INT_MAX;
- last_part_dist = INT64_MAX;
+ if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
+ last_part_rdc.rate = INT_MAX;
+ last_part_rdc.dist = INT64_MAX;
+ last_part_rdc.rdcost = INT64_MAX;
break;
}
- last_part_rate += rt;
- last_part_dist += dt;
+ last_part_rdc.rate += tmp_rdc.rate;
+ last_part_rdc.dist += tmp_rdc.dist;
+ last_part_rdc.rdcost += tmp_rdc.rdcost;
}
break;
case PARTITION_SPLIT:
if (bsize == BLOCK_8X8) {
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rate,
- &last_part_dist, subsize, pc_tree->leaf_split[0],
- INT64_MAX);
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &last_part_rdc,
+ subsize, pc_tree->leaf_split[0], INT64_MAX);
break;
}
- last_part_rate = 0;
- last_part_dist = 0;
+ last_part_rdc.rate = 0;
+ last_part_rdc.dist = 0;
+ last_part_rdc.rdcost = 0;
for (i = 0; i < 4; i++) {
int x_idx = (i & 1) * (mi_step >> 1);
int y_idx = (i >> 1) * (mi_step >> 1);
int jj = i >> 1, ii = i & 0x01;
- int rt;
- int64_t dt;
+ RD_COST tmp_rdc = {0, 0, 0};
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
- mi_row + y_idx, mi_col + x_idx, subsize, &rt, &dt,
+ mi_row + y_idx, mi_col + x_idx, subsize,
+ &tmp_rdc.rate, &tmp_rdc.dist,
i != 3, pc_tree->split[i]);
- if (rt == INT_MAX || dt == INT64_MAX) {
- last_part_rate = INT_MAX;
- last_part_dist = INT64_MAX;
+ if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
+ last_part_rdc.rate = INT_MAX;
+ last_part_rdc.dist = INT64_MAX;
+ last_part_rdc.rdcost = INT64_MAX;
break;
}
- last_part_rate += rt;
- last_part_dist += dt;
+ last_part_rdc.rate += tmp_rdc.rate;
+ last_part_rdc.dist += tmp_rdc.dist;
}
break;
default:
@@ -1676,9 +1675,10 @@
}
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- if (last_part_rate < INT_MAX) {
- last_part_rate += cpi->partition_cost[pl][partition];
- last_part_rd = RDCOST(x->rdmult, x->rddiv, last_part_rate, last_part_dist);
+ if (last_part_rdc.rate < INT_MAX) {
+ last_part_rdc.rate += cpi->partition_cost[pl][partition];
+ last_part_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ last_part_rdc.rate, last_part_rdc.dist);
}
if (do_partition_search
@@ -1690,8 +1690,8 @@
&& (mi_col + mi_step < cm->mi_cols ||
mi_col + (mi_step >> 1) == cm->mi_cols)) {
BLOCK_SIZE split_subsize = get_subsize(bsize, PARTITION_SPLIT);
- chosen_rate = 0;
- chosen_dist = 0;
+ chosen_rdc.rate = 0;
+ chosen_rdc.dist = 0;
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
pc_tree->partitioning = PARTITION_SPLIT;
@@ -1699,8 +1699,7 @@
for (i = 0; i < 4; i++) {
int x_idx = (i & 1) * (mi_step >> 1);
int y_idx = (i >> 1) * (mi_step >> 1);
- int rt = 0;
- int64_t dt = 0;
+ RD_COST tmp_rdc;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
@@ -1709,20 +1708,21 @@
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
pc_tree->split[i]->partitioning = PARTITION_NONE;
- rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &rt, &dt,
+ rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
split_subsize, &pc_tree->split[i]->none,
INT64_MAX);
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
- if (rt == INT_MAX || dt == INT64_MAX) {
- chosen_rate = INT_MAX;
- chosen_dist = INT64_MAX;
+ if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
+ chosen_rdc.rate = INT_MAX;
+ chosen_rdc.dist = INT64_MAX;
+ chosen_rdc.rdcost = INT64_MAX;
break;
}
- chosen_rate += rt;
- chosen_dist += dt;
+ chosen_rdc.rate += tmp_rdc.rate;
+ chosen_rdc.dist += tmp_rdc.dist;
if (i != 3)
encode_sb(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx, 0,
@@ -1730,30 +1730,28 @@
pl = partition_plane_context(xd, mi_row + y_idx, mi_col + x_idx,
split_subsize);
- chosen_rate += cpi->partition_cost[pl][PARTITION_NONE];
+ chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
}
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- if (chosen_rate < INT_MAX) {
- chosen_rate += cpi->partition_cost[pl][PARTITION_SPLIT];
- chosen_rd = RDCOST(x->rdmult, x->rddiv, chosen_rate, chosen_dist);
+ if (chosen_rdc.rate < INT_MAX) {
+ chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ chosen_rdc.rate, chosen_rdc.dist);
}
}
// If last_part is better set the partitioning to that.
- if (last_part_rd < chosen_rd) {
+ if (last_part_rdc.rdcost < chosen_rdc.rdcost) {
mi_8x8[0].src_mi->mbmi.sb_type = bsize;
if (bsize >= BLOCK_8X8)
pc_tree->partitioning = partition;
- chosen_rate = last_part_rate;
- chosen_dist = last_part_dist;
- chosen_rd = last_part_rd;
+ chosen_rdc = last_part_rdc;
}
// If none was better set the partitioning to that.
- if (none_rd < chosen_rd) {
+ if (none_rdc.rdcost < chosen_rdc.rdcost) {
if (bsize >= BLOCK_8X8)
pc_tree->partitioning = PARTITION_NONE;
- chosen_rate = none_rate;
- chosen_dist = none_dist;
+ chosen_rdc = none_rdc;
}
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
@@ -1761,7 +1759,7 @@
// We must have chosen a partitioning and encoding or we'll fail later on.
// No other opportunities for success.
if (bsize == BLOCK_64X64)
- assert(chosen_rate < INT_MAX && chosen_dist < INT64_MAX);
+ assert(chosen_rdc.rate < INT_MAX && chosen_rdc.dist < INT64_MAX);
if (do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
@@ -1771,18 +1769,18 @@
// closer to the target.
if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
vp9_select_in_frame_q_segment(cpi, mi_row, mi_col,
- output_enabled, chosen_rate);
+ output_enabled, chosen_rdc.rate);
}
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
- chosen_rate, chosen_dist);
+ chosen_rdc.rate, chosen_rdc.dist);
encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize,
pc_tree);
}
- *rate = chosen_rate;
- *dist = chosen_dist;
+ *rate = chosen_rdc.rate;
+ *dist = chosen_rdc.dist;
}
static const BLOCK_SIZE min_partition_size[BLOCK_SIZES] = {
@@ -2111,10 +2109,9 @@
// unlikely to be selected depending on previous rate-distortion optimization
// results, for encoding speed-up.
static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
- TOKENEXTRA **tp, int mi_row,
- int mi_col, BLOCK_SIZE bsize, int *rate,
- int64_t *dist, int64_t best_rd,
- PC_TREE *pc_tree) {
+ TOKENEXTRA **tp, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, RD_COST *rd_cost,
+ int64_t best_rd, PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -2125,9 +2122,9 @@
PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i, pl;
BLOCK_SIZE subsize;
- int this_rate, sum_rate = 0, best_rate = INT_MAX;
- int64_t this_dist, sum_dist = 0, best_dist = INT64_MAX;
- int64_t sum_rd = 0;
+ RD_COST this_rdc = {0, 0, 0};
+ RD_COST sum_rdc = {0, 0, 0};
+ RD_COST best_rdc = {INT_MAX, INT64_MAX, best_rd};
int do_split = bsize >= BLOCK_8X8;
int do_rect = 1;
@@ -2246,22 +2243,21 @@
// PARTITION_NONE
if (partition_none_allowed) {
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rate, &this_dist, bsize,
- ctx, best_rd);
- if (this_rate != INT_MAX) {
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &this_rdc, bsize, ctx,
+ best_rdc.rdcost);
+ if (this_rdc.rate != INT_MAX) {
if (bsize >= BLOCK_8X8) {
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- this_rate += cpi->partition_cost[pl][PARTITION_NONE];
+ this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ this_rdc.rate, this_rdc.dist);
}
- sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
- if (sum_rd < best_rd) {
+ if (this_rdc.rdcost < best_rdc.rdcost) {
int64_t dist_breakout_thr = cpi->sf.partition_search_breakout_dist_thr;
int rate_breakout_thr = cpi->sf.partition_search_breakout_rate_thr;
- best_rate = this_rate;
- best_dist = this_dist;
- best_rd = sum_rd;
+ best_rdc = this_rdc;
if (bsize >= BLOCK_8X8)
pc_tree->partitioning = PARTITION_NONE;
@@ -2277,8 +2273,8 @@
// The dist & rate thresholds are set to 0 at speed 0 to disable the
// early termination at that speed.
if (!x->e_mbd.lossless &&
- (ctx->skippable && best_dist < dist_breakout_thr &&
- best_rate < rate_breakout_thr)) {
+ (ctx->skippable && best_rdc.dist < dist_breakout_thr &&
+ best_rdc.rate < rate_breakout_thr)) {
do_split = 0;
do_rect = 0;
}
@@ -2338,7 +2334,6 @@
store_pred_mv(x, ctx);
// PARTITION_SPLIT
- sum_rd = 0;
// TODO(jingning): use the motion vectors given by the above search as
// the starting point of motion search in the following partition type check.
if (do_split) {
@@ -2348,14 +2343,12 @@
if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
pc_tree->leaf_split[0]->pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
- pc_tree->leaf_split[0], best_rd);
- if (sum_rate == INT_MAX)
- sum_rd = INT64_MAX;
- else
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
+ pc_tree->leaf_split[0], best_rdc.rdcost);
+ if (sum_rdc.rate == INT_MAX)
+ sum_rdc.rdcost = INT64_MAX;
} else {
- for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
+ for (i = 0; i < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++i) {
const int x_idx = (i & 1) * mi_step;
const int y_idx = (i >> 1) * mi_step;
@@ -2367,28 +2360,28 @@
pc_tree->split[i]->index = i;
rd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
- subsize, &this_rate, &this_dist,
- best_rd - sum_rd, pc_tree->split[i]);
+ subsize, &this_rdc,
+ best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[i]);
- if (this_rate == INT_MAX) {
- sum_rd = INT64_MAX;
+ if (this_rdc.rate == INT_MAX) {
+ sum_rdc.rdcost = INT64_MAX;
+ break;
} else {
- sum_rate += this_rate;
- sum_dist += this_dist;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ sum_rdc.rate += this_rdc.rate;
+ sum_rdc.dist += this_rdc.dist;
+ sum_rdc.rdcost += this_rdc.rdcost;
}
}
}
- if (sum_rd < best_rd && i == 4) {
+ if (sum_rdc.rdcost < best_rdc.rdcost && i == 4) {
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- sum_rate += cpi->partition_cost[pl][PARTITION_SPLIT];
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ sum_rdc.rate, sum_rdc.dist);
- if (sum_rd < best_rd) {
- best_rate = sum_rate;
- best_dist = sum_dist;
- best_rd = sum_rd;
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
+ best_rdc = sum_rdc;
pc_tree->partitioning = PARTITION_SPLIT;
}
} else {
@@ -2409,11 +2402,10 @@
partition_none_allowed)
pc_tree->horizontal[0].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
- &pc_tree->horizontal[0], best_rd);
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
+ &pc_tree->horizontal[0], best_rdc.rdcost);
- if (sum_rd < best_rd && mi_row + mi_step < cm->mi_rows &&
+ if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + mi_step < cm->mi_rows &&
bsize > BLOCK_8X8) {
PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
@@ -2425,25 +2417,24 @@
partition_none_allowed)
pc_tree->horizontal[1].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rate,
- &this_dist, subsize, &pc_tree->horizontal[1],
- best_rd - sum_rd);
- if (this_rate == INT_MAX) {
- sum_rd = INT64_MAX;
+ rd_pick_sb_modes(cpi, tile, mi_row + mi_step, mi_col, &this_rdc,
+ subsize, &pc_tree->horizontal[1],
+ best_rdc.rdcost - sum_rdc.rdcost);
+ if (this_rdc.rate == INT_MAX) {
+ sum_rdc.rdcost = INT64_MAX;
} else {
- sum_rate += this_rate;
- sum_dist += this_dist;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ sum_rdc.rate += this_rdc.rate;
+ sum_rdc.dist += this_rdc.dist;
+ sum_rdc.rdcost += this_rdc.rdcost;
}
}
- if (sum_rd < best_rd) {
+
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- sum_rate += cpi->partition_cost[pl][PARTITION_HORZ];
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd) {
- best_rd = sum_rd;
- best_rate = sum_rate;
- best_dist = sum_dist;
+ sum_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ];
+ sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
+ best_rdc = sum_rdc;
pc_tree->partitioning = PARTITION_HORZ;
}
}
@@ -2459,10 +2450,9 @@
partition_none_allowed)
pc_tree->vertical[0].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
- &pc_tree->vertical[0], best_rd);
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd && mi_col + mi_step < cm->mi_cols &&
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
+ &pc_tree->vertical[0], best_rdc.rdcost);
+ if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + mi_step < cm->mi_cols &&
bsize > BLOCK_8X8) {
update_state(cpi, &pc_tree->vertical[0], mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize,
@@ -2474,25 +2464,24 @@
partition_none_allowed)
pc_tree->vertical[1].pred_interp_filter =
ctx->mic.mbmi.interp_filter;
- rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rate,
- &this_dist, subsize,
- &pc_tree->vertical[1], best_rd - sum_rd);
- if (this_rate == INT_MAX) {
- sum_rd = INT64_MAX;
+ rd_pick_sb_modes(cpi, tile, mi_row, mi_col + mi_step, &this_rdc, subsize,
+ &pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost);
+ if (this_rdc.rate == INT_MAX) {
+ sum_rdc.rdcost = INT64_MAX;
} else {
- sum_rate += this_rate;
- sum_dist += this_dist;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ sum_rdc.rate += this_rdc.rate;
+ sum_rdc.dist += this_rdc.dist;
+ sum_rdc.rdcost += this_rdc.rdcost;
}
}
- if (sum_rd < best_rd) {
+
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- sum_rate += cpi->partition_cost[pl][PARTITION_VERT];
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd) {
- best_rate = sum_rate;
- best_dist = sum_dist;
- best_rd = sum_rd;
+ sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT];
+ sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ sum_rdc.rate, sum_rdc.dist);
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
+ best_rdc = sum_rdc;
pc_tree->partitioning = PARTITION_VERT;
}
}
@@ -2504,10 +2493,11 @@
// point. This code should be refactored so that the duplicate
// checks occur in some sub function and thus are used...
(void) best_rd;
- *rate = best_rate;
- *dist = best_dist;
+ *rd_cost = best_rdc;
- if (best_rate < INT_MAX && best_dist < INT64_MAX && pc_tree->index != 3) {
+
+ if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
+ pc_tree->index != 3) {
int output_enabled = (bsize == BLOCK_64X64);
// Check the projected output rate for this SB against it's target
@@ -2515,10 +2505,10 @@
// closer to the target.
if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map)
vp9_select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled,
- best_rate);
+ best_rdc.rate);
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
- best_rate, best_dist);
+ best_rdc.rate, best_rdc.dist);
encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
}
@@ -2525,8 +2515,8 @@
if (bsize == BLOCK_64X64) {
assert(tp_orig < *tp);
- assert(best_rate < INT_MAX);
- assert(best_dist < INT64_MAX);
+ assert(best_rdc.rate < INT_MAX);
+ assert(best_rdc.dist < INT64_MAX);
} else {
assert(tp_orig == *tp);
}
@@ -2548,6 +2538,7 @@
mi_col += MI_BLOCK_SIZE) {
int dummy_rate;
int64_t dummy_dist;
+ RD_COST dummy_rdc;
int i;
const int idx_str = cm->mi_stride * mi_row + mi_col;
@@ -2623,8 +2614,7 @@
&sf->max_partition_size);
}
rd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, INT64_MAX,
- cpi->pc_root);
+ &dummy_rdc, INT64_MAX, cpi->pc_root);
}
}
}
--- a/vp9/encoder/vp9_rd.h
+++ b/vp9/encoder/vp9_rd.h
@@ -117,6 +117,12 @@
int RDDIV;
} RD_OPT;
+typedef struct RD_COST {
+ int rate;
+ int64_t dist;
+ int64_t rdcost;
+} RD_COST;
+
struct TileInfo;
struct VP9_COMP;
struct macroblock;
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2702,8 +2702,7 @@
}
void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
- int *returnrate, int64_t *returndist,
- BLOCK_SIZE bsize,
+ RD_COST *rd_cost, BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -2720,7 +2719,7 @@
if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
&dist_y, &y_skip, bsize, tx_cache,
best_rd) >= best_rd) {
- *returnrate = INT_MAX;
+ rd_cost->rate = INT_MAX;
return;
}
} else {
@@ -2727,7 +2726,7 @@
y_skip = 0;
if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate_y, &rate_y_tokenonly,
&dist_y, best_rd) >= best_rd) {
- *returnrate = INT_MAX;
+ rd_cost->rate = INT_MAX;
return;
}
}
@@ -2739,14 +2738,15 @@
max_uv_tx_size);
if (y_skip && uv_skip) {
- *returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
- vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
- *returndist = dist_y + dist_uv;
+ rd_cost->rate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
+ vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
+ rd_cost->dist = dist_y + dist_uv;
vp9_zero(ctx->tx_rd_diff);
} else {
int i;
- *returnrate = rate_y + rate_uv + vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
- *returndist = dist_y + dist_uv;
+ rd_cost->rate = rate_y + rate_uv +
+ vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
+ rd_cost->dist = dist_y + dist_uv;
if (cpi->sf.tx_size_search_method == USE_FULL_RD)
for (i = 0; i < TX_MODES; i++) {
if (tx_cache[i] < INT64_MAX && tx_cache[cm->tx_mode] < INT64_MAX)
@@ -2757,6 +2757,7 @@
}
ctx->mic = *xd->mi[0].src_mi;
+ rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
}
static void update_rd_thresh_fact(VP9_COMP *cpi, int bsize,
@@ -2784,9 +2785,7 @@
int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
- BLOCK_SIZE bsize,
+ RD_COST *rd_cost, BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far) {
VP9_COMMON *const cm = &cpi->common;
@@ -2859,7 +2858,7 @@
}
}
- *returnrate = INT_MAX;
+ rd_cost->rate = INT_MAX;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
@@ -3256,8 +3255,9 @@
best_pred_sse = x->pred_sse[ref_frame];
}
- *returnrate = rate2;
- *returndistortion = distortion2;
+ rd_cost->rate = rate2;
+ rd_cost->dist = distortion2;
+ rd_cost->rdcost = this_rd;
best_rd = this_rd;
best_mbmode = *mbmi;
best_skip2 = this_skip2;
@@ -3473,8 +3473,7 @@
}
int64_t vp9_rd_pick_inter_mode_sb_seg_skip(VP9_COMP *cpi, MACROBLOCK *x,
- int *returnrate,
- int64_t *returndistortion,
+ RD_COST *rd_cost,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far) {
@@ -3505,7 +3504,7 @@
for (i = LAST_FRAME; i < MAX_REF_FRAMES; ++i)
x->pred_mv_sad[i] = INT_MAX;
- *returnrate = INT_MAX;
+ rd_cost->rate = INT_MAX;
assert(vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
@@ -3554,11 +3553,14 @@
rate2 += ref_costs_single[LAST_FRAME];
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
- *returnrate = rate2;
- *returndistortion = distortion2;
+ rd_cost->rate = rate2;
+ rd_cost->dist = distortion2;
+ rd_cost->rdcost = this_rd;
- if (this_rd >= best_rd_so_far)
+ if (this_rd >= best_rd_so_far) {
+ rd_cost->rdcost = INT64_MAX;
return INT64_MAX;
+ }
assert((cm->interp_filter == SWITCHABLE) ||
(cm->interp_filter == mbmi->interp_filter));
@@ -3580,8 +3582,7 @@
int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
+ RD_COST *rd_cost,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far) {
@@ -3639,7 +3640,7 @@
best_filter_rd[i] = INT64_MAX;
rate_uv_intra = INT_MAX;
- *returnrate = INT_MAX;
+ rd_cost->rate = INT_MAX;
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
@@ -4014,8 +4015,9 @@
max_plane = 1;
}
- *returnrate = rate2;
- *returndistortion = distortion2;
+ rd_cost->rate = rate2;
+ rd_cost->dist = distortion2;
+ rd_cost->rdcost = this_rd;
best_rd = this_rd;
best_yrd = best_rd -
RDCOST(x->rdmult, x->rddiv, rate_uv, distortion_uv);
@@ -4124,8 +4126,9 @@
}
if (best_rd == INT64_MAX) {
- *returnrate = INT_MAX;
- *returndistortion = INT64_MAX;
+ rd_cost->rate = INT_MAX;
+ rd_cost->dist = INT64_MAX;
+ rd_cost->rdcost = INT64_MAX;
return best_rd;
}
--- a/vp9/encoder/vp9_rdopt.h
+++ b/vp9/encoder/vp9_rdopt.h
@@ -23,24 +23,22 @@
struct TileInfo;
struct VP9_COMP;
struct macroblock;
+struct RD_COST;
void vp9_rd_pick_intra_mode_sb(struct VP9_COMP *cpi, struct macroblock *x,
- int *r, int64_t *d, BLOCK_SIZE bsize,
+ struct RD_COST *rd_cost, BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx, int64_t best_rd);
int64_t vp9_rd_pick_inter_mode_sb(struct VP9_COMP *cpi, struct macroblock *x,
const struct TileInfo *const tile,
int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
- BLOCK_SIZE bsize,
- PICK_MODE_CONTEXT *ctx,
+ struct RD_COST *rd_cost,
+ BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far);
int64_t vp9_rd_pick_inter_mode_sb_seg_skip(struct VP9_COMP *cpi,
struct macroblock *x,
- int *returnrate,
- int64_t *returndistortion,
+ struct RD_COST *rd_cost,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far);
@@ -49,10 +47,8 @@
struct macroblock *x,
const struct TileInfo *const tile,
int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
- BLOCK_SIZE bsize,
- PICK_MODE_CONTEXT *ctx,
+ struct RD_COST *rd_cost,
+ BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far);
#ifdef __cplusplus
} // extern "C"