summaryrefslogtreecommitdiff
path: root/vp8/encoder/pickinter.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder/pickinter.c')
-rw-r--r--vp8/encoder/pickinter.c151
1 files changed, 114 insertions, 37 deletions
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index 236cb2326..ef1fd9ffe 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -24,6 +24,9 @@
#include "mcomp.h"
#include "rdopt.h"
#include "vpx_mem/vpx_mem.h"
+#if CONFIG_TEMPORAL_DENOISING
+#include "denoising.h"
+#endif
extern int VP8_UVSSE(MACROBLOCK *x);
@@ -450,6 +453,48 @@ void get_lower_res_motion_info(VP8_COMP *cpi, MACROBLOCKD *xd, int *dissim,
}
#endif
+static void check_for_encode_breakout(unsigned int sse, MACROBLOCK* x)
+{
+ if (sse < x->encode_breakout)
+ {
+ // Check u and v to make sure skip is ok
+ int sse2 = 0;
+
+ sse2 = VP8_UVSSE(x);
+
+ if (sse2 * 2 < x->encode_breakout)
+ x->skip = 1;
+ else
+ x->skip = 0;
+ }
+}
+
+static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2, VP8_COMP *cpi, MACROBLOCK *x)
+{
+ MB_PREDICTION_MODE this_mode = x->e_mbd.mode_info_context->mbmi.mode;
+ int_mv mv = x->e_mbd.mode_info_context->mbmi.mv;
+ int this_rd;
+ /* Exit early and don't compute the distortion if this macroblock
+ * is marked inactive. */
+ if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+ {
+ *sse = 0;
+ *distortion2 = 0;
+ x->skip = 1;
+ return INT_MAX;
+ }
+
+ if((this_mode != NEWMV) ||
+ !(cpi->sf.half_pixel_search) || cpi->common.full_pixel==1)
+ *distortion2 = get_inter_mbpred_error(x,
+ &cpi->fn_ptr[BLOCK_16X16],
+ sse, mv);
+
+ this_rd = RDCOST(x->rdmult, x->rddiv, rate2, *distortion2);
+
+ check_for_encode_breakout(*sse, x);
+ return this_rd;
+}
void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int recon_uvoffset, int *returnrate,
@@ -476,7 +521,10 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int distortion2;
int bestsme = INT_MAX;
int best_mode_index = 0;
- unsigned int sse = INT_MAX, best_sse = INT_MAX;
+ unsigned int sse = INT_MAX, best_rd_sse = INT_MAX;
+#if CONFIG_TEMPORAL_DENOISING
+ unsigned int zero_mv_sse = 0, best_sse = INT_MAX;
+#endif
int_mv mvp;
@@ -488,9 +536,6 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int ref_frame_map[4];
int sign_bias = 0;
- int have_subp_search = cpi->sf.half_pixel_search; /* In real-time mode,
- when Speed >= 15, no sub-pixel search. */
-
#if CONFIG_MULTI_RES_ENCODING
int dissim = INT_MAX;
int parent_ref_frame = 0;
@@ -657,7 +702,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
{
case B_PRED:
/* Pass best so far to pick_intra4x4mby_modes to use as breakout */
- distortion2 = best_sse;
+ distortion2 = best_rd_sse;
pick_intra4x4mby_modes(x, &rate, &distortion2);
if (distortion2 == INT_MAX)
@@ -905,43 +950,38 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
x->e_mbd.mode_info_context->mbmi.mv.as_int =
mode_mv[this_mode].as_int;
-
- /* Exit early and don't compute the distortion if this macroblock
- * is marked inactive. */
- if (cpi->active_map_enabled && x->active_ptr[0] == 0)
- {
- sse = 0;
- distortion2 = 0;
- x->skip = 1;
- break;
- }
-
- if((this_mode != NEWMV) ||
- !(have_subp_search) || cpi->common.full_pixel==1)
- distortion2 = get_inter_mbpred_error(x,
- &cpi->fn_ptr[BLOCK_16X16],
- &sse, mode_mv[this_mode]);
-
- this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
-
- if (sse < x->encode_breakout)
- {
- // Check u and v to make sure skip is ok
- int sse2 = 0;
-
- sse2 = VP8_UVSSE(x);
-
- if (sse2 * 2 < x->encode_breakout)
- x->skip = 1;
- else
- x->skip = 0;
- }
+ this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x);
break;
default:
break;
}
+#if CONFIG_TEMPORAL_DENOISING
+ if (cpi->oxcf.noise_sensitivity)
+ {
+ // Store for later use by denoiser.
+ if (this_mode == ZEROMV &&
+ x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME)
+ {
+ zero_mv_sse = sse;
+ }
+
+ // Store the best NEWMV in x for later use in the denoiser.
+ // We are restricted to the LAST_FRAME since the denoiser only keeps
+ // one filter state.
+ if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV &&
+ x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME)
+ {
+ best_sse = sse;
+ x->e_mbd.best_sse_inter_mode = NEWMV;
+ x->e_mbd.best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
+ x->e_mbd.need_to_clamp_best_mvs =
+ x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
+ }
+ }
+#endif
+
if (this_rd < best_rd || x->skip)
{
// Note index of best mode
@@ -949,7 +989,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
*returnrate = rate2;
*returndistortion = distortion2;
- best_sse = sse;
+ best_rd_sse = sse;
best_rd = this_rd;
vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
sizeof(MB_MODE_INFO));
@@ -1011,6 +1051,43 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
cpi->error_bins[this_rdbin] ++;
}
+#if CONFIG_TEMPORAL_DENOISING
+ if (cpi->oxcf.noise_sensitivity)
+ {
+ if (x->e_mbd.best_sse_inter_mode == DC_PRED) {
+ // No best MV found.
+ x->e_mbd.best_sse_inter_mode = best_mbmode.mode;
+ x->e_mbd.best_sse_mv = best_mbmode.mv;
+ x->e_mbd.need_to_clamp_best_mvs = best_mbmode.need_to_clamp_mvs;
+ best_sse = best_rd_sse;
+ }
+ vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
+ recon_yoffset, recon_uvoffset);
+
+ // Reevaluate ZEROMV after denoising.
+ if (best_mbmode.ref_frame == INTRA_FRAME)
+ {
+ int this_rd = 0;
+ rate2 = 0;
+ distortion2 = 0;
+ x->e_mbd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
+ rate2 += x->ref_frame_cost[x->e_mbd.mode_info_context->mbmi.ref_frame];
+ this_mode = ZEROMV;
+ rate2 += vp8_cost_mv_ref(this_mode, mdcounts);
+ x->e_mbd.mode_info_context->mbmi.mode = this_mode;
+ x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
+ x->e_mbd.mode_info_context->mbmi.mv.as_int = 0;
+ this_rd = evaluate_inter_mode(&sse, rate2, &distortion2, cpi, x);
+
+ if (this_rd < best_rd || x->skip)
+ {
+ vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
+ sizeof(MB_MODE_INFO));
+ }
+ }
+ }
+#endif
+
if (cpi->is_src_frame_alt_ref &&
(best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
{