summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/common/blockd.h6
-rw-r--r--vp8/encoder/block.h10
-rw-r--r--vp8/encoder/denoising.c205
-rw-r--r--vp8/encoder/denoising.h4
-rw-r--r--vp8/encoder/encodeframe.c8
-rw-r--r--vp8/encoder/onyx_if.c42
-rw-r--r--vp8/encoder/pickinter.c112
-rw-r--r--vp8/encoder/pickinter.h4
-rw-r--r--vp8/encoder/rdopt.c129
-rw-r--r--vp8_scalable_patterns.c2
10 files changed, 321 insertions, 201 deletions
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index a4c1d920c..7c648daaa 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -216,12 +216,6 @@ typedef struct macroblockd
MODE_INFO *mode_info_context;
int mode_info_stride;
-#if CONFIG_TEMPORAL_DENOISING
- MB_PREDICTION_MODE best_sse_inter_mode;
- int_mv best_sse_mv;
- unsigned char need_to_clamp_best_mvs;
-#endif
-
FRAME_TYPE frame_type;
int up_available;
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index 6165d048c..a98fd50f0 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -119,6 +119,16 @@ typedef struct macroblock
int optimize;
int q_index;
+#if CONFIG_TEMPORAL_DENOISING
+ MB_PREDICTION_MODE best_sse_inter_mode;
+ int_mv best_sse_mv;
+ MV_REFERENCE_FRAME best_reference_frame;
+ MV_REFERENCE_FRAME best_zeromv_reference_frame;
+ unsigned char need_to_clamp_best_mvs;
+#endif
+
+
+
void (*short_fdct4x4)(short *input, short *output, int pitch);
void (*short_fdct8x4)(short *input, short *output, int pitch);
void (*short_walsh4x4)(short *input, short *output, int pitch);
diff --git a/vp8/encoder/denoising.c b/vp8/encoder/denoising.c
index 45d54ee01..194d42229 100644
--- a/vp8/encoder/denoising.c
+++ b/vp8/encoder/denoising.c
@@ -22,68 +22,6 @@ static const unsigned int SSE_DIFF_THRESHOLD = 16 * 16 * 20;
static const unsigned int SSE_THRESHOLD = 16 * 16 * 40;
-static unsigned int denoiser_motion_compensate(YV12_BUFFER_CONFIG *src,
- YV12_BUFFER_CONFIG *dst,
- MACROBLOCK *x,
- unsigned int best_sse,
- unsigned int zero_mv_sse,
- int recon_yoffset,
- int recon_uvoffset)
-{
- MACROBLOCKD filter_xd = x->e_mbd;
- int mv_col;
- int mv_row;
- int sse_diff = zero_mv_sse - best_sse;
- // Compensate the running average.
- filter_xd.pre.y_buffer = src->y_buffer + recon_yoffset;
- filter_xd.pre.u_buffer = src->u_buffer + recon_uvoffset;
- filter_xd.pre.v_buffer = src->v_buffer + recon_uvoffset;
- // Write the compensated running average to the destination buffer.
- filter_xd.dst.y_buffer = dst->y_buffer + recon_yoffset;
- filter_xd.dst.u_buffer = dst->u_buffer + recon_uvoffset;
- filter_xd.dst.v_buffer = dst->v_buffer + recon_uvoffset;
- // Use the best MV for the compensation.
- filter_xd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
- filter_xd.mode_info_context->mbmi.mode = filter_xd.best_sse_inter_mode;
- filter_xd.mode_info_context->mbmi.mv = filter_xd.best_sse_mv;
- filter_xd.mode_info_context->mbmi.need_to_clamp_mvs =
- filter_xd.need_to_clamp_best_mvs;
- mv_col = filter_xd.best_sse_mv.as_mv.col;
- mv_row = filter_xd.best_sse_mv.as_mv.row;
-
- if (filter_xd.mode_info_context->mbmi.mode <= B_PRED ||
- (mv_row *mv_row + mv_col *mv_col <= NOISE_MOTION_THRESHOLD &&
- sse_diff < SSE_DIFF_THRESHOLD))
- {
- // Handle intra blocks as referring to last frame with zero motion and
- // let the absolute pixel difference affect the filter factor.
- // Also consider small amount of motion as being random walk due to
- // noise, if it doesn't mean that we get a much bigger error.
- // Note that any changes to the mode info only affects the denoising.
- filter_xd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
- filter_xd.mode_info_context->mbmi.mode = ZEROMV;
- filter_xd.mode_info_context->mbmi.mv.as_int = 0;
- x->e_mbd.best_sse_inter_mode = ZEROMV;
- x->e_mbd.best_sse_mv.as_int = 0;
- best_sse = zero_mv_sse;
- }
-
- if (!x->skip)
- {
- vp8_build_inter_predictors_mb(&filter_xd);
- }
- else
- {
- vp8_build_inter16x16_predictors_mb(&filter_xd,
- filter_xd.dst.y_buffer,
- filter_xd.dst.u_buffer,
- filter_xd.dst.v_buffer,
- filter_xd.dst.y_stride,
- filter_xd.dst.uv_stride);
- }
-
- return best_sse;
-}
// The filtering coefficients used for denoizing are adjusted for static
// blocks, or blocks with very small motion vectors. This is done through
@@ -216,27 +154,34 @@ void vp8_denoiser_filter_c(YV12_BUFFER_CONFIG *mc_running_avg,
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
{
+ int i;
assert(denoiser);
- denoiser->yv12_running_avg.flags = 0;
- if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg), width,
- height, VP8BORDERINPIXELS) < 0)
+ /* don't need one for intra start at 1 */
+ for (i = 1; i < MAX_REF_FRAMES; i++)
{
- vp8_denoiser_free(denoiser);
- return 1;
- }
+ denoiser->yv12_running_avg[i].flags = 0;
+ if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_running_avg[i]), width,
+ height, VP8BORDERINPIXELS)
+ < 0)
+ {
+ vp8_denoiser_free(denoiser);
+ return 1;
+ }
+ vpx_memset(denoiser->yv12_running_avg[i].buffer_alloc, 0,
+ denoiser->yv12_running_avg[i].frame_size);
+
+ }
denoiser->yv12_mc_running_avg.flags = 0;
if (vp8_yv12_alloc_frame_buffer(&(denoiser->yv12_mc_running_avg), width,
- height, VP8BORDERINPIXELS) < 0)
+ height, VP8BORDERINPIXELS) < 0)
{
vp8_denoiser_free(denoiser);
return 1;
}
- vpx_memset(denoiser->yv12_running_avg.buffer_alloc, 0,
- denoiser->yv12_running_avg.frame_size);
vpx_memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0,
denoiser->yv12_mc_running_avg.frame_size);
return 0;
@@ -244,11 +189,18 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
void vp8_denoiser_free(VP8_DENOISER *denoiser)
{
+ int i;
assert(denoiser);
- vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg);
+
+ /* we don't have one for intra ref frame */
+ for (i = 1; i < MAX_REF_FRAMES ; i++)
+ {
+ vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_running_avg[i]);
+ }
vp8_yv12_de_alloc_frame_buffer(&denoiser->yv12_mc_running_avg);
}
+
void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
MACROBLOCK *x,
unsigned int best_sse,
@@ -259,32 +211,103 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
int mv_row;
int mv_col;
unsigned int motion_magnitude2;
+
+ MV_REFERENCE_FRAME frame = x->best_reference_frame;
+ MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame;
+
// Motion compensate the running average.
- best_sse = denoiser_motion_compensate(&denoiser->yv12_running_avg,
- &denoiser->yv12_mc_running_avg,
- x,
- best_sse,
- zero_mv_sse,
- recon_yoffset,
- recon_uvoffset);
-
- mv_row = x->e_mbd.best_sse_mv.as_mv.row;
- mv_col = x->e_mbd.best_sse_mv.as_mv.col;
- motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
+ if(zero_frame)
+ {
+ YV12_BUFFER_CONFIG *src = &denoiser->yv12_running_avg[frame];
+ YV12_BUFFER_CONFIG *dst = &denoiser->yv12_mc_running_avg;
+ YV12_BUFFER_CONFIG saved_pre,saved_dst;
+ MB_MODE_INFO saved_mbmi;
+ MACROBLOCKD *filter_xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &filter_xd->mode_info_context->mbmi;
+ int mv_col;
+ int mv_row;
+ int sse_diff = zero_mv_sse - best_sse;
+
+ saved_mbmi = *mbmi;
+
+ // Use the best MV for the compensation.
+ mbmi->ref_frame = x->best_reference_frame;
+ mbmi->mode = x->best_sse_inter_mode;
+ mbmi->mv = x->best_sse_mv;
+ mbmi->need_to_clamp_mvs = x->need_to_clamp_best_mvs;
+ mv_col = x->best_sse_mv.as_mv.col;
+ mv_row = x->best_sse_mv.as_mv.row;
+
+ if(frame == INTRA_FRAME ||
+ (mv_row *mv_row + mv_col *mv_col <= NOISE_MOTION_THRESHOLD &&
+ sse_diff < SSE_DIFF_THRESHOLD))
+ {
+ // Handle intra blocks as referring to last frame with zero motion
+ // and let the absolute pixel difference affect the filter factor.
+ // Also consider small amount of motion as being random walk due to
+ // noise, if it doesn't mean that we get a much bigger error.
+ // Note that any changes to the mode info only affects the denoising.
+ mbmi->ref_frame =
+ x->best_zeromv_reference_frame;
+
+ src = &denoiser->yv12_running_avg[zero_frame];
+
+ mbmi->mode = ZEROMV;
+ mbmi->mv.as_int = 0;
+ x->best_sse_inter_mode = ZEROMV;
+ x->best_sse_mv.as_int = 0;
+ best_sse = zero_mv_sse;
+ }
+
+ saved_pre = filter_xd->pre;
+ saved_dst = filter_xd->dst;
- if (best_sse > SSE_THRESHOLD ||
- motion_magnitude2 > 8 * NOISE_MOTION_THRESHOLD)
+ // Compensate the running average.
+ filter_xd->pre.y_buffer = src->y_buffer + recon_yoffset;
+ filter_xd->pre.u_buffer = src->u_buffer + recon_uvoffset;
+ filter_xd->pre.v_buffer = src->v_buffer + recon_uvoffset;
+ // Write the compensated running average to the destination buffer.
+ filter_xd->dst.y_buffer = dst->y_buffer + recon_yoffset;
+ filter_xd->dst.u_buffer = dst->u_buffer + recon_uvoffset;
+ filter_xd->dst.v_buffer = dst->v_buffer + recon_uvoffset;
+
+ if (!x->skip)
+ {
+ vp8_build_inter_predictors_mb(filter_xd);
+ }
+ else
+ {
+ vp8_build_inter16x16_predictors_mb(filter_xd,
+ filter_xd->dst.y_buffer,
+ filter_xd->dst.u_buffer,
+ filter_xd->dst.v_buffer,
+ filter_xd->dst.y_stride,
+ filter_xd->dst.uv_stride);
+ }
+ filter_xd->pre = saved_pre;
+ filter_xd->dst = saved_dst;
+ *mbmi = saved_mbmi;
+
+ }
+
+ mv_row = x->best_sse_mv.as_mv.row;
+ mv_col = x->best_sse_mv.as_mv.col;
+ motion_magnitude2 = mv_row * mv_row + mv_col * mv_col;
+ if (best_sse > SSE_THRESHOLD || motion_magnitude2
+ > 8 * NOISE_MOTION_THRESHOLD)
{
- // No filtering of this block since it differs too much from the
- // predictor, or the motion vector magnitude is considered too big.
- vp8_copy_mem16x16(x->thismb, 16,
- denoiser->yv12_running_avg.y_buffer + recon_yoffset,
- denoiser->yv12_running_avg.y_stride);
+ // No filtering of this block; it differs too much from the predictor,
+ // or the motion vector magnitude is considered too big.
+ vp8_copy_mem16x16(
+ x->thismb, 16,
+ denoiser->yv12_running_avg[LAST_FRAME].y_buffer + recon_yoffset,
+ denoiser->yv12_running_avg[LAST_FRAME].y_stride);
return;
}
// Filter.
vp8_denoiser_filter(&denoiser->yv12_mc_running_avg,
- &denoiser->yv12_running_avg, x, motion_magnitude2,
+ &denoiser->yv12_running_avg[LAST_FRAME], x,
+ motion_magnitude2,
recon_yoffset, recon_uvoffset);
}
diff --git a/vp8/encoder/denoising.h b/vp8/encoder/denoising.h
index 0a54e71a2..441bccde3 100644
--- a/vp8/encoder/denoising.h
+++ b/vp8/encoder/denoising.h
@@ -17,8 +17,8 @@
typedef struct vp8_denoiser
{
- YV12_BUFFER_CONFIG yv12_running_avg;
- YV12_BUFFER_CONFIG yv12_mc_running_avg;
+ YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES];
+ YV12_BUFFER_CONFIG yv12_mc_running_avg;
} VP8_DENOISER;
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height);
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 82338736d..4450ab21a 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1177,9 +1177,11 @@ int vp8cx_encode_inter_macroblock
#if CONFIG_TEMPORAL_DENOISING
// Reset the best sse mode/mv for each macroblock.
- x->e_mbd.best_sse_inter_mode = 0;
- x->e_mbd.best_sse_mv.as_int = 0;
- x->e_mbd.need_to_clamp_best_mvs = 0;
+ x->best_reference_frame = INTRA_FRAME;
+ x->best_zeromv_reference_frame = INTRA_FRAME;
+ x->best_sse_inter_mode = 0;
+ x->best_sse_mv.as_int = 0;
+ x->need_to_clamp_best_mvs = 0;
#endif
if (cpi->sf.RD)
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 0f4bc1d1a..878cad48b 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3156,9 +3156,49 @@ void vp8_loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
#if CONFIG_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity)
{
- vp8_yv12_extend_frame_borders(&cpi->denoiser.yv12_running_avg);
+
+
+ /* we shouldn't have to keep multiple copies as we know in advance which
+ * buffer we should start - for now to get something up and running
+ * I've chosen to copy the buffers
+ */
+ if (cm->frame_type == KEY_FRAME)
+ {
+ int i;
+ vp8_yv12_copy_frame(
+ cpi->Source,
+ &cpi->denoiser.yv12_running_avg[LAST_FRAME]);
+
+ vp8_yv12_extend_frame_borders(
+ &cpi->denoiser.yv12_running_avg[LAST_FRAME]);
+
+ for (i = 2; i < MAX_REF_FRAMES - 1; i++)
+ vp8_yv12_copy_frame(
+ cpi->Source,
+ &cpi->denoiser.yv12_running_avg[i]);
+ }
+ else /* For non key frames */
+ {
+ vp8_yv12_extend_frame_borders(
+ &cpi->denoiser.yv12_running_avg[LAST_FRAME]);
+
+ if (cm->refresh_alt_ref_frame || cm->copy_buffer_to_arf)
+ {
+ vp8_yv12_copy_frame(
+ &cpi->denoiser.yv12_running_avg[LAST_FRAME],
+ &cpi->denoiser.yv12_running_avg[ALTREF_FRAME]);
+ }
+ if (cm->refresh_golden_frame || cm->copy_buffer_to_gf)
+ {
+ vp8_yv12_copy_frame(
+ &cpi->denoiser.yv12_running_avg[LAST_FRAME],
+ &cpi->denoiser.yv12_running_avg[GOLDEN_FRAME]);
+ }
+ }
+
}
#endif
+
}
static void encode_frame_to_data_rate
diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c
index dafb64527..7f8171316 100644
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -61,7 +61,7 @@ int vp8_skip_fractional_mv_step(MACROBLOCK *mb, BLOCK *b, BLOCKD *d,
}
-static int get_inter_mbpred_error(MACROBLOCK *mb,
+int vp8_get_inter_mbpred_error(MACROBLOCK *mb,
const vp8_variance_fn_ptr_t *vfp,
unsigned int *sse,
int_mv this_mv)
@@ -486,7 +486,7 @@ static int evaluate_inter_mode(unsigned int* sse, int rate2, int* distortion2, V
if((this_mode != NEWMV) ||
!(cpi->sf.half_pixel_search) || cpi->common.full_pixel==1)
- *distortion2 = get_inter_mbpred_error(x,
+ *distortion2 = vp8_get_inter_mbpred_error(x,
&cpi->fn_ptr[BLOCK_16X16],
sse, mv);
@@ -523,7 +523,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int best_mode_index = 0;
unsigned int sse = INT_MAX, best_rd_sse = INT_MAX;
#if CONFIG_TEMPORAL_DENOISING
- unsigned int zero_mv_sse = 0, best_sse = INT_MAX;
+ unsigned int zero_mv_sse = INT_MAX, best_sse = INT_MAX;
#endif
int_mv mvp;
@@ -964,25 +964,27 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#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;
- }
+
+ // Store for later use by denoiser.
+ if (this_mode == ZEROMV && sse < zero_mv_sse )
+ {
+ zero_mv_sse = sse;
+ x->best_zeromv_reference_frame =
+ x->e_mbd.mode_info_context->mbmi.ref_frame;
+ }
+
+ // Store the best NEWMV in x for later use in the denoiser.
+ if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV &&
+ sse < best_sse)
+ {
+ best_sse = sse;
+ x->best_sse_inter_mode = NEWMV;
+ x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
+ x->need_to_clamp_best_mvs =
+ x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
+ x->best_reference_frame =
+ x->e_mbd.mode_info_context->mbmi.ref_frame;
+ }
}
#endif
@@ -1058,37 +1060,47 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#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 (x->best_sse_inter_mode == DC_PRED)
+ {
+ // No best MV found.
+ x->best_sse_inter_mode = best_mbmode.mode;
+ x->best_sse_mv = best_mbmode.mv;
+ x->need_to_clamp_best_mvs = best_mbmode.need_to_clamp_mvs;
+ x->best_reference_frame = best_mbmode.ref_frame;
+ best_sse = best_rd_sse;
+ }
+ vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
+ recon_yoffset, recon_uvoffset);
- if (this_rd < best_rd || x->skip)
+
+ // Reevaluate ZEROMV after denoising.
+ if (best_mbmode.ref_frame == INTRA_FRAME &&
+ x->best_zeromv_reference_frame != INTRA_FRAME)
{
- vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
- sizeof(MB_MODE_INFO));
+ int this_rd = 0;
+ int this_ref_frame = x->best_zeromv_reference_frame;
+ rate2 = x->ref_frame_cost[this_ref_frame] +
+ vp8_cost_mv_ref(ZEROMV, mdcounts);
+ distortion2 = 0;
+
+ // set up the proper prediction buffers for the frame
+ x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
+ x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
+ x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
+ x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
+
+ x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
+ 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)
+ {
+ vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi,
+ sizeof(MB_MODE_INFO));
+ }
}
- }
+
}
#endif
diff --git a/vp8/encoder/pickinter.h b/vp8/encoder/pickinter.h
index 3d83782b5..6fbd88795 100644
--- a/vp8/encoder/pickinter.h
+++ b/vp8/encoder/pickinter.h
@@ -20,4 +20,8 @@ extern void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int mb_row, int mb_col);
extern void vp8_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate);
+extern int vp8_get_inter_mbpred_error(MACROBLOCK *mb,
+ const vp8_variance_fn_ptr_t *vfp,
+ unsigned int *sse,
+ int_mv this_mv);
#endif
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 2b706ba9e..27956b154 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -21,6 +21,7 @@
#include "onyx_int.h"
#include "modecosts.h"
#include "encodeintra.h"
+#include "pickinter.h"
#include "vp8/common/entropymode.h"
#include "vp8/common/reconinter.h"
#include "vp8/common/reconintra4x4.h"
@@ -36,7 +37,6 @@
#if CONFIG_TEMPORAL_DENOISING
#include "denoising.h"
#endif
-
extern void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x);
#define MAXF(a,b) (((a) > (b)) ? (a) : (b))
@@ -1962,6 +1962,11 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int intra_rd_penalty = 10* vp8_dc_quant(cpi->common.base_qindex,
cpi->common.y1dc_delta_q);
+#if CONFIG_TEMPORAL_DENOISING
+ unsigned int zero_mv_sse = INT_MAX, best_sse = INT_MAX,
+ best_rd_sse = INT_MAX;
+#endif
+
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = 0;
best_mode.rd = INT_MAX;
@@ -2372,21 +2377,38 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
best_mode.intra_rd = this_rd;
*returnintra = rd.distortion2 ;
}
-
#if CONFIG_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity)
{
- // 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)
- {
- 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;
- }
+ unsigned int sse;
+ vp8_get_inter_mbpred_error(x,&cpi->fn_ptr[BLOCK_16X16],&sse,
+ mode_mv[this_mode]);
+
+ if (sse < best_rd_sse)
+ best_rd_sse = sse;
+
+ // Store for later use by denoiser.
+ if (this_mode == ZEROMV && sse < zero_mv_sse )
+ {
+ zero_mv_sse = sse;
+ x->best_zeromv_reference_frame =
+ x->e_mbd.mode_info_context->mbmi.ref_frame;
+ }
+
+ // Store the best NEWMV in x for later use in the denoiser.
+ if (x->e_mbd.mode_info_context->mbmi.mode == NEWMV &&
+ sse < best_sse)
+ {
+ best_sse = sse;
+ vp8_get_inter_mbpred_error(x,&cpi->fn_ptr[BLOCK_16X16],&best_sse,
+ mode_mv[this_mode]);
+ x->best_sse_inter_mode = NEWMV;
+ x->best_sse_mv = x->e_mbd.mode_info_context->mbmi.mv;
+ x->need_to_clamp_best_mvs =
+ x->e_mbd.mode_info_context->mbmi.need_to_clamp_mvs;
+ x->best_reference_frame =
+ x->e_mbd.mode_info_context->mbmi.ref_frame;
+ }
}
#endif
@@ -2459,42 +2481,55 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#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_mode.mbmode.mode;
- x->e_mbd.best_sse_mv = best_mode.mbmode.mv;
- x->e_mbd.need_to_clamp_best_mvs = best_mode.mbmode.need_to_clamp_mvs;
- }
-
- // TODO(holmer): No SSEs are calculated in rdopt.c. What else can be used?
- vp8_denoiser_denoise_mb(&cpi->denoiser, x, 0, 0,
- recon_yoffset, recon_uvoffset);
- // Reevalute ZEROMV if the current mode is INTRA.
- if (best_mode.mbmode.ref_frame == INTRA_FRAME)
- {
- int this_rd = INT_MAX;
- int disable_skip = 0;
- int other_cost = 0;
- vpx_memset(&rd, 0, sizeof(rd));
- x->e_mbd.mode_info_context->mbmi.ref_frame = LAST_FRAME;
- rd.rate2 += x->ref_frame_cost[LAST_FRAME];
- rd.rate2 += vp8_cost_mv_ref(ZEROMV, mdcounts);
- x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
- 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_rd(mdcounts, &rd, &disable_skip, cpi, x);
- this_rd = calculate_final_rd_costs(this_rd, &rd, &other_cost,
- disable_skip, uv_intra_tteob,
- intra_rd_penalty, cpi, x);
- if (this_rd < best_mode.rd || x->skip)
+ if (x->best_sse_inter_mode == DC_PRED)
{
- // Note index of best mode so far
- best_mode_index = mode_index;
- *returnrate = rd.rate2;
- *returndistortion = rd.distortion2;
- update_best_mode(&best_mode, this_rd, &rd, other_cost, x);
+ // No best MV found.
+ x->best_sse_inter_mode = best_mode.mbmode.mode;
+ x->best_sse_mv = best_mode.mbmode.mv;
+ x->need_to_clamp_best_mvs = best_mode.mbmode.need_to_clamp_mvs;
+ x->best_reference_frame = best_mode.mbmode.ref_frame;
+ 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_mode.mbmode.ref_frame == INTRA_FRAME &&
+ x->best_zeromv_reference_frame != INTRA_FRAME)
+ {
+ int this_rd = INT_MAX;
+ int disable_skip = 0;
+ int other_cost = 0;
+ int this_ref_frame = x->best_zeromv_reference_frame;
+ rd.rate2 = x->ref_frame_cost[this_ref_frame] +
+ vp8_cost_mv_ref(ZEROMV, mdcounts);
+ rd.distortion2 = 0;
+
+ // set up the proper prediction buffers for the frame
+ x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
+ x->e_mbd.pre.y_buffer = plane[this_ref_frame][0];
+ x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
+ x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
+
+ x->e_mbd.mode_info_context->mbmi.mode = ZEROMV;
+ 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_rd(mdcounts, &rd, &disable_skip, cpi, x);
+ this_rd = calculate_final_rd_costs(this_rd, &rd, &other_cost,
+ disable_skip, uv_intra_tteob,
+ intra_rd_penalty, cpi, x);
+ if (this_rd < best_mode.rd || x->skip)
+ {
+ // Note index of best mode so far
+ best_mode_index = mode_index;
+ *returnrate = rd.rate2;
+ *returndistortion = rd.distortion2;
+ update_best_mode(&best_mode, this_rd, &rd, other_cost, x);
+ }
+ }
+
}
#endif
diff --git a/vp8_scalable_patterns.c b/vp8_scalable_patterns.c
index 4311b1a04..935187418 100644
--- a/vp8_scalable_patterns.c
+++ b/vp8_scalable_patterns.c
@@ -493,7 +493,7 @@ int main(int argc, char **argv) {
// Cap CPU & first I-frame size
vpx_codec_control (&codec, VP8E_SET_CPUUSED, -6);
vpx_codec_control (&codec, VP8E_SET_STATIC_THRESHOLD, 800);
- vpx_codec_control (&codec, VP8E_SET_NOISE_SENSITIVITY, 2);
+ vpx_codec_control (&codec, VP8E_SET_NOISE_SENSITIVITY, 1);
max_intra_size_pct = (int) (((double)cfg.rc_buf_optimal_sz * 0.5)
* ((double) cfg.g_timebase.den / cfg.g_timebase.num)