Index: source/libvpx/vp9/encoder/vp9_rdopt.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_rdopt.c (revision 293588) |
+++ source/libvpx/vp9/encoder/vp9_rdopt.c (working copy) |
@@ -37,6 +37,7 @@ |
#include "vp9/encoder/vp9_rd.h" |
#include "vp9/encoder/vp9_rdopt.h" |
#include "vp9/encoder/vp9_variance.h" |
+#include "vp9/encoder/vp9_aq_variance.h" |
#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \ |
(1 << INTRA_FRAME)) |
@@ -48,6 +49,7 @@ |
#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01) |
#define MIN_EARLY_TERM_INDEX 3 |
+#define NEW_MV_DISCOUNT_FACTOR 8 |
typedef struct { |
PREDICTION_MODE mode; |
@@ -75,6 +77,7 @@ |
const scan_order *so; |
}; |
+#define LAST_NEW_MV_INDEX 6 |
static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = { |
{NEARESTMV, {LAST_FRAME, NONE}}, |
{NEARESTMV, {ALTREF_FRAME, NONE}}, |
@@ -126,19 +129,6 @@ |
{{INTRA_FRAME, NONE}}, |
}; |
-static int raster_block_offset(BLOCK_SIZE plane_bsize, |
- int raster_block, int stride) { |
- const int bw = b_width_log2_lookup[plane_bsize]; |
- const int y = 4 * (raster_block >> bw); |
- const int x = 4 * (raster_block & ((1 << bw) - 1)); |
- return y * stride + x; |
-} |
-static int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize, |
- int raster_block, int16_t *base) { |
- const int stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize]; |
- return base + raster_block_offset(plane_bsize, raster_block, stride); |
-} |
- |
static void swap_block_ptr(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, |
int m, int n, int min_plane, int max_plane) { |
int i; |
@@ -265,15 +255,15 @@ |
} else { |
#if CONFIG_VP9_HIGHBITDEPTH |
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
- vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs], |
+ vp9_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs], |
pd->dequant[1] >> (xd->bd - 5), |
&rate, &dist); |
} else { |
- vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs], |
+ vp9_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs], |
pd->dequant[1] >> 3, &rate, &dist); |
} |
#else |
- vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs], |
+ vp9_model_rd_from_var_lapndz(sum_sse, num_pels_log2_lookup[bs], |
pd->dequant[1] >> 3, &rate, &dist); |
#endif // CONFIG_VP9_HIGHBITDEPTH |
rate_sum += rate; |
@@ -357,6 +347,12 @@ |
uint8_t token_cache[32 * 32]; |
int pt = combine_entropy_contexts(*A, *L); |
int c, cost; |
+#if CONFIG_VP9_HIGHBITDEPTH |
+ const int16_t *cat6_high_cost = vp9_get_high_cost_table(xd->bd); |
+#else |
+ const int16_t *cat6_high_cost = vp9_get_high_cost_table(8); |
+#endif |
+ |
// Check for consistency of tx_size with mode info |
assert(type == PLANE_TYPE_Y ? mbmi->tx_size == tx_size |
: get_uv_tx_size(mbmi, pd) == tx_size); |
@@ -370,8 +366,12 @@ |
// dc token |
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]; |
+ int16_t prev_t; |
+ EXTRABIT e; |
+ vp9_get_token_extra(v, &prev_t, &e); |
+ cost = (*token_costs)[0][pt][prev_t] + |
+ vp9_get_cost(prev_t, e, cat6_high_cost); |
+ |
token_cache[0] = vp9_pt_energy_class[prev_t]; |
++token_costs; |
@@ -378,15 +378,17 @@ |
// ac tokens |
for (c = 1; c < eob; c++) { |
const int rc = scan[c]; |
- int t; |
+ int16_t t; |
v = qcoeff[rc]; |
- t = vp9_dct_value_tokens_ptr[v].token; |
+ vp9_get_token_extra(v, &t, &e); |
if (use_fast_coef_costing) { |
- cost += (*token_costs)[!prev_t][!prev_t][t] + vp9_dct_value_cost_ptr[v]; |
+ cost += (*token_costs)[!prev_t][!prev_t][t] + |
+ vp9_get_cost(t, e, cat6_high_cost); |
} else { |
pt = get_coef_context(nb, token_cache, c); |
- cost += (*token_costs)[!prev_t][pt][t] + vp9_dct_value_cost_ptr[v]; |
+ cost += (*token_costs)[!prev_t][pt][t] + |
+ vp9_get_cost(t, e, cat6_high_cost); |
token_cache[rc] = vp9_pt_energy_class[t]; |
} |
prev_t = t; |
@@ -758,10 +760,10 @@ |
struct macroblockd_plane *pd = &xd->plane[0]; |
const int src_stride = p->src.stride; |
const int dst_stride = pd->dst.stride; |
- const uint8_t *src_init = &p->src.buf[raster_block_offset(BLOCK_8X8, ib, |
- src_stride)]; |
- uint8_t *dst_init = &pd->dst.buf[raster_block_offset(BLOCK_8X8, ib, |
- dst_stride)]; |
+ const uint8_t *src_init = &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, ib, |
+ src_stride)]; |
+ uint8_t *dst_init = &pd->dst.buf[vp9_raster_block_offset(BLOCK_8X8, ib, |
+ dst_stride)]; |
ENTROPY_CONTEXT ta[2], tempa[2]; |
ENTROPY_CONTEXT tl[2], templ[2]; |
@@ -805,8 +807,9 @@ |
const int block = ib + idy * 2 + idx; |
const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride]; |
uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride]; |
- int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block, |
- p->src_diff); |
+ int16_t *const src_diff = vp9_raster_block_offset_int16(BLOCK_8X8, |
+ block, |
+ p->src_diff); |
tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block); |
xd->mi[0].src_mi->bmi[block].as_mode = mode; |
vp9_predict_intra_block(xd, block, 1, |
@@ -905,8 +908,8 @@ |
const int block = ib + idy * 2 + idx; |
const uint8_t *const src = &src_init[idx * 4 + idy * 4 * src_stride]; |
uint8_t *const dst = &dst_init[idx * 4 + idy * 4 * dst_stride]; |
- int16_t *const src_diff = raster_block_offset_int16(BLOCK_8X8, block, |
- p->src_diff); |
+ int16_t *const src_diff = |
+ vp9_raster_block_offset_int16(BLOCK_8X8, block, p->src_diff); |
tran_low_t *const coeff = BLOCK_OFFSET(x->plane[0].coeff, block); |
xd->mi[0].src_mi->bmi[block].as_mode = mode; |
vp9_predict_intra_block(xd, block, 1, |
@@ -982,8 +985,8 @@ |
int i, j; |
const MACROBLOCKD *const xd = &mb->e_mbd; |
MODE_INFO *const mic = xd->mi[0].src_mi; |
- const MODE_INFO *above_mi = xd->mi[-xd->mi_stride].src_mi; |
- const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL; |
+ const MODE_INFO *above_mi = xd->above_mi; |
+ const MODE_INFO *left_mi = xd->left_mi; |
const BLOCK_SIZE bsize = xd->mi[0].src_mi->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]; |
@@ -1058,8 +1061,8 @@ |
TX_SIZE best_tx = TX_4X4; |
int i; |
int *bmode_costs; |
- const MODE_INFO *above_mi = xd->mi[-xd->mi_stride].src_mi; |
- const MODE_INFO *left_mi = xd->left_available ? xd->mi[-1].src_mi : NULL; |
+ const MODE_INFO *above_mi = xd->above_mi; |
+ const MODE_INFO *left_mi = xd->left_mi; |
const PREDICTION_MODE A = vp9_above_block_mode(mic, above_mi, 0); |
const PREDICTION_MODE L = vp9_left_block_mode(mic, left_mi, 0); |
bmode_costs = cpi->y_mode_costs[A][L]; |
@@ -1072,6 +1075,16 @@ |
/* Y Search for intra prediction mode */ |
for (mode = DC_PRED; mode <= TM_PRED; mode++) { |
int64_t local_tx_cache[TX_MODES]; |
+ |
+ if (cpi->sf.use_nonrd_pick_mode) { |
+ // These speed features are turned on in hybrid non-RD and RD mode |
+ // for key frame coding in the context of real-time setting. |
+ if (conditional_skipintra(mode, mode_selected)) |
+ continue; |
+ if (*skippable) |
+ break; |
+ } |
+ |
mic->mbmi.mode = mode; |
super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, |
@@ -1328,10 +1341,10 @@ |
const int height = 4 * num_4x4_blocks_high_lookup[plane_bsize]; |
int idx, idy; |
- const uint8_t *const src = &p->src.buf[raster_block_offset(BLOCK_8X8, i, |
- p->src.stride)]; |
- uint8_t *const dst = &pd->dst.buf[raster_block_offset(BLOCK_8X8, i, |
- pd->dst.stride)]; |
+ const uint8_t *const src = |
+ &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, i, p->src.stride)]; |
+ uint8_t *const dst = &pd->dst.buf[vp9_raster_block_offset(BLOCK_8X8, i, |
+ pd->dst.stride)]; |
int64_t thisdistortion = 0, thissse = 0; |
int thisrate = 0, ref; |
const scan_order *so = &vp9_default_scan_orders[TX_4X4]; |
@@ -1339,7 +1352,7 @@ |
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, |
+ const uint8_t *pre = &pd->pre[ref].buf[vp9_raster_block_offset(BLOCK_8X8, i, |
pd->pre[ref].stride)]; |
#if CONFIG_VP9_HIGHBITDEPTH |
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
@@ -1373,17 +1386,17 @@ |
#if CONFIG_VP9_HIGHBITDEPTH |
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
vp9_highbd_subtract_block( |
- height, width, raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8, |
- src, p->src.stride, dst, pd->dst.stride, xd->bd); |
+ height, width, vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), |
+ 8, src, p->src.stride, dst, pd->dst.stride, xd->bd); |
} else { |
vp9_subtract_block( |
- height, width, raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8, |
- src, p->src.stride, dst, pd->dst.stride); |
+ height, width, vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), |
+ 8, src, p->src.stride, dst, pd->dst.stride); |
} |
#else |
vp9_subtract_block(height, width, |
- raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), 8, |
- src, p->src.stride, dst, pd->dst.stride); |
+ vp9_raster_block_offset_int16(BLOCK_8X8, i, p->src_diff), |
+ 8, src, p->src.stride, dst, pd->dst.stride); |
#endif // CONFIG_VP9_HIGHBITDEPTH |
k = i; |
@@ -1394,7 +1407,7 @@ |
k += (idy * 2 + idx); |
coeff = BLOCK_OFFSET(p->coeff, k); |
- x->fwd_txm4x4(raster_block_offset_int16(BLOCK_8X8, k, p->src_diff), |
+ x->fwd_txm4x4(vp9_raster_block_offset_int16(BLOCK_8X8, k, p->src_diff), |
coeff, 8); |
vp9_regular_quantize_b_4x4(x, 0, k, so->scan, so->iscan); |
#if CONFIG_VP9_HIGHBITDEPTH |
@@ -1467,13 +1480,14 @@ |
struct macroblock_plane *const p = &x->plane[0]; |
struct macroblockd_plane *const pd = &x->e_mbd.plane[0]; |
- p->src.buf = &p->src.buf[raster_block_offset(BLOCK_8X8, i, p->src.stride)]; |
+ p->src.buf = &p->src.buf[vp9_raster_block_offset(BLOCK_8X8, i, |
+ p->src.stride)]; |
assert(((intptr_t)pd->pre[0].buf & 0x7) == 0); |
- pd->pre[0].buf = &pd->pre[0].buf[raster_block_offset(BLOCK_8X8, i, |
- pd->pre[0].stride)]; |
+ pd->pre[0].buf = &pd->pre[0].buf[vp9_raster_block_offset(BLOCK_8X8, i, |
+ pd->pre[0].stride)]; |
if (has_second_ref(mbmi)) |
- pd->pre[1].buf = &pd->pre[1].buf[raster_block_offset(BLOCK_8X8, i, |
- pd->pre[1].stride)]; |
+ pd->pre[1].buf = &pd->pre[1].buf[vp9_raster_block_offset(BLOCK_8X8, i, |
+ pd->pre[1].stride)]; |
} |
static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, |
@@ -2345,6 +2359,27 @@ |
} |
} |
+// In some situations we want to discount tha pparent cost of a new motion |
+// vector. Where there is a subtle motion field and especially where there is |
+// low spatial complexity then it can be hard to cover the cost of a new motion |
+// vector in a single block, even if that motion vector reduces distortion. |
+// However, once established that vector may be usable through the nearest and |
+// near mv modes to reduce distortion in subsequent blocks and also improve |
+// visual quality. |
+static int discount_newmv_test(const VP9_COMP *cpi, |
+ int this_mode, |
+ int_mv this_mv, |
+ int_mv (*mode_mv)[MAX_REF_FRAMES], |
+ int ref_frame) { |
+ return (!cpi->rc.is_src_frame_alt_ref && |
+ (this_mode == NEWMV) && |
+ (this_mv.as_int != 0) && |
+ ((mode_mv[NEARESTMV][ref_frame].as_int == 0) || |
+ (mode_mv[NEARESTMV][ref_frame].as_int == INVALID_MV)) && |
+ ((mode_mv[NEARMV][ref_frame].as_int == 0) || |
+ (mode_mv[NEARMV][ref_frame].as_int == INVALID_MV))); |
+} |
+ |
static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, |
BLOCK_SIZE bsize, |
int64_t txfm_cache[], |
@@ -2454,10 +2489,20 @@ |
&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[0].src_mi->bmi[0].as_mv[0].as_int = tmp_mv.as_int; |
single_newmv[refs[0]].as_int = tmp_mv.as_int; |
+ |
+ // Estimate the rate implications of a new mv but discount this |
+ // under certain circumstances where we want to help initiate a weak |
+ // motion field, where the distortion gain for a single block may not |
+ // be enough to overcome the cost of a new mv. |
+ if (discount_newmv_test(cpi, this_mode, tmp_mv, mode_mv, refs[0])) { |
+ *rate2 += MAX((rate_mv / NEW_MV_DISCOUNT_FACTOR), 1); |
+ } else { |
+ *rate2 += rate_mv; |
+ } |
} |
} |
@@ -2482,11 +2527,20 @@ |
orig_dst_stride[i] = xd->plane[i].dst.stride; |
} |
- /* We don't include the cost of the second reference here, because there |
- * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other |
- * words if you present them in that order, the second one is always known |
- * if the first is known */ |
- *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]); |
+ // We don't include the cost of the second reference here, because there |
+ // are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other |
+ // words if you present them in that order, the second one is always known |
+ // if the first is known. |
+ // |
+ // Under some circumstances we discount the cost of new mv mode to encourage |
+ // initiation of a motion field. |
+ if (discount_newmv_test(cpi, this_mode, frame_mv[refs[0]], |
+ mode_mv, refs[0])) { |
+ *rate2 += MIN(cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]), |
+ cost_mv_ref(cpi, NEARESTMV, mbmi->mode_context[refs[0]])); |
+ } else { |
+ *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) |
@@ -2716,6 +2770,7 @@ |
x->skip_encode = 0; |
ctx->skip = 0; |
xd->mi[0].src_mi->mbmi.ref_frame[0] = INTRA_FRAME; |
+ xd->mi[0].src_mi->mbmi.ref_frame[1] = NONE; |
if (bsize >= BLOCK_8X8) { |
if (rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, |
@@ -2931,7 +2986,9 @@ |
mode_skip_mask[INTRA_FRAME] |= |
~(sf->intra_y_mode_mask[max_txsize_lookup[bsize]]); |
- for (i = 0; i < MAX_MODES; ++i) |
+ for (i = 0; i <= LAST_NEW_MV_INDEX; ++i) |
+ mode_threshold[i] = 0; |
+ for (i = LAST_NEW_MV_INDEX + 1; i < MAX_MODES; ++i) |
mode_threshold[i] = ((int64_t)rd_threshes[i] * rd_thresh_freq_fact[i]) >> 5; |
midx = sf->schedule_mode_search ? mode_skip_start : 0; |
@@ -3055,7 +3112,7 @@ |
comp_pred = second_ref_frame > INTRA_FRAME; |
if (comp_pred) { |
- if (!cm->allow_comp_inter_inter) |
+ if (!cpi->allow_comp_inter_inter) |
continue; |
// Skip compound inter modes if ARF is not available. |
@@ -3705,7 +3762,7 @@ |
comp_pred = second_ref_frame > INTRA_FRAME; |
if (comp_pred) { |
- if (!cm->allow_comp_inter_inter) |
+ if (!cpi->allow_comp_inter_inter) |
continue; |
if (!(cpi->ref_frame_flags & flag_list[second_ref_frame])) |
continue; |