summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_encodeframe.c310
-rw-r--r--vp9/encoder/vp9_pickmode.c76
-rw-r--r--vp9/encoder/vp9_pickmode.h4
3 files changed, 188 insertions, 202 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index eb63b1a51..a7370bff6 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -750,8 +750,8 @@ void vp9_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
x->e_mbd.plane[i].subsampling_y);
}
-static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, int *rate,
- int64_t *dist, BLOCK_SIZE bsize) {
+static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode,
+ RD_COST *rd_cost, BLOCK_SIZE bsize) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
INTERP_FILTER filter_ref;
@@ -777,8 +777,7 @@ static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode, int *rate,
xd->mi[0].src_mi->bmi[0].as_mv[0].as_int = 0;
x->skip = 1;
- *rate = 0;
- *dist = 0;
+ vp9_rd_cost_init(rd_cost);
}
static void rd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
@@ -2577,8 +2576,7 @@ static TX_MODE select_tx_mode(const VP9_COMP *cpi) {
}
static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
- int mi_row, int mi_col,
- int *rate, int64_t *dist,
+ int mi_row, int mi_col, RD_COST *rd_cost,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
@@ -2593,11 +2591,14 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
- set_mode_info_seg_skip(x, cm->tx_mode, rate, dist, bsize);
+ set_mode_info_seg_skip(x, cm->tx_mode, rd_cost, bsize);
else
- vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rate, dist, bsize, ctx);
+ vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col, rd_cost, bsize, ctx);
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
+
+ if (rd_cost->rate == INT_MAX)
+ vp9_rd_cost_reset(rd_cost);
}
static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
@@ -2659,8 +2660,8 @@ static void fill_mode_info_sb(VP9_COMMON *cm, MACROBLOCK *x,
static void nonrd_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, int do_recon, int64_t best_rd,
+ int mi_col, BLOCK_SIZE bsize, RD_COST *rd_cost,
+ int do_recon, int64_t best_rd,
PC_TREE *pc_tree) {
const SPEED_FEATURES *const sf = &cpi->sf;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
@@ -2672,9 +2673,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i;
BLOCK_SIZE subsize = bsize;
- 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, sum_rdc, best_rdc;
int do_split = bsize >= BLOCK_8X8;
int do_rect = 1;
// Override skipping rectangular partition operations for edge blocks
@@ -2693,6 +2692,10 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
assert(num_8x8_blocks_wide_lookup[bsize] ==
num_8x8_blocks_high_lookup[bsize]);
+ vp9_rd_cost_init(&sum_rdc);
+ vp9_rd_cost_reset(&best_rdc);
+ best_rdc.rdcost = best_rd;
+
// Determine partition types in search according to the speed features.
// The threshold set here has to be of square block size.
if (sf->auto_min_max_partition_size) {
@@ -2714,17 +2717,18 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// PARTITION_NONE
if (partition_none_allowed) {
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
- &this_rate, &this_dist, bsize, ctx);
+ &this_rdc, bsize, ctx);
ctx->mic.mbmi = xd->mi[0].src_mi->mbmi;
ctx->skip_txfm[0] = x->skip_txfm[0];
ctx->skip = x->skip;
ctx->pred_pixel_ready = 0;
- if (this_rate != INT_MAX) {
+ if (this_rdc.rate != INT_MAX) {
int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- this_rate += cpi->partition_cost[pl][PARTITION_NONE];
- sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
- if (sum_rd < best_rd) {
+ this_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ this_rdc.rate, this_rdc.dist);
+ if (this_rdc.rdcost < best_rdc.rdcost) {
int64_t dist_breakout_thr = sf->partition_search_breakout_dist_thr;
int64_t rate_breakout_thr = sf->partition_search_breakout_rate_thr;
@@ -2733,15 +2737,13 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
rate_breakout_thr *= num_pels_log2_lookup[bsize];
- 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;
if (!x->e_mbd.lossless &&
- this_rate < rate_breakout_thr &&
- this_dist < dist_breakout_thr) {
+ this_rdc.rate < rate_breakout_thr &&
+ this_rdc.dist < dist_breakout_thr) {
do_split = 0;
do_rect = 0;
}
@@ -2753,12 +2755,12 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
store_pred_mv(x, ctx);
// PARTITION_SPLIT
- sum_rd = 0;
if (do_split) {
int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- sum_rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ sum_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, sum_rdc.rate, sum_rdc.dist);
subsize = get_subsize(bsize, PARTITION_SPLIT);
- 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) * ms;
const int y_idx = (i >> 1) * ms;
@@ -2766,22 +2768,20 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
continue;
load_pred_mv(x, ctx);
nonrd_pick_partition(cpi, tile, tp, mi_row + y_idx, mi_col + x_idx,
- subsize, &this_rate, &this_dist, 0,
- best_rd - sum_rd, pc_tree->split[i]);
+ subsize, &this_rdc, 0,
+ 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) {
+ vp9_rd_cost_reset(&sum_rdc);
} 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) {
- 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 {
// skip rectangular partition test when larger block size
@@ -2797,8 +2797,7 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (sf->adaptive_motion_search)
load_pred_mv(x, ctx);
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
- &this_rate, &this_dist, subsize,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
&pc_tree->horizontal[0]);
pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
@@ -2806,12 +2805,9 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
pc_tree->horizontal[0].skip = x->skip;
pc_tree->horizontal[0].pred_pixel_ready = 0;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
-
- if (sum_rd < best_rd && mi_row + ms < cm->mi_rows) {
+ if (sum_rdc.rdcost < best_rdc.rdcost && mi_row + ms < cm->mi_rows) {
load_pred_mv(x, ctx);
- nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col,
- &this_rate, &this_dist, subsize,
+ nonrd_pick_sb_modes(cpi, tile, mi_row + ms, mi_col, &this_rdc, subsize,
&pc_tree->horizontal[1]);
pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
@@ -2819,20 +2815,20 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
pc_tree->horizontal[1].skip = x->skip;
pc_tree->horizontal[1].pred_pixel_ready = 0;
- if (this_rate == INT_MAX) {
- sum_rd = INT64_MAX;
+ if (this_rdc.rate == INT_MAX) {
+ vp9_rd_cost_reset(&sum_rdc);
} else {
int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- this_rate += cpi->partition_cost[pl][PARTITION_HORZ];
- sum_rate += this_rate;
- sum_dist += this_dist;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ this_rdc.rate += cpi->partition_cost[pl][PARTITION_HORZ];
+ sum_rdc.rate += this_rdc.rate;
+ sum_rdc.dist += this_rdc.dist;
+ sum_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ sum_rdc.rate, sum_rdc.dist);
}
}
- if (sum_rd < best_rd) {
- best_rd = sum_rd;
- best_rate = sum_rate;
- best_dist = sum_dist;
+
+ if (sum_rdc.rdcost < best_rdc.rdcost) {
+ best_rdc = sum_rdc;
pc_tree->partitioning = PARTITION_HORZ;
}
}
@@ -2844,57 +2840,53 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
if (sf->adaptive_motion_search)
load_pred_mv(x, ctx);
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col,
- &this_rate, &this_dist, subsize,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, &sum_rdc, subsize,
&pc_tree->vertical[0]);
pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[0].skip = x->skip;
pc_tree->vertical[0].pred_pixel_ready = 0;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
- if (sum_rd < best_rd && mi_col + ms < cm->mi_cols) {
+
+ if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + ms < cm->mi_cols) {
load_pred_mv(x, ctx);
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms,
- &this_rate, &this_dist, subsize,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + ms, &this_rdc, subsize,
&pc_tree->vertical[1]);
pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[1].skip = x->skip;
pc_tree->vertical[1].pred_pixel_ready = 0;
- if (this_rate == INT_MAX) {
- sum_rd = INT64_MAX;
+
+ if (this_rdc.rate == INT_MAX) {
+ vp9_rd_cost_reset(&sum_rdc);
} else {
int pl = partition_plane_context(xd, mi_row, mi_col, bsize);
- this_rate += cpi->partition_cost[pl][PARTITION_VERT];
- sum_rate += this_rate;
- sum_dist += this_dist;
- sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
+ sum_rdc.rate += cpi->partition_cost[pl][PARTITION_VERT];
+ sum_rdc.rate += this_rdc.rate;
+ sum_rdc.dist += this_rdc.dist;
+ 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_VERT;
}
}
- // TODO(JBB): The following line is here just to avoid a static warning
- // that occurs because at this point we never again reuse best_rd
- // despite setting it here. The code should be refactored to avoid this.
- (void) best_rd;
- *rate = best_rate;
- *dist = best_dist;
+ *rd_cost = best_rdc;
- if (best_rate == INT_MAX)
+ if (best_rdc.rate == INT_MAX) {
+ vp9_rd_cost_reset(rd_cost);
return;
+ }
// update mode info array
subsize = get_subsize(bsize, pc_tree->partitioning);
fill_mode_info_sb(cm, x, mi_row, mi_col, bsize, subsize,
pc_tree);
- if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon) {
+ if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
// Check the projected output rate for this SB against it's target
@@ -2902,20 +2894,20 @@ static void nonrd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
// closer to the target.
if ((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 (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_rt(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize, pc_tree);
}
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);
}
@@ -2927,8 +2919,7 @@ static void nonrd_select_partition(VP9_COMP *cpi,
TOKENEXTRA **tp,
int mi_row, int mi_col,
BLOCK_SIZE bsize, int output_enabled,
- int *totrate, int64_t *totdist,
- PC_TREE *pc_tree) {
+ RD_COST *rd_cost, PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -2936,9 +2927,9 @@ static void nonrd_select_partition(VP9_COMP *cpi,
const int mis = cm->mi_stride;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
- int rate = INT_MAX;
- int64_t dist = INT64_MAX;
+ RD_COST this_rdc;
+ vp9_rd_cost_reset(&this_rdc);
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -2950,16 +2941,16 @@ static void nonrd_select_partition(VP9_COMP *cpi,
cpi->sf.max_partition_size = BLOCK_32X32;
cpi->sf.min_partition_size = BLOCK_8X8;
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, bsize,
- totrate, totdist, 0, INT64_MAX, pc_tree);
+ rd_cost, 0, INT64_MAX, pc_tree);
} else if (bsize == BLOCK_16X16 && partition != PARTITION_NONE) {
cpi->sf.max_partition_size = BLOCK_16X16;
cpi->sf.min_partition_size = BLOCK_8X8;
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, bsize,
- totrate, totdist, 0, INT64_MAX, pc_tree);
+ rd_cost, 0, INT64_MAX, pc_tree);
} else {
switch (partition) {
case PARTITION_NONE:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->none);
pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
@@ -2967,7 +2958,7 @@ static void nonrd_select_partition(VP9_COMP *cpi,
pc_tree->none.pred_pixel_ready = 1;
break;
case PARTITION_VERT:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->vertical[0]);
pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
@@ -2975,20 +2966,20 @@ static void nonrd_select_partition(VP9_COMP *cpi,
pc_tree->vertical[0].pred_pixel_ready = 1;
if (mi_col + hbs < cm->mi_cols) {
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
- &rate, &dist, subsize, &pc_tree->vertical[1]);
+ &this_rdc, subsize, &pc_tree->vertical[1]);
pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[1].skip = x->skip;
pc_tree->vertical[1].pred_pixel_ready = 1;
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
}
break;
case PARTITION_HORZ:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->horizontal[0]);
pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
@@ -2996,46 +2987,46 @@ static void nonrd_select_partition(VP9_COMP *cpi,
pc_tree->horizontal[0].pred_pixel_ready = 1;
if (mi_row + hbs < cm->mi_rows) {
nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
- &rate, &dist, subsize, &pc_tree->horizontal[0]);
+ &this_rdc, subsize, &pc_tree->horizontal[0]);
pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->horizontal[1].skip = x->skip;
pc_tree->horizontal[1].pred_pixel_ready = 1;
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
}
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
nonrd_select_partition(cpi, tile, mi, tp, mi_row, mi_col,
- subsize, output_enabled, totrate, totdist,
+ subsize, output_enabled, rd_cost,
pc_tree->split[0]);
nonrd_select_partition(cpi, tile, mi + hbs, tp,
mi_row, mi_col + hbs, subsize, output_enabled,
- &rate, &dist, pc_tree->split[1]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ &this_rdc, pc_tree->split[1]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
nonrd_select_partition(cpi, tile, mi + hbs * mis, tp,
mi_row + hbs, mi_col, subsize, output_enabled,
- &rate, &dist, pc_tree->split[2]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ &this_rdc, pc_tree->split[2]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
nonrd_select_partition(cpi, tile, mi + hbs * mis + hbs, tp,
- mi_row + hbs, mi_col + hbs, subsize,
- output_enabled, &rate, &dist, pc_tree->split[3]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ mi_row + hbs, mi_col + hbs, subsize,
+ output_enabled, &this_rdc, pc_tree->split[3]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
break;
default:
@@ -3047,7 +3038,7 @@ static void nonrd_select_partition(VP9_COMP *cpi,
if (bsize == BLOCK_64X64 && output_enabled) {
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
- *totrate, *totdist);
+ rd_cost->rate, rd_cost->dist);
encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize, pc_tree);
}
}
@@ -3059,8 +3050,7 @@ static void nonrd_use_partition(VP9_COMP *cpi,
TOKENEXTRA **tp,
int mi_row, int mi_col,
BLOCK_SIZE bsize, int output_enabled,
- int *totrate, int64_t *totdist,
- PC_TREE *pc_tree) {
+ RD_COST *rd_cost, PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -3068,9 +3058,9 @@ static void nonrd_use_partition(VP9_COMP *cpi,
const int mis = cm->mi_stride;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
- int rate = INT_MAX;
- int64_t dist = INT64_MAX;
+ RD_COST this_rdc;
+ vp9_rd_cost_reset(&this_rdc);
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -3079,78 +3069,78 @@ static void nonrd_use_partition(VP9_COMP *cpi,
switch (partition) {
case PARTITION_NONE:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->none);
pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
pc_tree->none.skip = x->skip;
break;
case PARTITION_VERT:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->vertical[0]);
pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[0].skip = x->skip;
if (mi_col + hbs < cm->mi_cols) {
nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col + hbs,
- &rate, &dist, subsize, &pc_tree->vertical[1]);
+ &this_rdc, subsize, &pc_tree->vertical[1]);
pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[1].skip = x->skip;
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
}
break;
case PARTITION_HORZ:
- nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, totrate, totdist,
+ nonrd_pick_sb_modes(cpi, tile, mi_row, mi_col, rd_cost,
subsize, &pc_tree->horizontal[0]);
pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
pc_tree->horizontal[0].skip = x->skip;
if (mi_row + hbs < cm->mi_rows) {
nonrd_pick_sb_modes(cpi, tile, mi_row + hbs, mi_col,
- &rate, &dist, subsize, &pc_tree->horizontal[0]);
+ &this_rdc, subsize, &pc_tree->horizontal[0]);
pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->horizontal[1].skip = x->skip;
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
}
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col,
- subsize, output_enabled, totrate, totdist,
+ subsize, output_enabled, rd_cost,
pc_tree->split[0]);
nonrd_use_partition(cpi, tile, mi + hbs, tp,
mi_row, mi_col + hbs, subsize, output_enabled,
- &rate, &dist, pc_tree->split[1]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ &this_rdc, pc_tree->split[1]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
nonrd_use_partition(cpi, tile, mi + hbs * mis, tp,
mi_row + hbs, mi_col, subsize, output_enabled,
- &rate, &dist, pc_tree->split[2]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ &this_rdc, pc_tree->split[2]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
nonrd_use_partition(cpi, tile, mi + hbs * mis + hbs, tp,
mi_row + hbs, mi_col + hbs, subsize, output_enabled,
- &rate, &dist, pc_tree->split[3]);
- if (rate != INT_MAX && dist != INT64_MAX &&
- *totrate != INT_MAX && *totdist != INT64_MAX) {
- *totrate += rate;
- *totdist += dist;
+ &this_rdc, pc_tree->split[3]);
+ if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
+ rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
+ rd_cost->rate += this_rdc.rate;
+ rd_cost->dist += this_rdc.dist;
}
break;
default:
@@ -3161,7 +3151,7 @@ static void nonrd_use_partition(VP9_COMP *cpi,
if (bsize == BLOCK_64X64 && output_enabled) {
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_set_rate_and_dist_sb(cpi->cyclic_refresh,
- *totrate, *totdist);
+ rd_cost->rate, rd_cost->dist);
encode_sb_rt(cpi, tile, tp, mi_row, mi_col, 1, bsize, pc_tree);
}
}
@@ -3181,26 +3171,26 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
// Code each SB in the row
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE) {
- int dummy_rate = 0;
- int64_t dummy_dist = 0;
+ RD_COST dummy_rdc;
const int idx_str = cm->mi_stride * mi_row + mi_col;
MODE_INFO *mi = cm->mi + idx_str;
BLOCK_SIZE bsize;
x->in_static_area = 0;
x->source_variance = UINT_MAX;
vp9_zero(x->pred_mv);
+ vp9_rd_cost_init(&dummy_rdc);
// Set the partition type of the 64X64 block
switch (sf->partition_search_type) {
case VAR_BASED_PARTITION:
choose_partitioning(cpi, tile, mi_row, mi_col);
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist, cpi->pc_root);
+ 1, &dummy_rdc, cpi->pc_root);
break;
case SOURCE_VAR_BASED_PARTITION:
set_source_var_based_partition(cpi, tile, mi, mi_row, mi_col);
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist, cpi->pc_root);
+ 1, &dummy_rdc, cpi->pc_root);
break;
case FIXED_PARTITION:
bsize = sf->partition_search_type == FIXED_PARTITION ?
@@ -3208,7 +3198,7 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
set_fixed_partitioning(cpi, tile, mi, mi_row, mi_col, bsize);
nonrd_use_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist, cpi->pc_root);
+ 1, &dummy_rdc, cpi->pc_root);
break;
case REFERENCE_PARTITION:
set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
@@ -3220,12 +3210,12 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
&sf->min_partition_size,
&sf->max_partition_size);
nonrd_pick_partition(cpi, tile, tp, mi_row, mi_col, BLOCK_64X64,
- &dummy_rate, &dummy_dist, 1,
+ &dummy_rdc, 1,
INT64_MAX, cpi->pc_root);
} else {
choose_partitioning(cpi, tile, mi_row, mi_col);
nonrd_select_partition(cpi, tile, mi, tp, mi_row, mi_col, BLOCK_64X64,
- 1, &dummy_rate, &dummy_dist, cpi->pc_root);
+ 1, &dummy_rdc, cpi->pc_root);
}
break;
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index b74b2dd56..9d20bae2b 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -460,11 +460,8 @@ static const THR_MODES mode_idx[MAX_REF_FRAMES - 1][INTER_MODES] = {
// this needs various further optimizations. to be continued..
void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
- int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
- BLOCK_SIZE bsize,
- PICK_MODE_CONTEXT *ctx) {
+ int mi_row, int mi_col, RD_COST *rd_cost,
+ BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0].src_mi->mbmi;
@@ -478,11 +475,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
- int64_t best_rd = INT64_MAX;
- int64_t this_rd = INT64_MAX;
+ RD_COST this_rdc, best_rdc;
uint8_t skip_txfm = 0;
- int rate = INT_MAX;
- int64_t dist = INT64_MAX;
// var_y and sse_y are saved to be used in skipping checking
unsigned int var_y = UINT_MAX;
unsigned int sse_y = UINT_MAX;
@@ -543,8 +537,9 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
x->skip = 0;
// initialize mode decisions
- *returnrate = INT_MAX;
- *returndistortion = INT64_MAX;
+ vp9_rd_cost_reset(&best_rdc);
+ vp9_rd_cost_reset(&this_rdc);
+ vp9_rd_cost_reset(rd_cost);
vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO));
mbmi->sb_type = bsize;
mbmi->ref_frame[0] = NONE;
@@ -614,17 +609,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mode_rd_thresh =
rd_threshes[mode_idx[ref_frame -
LAST_FRAME][INTER_OFFSET(this_mode)]];
- if (rd_less_than_thresh(best_rd, mode_rd_thresh,
+ if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
rd_thresh_freq_fact[this_mode]))
continue;
if (this_mode == NEWMV) {
if (cpi->sf.partition_search_type != VAR_BASED_PARTITION &&
- this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
+ this_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize]))
continue;
if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
&frame_mv[NEWMV][ref_frame],
- &rate_mv, best_rd))
+ &rate_mv, best_rdc.rdcost))
continue;
}
@@ -697,30 +692,34 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->interp_filter = best_filter;
mbmi->tx_size = pf_tx_size[mbmi->interp_filter];
- rate = pf_rate[mbmi->interp_filter];
- dist = pf_dist[mbmi->interp_filter];
+ this_rdc.rate = pf_rate[mbmi->interp_filter];
+ this_rdc.dist = pf_dist[mbmi->interp_filter];
var_y = pf_var[mbmi->interp_filter];
sse_y = pf_sse[mbmi->interp_filter];
x->skip_txfm[0] = skip_txfm;
} else {
mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP: filter_ref;
vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
- model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y);
+ model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
+ &var_y, &sse_y);
}
- rate += rate_mv;
- rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
+ this_rdc.rate += rate_mv;
+ this_rdc.rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
[INTER_OFFSET(this_mode)];
- this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ this_rdc.rate, this_rdc.dist);
// Skipping checking: test to see if this block can be reconstructed by
// prediction only.
if (cpi->allow_encode_breakout) {
encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame,
- this_mode, var_y, sse_y, yv12_mb, &rate, &dist);
+ this_mode, var_y, sse_y, yv12_mb,
+ &this_rdc.rate, &this_rdc.dist);
if (x->skip) {
- rate += rate_mv;
- this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
+ this_rdc.rate += rate_mv;
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ this_rdc.rate, this_rdc.dist);
}
}
@@ -732,10 +731,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
(void)ctx;
#endif
- if (this_rd < best_rd || x->skip) {
- best_rd = this_rd;
- *returnrate = rate;
- *returndistortion = dist;
+ if (this_rdc.rdcost < best_rdc.rdcost || x->skip) {
+ best_rdc = this_rdc;
best_mode = this_mode;
best_pred_filter = mbmi->interp_filter;
best_tx_size = mbmi->tx_size;
@@ -757,7 +754,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
// If the current reference frame is valid and we found a usable mode,
// we are done.
- if (best_rd < INT64_MAX)
+ if (best_rdc.rdcost < INT64_MAX)
break;
}
@@ -790,7 +787,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// Perform intra prediction search, if the best SAD is above a certain
// threshold.
- if (!x->skip && best_rd > inter_mode_thresh &&
+ if (!x->skip && best_rdc.rdcost > inter_mode_thresh &&
bsize <= cpi->sf.max_intra_bsize) {
PREDICTION_MODE this_mode;
struct estimate_block_intra_args args = { cpi, x, DC_PRED, 0, 0 };
@@ -812,16 +809,15 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
vp9_foreach_transformed_block_in_plane(xd, bsize, 0,
estimate_block_intra, &args);
mbmi->tx_size = saved_tx_size;
- rate = args.rate;
- dist = args.dist;
- rate += cpi->mbmode_cost[this_mode];
- rate += intra_cost_penalty;
- this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
-
- if (this_rd + intra_mode_cost < best_rd) {
- best_rd = this_rd;
- *returnrate = rate;
- *returndistortion = dist;
+ this_rdc.rate = args.rate;
+ this_rdc.dist = args.dist;
+ this_rdc.rate += cpi->mbmode_cost[this_mode];
+ this_rdc.rate += intra_cost_penalty;
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv,
+ this_rdc.rate, this_rdc.dist);
+
+ if (this_rdc.rdcost + intra_mode_cost < best_rdc.rdcost) {
+ best_rdc = this_rdc;
mbmi->mode = this_mode;
mbmi->tx_size = intra_tx_size;
mbmi->ref_frame[0] = INTRA_FRAME;
@@ -834,4 +830,6 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (cpi->sf.reuse_inter_pred_sby)
pd->dst = orig_dst;
}
+
+ *rd_cost = best_rdc;
}
diff --git a/vp9/encoder/vp9_pickmode.h b/vp9/encoder/vp9_pickmode.h
index 97aeca76a..27a319d3c 100644
--- a/vp9/encoder/vp9_pickmode.h
+++ b/vp9/encoder/vp9_pickmode.h
@@ -19,9 +19,7 @@ extern "C" {
void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const struct TileInfo *const tile,
- int mi_row, int mi_col,
- int *returnrate,
- int64_t *returndistortion,
+ int mi_row, int mi_col, RD_COST *rd_cost,
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx);