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

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

Issue 232133009: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 8 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_rdopt.h ('k') | source/libvpx/vp9/encoder/vp9_sad.c » ('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 263011)
+++ source/libvpx/vp9/encoder/vp9_rdopt.c (working copy)
@@ -30,6 +30,7 @@
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_systemdependent.h"
+#include "vp9/encoder/vp9_cost.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
#include "vp9/encoder/vp9_mcomp.h"
@@ -38,9 +39,13 @@
#include "vp9/encoder/vp9_ratectrl.h"
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_tokenize.h"
-#include "vp9/encoder/vp9_treewriter.h"
#include "vp9/encoder/vp9_variance.h"
+#define RD_THRESH_MAX_FACT 64
+#define RD_THRESH_INC 1
+#define RD_THRESH_POW 1.25
+#define RD_MULT_EPB_RATIO 64
+
/* Factor to weigh the rate for switchable interp filters */
#define SWITCHABLE_INTERP_RATE_FACTOR 1
@@ -72,6 +77,7 @@
int64_t this_rd;
int64_t best_rd;
int skip;
+ int use_fast_coef_costing;
const scan_order *so;
};
@@ -145,9 +151,8 @@
}
static void fill_mode_costs(VP9_COMP *cpi) {
- VP9_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->mb;
- FRAME_CONTEXT *const fc = &cm->fc;
+ const FRAME_CONTEXT *const fc = &cpi->common.fc;
int i, j;
for (i = 0; i < INTRA_MODES; i++)
@@ -157,15 +162,14 @@
// TODO(rbultje) separate tables for superblock costing?
vp9_cost_tokens(x->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
- vp9_cost_tokens(x->intra_uv_mode_cost[1],
- fc->uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree);
- vp9_cost_tokens(x->intra_uv_mode_cost[0],
- vp9_kf_uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree);
+ vp9_cost_tokens(x->intra_uv_mode_cost[KEY_FRAME],
+ vp9_kf_uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
+ vp9_cost_tokens(x->intra_uv_mode_cost[INTER_FRAME],
+ fc->uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
vp9_cost_tokens((int *)x->switchable_interp_costs[i],
- fc->switchable_interp_prob[i],
- vp9_switchable_interp_tree);
+ fc->switchable_interp_prob[i], vp9_switchable_interp_tree);
}
static void fill_token_costs(vp9_coeff_cost *c,
@@ -214,7 +218,7 @@
}
}
-int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex) {
+int vp9_compute_rd_mult(const VP9_COMP *cpi, int qindex) {
const int q = vp9_dc_quant(qindex, 0);
// TODO(debargha): Adjust the function below
int rdmult = 88 * q * q / 25;
@@ -228,12 +232,9 @@
}
static int compute_rd_thresh_factor(int qindex) {
- int q;
// TODO(debargha): Adjust the function below
- q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12);
- if (q < 8)
- q = 8;
- return q;
+ const int q = (int)(pow(vp9_dc_quant(qindex, 0) / 4.0, RD_THRESH_POW) * 5.12);
+ return MAX(q, 8);
}
void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) {
@@ -242,9 +243,8 @@
}
static void set_block_thresholds(VP9_COMP *cpi) {
+ const VP9_COMMON *const cm = &cpi->common;
int i, bsize, segment_id;
- VP9_COMMON *cm = &cpi->common;
- SPEED_FEATURES *sf = &cpi->sf;
for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) {
const int qindex = clamp(vp9_get_qindex(&cm->seg, segment_id,
@@ -260,13 +260,13 @@
for (i = 0; i < MAX_MODES; ++i)
cpi->rd_threshes[segment_id][bsize][i] =
- sf->thresh_mult[i] < thresh_max ? sf->thresh_mult[i] * t / 4
+ cpi->rd_thresh_mult[i] < thresh_max ? cpi->rd_thresh_mult[i] * t / 4
: INT_MAX;
for (i = 0; i < MAX_REFS; ++i) {
cpi->rd_thresh_sub8x8[segment_id][bsize][i] =
- sf->thresh_mult_sub8x8[i] < thresh_max
- ? sf->thresh_mult_sub8x8[i] * t / 4
+ cpi->rd_thresh_mult_sub8x8[i] < thresh_max
+ ? cpi->rd_thresh_mult_sub8x8[i] * t / 4
: INT_MAX;
}
}
@@ -274,8 +274,8 @@
}
void vp9_initialize_rd_consts(VP9_COMP *cpi) {
- VP9_COMMON *cm = &cpi->common;
- MACROBLOCK *x = &cpi->mb;
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCK *const x = &cpi->mb;
int i;
vp9_clear_system_state();
@@ -286,14 +286,12 @@
x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
x->errorperbit += (x->errorperbit == 0);
- vp9_set_speed_features(cpi);
-
x->select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
cm->frame_type != KEY_FRAME) ? 0 : 1;
set_block_thresholds(cpi);
- if (!cpi->sf.use_nonrd_pick_mode) {
+ if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME) {
fill_token_costs(x->token_costs, cm->fc.coef_probs);
for (i = 0; i < PARTITION_CONTEXTS; i++)
@@ -301,7 +299,8 @@
vp9_partition_tree);
}
- if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1) {
+ if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 ||
+ cm->frame_type == KEY_FRAME) {
fill_mode_costs(cpi);
if (!frame_is_intra_only(cm)) {
@@ -400,9 +399,9 @@
*d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10;
}
-static void model_rd_from_var_lapndz(unsigned int var, unsigned int n,
- unsigned int qstep, int *rate,
- int64_t *dist) {
+void vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n,
+ unsigned int qstep, int *rate,
+ int64_t *dist) {
// This function models the rate and distortion for a Laplacian
// source with given variance when quantized with a uniform quantizer
// with given stepsize. The closed form expressions are in:
@@ -433,7 +432,7 @@
int i;
int64_t rate_sum = 0;
int64_t dist_sum = 0;
- int ref = xd->mi_8x8[0]->mbmi.ref_frame[0];
+ const int ref = xd->mi[0]->mbmi.ref_frame[0];
unsigned int sse;
for (i = 0; i < MAX_MB_PLANE; ++i) {
@@ -464,8 +463,8 @@
} else {
int rate;
int64_t dist;
- model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
- pd->dequant[1] >> 3, &rate, &dist);
+ vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
+ pd->dequant[1] >> 3, &rate, &dist);
rate_sum += rate;
dist_sum += dist;
}
@@ -482,8 +481,8 @@
int *out_skip) {
int j, k;
BLOCK_SIZE bs;
- struct macroblock_plane *const p = &x->plane[0];
- struct macroblockd_plane *const pd = &xd->plane[0];
+ const struct macroblock_plane *const p = &x->plane[0];
+ const struct macroblockd_plane *const pd = &xd->plane[0];
const int width = 4 * num_4x4_blocks_wide_lookup[bsize];
const int height = 4 * num_4x4_blocks_high_lookup[bsize];
int rate_sum = 0;
@@ -512,7 +511,8 @@
&pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride,
&sse);
// sse works better than var, since there is no dc prediction used
- model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3, &rate, &dist);
+ vp9_model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3,
+ &rate, &dist);
rate_sum += rate;
dist_sum += dist;
*out_skip &= (rate < 1024);
@@ -549,26 +549,25 @@
{ 1, 2, 3, 4, 11, 256 - 21, 0 },
{ 1, 2, 3, 4, 11, 1024 - 21, 0 },
};
-
static INLINE int cost_coeffs(MACROBLOCK *x,
int plane, int block,
ENTROPY_CONTEXT *A, ENTROPY_CONTEXT *L,
TX_SIZE tx_size,
- const int16_t *scan, const int16_t *nb) {
+ const int16_t *scan, const int16_t *nb,
+ int use_fast_coef_costing) {
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
- struct macroblock_plane *p = &x->plane[plane];
- struct macroblockd_plane *pd = &xd->plane[plane];
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+ const struct macroblock_plane *p = &x->plane[plane];
+ const struct macroblockd_plane *pd = &xd->plane[plane];
const PLANE_TYPE type = pd->plane_type;
const int16_t *band_count = &band_counts[tx_size][1];
const int eob = p->eobs[block];
const int16_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
unsigned int (*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
x->token_costs[tx_size][type][is_inter_block(mbmi)];
- uint8_t *p_tok = x->token_cache;
+ uint8_t token_cache[32 * 32];
int pt = combine_entropy_contexts(*A, *L);
int c, cost;
-
// Check for consistency of tx_size with mode info
assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size
: get_uv_tx_size(mbmi) == tx_size);
@@ -584,7 +583,7 @@
int v = qcoeff[0];
int prev_t = vp9_dct_value_tokens_ptr[v].token;
cost = (*token_costs)[0][pt][prev_t] + vp9_dct_value_cost_ptr[v];
- p_tok[0] = vp9_pt_energy_class[prev_t];
+ token_cache[0] = vp9_pt_energy_class[prev_t];
++token_costs;
// ac tokens
@@ -594,9 +593,13 @@
v = qcoeff[rc];
t = vp9_dct_value_tokens_ptr[v].token;
- pt = get_coef_context(nb, p_tok, c);
- cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
- p_tok[rc] = vp9_pt_energy_class[t];
+ if (use_fast_coef_costing) {
+ cost += (*token_costs)[!prev_t][!prev_t][t] + vp9_dct_value_cost_ptr[v];
+ } else {
+ pt = get_coef_context(nb, token_cache, c);
+ cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v];
+ token_cache[rc] = vp9_pt_energy_class[t];
+ }
prev_t = t;
if (!--band_left) {
band_left = *band_count++;
@@ -606,8 +609,12 @@
// eob token
if (band_left) {
- pt = get_coef_context(nb, p_tok, c);
- cost += (*token_costs)[0][pt][EOB_TOKEN];
+ if (use_fast_coef_costing) {
+ cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
+ } else {
+ pt = get_coef_context(nb, token_cache, c);
+ cost += (*token_costs)[0][pt][EOB_TOKEN];
+ }
}
}
@@ -616,14 +623,13 @@
return cost;
}
-
static void dist_block(int plane, int block, TX_SIZE tx_size,
struct rdcost_block_args* args) {
const int ss_txfrm_size = tx_size << 1;
MACROBLOCK* const x = args->x;
MACROBLOCKD* const xd = &x->e_mbd;
- struct macroblock_plane *const p = &x->plane[plane];
- struct macroblockd_plane *const pd = &xd->plane[plane];
+ const struct macroblock_plane *const p = &x->plane[plane];
+ const struct macroblockd_plane *const pd = &xd->plane[plane];
int64_t this_sse;
int shift = tx_size == TX_32X32 ? 0 : 2;
int16_t *const coeff = BLOCK_OFFSET(p->coeff, block);
@@ -632,7 +638,7 @@
&this_sse) >> shift;
args->sse = this_sse >> shift;
- if (x->skip_encode && !is_inter_block(&xd->mi_8x8[0]->mbmi)) {
+ if (x->skip_encode && !is_inter_block(&xd->mi[0]->mbmi)) {
// TODO(jingning): tune the model to better capture the distortion.
int64_t p = (pd->dequant[1] * pd->dequant[1] *
(1 << ss_txfrm_size)) >> (shift + 2);
@@ -648,7 +654,8 @@
args->rate = cost_coeffs(args->x, plane, block, args->t_above + x_idx,
args->t_left + y_idx, tx_size,
- args->so->scan, args->so->neighbors);
+ args->so->scan, args->so->neighbors,
+ args->use_fast_coef_costing);
}
static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
@@ -656,7 +663,7 @@
struct rdcost_block_args *args = arg;
MACROBLOCK *const x = args->x;
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
int64_t rd1, rd2, rd;
if (args->skip)
@@ -732,15 +739,17 @@
int *rate, int64_t *distortion,
int *skippable, int64_t *sse,
int64_t ref_best_rd, int plane,
- BLOCK_SIZE bsize, TX_SIZE tx_size) {
+ BLOCK_SIZE bsize, TX_SIZE tx_size,
+ int use_fast_coef_casting) {
MACROBLOCKD *const xd = &x->e_mbd;
- struct macroblockd_plane *const pd = &xd->plane[plane];
+ const struct macroblockd_plane *const pd = &xd->plane[plane];
struct rdcost_block_args args = { 0 };
args.x = x;
args.best_rd = ref_best_rd;
+ args.use_fast_coef_costing = use_fast_coef_casting;
if (plane == 0)
- xd->mi_8x8[0]->mbmi.tx_size = tx_size;
+ xd->mi[0]->mbmi.tx_size = tx_size;
vp9_get_entropy_contexts(bsize, tx_size, pd, args.t_above, args.t_left);
@@ -770,13 +779,13 @@
VP9_COMMON *const cm = &cpi->common;
const TX_SIZE largest_tx_size = tx_mode_to_biggest_tx_size[cm->tx_mode];
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
txfm_rd_in_plane(x, rate, distortion, skip,
&sse[mbmi->tx_size], ref_best_rd, 0, bs,
- mbmi->tx_size);
+ mbmi->tx_size, cpi->sf.use_fast_coef_costing);
cpi->tx_stepdown_count[0]++;
}
@@ -789,7 +798,7 @@
const TX_SIZE max_tx_size = max_txsize_lookup[bs];
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
{INT64_MAX, INT64_MAX},
@@ -872,7 +881,7 @@
const TX_SIZE max_tx_size = max_txsize_lookup[bs];
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
{INT64_MAX, INT64_MAX},
@@ -920,7 +929,8 @@
// Actually encode using the chosen mode if a model was used, but do not
// update the r, d costs
txfm_rd_in_plane(x, rate, distortion, skip,
- &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size);
+ &sse[mbmi->tx_size], ref_best_rd, 0, bs, mbmi->tx_size,
+ cpi->sf.use_fast_coef_costing);
if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
cpi->tx_stepdown_count[0]++;
@@ -941,7 +951,7 @@
int r[TX_SIZES][2], s[TX_SIZES];
int64_t d[TX_SIZES], sse[TX_SIZES];
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const TX_SIZE max_tx_size = max_txsize_lookup[bs];
TX_SIZE tx_size;
@@ -968,7 +978,8 @@
for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
&s[tx_size], &sse[tx_size],
- ref_best_rd, 0, bs, tx_size);
+ ref_best_rd, 0, bs, tx_size,
+ cpi->sf.use_fast_coef_costing);
choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
skip, txfm_cache, bs);
}
@@ -983,7 +994,7 @@
int64_t ref_best_rd) {
int64_t sse[TX_SIZES];
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
assert(bs == mbmi->sb_type);
if (cpi->sf.tx_size_search_method != USE_FULL_RD) {
@@ -997,7 +1008,8 @@
for (tx_size = TX_4X4; tx_size <= max_txsize_lookup[bs]; ++tx_size)
txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
&s[tx_size], &sse[tx_size],
- ref_best_rd, 0, bs, tx_size);
+ ref_best_rd, 0, bs, tx_size,
+ cpi->sf.use_fast_coef_costing);
choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
skip, txfm_cache, bs);
}
@@ -1029,7 +1041,7 @@
static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
MB_PREDICTION_MODE *best_mode,
- int *bmode_costs,
+ const int *bmode_costs,
ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
int *bestrate, int *bestratey,
int64_t *bestdistortion,
@@ -1058,7 +1070,7 @@
vpx_memcpy(ta, a, sizeof(ta));
vpx_memcpy(tl, l, sizeof(tl));
- xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
+ xd->mi[0]->mbmi.tx_size = TX_4X4;
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
int64_t this_rd;
@@ -1087,7 +1099,7 @@
int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block,
p->src_diff);
int16_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block);
- xd->mi_8x8[0]->bmi[block].as_mode = mode;
+ xd->mi[0]->bmi[block].as_mode = mode;
vp9_predict_intra_block(xd, block, 1,
TX_4X4, mode,
x->skip_encode ? src : dst,
@@ -1100,7 +1112,8 @@
vp9_fwht4x4(src_diff, coeff, 8);
vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
- so->scan, so->neighbors);
+ so->scan, so->neighbors,
+ cpi->sf.use_fast_coef_costing);
if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
goto next;
vp9_iwht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block), dst, dst_stride,
@@ -1112,7 +1125,8 @@
vp9_fht4x4(src_diff, coeff, 8, tx_type);
vp9_regular_quantize_b_4x4(x, 0, block, so->scan, so->iscan);
ratey += cost_coeffs(x, 0, block, tempa + idx, templ + idy, TX_4X4,
- so->scan, so->neighbors);
+ so->scan, so->neighbors,
+ cpi->sf.use_fast_coef_costing);
distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff, block),
16, &unused) >> 2;
if (RDCOST(x->rdmult, x->rddiv, ratey, distortion) >= best_rd)
@@ -1152,18 +1166,16 @@
return best_rd;
}
-static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP * const cpi,
- MACROBLOCK * const mb,
- int * const rate,
- int * const rate_y,
- int64_t * const distortion,
+static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
+ int *rate, int *rate_y,
+ int64_t *distortion,
int64_t best_rd) {
int i, j;
- MACROBLOCKD *const xd = &mb->e_mbd;
- MODE_INFO *const mic = xd->mi_8x8[0];
- const MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride];
- const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
- const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
+ const MACROBLOCKD *const xd = &mb->e_mbd;
+ MODE_INFO *const mic = xd->mi[0];
+ const MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
+ const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
+ const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize];
int idx, idy;
@@ -1172,13 +1184,11 @@
int tot_rate_y = 0;
int64_t total_rd = 0;
ENTROPY_CONTEXT t_above[4], t_left[4];
- int *bmode_costs;
+ const int *bmode_costs = mb->mbmode_cost;
vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
- bmode_costs = mb->mbmode_cost;
-
// Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
@@ -1232,7 +1242,7 @@
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE mode_selected = DC_PRED;
MACROBLOCKD *const xd = &x->e_mbd;
- MODE_INFO *const mic = xd->mi_8x8[0];
+ MODE_INFO *const mic = xd->mi[0];
int this_rate, this_rate_tokenonly, s;
int64_t this_distortion, this_rd;
TX_SIZE best_tx = TX_4X4;
@@ -1246,8 +1256,8 @@
/* Y Search for intra prediction mode */
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
int64_t local_tx_cache[TX_MODES];
- MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride];
- MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
+ MODE_INFO *above_mi = xd->mi[-xd->mi_stride];
+ MODE_INFO *left_mi = xd->left_available ? xd->mi[-1] : NULL;
if (!(cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]] & (1 << mode)))
continue;
@@ -1296,12 +1306,12 @@
return best_rd;
}
-static void super_block_uvrd(MACROBLOCK *x,
+static void super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
int *rate, int64_t *distortion, int *skippable,
int64_t *sse, BLOCK_SIZE bsize,
int64_t ref_best_rd) {
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi);
int plane;
int pnrate = 0, pnskip = 1;
@@ -1323,7 +1333,8 @@
for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse,
- ref_best_rd, plane, bsize, uv_txfm_size);
+ ref_best_rd, plane, bsize, uv_txfm_size,
+ cpi->sf.use_fast_coef_costing);
if (pnrate == INT_MAX)
goto term;
*rate += pnrate;
@@ -1357,9 +1368,9 @@
if (!(cpi->sf.intra_uv_mode_mask[max_tx_size] & (1 << mode)))
continue;
- xd->mi_8x8[0]->mbmi.uv_mode = mode;
+ xd->mi[0]->mbmi.uv_mode = mode;
- super_block_uvrd(x, &this_rate_tokenonly,
+ super_block_uvrd(cpi, x, &this_rate_tokenonly,
&this_distortion, &s, &this_sse, bsize, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -1398,18 +1409,19 @@
}
}
- xd->mi_8x8[0]->mbmi.uv_mode = mode_selected;
+ xd->mi[0]->mbmi.uv_mode = mode_selected;
return best_rd;
}
-static int64_t rd_sbuv_dcpred(const VP9_COMMON *cm, MACROBLOCK *x,
+static int64_t rd_sbuv_dcpred(const VP9_COMP *cpi, MACROBLOCK *x,
int *rate, int *rate_tokenonly,
int64_t *distortion, int *skippable,
BLOCK_SIZE bsize) {
+ const VP9_COMMON *cm = &cpi->common;
int64_t unused;
- x->e_mbd.mi_8x8[0]->mbmi.uv_mode = DC_PRED;
- super_block_uvrd(x, rate_tokenonly, distortion,
+ x->e_mbd.mi[0]->mbmi.uv_mode = DC_PRED;
+ super_block_uvrd(cpi, x, rate_tokenonly, distortion,
skippable, &unused, bsize, INT64_MAX);
*rate = *rate_tokenonly + x->intra_uv_mode_cost[cm->frame_type][DC_PRED];
return RDCOST(x->rdmult, x->rddiv, *rate, *distortion);
@@ -1425,7 +1437,7 @@
// Use an estimated rd for uv_intra based on DC_PRED if the
// appropriate speed flag is set.
if (cpi->sf.use_uv_intra_rd_estimate) {
- rd_sbuv_dcpred(&cpi->common, x, rate_uv, rate_uv_tokenonly, dist_uv,
+ rd_sbuv_dcpred(cpi, x, rate_uv, rate_uv_tokenonly, dist_uv,
skip_uv, bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize);
// Else do a proper rd search for each possible transform size that may
// be considered in the main rd loop.
@@ -1434,13 +1446,13 @@
rate_uv, rate_uv_tokenonly, dist_uv, skip_uv,
bsize < BLOCK_8X8 ? BLOCK_8X8 : bsize, max_tx_size);
}
- *mode_uv = x->e_mbd.mi_8x8[0]->mbmi.uv_mode;
+ *mode_uv = x->e_mbd.mi[0]->mbmi.uv_mode;
}
-static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode,
+static int cost_mv_ref(const VP9_COMP *cpi, MB_PREDICTION_MODE mode,
int mode_context) {
- MACROBLOCK *const x = &cpi->mb;
- const int segment_id = x->e_mbd.mi_8x8[0]->mbmi.segment_id;
+ const MACROBLOCK *const x = &cpi->mb;
+ const int segment_id = x->e_mbd.mi[0]->mbmi.segment_id;
// Don't account for mode here if segment skip is enabled.
if (!vp9_segfeature_active(&cpi->common.seg, segment_id, SEG_LVL_SKIP)) {
@@ -1451,12 +1463,6 @@
}
}
-void vp9_set_mbmode_and_mvs(MACROBLOCKD *xd, MB_PREDICTION_MODE mode,
- const MV *mv) {
- xd->mi_8x8[0]->mbmi.mode = mode;
- xd->mi_8x8[0]->mbmi.mv[0].as_mv = *mv;
-}
-
static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize,
int_mv *frame_mv,
@@ -1464,59 +1470,56 @@
int_mv single_newmv[MAX_REF_FRAMES],
int *rate_mv);
-static int labels2mode(MACROBLOCK *x, int i,
+static int labels2mode(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
MB_PREDICTION_MODE mode,
- int_mv *this_mv, int_mv *this_second_mv,
+ int_mv this_mv[2],
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
int_mv seg_mvs[MAX_REF_FRAMES],
- int_mv *best_ref_mv,
- int_mv *second_best_ref_mv,
- int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
- MACROBLOCKD *const xd = &x->e_mbd;
- MODE_INFO *const mic = xd->mi_8x8[0];
- MB_MODE_INFO *mbmi = &mic->mbmi;
+ int_mv *best_ref_mv[2],
+ const int *mvjcost, int *mvcost[2]) {
+ MODE_INFO *const mic = xd->mi[0];
+ const MB_MODE_INFO *const mbmi = &mic->mbmi;
int thismvcost = 0;
int idx, idy;
const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
- const int has_second_rf = has_second_ref(mbmi);
+ const int is_compound = has_second_ref(mbmi);
// the only time we should do costing for new motion vector or mode
// is when we are on a new label (jbb May 08, 2007)
switch (mode) {
case NEWMV:
- this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
- thismvcost += vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv,
+ this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
+ thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
mvjcost, mvcost, MV_COST_WEIGHT_SUB);
- if (has_second_rf) {
- this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
- thismvcost += vp9_mv_bit_cost(&this_second_mv->as_mv,
- &second_best_ref_mv->as_mv,
+ if (is_compound) {
+ this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
+ thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
mvjcost, mvcost, MV_COST_WEIGHT_SUB);
}
break;
case NEARESTMV:
- this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
- if (has_second_rf)
- this_second_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
+ this_mv[0].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
+ if (is_compound)
+ this_mv[1].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
break;
case NEARMV:
- this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
- if (has_second_rf)
- this_second_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
+ this_mv[0].as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
+ if (is_compound)
+ this_mv[1].as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
break;
case ZEROMV:
- this_mv->as_int = 0;
- if (has_second_rf)
- this_second_mv->as_int = 0;
+ this_mv[0].as_int = 0;
+ if (is_compound)
+ this_mv[1].as_int = 0;
break;
default:
break;
}
- mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
- if (has_second_rf)
- mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
+ mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
+ if (is_compound)
+ mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
mic->bmi[i].as_mode = mode;
@@ -1542,7 +1545,7 @@
MACROBLOCKD *xd = &x->e_mbd;
struct macroblockd_plane *const pd = &xd->plane[0];
struct macroblock_plane *const p = &x->plane[0];
- MODE_INFO *const mi = xd->mi_8x8[0];
+ MODE_INFO *const mi = xd->mi[0];
const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
const int width = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize];
@@ -1556,6 +1559,8 @@
int thisrate = 0, ref;
const scan_order *so = &vp9_default_scan_orders[TX_4X4];
const int is_compound = has_second_ref(&mi->mbmi);
+ const InterpKernel *kernel = vp9_get_interp_kernel(mi->mbmi.interp_filter);
+
for (ref = 0; ref < 1 + is_compound; ++ref) {
const uint8_t *pre = &pd->pre[ref].buf[raster_block_offset(BLOCK_8X8, i,
pd->pre[ref].stride)];
@@ -1563,7 +1568,7 @@
dst, pd->dst.stride,
&mi->bmi[i].as_mv[ref].as_mv,
&xd->block_refs[ref]->sf, width, height, ref,
- xd->interp_kernel, MV_PRECISION_Q3,
+ kernel, MV_PRECISION_Q3,
mi_col * MI_SIZE + 4 * (i % 2),
mi_row * MI_SIZE + 4 * (i / 2));
}
@@ -1588,7 +1593,8 @@
16, &ssz);
thissse += ssz;
thisrate += cost_coeffs(x, 0, k, ta + (k & 1), tl + (k >> 1), TX_4X4,
- so->scan, so->neighbors);
+ so->scan, so->neighbors,
+ cpi->sf.use_fast_coef_costing);
rd1 = RDCOST(x->rdmult, x->rddiv, thisrate, thisdistortion >> 2);
rd2 = RDCOST(x->rdmult, x->rddiv, 0, thissse >> 2);
rd = MIN(rd1, rd2);
@@ -1638,7 +1644,7 @@
}
static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
- MB_MODE_INFO *const mbmi = &x->e_mbd.mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &x->e_mbd.mi[0]->mbmi;
struct macroblock_plane *const p = &x->plane[0];
struct macroblockd_plane *const pd = &x->e_mbd.plane[0];
@@ -1653,7 +1659,7 @@
static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
struct buf_2d orig_pre[2]) {
- MB_MODE_INFO *mbmi = &x->e_mbd.mi_8x8[0]->mbmi;
+ MB_MODE_INFO *mbmi = &x->e_mbd.mi[0]->mbmi;
x->plane[0].src = orig_src;
x->e_mbd.plane[0].pre[0] = orig_pre[0];
if (has_second_ref(mbmi))
@@ -1664,6 +1670,45 @@
return (mv->row & 0x0F) || (mv->col & 0x0F);
}
+// Check if NEARESTMV/NEARMV/ZEROMV is the cheapest way encode zero motion.
+// TODO(aconverse): Find out if this is still productive then clean up or remove
+static int check_best_zero_mv(
+ const VP9_COMP *cpi, const uint8_t mode_context[MAX_REF_FRAMES],
+ int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
+ int disable_inter_mode_mask, int this_mode, int ref_frame,
+ int second_ref_frame) {
+ if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
+ (this_mode == NEARMV || this_mode == NEARESTMV || this_mode == ZEROMV) &&
+ frame_mv[this_mode][ref_frame].as_int == 0 &&
+ (second_ref_frame == NONE ||
+ frame_mv[this_mode][second_ref_frame].as_int == 0)) {
+ int rfc = mode_context[ref_frame];
+ int c1 = cost_mv_ref(cpi, NEARMV, rfc);
+ int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
+ int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
+
+ if (this_mode == NEARMV) {
+ if (c1 > c3) return 0;
+ } else if (this_mode == NEARESTMV) {
+ if (c2 > c3) return 0;
+ } else {
+ assert(this_mode == ZEROMV);
+ if (second_ref_frame == NONE) {
+ if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0) ||
+ (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0))
+ return 0;
+ } else {
+ if ((c3 >= c2 && frame_mv[NEARESTMV][ref_frame].as_int == 0 &&
+ frame_mv[NEARESTMV][second_ref_frame].as_int == 0) ||
+ (c3 >= c1 && frame_mv[NEARMV][ref_frame].as_int == 0 &&
+ frame_mv[NEARMV][second_ref_frame].as_int == 0))
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
const TileInfo *const tile,
BEST_SEG_INFO *bsi_buf, int filter_idx,
@@ -1674,7 +1719,7 @@
MB_PREDICTION_MODE this_mode;
MACROBLOCKD *xd = &x->e_mbd;
VP9_COMMON *cm = &cpi->common;
- MODE_INFO *mi = xd->mi_8x8[0];
+ MODE_INFO *mi = xd->mi[0];
MB_MODE_INFO *const mbmi = &mi->mbmi;
struct macroblock_plane *const p = &x->plane[0];
struct macroblockd_plane *const pd = &xd->plane[0];
@@ -1691,6 +1736,7 @@
int mode_idx;
int subpelmv = 1, have_ref = 0;
const int has_second_rf = has_second_ref(mbmi);
+ const int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
vpx_memcpy(t_above, pd->above_context, sizeof(t_above));
vpx_memcpy(t_left, pd->left_context, sizeof(t_left));
@@ -1706,7 +1752,7 @@
for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
// TODO(jingning,rbultje): rewrite the rate-distortion optimization
// loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
- int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT];
+ int_mv mode_mv[MB_MODE_COUNT][2];
int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
MB_PREDICTION_MODE mode_selected = ZEROMV;
int64_t best_rd = INT64_MAX;
@@ -1728,46 +1774,15 @@
mode_idx = INTER_OFFSET(this_mode);
bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
- if (cpi->sf.disable_inter_mode_mask[bsize] & (1 << mode_idx))
+ if (disable_inter_mode_mask & (1 << mode_idx))
continue;
- // if we're near/nearest and mv == 0,0, compare to zeromv
- if ((this_mode == NEARMV || this_mode == NEARESTMV ||
- this_mode == ZEROMV) &&
- frame_mv[this_mode][mbmi->ref_frame[0]].as_int == 0 &&
- (!has_second_rf ||
- frame_mv[this_mode][mbmi->ref_frame[1]].as_int == 0)) {
- int rfc = mbmi->mode_context[mbmi->ref_frame[0]];
- int c1 = cost_mv_ref(cpi, NEARMV, rfc);
- int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
- int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
+ if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
+ disable_inter_mode_mask,
+ this_mode, mbmi->ref_frame[0],
+ mbmi->ref_frame[1]))
+ continue;
- if (this_mode == NEARMV) {
- if (c1 > c3)
- continue;
- } else if (this_mode == NEARESTMV) {
- if (c2 > c3)
- continue;
- } else {
- assert(this_mode == ZEROMV);
- if (!has_second_rf) {
- if ((c3 >= c2 &&
- frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0) ||
- (c3 >= c1 &&
- frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0))
- continue;
- } else {
- if ((c3 >= c2 &&
- frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int == 0 &&
- frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int == 0) ||
- (c3 >= c1 &&
- frame_mv[NEARMV][mbmi->ref_frame[0]].as_int == 0 &&
- frame_mv[NEARMV][mbmi->ref_frame[1]].as_int == 0))
- continue;
- }
- }
- }
-
vpx_memcpy(orig_pre, pd->pre, sizeof(orig_pre));
vpx_memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
sizeof(bsi->rdstat[i][mode_idx].ta));
@@ -1777,7 +1792,7 @@
// motion search for newmv (single predictor case only)
if (!has_second_rf && this_mode == NEWMV &&
seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
- int_mv *const new_mv = &mode_mv[NEWMV];
+ int_mv *const new_mv = &mode_mv[NEWMV][0];
int step_param = 0;
int further_steps;
int thissme, bestsme = INT_MAX;
@@ -1835,18 +1850,30 @@
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv[0]->as_mv,
&new_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
+ &bsi->ref_mv[0]->as_mv,
+ v_fn_ptr, 1);
} else if (cpi->sf.search_method == SQUARE) {
bestsme = vp9_square_search(x, &mvp_full,
step_param,
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv[0]->as_mv,
&new_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
+ &bsi->ref_mv[0]->as_mv,
+ v_fn_ptr, 1);
} else if (cpi->sf.search_method == BIGDIA) {
bestsme = vp9_bigdia_search(x, &mvp_full,
step_param,
sadpb, 1, v_fn_ptr, 1,
&bsi->ref_mv[0]->as_mv,
&new_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
+ &bsi->ref_mv[0]->as_mv,
+ v_fn_ptr, 1);
} else {
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 0, v_fn_ptr,
@@ -1925,55 +1952,43 @@
}
bsi->rdstat[i][mode_idx].brate =
- labels2mode(x, i, this_mode, &mode_mv[this_mode],
- &second_mode_mv[this_mode], frame_mv, seg_mvs[i],
- bsi->ref_mv[0], bsi->ref_mv[1], x->nmvjointcost,
- x->mvcost, cpi);
+ labels2mode(cpi, xd, i, this_mode, mode_mv[this_mode], frame_mv,
+ seg_mvs[i], bsi->ref_mv, x->nmvjointcost, x->mvcost);
-
- bsi->rdstat[i][mode_idx].mvs[0].as_int = mode_mv[this_mode].as_int;
- if (num_4x4_blocks_wide > 1)
- bsi->rdstat[i + 1][mode_idx].mvs[0].as_int =
- mode_mv[this_mode].as_int;
- if (num_4x4_blocks_high > 1)
- bsi->rdstat[i + 2][mode_idx].mvs[0].as_int =
- mode_mv[this_mode].as_int;
- if (has_second_rf) {
- bsi->rdstat[i][mode_idx].mvs[1].as_int =
- second_mode_mv[this_mode].as_int;
+ for (ref = 0; ref < 1 + has_second_rf; ++ref) {
+ bsi->rdstat[i][mode_idx].mvs[ref].as_int =
+ mode_mv[this_mode][ref].as_int;
if (num_4x4_blocks_wide > 1)
- bsi->rdstat[i + 1][mode_idx].mvs[1].as_int =
- second_mode_mv[this_mode].as_int;
+ bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
+ mode_mv[this_mode][ref].as_int;
if (num_4x4_blocks_high > 1)
- bsi->rdstat[i + 2][mode_idx].mvs[1].as_int =
- second_mode_mv[this_mode].as_int;
+ bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
+ mode_mv[this_mode][ref].as_int;
}
// Trap vectors that reach beyond the UMV borders
- if (mv_check_bounds(x, &mode_mv[this_mode].as_mv) ||
+ if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
(has_second_rf &&
- mv_check_bounds(x, &second_mode_mv[this_mode].as_mv)))
+ mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
continue;
if (filter_idx > 0) {
BEST_SEG_INFO *ref_bsi = bsi_buf;
- subpelmv = mv_has_subpel(&mode_mv[this_mode].as_mv);
- have_ref = mode_mv[this_mode].as_int ==
- ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
- if (has_second_rf) {
- subpelmv |= mv_has_subpel(&second_mode_mv[this_mode].as_mv);
- have_ref &= second_mode_mv[this_mode].as_int ==
- ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
+ subpelmv = 0;
+ have_ref = 1;
+
+ for (ref = 0; ref < 1 + has_second_rf; ++ref) {
+ subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
+ have_ref &= mode_mv[this_mode][ref].as_int ==
+ ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
}
if (filter_idx > 1 && !subpelmv && !have_ref) {
ref_bsi = bsi_buf + 1;
- have_ref = mode_mv[this_mode].as_int ==
- ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
- if (has_second_rf) {
- have_ref &= second_mode_mv[this_mode].as_int ==
- ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
- }
+ have_ref = 1;
+ for (ref = 0; ref < 1 + has_second_rf; ++ref)
+ have_ref &= mode_mv[this_mode][ref].as_int ==
+ ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
}
if (!subpelmv && have_ref &&
@@ -2034,10 +2049,9 @@
vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
- labels2mode(x, i, mode_selected, &mode_mv[mode_selected],
- &second_mode_mv[mode_selected], frame_mv, seg_mvs[i],
- bsi->ref_mv[0], bsi->ref_mv[1], x->nmvjointcost,
- x->mvcost, cpi);
+ labels2mode(cpi, xd, i, mode_selected, mode_mv[mode_selected],
+ frame_mv, seg_mvs[i], bsi->ref_mv, x->nmvjointcost,
+ x->mvcost);
br += bsi->rdstat[i][mode_idx].brate;
bd += bsi->rdstat[i][mode_idx].bdist;
@@ -2084,7 +2098,7 @@
int i;
BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
MACROBLOCKD *xd = &x->e_mbd;
- MODE_INFO *mi = xd->mi_8x8[0];
+ MODE_INFO *mi = xd->mi[0];
MB_MODE_INFO *mbmi = &mi->mbmi;
int mode_idx;
@@ -2131,7 +2145,7 @@
uint8_t *ref_y_buffer, int ref_y_stride,
int ref_frame, BLOCK_SIZE block_size ) {
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
int_mv this_mv;
int i;
int zero_seen = 0;
@@ -2160,10 +2174,9 @@
max_mv = MAX(max_mv,
MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
// only need to check zero mv once
- if (!this_mv.as_int && zero_seen) {
- x->mode_sad[ref_frame][i] = x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)];
+ if (!this_mv.as_int && zero_seen)
continue;
- }
+
zero_seen = zero_seen || !this_mv.as_int;
row_offset = this_mv.as_mv.row >> 3;
@@ -2174,9 +2187,6 @@
this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
ref_y_ptr, ref_y_stride,
0x7fffffff);
- x->mode_sad[ref_frame][i] = this_sad;
- if (this_mv.as_int == 0)
- x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = this_sad;
// Note if it is the best so far.
if (this_sad < best_sad) {
@@ -2185,12 +2195,6 @@
}
}
- if (!zero_seen)
- x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] =
- cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride,
- ref_y_buffer, ref_y_stride,
- 0x7fffffff);
-
// Note the index of the mv that worked best in the reference list.
x->mv_best_ref_index[ref_frame] = best_index;
x->max_mv_context[ref_frame] = max_mv;
@@ -2271,7 +2275,7 @@
// restored if we decide to encode this way
ctx->skip = x->skip;
ctx->best_mode_index = mode_index;
- ctx->mic = *xd->mi_8x8[0];
+ ctx->mic = *xd->mi[0];
ctx->best_ref_mv[0].as_int = ref_mv->as_int;
ctx->best_ref_mv[1].as_int = second_ref_mv->as_int;
@@ -2322,7 +2326,7 @@
const VP9_COMMON *cm = &cpi->common;
const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, ref_frame);
MACROBLOCKD *const xd = &x->e_mbd;
- MODE_INFO *const mi = xd->mi_8x8[0];
+ MODE_INFO *const mi = xd->mi[0];
int_mv *const candidates = mi->mbmi.ref_mvs[ref_frame];
const struct scale_factors *const sf = &cm->frame_refs[ref_frame - 1].sf;
@@ -2331,8 +2335,7 @@
setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
// Gets an initial list of candidate vectors from neighbours and orders them
- vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi, ref_frame, candidates,
- mi_row, mi_col);
+ vp9_find_mv_refs(cm, xd, tile, mi, ref_frame, candidates, mi_row, mi_col);
// Candidate refinement carried out at encoder and decoder
vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, candidates,
@@ -2355,22 +2358,21 @@
return (scaled_idx != ref_idx) ? &cm->frame_bufs[scaled_idx].buf : NULL;
}
-static INLINE int get_switchable_rate(const MACROBLOCK *x) {
+int vp9_get_switchable_rate(const MACROBLOCK *x) {
const MACROBLOCKD *const xd = &x->e_mbd;
- const MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const int ctx = vp9_get_pred_context_switchable_interp(xd);
return SWITCHABLE_INTERP_RATE_FACTOR *
x->switchable_interp_costs[ctx][mbmi->interp_filter];
}
static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
- const TileInfo *const tile,
BLOCK_SIZE bsize,
int mi_row, int mi_col,
int_mv *tmp_mv, int *rate_mv) {
MACROBLOCKD *xd = &x->e_mbd;
VP9_COMMON *cm = &cpi->common;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
int bestsme = INT_MAX;
int further_steps, step_param;
@@ -2400,7 +2402,7 @@
for (i = 0; i < MAX_MB_PLANE; i++)
backup_yv12[i] = xd->plane[i].pre[0];
- setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
+ vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
vp9_set_mv_search_range(x, &ref_mv);
@@ -2456,22 +2458,41 @@
// Further step/diamond searches as necessary
further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
- if (cpi->sf.search_method == FAST_HEX) {
- bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb,
+ if (cpi->sf.search_method == FAST_DIAMOND) {
+ bestsme = vp9_fast_dia_search(x, &mvp_full, step_param, sadpb, 0,
&cpi->fn_ptr[bsize], 1,
&ref_mv, &tmp_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
+ &cpi->fn_ptr[bsize], 1);
+ } else if (cpi->sf.search_method == FAST_HEX) {
+ bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
+ &cpi->fn_ptr[bsize], 1,
+ &ref_mv, &tmp_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
+ &cpi->fn_ptr[bsize], 1);
} else if (cpi->sf.search_method == HEX) {
bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv, &tmp_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
+ &cpi->fn_ptr[bsize], 1);
} else if (cpi->sf.search_method == SQUARE) {
bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv, &tmp_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
+ &cpi->fn_ptr[bsize], 1);
} else if (cpi->sf.search_method == BIGDIA) {
bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
&cpi->fn_ptr[bsize], 1,
&ref_mv, &tmp_mv->as_mv);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
+ &cpi->fn_ptr[bsize], 1);
} else {
bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
sadpb, further_steps, 1,
@@ -2517,13 +2538,14 @@
const int pw = 4 * num_4x4_blocks_wide_lookup[bsize];
const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const int refs[2] = { mbmi->ref_frame[0],
mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
int_mv ref_mv[2];
int ite, ref;
// Prediction buffer from second frame.
uint8_t *second_pred = vpx_memalign(16, pw * ph * sizeof(uint8_t));
+ const InterpKernel *kernel = vp9_get_interp_kernel(mbmi->interp_filter);
// Do joint motion search in compound mode to get more accurate mv.
struct buf_2d backup_yv12[2][MAX_MB_PLANE];
@@ -2544,7 +2566,8 @@
// motion search code to be used without additional modifications.
for (i = 0; i < MAX_MB_PLANE; i++)
backup_yv12[ref][i] = xd->plane[i].pre[ref];
- setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, NULL);
+ vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
+ NULL);
}
frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
@@ -2576,7 +2599,7 @@
&frame_mv[refs[!id]].as_mv,
&xd->block_refs[!id]->sf,
pw, ph, 0,
- xd->interp_kernel, MV_PRECISION_Q3,
+ kernel, MV_PRECISION_Q3,
mi_col * MI_SIZE, mi_row * MI_SIZE);
// Compound motion search on first ref frame.
@@ -2597,6 +2620,9 @@
x->nmvjointcost, x->mvcost,
&ref_mv[id].as_mv, second_pred,
pw, ph);
+ if (bestsme < INT_MAX)
+ bestsme = vp9_get_mvpred_av_var(x, &tmp_mv.as_mv, &ref_mv[id].as_mv,
+ second_pred, &cpi->fn_ptr[bsize], 1);
x->mv_col_min = tmp_col_min;
x->mv_col_max = tmp_col_max;
@@ -2658,7 +2684,6 @@
}
static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
- const TileInfo *const tile,
BLOCK_SIZE bsize,
int64_t txfm_cache[],
int *rate2, int64_t *distortion,
@@ -2674,7 +2699,7 @@
const int64_t ref_best_rd) {
VP9_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const int is_comp_pred = has_second_ref(mbmi);
const int num_refs = is_comp_pred ? 2 : 1;
const int this_mode = mbmi->mode;
@@ -2720,13 +2745,13 @@
*rate2 += rate_mv;
} else {
int_mv tmp_mv;
- single_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
+ single_motion_search(cpi, x, bsize, mi_row, mi_col,
&tmp_mv, &rate_mv);
if (tmp_mv.as_int == INVALID_MV)
return INT64_MAX;
*rate2 += rate_mv;
frame_mv[refs[0]].as_int =
- xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
+ xd->mi[0]->bmi[0].as_mv[0].as_int = tmp_mv.as_int;
single_newmv[refs[0]].as_int = tmp_mv.as_int;
}
}
@@ -2788,8 +2813,7 @@
int j;
int64_t rs_rd;
mbmi->interp_filter = i;
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
- rs = get_switchable_rate(x);
+ rs = vp9_get_switchable_rate(x);
rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
if (i > 0 && intpel_mv) {
@@ -2859,8 +2883,7 @@
// Set the appropriate filter
mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
cm->interp_filter : *best_filter;
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
- rs = cm->interp_filter == SWITCHABLE ? get_switchable_rate(x) : 0;
+ rs = cm->interp_filter == SWITCHABLE ? vp9_get_switchable_rate(x) : 0;
if (pred_exists) {
if (best_needs_copy) {
@@ -2890,12 +2913,15 @@
}
if (cm->interp_filter == SWITCHABLE)
- *rate2 += get_switchable_rate(x);
+ *rate2 += vp9_get_switchable_rate(x);
if (!is_comp_pred) {
- if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+ if (!x->in_active_map) {
+ if (psse)
+ *psse = 0;
+ *distortion = 0;
x->skip = 1;
- else if (cpi->allow_encode_breakout && x->encode_breakout) {
+ } else if (cpi->allow_encode_breakout && x->encode_breakout) {
const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
unsigned int var, sse;
@@ -2990,7 +3016,7 @@
rdcosty = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
rdcosty = MIN(rdcosty, RDCOST(x->rdmult, x->rddiv, 0, *psse));
- super_block_uvrd(x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
+ super_block_uvrd(cpi, x, rate_uv, distortion_uv, &skippable_uv, &sseuv,
bsize, ref_best_rd - rdcosty);
if (*rate_uv == INT_MAX) {
*rate2 = INT_MAX;
@@ -3045,7 +3071,7 @@
TX_SIZE max_uv_tx_size;
x->skip_encode = 0;
ctx->skip = 0;
- xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME;
+ xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
if (bsize >= BLOCK_8X8) {
if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
@@ -3054,7 +3080,7 @@
*returnrate = INT_MAX;
return;
}
- max_uv_tx_size = get_uv_tx_size_impl(xd->mi_8x8[0]->mbmi.tx_size, bsize);
+ max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
&dist_uv, &uv_skip, bsize, max_uv_tx_size);
} else {
@@ -3064,7 +3090,7 @@
*returnrate = INT_MAX;
return;
}
- max_uv_tx_size = get_uv_tx_size_impl(xd->mi_8x8[0]->mbmi.tx_size, bsize);
+ max_uv_tx_size = get_uv_tx_size_impl(xd->mi[0]->mbmi.tx_size, bsize);
rd_pick_intra_sbuv_mode(cpi, x, ctx, &rate_uv, &rate_uv_tokenonly,
&dist_uv, &uv_skip, BLOCK_8X8, max_uv_tx_size);
}
@@ -3087,7 +3113,7 @@
}
}
- ctx->mic = *xd->mi_8x8[0];
+ ctx->mic = *xd->mi[0];
}
int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
@@ -3100,9 +3126,8 @@
int64_t best_rd_so_far) {
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const struct segmentation *const seg = &cm->seg;
- const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
MB_PREDICTION_MODE this_mode;
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
unsigned char segment_id = mbmi->segment_id;
@@ -3120,7 +3145,7 @@
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode = { 0 };
- int mode_index, best_mode_index = 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;
int64_t best_intra_rd = INT64_MAX;
@@ -3138,12 +3163,13 @@
const int bhs = num_8x8_blocks_high_lookup[bsize] / 2;
int best_skip2 = 0;
int mode_skip_mask = 0;
- const int mode_skip_start = cpi->sf.mode_skip_start + 1;
+ int mode_skip_start = cpi->sf.mode_skip_start + 1;
const int *const rd_threshes = cpi->rd_threshes[segment_id][bsize];
const int *const rd_thresh_freq_fact = cpi->rd_thresh_freq_fact[bsize];
const int mode_search_skip_flags = cpi->sf.mode_search_skip_flags;
const int intra_y_mode_mask =
cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
+ int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
@@ -3167,7 +3193,7 @@
x->pred_mv_sad[ref_frame] = INT_MAX;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
vp9_setup_buffer_inter(cpi, x, tile,
- ref_frame, block_size, mi_row, mi_col,
+ ref_frame, bsize, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
}
frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
@@ -3242,6 +3268,24 @@
mode_skip_mask |= new_modes_mask;
}
+ if (bsize > cpi->sf.max_intra_bsize) {
+ mode_skip_mask |= 0xFF30808;
+ }
+
+ if (!x->in_active_map) {
+ int mode_index;
+ assert(cpi->ref_frame_flags & VP9_LAST_FLAG);
+ if (frame_mv[NEARESTMV][LAST_FRAME].as_int == 0)
+ mode_index = THR_NEARESTMV;
+ else if (frame_mv[NEARMV][LAST_FRAME].as_int == 0)
+ mode_index = THR_NEARMV;
+ else
+ mode_index = THR_ZEROMV;
+ mode_skip_mask = ~(1 << mode_index);
+ mode_skip_start = MAX_MODES;
+ disable_inter_mode_mask = 0;
+ }
+
for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
int mode_excluded = 0;
int64_t this_rd = INT64_MAX;
@@ -3258,7 +3302,7 @@
// Look at the reference frame of the best mode so far and set the
// skip mask to look at a subset of the remaining modes.
- if (mode_index == mode_skip_start) {
+ if (mode_index == mode_skip_start && best_mode_index >= 0) {
switch (vp9_mode_order[best_mode_index].ref_frame[0]) {
case INTRA_FRAME:
break;
@@ -3288,13 +3332,14 @@
this_mode = vp9_mode_order[mode_index].mode;
ref_frame = vp9_mode_order[mode_index].ref_frame[0];
if (ref_frame != INTRA_FRAME &&
- cpi->sf.disable_inter_mode_mask[bsize] & (1 << INTER_OFFSET(this_mode)))
+ disable_inter_mode_mask & (1 << INTER_OFFSET(this_mode)))
continue;
second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
+ best_mode_index >=0 &&
vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
continue;
if ((mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) &&
@@ -3322,7 +3367,8 @@
// one of the neighboring directional modes
if ((mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
(this_mode >= D45_PRED && this_mode <= TM_PRED)) {
- if (vp9_mode_order[best_mode_index].ref_frame[0] > INTRA_FRAME)
+ if (best_mode_index >= 0 &&
+ vp9_mode_order[best_mode_index].ref_frame[0] > INTRA_FRAME)
continue;
}
if (mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
@@ -3331,46 +3377,16 @@
}
}
} else {
- // if we're near/nearest and mv == 0,0, compare to zeromv
- if ((this_mode == NEARMV || this_mode == NEARESTMV ||
- this_mode == ZEROMV) &&
- frame_mv[this_mode][ref_frame].as_int == 0 &&
- !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
- (!comp_pred || frame_mv[this_mode][second_ref_frame].as_int == 0)) {
- int rfc = mbmi->mode_context[ref_frame];
- int c1 = cost_mv_ref(cpi, NEARMV, rfc);
- int c2 = cost_mv_ref(cpi, NEARESTMV, rfc);
- int c3 = cost_mv_ref(cpi, ZEROMV, rfc);
-
- if (this_mode == NEARMV) {
- if (c1 > c3)
- continue;
- } else if (this_mode == NEARESTMV) {
- if (c2 > c3)
- continue;
- } else {
- assert(this_mode == ZEROMV);
- if (!comp_pred) {
- if ((c3 >= c2 &&
- frame_mv[NEARESTMV][ref_frame].as_int == 0) ||
- (c3 >= c1 &&
- frame_mv[NEARMV][ref_frame].as_int == 0))
- continue;
- } else {
- if ((c3 >= c2 &&
- frame_mv[NEARESTMV][ref_frame].as_int == 0 &&
- frame_mv[NEARESTMV][second_ref_frame].as_int == 0) ||
- (c3 >= c1 &&
- frame_mv[NEARMV][ref_frame].as_int == 0 &&
- frame_mv[NEARMV][second_ref_frame].as_int == 0))
- continue;
- }
- }
- }
+ if (x->in_active_map &&
+ !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
+ if (!check_best_zero_mv(cpi, mbmi->mode_context, frame_mv,
+ disable_inter_mode_mask, this_mode, ref_frame,
+ second_ref_frame))
+ continue;
}
mbmi->mode = this_mode;
- mbmi->uv_mode = DC_PRED;
+ mbmi->uv_mode = x->in_active_map ? DC_PRED : this_mode;
mbmi->ref_frame[0] = ref_frame;
mbmi->ref_frame[1] = second_ref_frame;
// Evaluate all sub-pel filters irrespective of whether we can use
@@ -3379,7 +3395,6 @@
: cm->interp_filter;
x->skip = 0;
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
// Select prediction reference frames.
for (i = 0; i < MAX_MB_PLANE; i++) {
@@ -3422,7 +3437,7 @@
rate2 += intra_cost_penalty;
distortion2 = distortion_y + distortion_uv;
} else {
- this_rd = handle_inter_mode(cpi, x, tile, bsize,
+ this_rd = handle_inter_mode(cpi, x, bsize,
tx_cache,
&rate2, &distortion2, &skippable,
&rate_y, &distortion_y,
@@ -3641,7 +3656,7 @@
break;
}
- if (best_rd >= best_rd_so_far)
+ if (best_mode_index < 0 || best_rd >= best_rd_so_far)
return INT64_MAX;
// If we used an estimate for the uv intra rd in the loop above...
@@ -3671,16 +3686,13 @@
// combination that wins out.
if (cpi->sf.adaptive_rd_thresh) {
for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
+ int *const fact = &cpi->rd_thresh_freq_fact[bsize][mode_index];
+
if (mode_index == best_mode_index) {
- cpi->rd_thresh_freq_fact[bsize][mode_index] -=
- (cpi->rd_thresh_freq_fact[bsize][mode_index] >> 3);
+ *fact -= (*fact >> 3);
} else {
- cpi->rd_thresh_freq_fact[bsize][mode_index] += RD_THRESH_INC;
- if (cpi->rd_thresh_freq_fact[bsize][mode_index] >
- (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) {
- cpi->rd_thresh_freq_fact[bsize][mode_index] =
- cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT;
- }
+ *fact = MIN(*fact + RD_THRESH_INC,
+ cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
}
}
}
@@ -3716,6 +3728,16 @@
vp9_zero(best_tx_diff);
}
+ if (!x->in_active_map) {
+ assert(mbmi->ref_frame[0] == LAST_FRAME);
+ assert(mbmi->ref_frame[1] == NONE);
+ assert(mbmi->mode == NEARESTMV ||
+ mbmi->mode == NEARMV ||
+ mbmi->mode == ZEROMV);
+ assert(frame_mv[mbmi->mode][LAST_FRAME].as_int == 0);
+ assert(mbmi->mode == mbmi->uv_mode);
+ }
+
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
store_coding_context(x, ctx, best_mode_index,
&mbmi->ref_mvs[mbmi->ref_frame[0]][0],
@@ -3735,11 +3757,10 @@
BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx,
int64_t best_rd_so_far) {
- VP9_COMMON *cm = &cpi->common;
- MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
- const struct segmentation *seg = &cm->seg;
- const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
+ VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ const struct segmentation *const seg = &cm->seg;
MV_REFERENCE_FRAME ref_frame, second_ref_frame;
unsigned char segment_id = mbmi->segment_id;
int comp_pred, i;
@@ -3799,7 +3820,7 @@
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
vp9_setup_buffer_inter(cpi, x, tile,
- ref_frame, block_size, mi_row, mi_col,
+ ref_frame, bsize, mi_row, mi_col,
frame_mv[NEARESTMV], frame_mv[NEARMV],
yv12_mb);
}
@@ -3832,10 +3853,6 @@
int64_t total_sse = INT_MAX;
int early_term = 0;
- for (i = 0; i < TX_MODES; ++i)
- tx_cache[i] = INT64_MAX;
-
- x->skip = 0;
ref_frame = vp9_ref_order[mode_index].ref_frame[0];
second_ref_frame = vp9_ref_order[mode_index].ref_frame[1];
@@ -3872,73 +3889,45 @@
cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] == INT_MAX)
continue;
- // Do not allow compound prediction if the segment level reference
- // frame feature is in use as in this case there can only be one reference.
- if ((second_ref_frame > INTRA_FRAME) &&
- vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
+ if (ref_frame > INTRA_FRAME &&
+ !(cpi->ref_frame_flags & flag_list[ref_frame])) {
continue;
-
- mbmi->ref_frame[0] = ref_frame;
- mbmi->ref_frame[1] = second_ref_frame;
-
- if (!(ref_frame == INTRA_FRAME
- || (cpi->ref_frame_flags & flag_list[ref_frame]))) {
- continue;
}
- if (!(second_ref_frame == NONE
- || (cpi->ref_frame_flags & flag_list[second_ref_frame]))) {
- continue;
- }
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
- if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
- if (vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
- continue;
- if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
- if (ref_frame != best_inter_ref_frame &&
- second_ref_frame != best_inter_ref_frame)
- continue;
+ if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
+ continue;
+ // Do not allow compound prediction if the segment level reference frame
+ // feature is in use as in this case there can only be one reference.
+ if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME))
+ continue;
+ if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
+ vp9_ref_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
+ continue;
+ if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH) &&
+ ref_frame != best_inter_ref_frame &&
+ second_ref_frame != best_inter_ref_frame)
+ continue;
}
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// sub8x8 blocks.
- if (ref_frame > 0 && vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
+ if (ref_frame > NONE && vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
continue;
- if (second_ref_frame > 0 &&
+ if (second_ref_frame > NONE &&
vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
continue;
- set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
- mbmi->uv_mode = DC_PRED;
-
- // Evaluate all sub-pel filters irrespective of whether we can use
- // them for this frame.
- mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
- : cm->interp_filter;
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
-
if (comp_pred) {
- if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
- continue;
-
mode_excluded = mode_excluded ? mode_excluded
: cm->reference_mode == SINGLE_REFERENCE;
- } else {
- if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
- mode_excluded = mode_excluded ?
- mode_excluded : cm->reference_mode == COMPOUND_REFERENCE;
- }
+ } else if (ref_frame != INTRA_FRAME) {
+ mode_excluded = mode_excluded ? mode_excluded
+ : cm->reference_mode == COMPOUND_REFERENCE;
}
- // Select prediction reference frames.
- for (i = 0; i < MAX_MB_PLANE; i++) {
- xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
- if (comp_pred)
- xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
- }
-
// If the segment reference frame feature is enabled....
// then do nothing if the current ref frame is not allowed..
if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
@@ -3963,6 +3952,27 @@
continue;
}
+ mbmi->tx_size = TX_4X4;
+ mbmi->uv_mode = DC_PRED;
+ mbmi->ref_frame[0] = ref_frame;
+ mbmi->ref_frame[1] = second_ref_frame;
+ // Evaluate all sub-pel filters irrespective of whether we can use
+ // them for this frame.
+ mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
+ : cm->interp_filter;
+ x->skip = 0;
+ set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
+
+ // Select prediction reference frames.
+ for (i = 0; i < MAX_MB_PLANE; i++) {
+ xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
+ if (comp_pred)
+ xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
+ }
+
+ for (i = 0; i < TX_MODES; ++i)
+ tx_cache[i] = INT64_MAX;
+
#ifdef MODE_TEST_HIT_STATS
// TEST/DEBUG CODE
// Keep a rcord of the number of test hits at each size
@@ -3971,7 +3981,6 @@
if (ref_frame == INTRA_FRAME) {
int rate;
- mbmi->tx_size = TX_4X4;
if (rd_pick_intra_sub_8x8_y_mode(cpi, x, &rate, &rate_y,
&distortion_y, best_rd) >= best_rd)
continue;
@@ -4016,7 +4025,6 @@
cpi->rd_thresh_sub8x8[segment_id][bsize][THR_ALTR];
this_rd_thresh = (ref_frame == GOLDEN_FRAME) ?
cpi->rd_thresh_sub8x8[segment_id][bsize][THR_GOLD] : this_rd_thresh;
- xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
cpi->mask_filter_rd = 0;
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
@@ -4024,8 +4032,7 @@
if (cm->interp_filter != BILINEAR) {
tmp_best_filter = EIGHTTAP;
- if (x->source_variance <
- cpi->sf.disable_filter_search_var_thresh) {
+ if (x->source_variance < cpi->sf.disable_filter_search_var_thresh) {
tmp_best_filter = EIGHTTAP;
} else if (cpi->sf.adaptive_pred_interp_filter == 1 &&
ctx->pred_interp_filter < SWITCHABLE) {
@@ -4040,7 +4047,6 @@
int newbest, rs;
int64_t rs_rd;
mbmi->interp_filter = switchable_filter_index;
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
tmp_rd = rd_pick_best_mbsegmentation(cpi, x, tile,
&mbmi->ref_mvs[ref_frame][0],
second_ref,
@@ -4053,7 +4059,7 @@
if (tmp_rd == INT64_MAX)
continue;
- rs = get_switchable_rate(x);
+ rs = vp9_get_switchable_rate(x);
rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
cpi->rd_filter_cache[switchable_filter_index] = tmp_rd;
cpi->rd_filter_cache[SWITCHABLE_FILTERS] =
@@ -4080,7 +4086,7 @@
tmp_best_skippable = skippable;
tmp_best_mbmode = *mbmi;
for (i = 0; i < 4; i++) {
- tmp_best_bmodes[i] = xd->mi_8x8[0]->bmi[i];
+ tmp_best_bmodes[i] = xd->mi[0]->bmi[i];
x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
}
pred_exists = 1;
@@ -4105,7 +4111,6 @@
mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
tmp_best_filter : cm->interp_filter);
- xd->interp_kernel = vp9_get_interp_kernel(mbmi->interp_filter);
if (!pred_exists) {
// Handles the special case when a filter that is not in the
// switchable list (bilinear, 6-tap) is indicated at the frame level
@@ -4128,14 +4133,14 @@
skippable = tmp_best_skippable;
*mbmi = tmp_best_mbmode;
for (i = 0; i < 4; i++)
- xd->mi_8x8[0]->bmi[i] = tmp_best_bmodes[i];
+ xd->mi[0]->bmi[i] = tmp_best_bmodes[i];
}
rate2 += rate;
distortion2 += distortion;
if (cm->interp_filter == SWITCHABLE)
- rate2 += get_switchable_rate(x);
+ rate2 += vp9_get_switchable_rate(x);
if (!mode_excluded)
mode_excluded = comp_pred ? cm->reference_mode == SINGLE_REFERENCE
@@ -4152,7 +4157,7 @@
// then dont bother looking at UV
vp9_build_inter_predictors_sbuv(&x->e_mbd, mi_row, mi_col,
BLOCK_8X8);
- super_block_uvrd(x, &rate_uv, &distortion_uv, &uv_skippable,
+ super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
&uv_sse, BLOCK_8X8, tmp_best_rdu);
if (rate_uv == INT_MAX)
continue;
@@ -4212,8 +4217,8 @@
}
// Keep record of best inter rd with single reference
- if (is_inter_block(&xd->mi_8x8[0]->mbmi) &&
- !has_second_ref(&xd->mi_8x8[0]->mbmi) &&
+ if (is_inter_block(mbmi) &&
+ !has_second_ref(mbmi) &&
!mode_excluded &&
this_rd < best_inter_rd) {
best_inter_rd = this_rd;
@@ -4249,11 +4254,11 @@
best_skip2 = this_skip2;
if (!x->select_txfm_size)
swap_block_ptr(x, ctx, max_plane);
- vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
+ vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[TX_4X4],
sizeof(uint8_t) * ctx->num_4x4_blk);
for (i = 0; i < 4; i++)
- best_bmodes[i] = xd->mi_8x8[0]->bmi[i];
+ best_bmodes[i] = xd->mi[0]->bmi[i];
// TODO(debargha): enhance this test with a better distortion prediction
// based on qp, activity mask and history
@@ -4289,11 +4294,9 @@
single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
- if (second_ref_frame <= INTRA_FRAME &&
- single_rd < best_pred_rd[SINGLE_REFERENCE]) {
+ if (!comp_pred && single_rd < best_pred_rd[SINGLE_REFERENCE]) {
best_pred_rd[SINGLE_REFERENCE] = single_rd;
- } else if (second_ref_frame > INTRA_FRAME &&
- single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
+ } else if (comp_pred && single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
best_pred_rd[COMPOUND_REFERENCE] = single_rd;
}
if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
@@ -4324,13 +4327,9 @@
}
/* keep record of best txfm size */
- if (bsize < BLOCK_32X32) {
- if (bsize < BLOCK_16X16) {
- tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4];
- tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
- }
- tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
- }
+ tx_cache[ALLOW_8X8] = tx_cache[ONLY_4X4];
+ tx_cache[ALLOW_16X16] = tx_cache[ALLOW_8X8];
+ tx_cache[ALLOW_32X32] = tx_cache[ALLOW_16X16];
if (!mode_excluded && this_rd != INT64_MAX) {
for (i = 0; i < TX_MODES && tx_cache[i] < INT64_MAX; i++) {
int64_t adj_rd = INT64_MAX;
@@ -4369,7 +4368,7 @@
}
}
- if (best_rd == INT64_MAX && bsize < BLOCK_8X8) {
+ if (best_rd == INT64_MAX) {
*returnrate = INT_MAX;
*returndistortion = INT64_MAX;
return best_rd;
@@ -4386,16 +4385,13 @@
// combination that wins out.
if (cpi->sf.adaptive_rd_thresh) {
for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
+ int *const fact = &cpi->rd_thresh_freq_sub8x8[bsize][mode_index];
+
if (mode_index == best_mode_index) {
- cpi->rd_thresh_freq_sub8x8[bsize][mode_index] -=
- (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >> 3);
+ *fact -= (*fact >> 3);
} else {
- cpi->rd_thresh_freq_sub8x8[bsize][mode_index] += RD_THRESH_INC;
- if (cpi->rd_thresh_freq_sub8x8[bsize][mode_index] >
- (cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT)) {
- cpi->rd_thresh_freq_sub8x8[bsize][mode_index] =
- cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT;
- }
+ *fact = MIN(*fact + RD_THRESH_INC,
+ cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
}
}
}
@@ -4405,13 +4401,13 @@
x->skip |= best_skip2;
if (!is_inter_block(&best_mbmode)) {
for (i = 0; i < 4; i++)
- xd->mi_8x8[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
+ xd->mi[0]->bmi[i].as_mode = best_bmodes[i].as_mode;
} else {
for (i = 0; i < 4; ++i)
- vpx_memcpy(&xd->mi_8x8[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
+ vpx_memcpy(&xd->mi[0]->bmi[i], &best_bmodes[i], sizeof(b_mode_info));
- mbmi->mv[0].as_int = xd->mi_8x8[0]->bmi[3].as_mv[0].as_int;
- mbmi->mv[1].as_int = xd->mi_8x8[0]->bmi[3].as_mv[1].as_int;
+ mbmi->mv[0].as_int = xd->mi[0]->bmi[3].as_mv[0].as_int;
+ mbmi->mv[1].as_int = xd->mi[0]->bmi[3].as_mv[1].as_int;
}
for (i = 0; i < REFERENCE_MODES; ++i) {
@@ -4430,11 +4426,6 @@
}
if (cm->interp_filter == SWITCHABLE)
assert(best_filter_diff[SWITCHABLE_FILTERS] == 0);
- } else {
- vp9_zero(best_filter_diff);
- }
-
- if (!x->skip) {
for (i = 0; i < TX_MODES; i++) {
if (best_tx_rd[i] == INT64_MAX)
best_tx_diff[i] = 0;
@@ -4442,6 +4433,7 @@
best_tx_diff[i] = best_rd - best_tx_rd[i];
}
} else {
+ vp9_zero(best_filter_diff);
vp9_zero(best_tx_diff);
}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rdopt.h ('k') | source/libvpx/vp9/encoder/vp9_sad.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698