Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Unified Diff: source/libvpx/vp9/encoder/vp9_rdopt.c

Issue 554673004: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rd.c ('k') | source/libvpx/vp9/encoder/vp9_speed_features.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vp9/encoder/vp9_rdopt.c
===================================================================
--- source/libvpx/vp9/encoder/vp9_rdopt.c (revision 291857)
+++ source/libvpx/vp9/encoder/vp9_rdopt.c (working copy)
@@ -171,30 +171,53 @@
int64_t dist_sum = 0;
const int ref = xd->mi[0]->mbmi.ref_frame[0];
unsigned int sse;
+ unsigned int var = 0;
+ unsigned int sum_sse = 0;
const int shift = 8;
+ int rate;
+ int64_t dist;
+ x->pred_sse[ref] = 0;
+
for (i = 0; i < MAX_MB_PLANE; ++i) {
struct macroblock_plane *const p = &x->plane[i];
struct macroblockd_plane *const pd = &xd->plane[i];
const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
+ const TX_SIZE max_tx_size = max_txsize_lookup[bs];
+ const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
+ int bw = 1 << (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
+ int bh = 1 << (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
+ int idx, idy;
+ int lw = b_width_log2_lookup[unit_size] + 2;
+ int lh = b_height_log2_lookup[unit_size] + 2;
- const unsigned int var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
- pd->dst.buf, pd->dst.stride,
- &sse);
+ sum_sse = 0;
- if (!x->select_tx_size) {
- if (sse < p->quant_thred[0] >> shift)
- x->skip_txfm[i] = 1;
- else if (var < p->quant_thred[1] >> shift)
- x->skip_txfm[i] = 2;
- else
- x->skip_txfm[i] = 0;
+ for (idy = 0; idy < bh; ++idy) {
+ for (idx = 0; idx < bw; ++idx) {
+ uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
+ uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
+ int block_idx = (idy << 1) + idx;
+
+ var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
+ dst, pd->dst.stride, &sse);
+ x->bsse[(i << 2) + block_idx] = sse;
+ sum_sse += sse;
+
+ if (!x->select_tx_size) {
+ if (x->bsse[(i << 2) + block_idx] < p->quant_thred[0] >> shift)
+ x->skip_txfm[(i << 2) + block_idx] = 1;
+ else if (var < p->quant_thred[1] >> shift)
+ x->skip_txfm[(i << 2) + block_idx] = 2;
+ else
+ x->skip_txfm[(i << 2) + block_idx] = 0;
+ }
+
+ if (i == 0)
+ x->pred_sse[ref] += sse;
+ }
}
- x->bsse[i] = sse;
- if (i == 0)
- x->pred_sse[ref] = sse;
-
// Fast approximate the modelling function.
if (cpi->oxcf.speed > 4) {
int64_t rate;
@@ -210,9 +233,7 @@
rate_sum += rate;
dist_sum += dist;
} else {
- int rate;
- int64_t dist;
- vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
+ vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs],
pd->dequant[1] >> 3, &rate, &dist);
rate_sum += rate;
dist_sum += dist;
@@ -372,17 +393,17 @@
if (!is_inter_block(mbmi)) {
vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
dist_block(plane, block, tx_size, args);
- } else {
- if (x->skip_txfm[plane] == 0) {
+ } else if (max_txsize_lookup[plane_bsize] == tx_size) {
+ if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 0) {
// full forward transform and quantization
vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
dist_block(plane, block, tx_size, args);
- } else if (x->skip_txfm[plane] == 2) {
+ } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 2) {
// compute DC coefficient
int16_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
int16_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
vp9_xform_quant_dc(x, plane, block, plane_bsize, tx_size);
- args->sse = x->bsse[plane] << 4;
+ args->sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
args->dist = args->sse;
if (!x->plane[plane].eobs[block])
args->dist = args->sse - ((coeff[0] * coeff[0] -
@@ -390,9 +411,13 @@
} else {
// skip forward transform
x->plane[plane].eobs[block] = 0;
- args->sse = x->bsse[plane] << 4;
+ args->sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
args->dist = args->sse;
}
+ } else {
+ // full forward transform and quantization
+ vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
+ dist_block(plane, block, tx_size, args);
}
rate_block(plane, block, plane_bsize, tx_size, args);
@@ -468,7 +493,6 @@
txfm_rd_in_plane(x, rate, distortion, skip,
sse, ref_best_rd, 0, bs,
mbmi->tx_size, cpi->sf.use_fast_coef_costing);
- cpi->tx_stepdown_count[0]++;
}
static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
@@ -551,60 +575,36 @@
if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
- cpi->tx_stepdown_count[0]++;
} else if (max_tx_size >= TX_16X16 && best_tx == TX_16X16) {
tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
- cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
} else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
tx_cache[TX_MODE_SELECT] = rd[TX_8X8][1];
- cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
} else {
tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1];
- cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
}
}
-static void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
- int64_t *distortion, int *skip,
- int64_t *psse, BLOCK_SIZE bs,
- int64_t txfm_cache[TX_MODES],
- int64_t ref_best_rd) {
+static void super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
+ int64_t *distortion, int *skip,
+ int64_t *psse, BLOCK_SIZE bs,
+ int64_t txfm_cache[TX_MODES],
+ int64_t ref_best_rd) {
MACROBLOCKD *xd = &x->e_mbd;
+ int64_t sse;
+ int64_t *ret_sse = psse ? psse : &sse;
assert(bs == xd->mi[0]->mbmi.sb_type);
- vp9_subtract_plane(x, bs, 0);
-
if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) {
vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
- choose_largest_tx_size(cpi, x, rate, distortion, skip, psse, ref_best_rd,
+ choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
bs);
} else {
- choose_tx_size_from_rd(cpi, x, rate, distortion, skip, psse,
+ choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
txfm_cache, ref_best_rd, bs);
}
}
-static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
- int64_t *distortion, int *skip,
- BLOCK_SIZE bs,
- int64_t txfm_cache[TX_MODES],
- int64_t ref_best_rd) {
- MACROBLOCKD *xd = &x->e_mbd;
- int64_t sse;
-
- assert(bs == xd->mi[0]->mbmi.sb_type);
- if (cpi->sf.tx_size_search_method != USE_FULL_RD || xd->lossless) {
- vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
- choose_largest_tx_size(cpi, x, rate, distortion, skip, &sse, ref_best_rd,
- bs);
- } else {
- choose_tx_size_from_rd(cpi, x, rate, distortion, skip, &sse,
- txfm_cache, ref_best_rd, bs);
- }
-}
-
-
static int conditional_skipintra(PREDICTION_MODE mode,
PREDICTION_MODE best_intra_mode) {
if (mode == D117_PRED &&
@@ -854,8 +854,8 @@
}
mic->mbmi.mode = mode;
- intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, bsize, local_tx_cache, best_rd);
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, local_tx_cache, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -1365,13 +1365,14 @@
int sadpb = x->sadperbit4;
MV mvp_full;
int max_mv;
+ int sad_list[5];
/* Is the best so far sufficiently good that we cant justify doing
* and new motion search. */
if (best_rd < label_mv_thresh)
break;
- if (!is_best_mode(cpi->oxcf.mode)) {
+ if (cpi->oxcf.mode != BEST) {
// use previous block's result as next block's MV predictor.
if (i > 0) {
bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
@@ -1397,7 +1398,7 @@
mvp_full.row = bsi->mvp.as_mv.row >> 3;
mvp_full.col = bsi->mvp.as_mv.col >> 3;
- if (cpi->sf.adaptive_motion_search && cm->show_frame) {
+ if (cpi->sf.adaptive_motion_search) {
mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
step_param = MAX(step_param, 8);
@@ -1408,12 +1409,14 @@
vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
- bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
- sadpb, &bsi->ref_mv[0]->as_mv, new_mv,
- INT_MAX, 1);
+ bestsme = vp9_full_pixel_search(
+ cpi, x, bsize, &mvp_full, step_param, sadpb,
+ cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? sad_list : NULL,
+ &bsi->ref_mv[0]->as_mv, new_mv,
+ INT_MAX, 1);
// Should we do a full search (best quality only)
- if (is_best_mode(cpi->oxcf.mode)) {
+ if (cpi->oxcf.mode == BEST) {
int_mv *const best_mv = &mi->bmi[i].as_mv[0];
/* Check if mvp_full is within the range. */
clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
@@ -1422,6 +1425,7 @@
sadpb, 16, &cpi->fn_ptr[bsize],
&bsi->ref_mv[0]->as_mv,
&best_mv->as_mv);
+ sad_list[1] = sad_list[2] = sad_list[3] = sad_list[4] = INT_MAX;
if (thissme < bestsme) {
bestsme = thissme;
*new_mv = best_mv->as_mv;
@@ -1434,17 +1438,19 @@
if (bestsme < INT_MAX) {
int distortion;
- cpi->find_fractional_mv_step(x,
- new_mv,
- &bsi->ref_mv[0]->as_mv,
- cm->allow_high_precision_mv,
- x->errorperbit, &cpi->fn_ptr[bsize],
- cpi->sf.mv.subpel_force_stop,
- cpi->sf.mv.subpel_iters_per_step,
- x->nmvjointcost, x->mvcost,
- &distortion,
- &x->pred_sse[mbmi->ref_frame[0]],
- NULL, 0, 0);
+ cpi->find_fractional_mv_step(
+ x,
+ new_mv,
+ &bsi->ref_mv[0]->as_mv,
+ cm->allow_high_precision_mv,
+ x->errorperbit, &cpi->fn_ptr[bsize],
+ cpi->sf.mv.subpel_force_stop,
+ cpi->sf.mv.subpel_iters_per_step,
+ cond_sad_list(cpi, sad_list),
+ x->nmvjointcost, x->mvcost,
+ &distortion,
+ &x->pred_sse[mbmi->ref_frame[0]],
+ NULL, 0, 0);
// save motion search result for use in compound prediction
seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
@@ -1701,12 +1707,14 @@
int mode_index,
int64_t comp_pred_diff[REFERENCE_MODES],
const int64_t tx_size_diff[TX_MODES],
- int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
+ int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
+ int skippable) {
MACROBLOCKD *const xd = &x->e_mbd;
// Take a snapshot of the coding context so it can be
// restored if we decide to encode this way
ctx->skip = x->skip;
+ ctx->skippable = skippable;
ctx->best_mode_index = mode_index;
ctx->mic = *xd->mi[0];
ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
@@ -1772,6 +1780,7 @@
int tmp_col_max = x->mv_col_max;
int tmp_row_min = x->mv_row_min;
int tmp_row_max = x->mv_row_max;
+ int sad_list[5];
const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
ref);
@@ -1806,8 +1815,7 @@
step_param = cpi->mv_step_param;
}
- if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
- cm->show_frame) {
+ if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
b_width_log2(bsize)));
step_param = MAX(step_param, boffset);
@@ -1844,6 +1852,7 @@
mvp_full.row >>= 3;
bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
+ cond_sad_list(cpi, sad_list),
&ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
x->mv_col_min = tmp_col_min;
@@ -1859,13 +1868,14 @@
&cpi->fn_ptr[bsize],
cpi->sf.mv.subpel_force_stop,
cpi->sf.mv.subpel_iters_per_step,
+ cond_sad_list(cpi, sad_list),
x->nmvjointcost, x->mvcost,
&dis, &x->pred_sse[ref], NULL, 0, 0);
}
*rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
- if (cpi->sf.adaptive_motion_search && cm->show_frame)
+ if (cpi->sf.adaptive_motion_search)
x->pred_mv[ref] = tmp_mv->as_mv;
if (scaled_ref_frame) {
@@ -1983,6 +1993,7 @@
x->errorperbit,
&cpi->fn_ptr[bsize],
0, cpi->sf.mv.subpel_iters_per_step,
+ NULL,
x->nmvjointcost, x->mvcost,
&dis, &sse, second_pred,
pw, ph);
@@ -2118,6 +2129,8 @@
int_mv (*mode_mv)[MAX_REF_FRAMES],
int mi_row, int mi_col,
int_mv single_newmv[MAX_REF_FRAMES],
+ INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
+ int (*single_skippable)[MAX_REF_FRAMES],
int64_t *psse,
const int64_t ref_best_rd) {
VP9_COMMON *cm = &cpi->common;
@@ -2135,14 +2148,14 @@
DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
int pred_exists = 0;
int intpel_mv;
- int64_t rd, best_rd = INT64_MAX;
+ int64_t rd, tmp_rd, best_rd = INT64_MAX;
int best_needs_copy = 0;
uint8_t *orig_dst[MAX_MB_PLANE];
int orig_dst_stride[MAX_MB_PLANE];
int rs = 0;
INTERP_FILTER best_filter = SWITCHABLE;
- int skip_txfm[MAX_MB_PLANE] = {0};
- int64_t bsse[MAX_MB_PLANE] = {0};
+ uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
+ int64_t bsse[MAX_MB_PLANE << 2] = {0};
int bsl = mi_width_log2_lookup[bsize];
int pred_filter_search = cpi->sf.cb_pred_filter_search ?
@@ -2164,6 +2177,12 @@
if (frame_mv[refs[0]].as_int == INVALID_MV ||
frame_mv[refs[1]].as_int == INVALID_MV)
return INT64_MAX;
+
+ if (cpi->sf.adaptive_mode_search) {
+ if (single_filter[this_mode][refs[0]] ==
+ single_filter[this_mode][refs[1]])
+ best_filter = single_filter[this_mode][refs[0]];
+ }
}
if (this_mode == NEWMV) {
@@ -2225,6 +2244,10 @@
* if the first is known */
*rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
+ if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
+ mbmi->mode != NEARESTMV)
+ return INT64_MAX;
+
pred_exists = 0;
// Are all MVs integer pel for Y and UV
intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
@@ -2263,6 +2286,13 @@
} else {
int rate_sum = 0;
int64_t dist_sum = 0;
+ if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
+ (cpi->sf.interp_filter_search_mask & (1 << i))) {
+ rate_sum = INT_MAX;
+ dist_sum = INT64_MAX;
+ continue;
+ }
+
if ((cm->interp_filter == SWITCHABLE &&
(!i || best_needs_copy)) ||
(cm->interp_filter != SWITCHABLE &&
@@ -2313,6 +2343,7 @@
(cm->interp_filter != SWITCHABLE &&
cm->interp_filter == mbmi->interp_filter)) {
pred_exists = 1;
+ tmp_rd = best_rd;
}
}
restore_dst_buf(xd, orig_dst, orig_dst_stride);
@@ -2331,17 +2362,30 @@
xd->plane[i].dst.stride = 64;
}
}
+ rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
} else {
+ int tmp_rate;
+ int64_t tmp_dist;
// Handles the special case when a filter that is not in the
- // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
+ // switchable list (ex. bilinear) is indicated at the frame level, or
+ // skip condition holds.
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
+ model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
+ rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
+ vpx_memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
+ vpx_memcpy(bsse, x->bsse, sizeof(bsse));
}
+ if (!is_comp_pred)
+ single_filter[this_mode][refs[0]] = mbmi->interp_filter;
+
+ if (cpi->sf.adaptive_mode_search)
+ if (is_comp_pred)
+ if (single_skippable[this_mode][refs[0]] &&
+ single_skippable[this_mode][refs[1]])
+ vpx_memset(skip_txfm, 1, sizeof(skip_txfm));
+
if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
- int tmp_rate;
- int64_t tmp_dist;
- model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
- rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
// if current pred_error modeled rd is substantially more than the best
// so far, do not bother doing full rd
if (rd / 2 > ref_best_rd) {
@@ -2351,7 +2395,7 @@
}
if (cm->interp_filter == SWITCHABLE)
- *rate2 += vp9_get_switchable_rate(cpi);
+ *rate2 += rs;
if (!is_comp_pred) {
if (cpi->allow_encode_breakout)
@@ -2368,8 +2412,9 @@
int64_t rdcosty = INT64_MAX;
// Y cost and distortion
- inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
- bsize, txfm_cache, ref_best_rd);
+ vp9_subtract_plane(x, bsize, 0);
+ super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
+ bsize, txfm_cache, ref_best_rd);
if (*rate_y == INT_MAX) {
*rate2 = INT_MAX;
@@ -2399,6 +2444,9 @@
*skippable = skippable_y && skippable_uv;
}
+ if (!is_comp_pred)
+ single_skippable[this_mode][refs[0]] = *skippable;
+
restore_dst_buf(xd, orig_dst, orig_dst_stride);
return this_rd; // if 0, this will be re-calculated by caller
}
@@ -2505,10 +2553,12 @@
PREDICTION_MODE this_mode;
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
unsigned char segment_id = mbmi->segment_id;
- int comp_pred, i;
+ int comp_pred, i, k;
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
struct buf_2d yv12_mb[4][MAX_MB_PLANE];
int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
+ INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
+ int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
VP9_ALT_FLAG };
int64_t best_rd = best_rd_so_far;
@@ -2519,6 +2569,7 @@
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode;
+ int best_mode_skippable = 0;
int mode_index, best_mode_index = -1;
unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
vp9_prob comp_mode_p;
@@ -2556,6 +2607,12 @@
rate_uv_intra[i] = INT_MAX;
for (i = 0; i < MAX_REF_FRAMES; ++i)
x->pred_sse[i] = INT_MAX;
+ for (i = 0; i < MB_MODE_COUNT; ++i) {
+ for (k = 0; k < MAX_REF_FRAMES; ++k) {
+ single_inter_filter[i][k] = SWITCHABLE;
+ single_skippable[i][k] = 0;
+ }
+ }
*returnrate = INT_MAX;
@@ -2732,6 +2789,9 @@
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
+ if (!cm->allow_comp_inter_inter)
+ continue;
+
if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
best_mode_index >=0 &&
vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
@@ -2747,6 +2807,10 @@
}
if (ref_frame == INTRA_FRAME) {
+ if (cpi->sf.adaptive_mode_search)
+ if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_intra_rd)
+ continue;
+
if (!(intra_y_mode_mask & (1 << this_mode)))
continue;
if (this_mode != DC_PRED) {
@@ -2785,6 +2849,8 @@
// them for this frame.
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
: cm->interp_filter;
+ mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
+
x->skip = 0;
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
@@ -2800,8 +2866,8 @@
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
- intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
- bsize, tx_cache, best_rd);
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ NULL, bsize, tx_cache, best_rd);
if (rate_y == INT_MAX)
continue;
@@ -2831,7 +2897,8 @@
&rate_uv, &distortion_uv,
&disable_skip, frame_mv,
mi_row, mi_col,
- single_newmv, &total_sse, best_rd);
+ single_newmv, single_inter_filter,
+ single_skippable, &total_sse, best_rd);
if (this_rd == INT64_MAX)
continue;
@@ -2919,6 +2986,8 @@
/* required for left and above block mv */
mbmi->mv[0].as_int = 0;
max_plane = 1;
+ } else {
+ best_intra_rd = x->pred_sse[ref_frame];
}
*returnrate = rate2;
@@ -2926,6 +2995,8 @@
best_rd = this_rd;
best_mbmode = *mbmi;
best_skip2 = this_skip2;
+ best_mode_skippable = skippable;
+
if (!x->select_tx_size)
swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
@@ -3025,6 +3096,28 @@
break;
}
+ // The inter modes' rate costs are not calculated precisely in some cases.
+ // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
+ // ZEROMV. Here, checks are added for those cases, and the mode decisions
+ // are corrected.
+ if (best_mbmode.mode == NEWMV) {
+ const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
+ best_mbmode.ref_frame[1]};
+ int comp_pred_mode = refs[1] > INTRA_FRAME;
+
+ if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
+ ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
+ best_mbmode.mv[1].as_int) || !comp_pred_mode))
+ best_mbmode.mode = NEARESTMV;
+ else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
+ ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
+ best_mbmode.mv[1].as_int) || !comp_pred_mode))
+ best_mbmode.mode = NEARMV;
+ else if (best_mbmode.mv[0].as_int == 0 &&
+ ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
+ best_mbmode.mode = ZEROMV;
+ }
+
if (best_mode_index < 0 || best_rd >= best_rd_so_far)
return INT64_MAX;
@@ -3082,8 +3175,8 @@
}
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
- store_coding_context(x, ctx, best_mode_index,
- best_pred_diff, best_tx_diff, best_filter_diff);
+ store_coding_context(x, ctx, best_mode_index, best_pred_diff,
+ best_tx_diff, best_filter_diff, best_mode_skippable);
return best_rd;
}
@@ -3188,7 +3281,7 @@
if (!x->select_tx_size)
swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
store_coding_context(x, ctx, THR_ZEROMV,
- best_pred_diff, best_tx_diff, best_filter_diff);
+ best_pred_diff, best_tx_diff, best_filter_diff, 0);
return this_rd;
}
@@ -3325,6 +3418,9 @@
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
+ if (!cm->allow_comp_inter_inter)
+ continue;
+
if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
continue;
// Do not allow compound prediction if the segment level reference frame
@@ -3793,7 +3889,7 @@
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
store_coding_context(x, ctx, best_ref_index,
- best_pred_diff, best_tx_diff, best_filter_diff);
+ best_pred_diff, best_tx_diff, best_filter_diff, 0);
return best_rd;
}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rd.c ('k') | source/libvpx/vp9/encoder/vp9_speed_features.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698