summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorMarco Paniconi <marpan@google.com>2015-11-25 04:24:00 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-11-25 04:24:00 +0000
commit610b413d7b9c7b9633ce6eb79e3daa7275542a40 (patch)
treea09ed32b7776d902e4a35ba4ce437df6dda23fc6 /vp9/encoder
parent901d20369a96871e63a4c78575a4b02db54785a9 (diff)
parent5b0ddb931d1bc8f890e138f5fa36950f385c6480 (diff)
downloadlibvpx-610b413d7b9c7b9633ce6eb79e3daa7275542a40.tar
libvpx-610b413d7b9c7b9633ce6eb79e3daa7275542a40.tar.gz
libvpx-610b413d7b9c7b9633ce6eb79e3daa7275542a40.tar.bz2
libvpx-610b413d7b9c7b9633ce6eb79e3daa7275542a40.zip
Merge "vp9 denoiser: Re-evaluate ZEROMV after denoiser filtering."
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_denoiser.c4
-rw-r--r--vp9/encoder/vp9_denoiser.h3
-rw-r--r--vp9/encoder/vp9_encodeframe.c10
-rw-r--r--vp9/encoder/vp9_pickmode.c57
-rw-r--r--vp9/encoder/vp9_speed_features.c10
5 files changed, 71 insertions, 13 deletions
diff --git a/vp9/encoder/vp9_denoiser.c b/vp9/encoder/vp9_denoiser.c
index 31ac61daa..fc76c11c4 100644
--- a/vp9/encoder/vp9_denoiser.c
+++ b/vp9/encoder/vp9_denoiser.c
@@ -316,7 +316,8 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
int mi_row, int mi_col, BLOCK_SIZE bs,
- PICK_MODE_CONTEXT *ctx) {
+ PICK_MODE_CONTEXT *ctx,
+ VP9_DENOISER_DECISION *denoiser_decision) {
int mv_col, mv_row;
int motion_magnitude = 0;
VP9_DENOISER_DECISION decision = COPY_BLOCK;
@@ -380,6 +381,7 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
num_4x4_blocks_wide_lookup[bs] << 2,
num_4x4_blocks_high_lookup[bs] << 2);
}
+ *denoiser_decision = decision;
}
static void copy_frame(YV12_BUFFER_CONFIG * const dest,
diff --git a/vp9/encoder/vp9_denoiser.h b/vp9/encoder/vp9_denoiser.h
index bc676e925..c8c93528b 100644
--- a/vp9/encoder/vp9_denoiser.h
+++ b/vp9/encoder/vp9_denoiser.h
@@ -54,7 +54,8 @@ void vp9_denoiser_update_frame_info(VP9_DENOISER *denoiser,
void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
int mi_row, int mi_col, BLOCK_SIZE bs,
- PICK_MODE_CONTEXT *ctx);
+ PICK_MODE_CONTEXT *ctx ,
+ VP9_DENOISER_DECISION *denoiser_decision);
void vp9_denoiser_reset_frame_stats(PICK_MODE_CONTEXT *ctx);
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index f9c28f6a9..7e569899e 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1746,16 +1746,6 @@ static void encode_b_rt(VP9_COMP *cpi, ThreadData *td,
set_offsets(cpi, tile, x, mi_row, mi_col, bsize);
update_state_rt(cpi, td, ctx, mi_row, mi_col, bsize);
-#if CONFIG_VP9_TEMPORAL_DENOISING
- if (cpi->oxcf.noise_sensitivity > 0 &&
- output_enabled &&
- cpi->common.frame_type != KEY_FRAME &&
- cpi->resize_pending == 0) {
- vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col,
- VPXMAX(BLOCK_8X8, bsize), ctx);
- }
-#endif
-
encode_superblock(cpi, td, tp, output_enabled, mi_row, mi_col, bsize, ctx);
update_stats(&cpi->common, td);
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 938a527c5..02e967401 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1143,6 +1143,9 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int best_pred_sad = INT_MAX;
int best_early_term = 0;
int ref_frame_cost[MAX_REF_FRAMES];
+#if CONFIG_VP9_TEMPORAL_DENOISING
+ int64_t zero_last_cost_orig = INT64_MAX;
+#endif
init_ref_frame_cost(cm, xd, ref_frame_cost);
@@ -1524,8 +1527,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
#if CONFIG_VP9_TEMPORAL_DENOISING
- if (cpi->oxcf.noise_sensitivity > 0)
+ if (cpi->oxcf.noise_sensitivity > 0) {
vp9_denoiser_update_frame_stats(mbmi, sse_y, this_mode, ctx);
+ // Keep track of zero_last cost.
+ if (ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0)
+ zero_last_cost_orig = this_rdc.rdcost;
+ }
#else
(void)ctx;
#endif
@@ -1683,6 +1690,54 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
}
+#if CONFIG_VP9_TEMPORAL_DENOISING
+ if (cpi->oxcf.noise_sensitivity > 0 &&
+ cpi->resize_pending == 0) {
+ VP9_DENOISER_DECISION decision = COPY_BLOCK;
+ vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col,
+ VPXMAX(BLOCK_8X8, bsize), ctx, &decision);
+ // If INTRA mode was selected, re-evaluate ZEROMV on denoised result.
+ // Only do this under noise conditions, and if rdcost of ZEROMV on
+ // original source is not significantly higher than rdcost of INTRA MODE.
+ if (best_ref_frame == INTRA_FRAME &&
+ decision == FILTER_BLOCK &&
+ cpi->noise_estimate.enabled &&
+ cpi->noise_estimate.level > kLow &&
+ zero_last_cost_orig < (best_rdc.rdcost << 2) &&
+ !reuse_inter_pred) {
+ // Check if we should pick ZEROMV on denoised signal.
+ int rate = 0;
+ int64_t dist = 0;
+ mbmi->mode = ZEROMV;
+ mbmi->ref_frame[0] = LAST_FRAME;
+ mbmi->ref_frame[1] = NONE;
+ mbmi->mv[0].as_int = 0;
+ mbmi->interp_filter = EIGHTTAP;
+ vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
+ model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y);
+ this_rdc.rate = rate + ref_frame_cost[LAST_FRAME] +
+ cpi->inter_mode_cost[x->mbmi_ext->mode_context[LAST_FRAME]]
+ [INTER_OFFSET(ZEROMV)];
+ this_rdc.dist = dist;
+ this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, rate, dist);
+ // Switch to ZEROMV if the rdcost for ZEROMV on denoised source
+ // is lower than INTRA (on original source).
+ if (this_rdc.rdcost > best_rdc.rdcost) {
+ this_rdc = best_rdc;
+ mbmi->mode = best_mode;
+ mbmi->ref_frame[0] = best_ref_frame;
+ mbmi->mv[0].as_int = INVALID_MV;
+ mbmi->interp_filter = best_pred_filter;
+ mbmi->tx_size = best_tx_size;
+ x->skip_txfm[0] = best_mode_skip_txfm;
+ } else {
+ best_ref_frame = LAST_FRAME;
+ best_rdc = this_rdc;
+ }
+ }
+ }
+#endif
+
if (cpi->sf.adaptive_rd_thresh) {
THR_MODES best_mode_idx = mode_idx[best_ref_frame][mode_offset(mbmi->mode)];
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 318d8100c..20516a0c9 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -380,6 +380,16 @@ static void set_rt_speed_feature(VP9_COMP *cpi, SPEED_FEATURES *sf,
sf->adaptive_rd_thresh = 2;
// This feature is only enabled when partition search is disabled.
sf->reuse_inter_pred_sby = 1;
+ // TODO(marpan): When denoising, we may re-evaluate the mode selection and
+ // this seems to cause problems when reuse_inter_pred_sby is enabled.
+ // Disabling reuse_inter_pred_sby for now (under denoising conditions), and
+ // will look into re-enabling it.
+#if CONFIG_VP9_TEMPORAL_DENOISING
+ if (cpi->oxcf.noise_sensitivity > 0 &&
+ cpi->noise_estimate.enabled &&
+ cpi->noise_estimate.level > kLow)
+ sf->reuse_inter_pred_sby = 0;
+#endif
sf->partition_search_breakout_rate_thr = 200;
sf->coeff_prob_appx_step = 4;
sf->use_fast_coef_updates = is_keyframe ? TWO_LOOP : ONE_LOOP_REDUCED;