summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encodeframe.c
diff options
context:
space:
mode:
authorJingning Han <jingning@google.com>2018-06-20 13:15:10 -0700
committerJingning Han <jingning@google.com>2018-06-29 09:15:55 -0700
commit3df55cebb25d18f75f7711f84d9786ac2ce33b72 (patch)
treea1c0d8da1295c5f3b64c6a545b8cc93b4abbfc53 /vp9/encoder/vp9_encodeframe.c
parenta2d35b234f176316fb978d8c7099a003ddd4e8ab (diff)
downloadlibvpx-3df55cebb25d18f75f7711f84d9786ac2ce33b72.tar
libvpx-3df55cebb25d18f75f7711f84d9786ac2ce33b72.tar.gz
libvpx-3df55cebb25d18f75f7711f84d9786ac2ce33b72.tar.bz2
libvpx-3df55cebb25d18f75f7711f84d9786ac2ce33b72.zip
Exploit the spatial variance in temporal dependency model
Adapt the Lagrangian multipler based on the spatial variance in the temporal dependency model. The functionality is disabled by default. To turn on, set enable_tpl_model to 1. Change-Id: I1b50606d9e2c8eb9c790c49eacc12c00d3d7c211
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r--vp9/encoder/vp9_encodeframe.c76
1 files changed, 73 insertions, 3 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 34eaeb783..c28829a87 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1950,6 +1950,8 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data,
x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
}
+ if (cpi->sf.enable_tpl_model) x->rdmult = x->cb_rdmult;
+
// Find best coding mode & reconstruct the MB so it is available
// as a predictor for MBs that follow in the SB
if (frame_is_intra_only(cm)) {
@@ -1976,8 +1978,6 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data,
vp9_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
}
- x->rdmult = orig_rdmult;
-
// TODO(jingning) The rate-distortion optimization flow needs to be
// refactored to provide proper exit/return handle.
if (rd_cost->rate == INT_MAX)
@@ -1985,6 +1985,8 @@ static void rd_pick_sb_modes(VP9_COMP *cpi, TileDataEnc *tile_data,
else
rd_cost->rdcost = RDCOST(x->rdmult, x->rddiv, rd_cost->rate, rd_cost->dist);
+ x->rdmult = orig_rdmult;
+
ctx->rate = rd_cost->rate;
ctx->dist = rd_cost->dist;
}
@@ -2110,6 +2112,7 @@ static void encode_b(VP9_COMP *cpi, const TileInfo *const tile, ThreadData *td,
PICK_MODE_CONTEXT *ctx) {
MACROBLOCK *const x = &td->mb;
set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
+ if (cpi->sf.enable_tpl_model) x->rdmult = x->cb_rdmult;
update_state(cpi, td, ctx, mi_row, mi_col, bsize, output_enabled);
encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx);
@@ -3491,6 +3494,47 @@ static int ml_predict_breakout(const VP9_COMP *const cpi, BLOCK_SIZE bsize,
#undef FEATURES
#undef Q_CTX
+int get_rdmult_delta(VP9_COMP *cpi, BLOCK_SIZE bsize, int mi_row, int mi_col,
+ int orig_rdmult) {
+ TplDepFrame *tpl_frame = &cpi->tpl_stats[cpi->twopass.gf_group.index];
+ TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
+ int tpl_stride = tpl_frame->stride;
+ int64_t intra_cost = 0;
+ int64_t mc_dep_cost = 0;
+ int mi_wide = num_8x8_blocks_wide_lookup[bsize];
+ int mi_high = num_8x8_blocks_high_lookup[bsize];
+ int row, col;
+
+ int dr = 0;
+ int count = 0;
+ double r0, rk, beta;
+
+ r0 = cpi->rd.r0;
+
+ for (row = mi_row; row < mi_row + mi_high; ++row) {
+ for (col = mi_col; col < mi_col + mi_wide; ++col) {
+ TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col];
+
+ if (row >= cpi->common.mi_rows || col >= cpi->common.mi_cols) continue;
+
+ intra_cost += this_stats->intra_cost;
+ mc_dep_cost += this_stats->mc_dep_cost;
+
+ ++count;
+ }
+ }
+
+ rk = (double)intra_cost / (intra_cost + mc_dep_cost);
+ beta = r0 / rk;
+ dr = vp9_get_adaptive_rdmult(cpi, beta);
+
+ dr = VPXMIN(dr, orig_rdmult * 5 / 4);
+ dr = VPXMAX(dr, orig_rdmult * 3 / 4);
+
+ dr = VPXMAX(1, dr);
+ return dr;
+}
+
// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
// unlikely to be selected depending on previous rate-distortion optimization
// results, for encoding speed-up.
@@ -3540,7 +3584,7 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
int rate_breakout_thr = cpi->sf.partition_search_breakout_thr.rate;
int must_split = 0;
- int partition_mul = cpi->rd.RDMULT;
+ int partition_mul = cpi->sf.enable_tpl_model ? x->cb_rdmult : cpi->rd.RDMULT;
(void)*tp_orig;
@@ -4056,6 +4100,14 @@ static void encode_rd_sb_row(VP9_COMP *cpi, ThreadData *td,
rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, BLOCK_64X64,
&dummy_rate, &dummy_dist, 1, td->pc_root);
} else {
+ int orig_rdmult = cpi->rd.RDMULT;
+ x->cb_rdmult = orig_rdmult;
+ if (cpi->twopass.gf_group.index > 0 && cpi->sf.enable_tpl_model) {
+ int dr =
+ get_rdmult_delta(cpi, BLOCK_64X64, mi_row, mi_col, orig_rdmult);
+ x->cb_rdmult = dr;
+ }
+
// If required set upper and lower partition size limits
if (sf->auto_min_max_partition_size) {
set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
@@ -5265,6 +5317,24 @@ static void encode_frame_internal(VP9_COMP *cpi) {
if (sf->partition_search_type == SOURCE_VAR_BASED_PARTITION)
source_var_based_partition_search_method(cpi);
+ } else if (cpi->twopass.gf_group.index) {
+ TplDepFrame *tpl_frame = &cpi->tpl_stats[cpi->twopass.gf_group.index];
+ TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
+
+ int tpl_stride = tpl_frame->stride;
+ int64_t intra_cost_base = 0;
+ int64_t mc_dep_cost_base = 0;
+ int row, col;
+
+ for (row = 0; row < cm->mi_rows; ++row) {
+ for (col = 0; col < cm->mi_cols; ++col) {
+ TplDepStats *this_stats = &tpl_stats[row * tpl_stride + col];
+ intra_cost_base += this_stats->intra_cost;
+ mc_dep_cost_base += this_stats->mc_dep_cost;
+ }
+ }
+
+ cpi->rd.r0 = (double)intra_cost_base / (intra_cost_base + mc_dep_cost_base);
}
{