Commit c1539036 authored by Marco Paniconi's avatar Marco Paniconi Committed by Gerrit Code Review
Browse files

Merge "Allow for deblocking temporal-denoised signal."

parents bcfbd2f9 d08b2ba1
......@@ -191,10 +191,12 @@ int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride,
return FILTER_BLOCK;
}
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
int num_mb_rows, int num_mb_cols)
{
int i;
assert(denoiser);
denoiser->num_mb_cols = num_mb_cols;
for (i = 0; i < MAX_REF_FRAMES; i++)
{
......@@ -222,6 +224,10 @@ int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height)
vpx_memset(denoiser->yv12_mc_running_avg.buffer_alloc, 0,
denoiser->yv12_mc_running_avg.frame_size);
denoiser->denoise_state = vpx_calloc((num_mb_rows * num_mb_cols), 1);
vpx_memset(denoiser->denoise_state, 0, (num_mb_rows * num_mb_cols));
return 0;
}
......@@ -243,13 +249,20 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
unsigned int best_sse,
unsigned int zero_mv_sse,
int recon_yoffset,
int recon_uvoffset)
int recon_uvoffset,
loop_filter_info_n *lfi_n,
int mb_row,
int mb_col,
int block_index)
{
int mv_row;
int mv_col;
unsigned int motion_magnitude2;
unsigned int sse_thresh;
int sse_diff_thresh = 0;
// Spatial loop filter: only applied selectively based on
// temporal filter state of block relative to top/left neighbors.
int apply_spatial_loop_filter = 1;
MV_REFERENCE_FRAME frame = x->best_reference_frame;
MV_REFERENCE_FRAME zero_frame = x->best_zeromv_reference_frame;
......@@ -362,6 +375,8 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
running_avg_y, avg_y_stride,
x->thismb, 16, motion_magnitude2,
x->increase_denoising);
denoiser->denoise_state[block_index] = motion_magnitude2 > 0 ?
kFilterNonZeroMV : kFilterZeroMV;
}
if (decision == COPY_BLOCK)
{
......@@ -372,5 +387,59 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
x->thismb, 16,
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
denoiser->yv12_running_avg[INTRA_FRAME].y_stride);
denoiser->denoise_state[block_index] = kNoFilter;
}
// Option to selectively deblock the denoised signal.
if (apply_spatial_loop_filter) {
loop_filter_info lfi;
int apply_filter_col = 0;
int apply_filter_row = 0;
int apply_filter = 0;
int y_stride = denoiser->yv12_running_avg[INTRA_FRAME].y_stride;
int uv_stride =denoiser->yv12_running_avg[INTRA_FRAME].uv_stride;
// Fix filter level to some nominal value for now.
int filter_level = 32;
int hev_index = lfi_n->hev_thr_lut[INTER_FRAME][filter_level];
lfi.mblim = lfi_n->mblim[filter_level];
lfi.blim = lfi_n->blim[filter_level];
lfi.lim = lfi_n->lim[filter_level];
lfi.hev_thr = lfi_n->hev_thr[hev_index];
// Apply filter if there is a difference in the denoiser filter state
// between the current and left/top block, or if non-zero motion vector
// is used for the motion-compensated filtering.
if (mb_col > 0) {
apply_filter_col = !((denoiser->denoise_state[block_index] ==
denoiser->denoise_state[block_index - 1]) &&
denoiser->denoise_state[block_index] != kFilterNonZeroMV);
if (apply_filter_col) {
// Filter left vertical edge.
apply_filter = 1;
vp8_loop_filter_mbv(
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
NULL, NULL, y_stride, uv_stride, &lfi);
}
}
if (mb_row > 0) {
apply_filter_row = !((denoiser->denoise_state[block_index] ==
denoiser->denoise_state[block_index - denoiser->num_mb_cols]) &&
denoiser->denoise_state[block_index] != kFilterNonZeroMV);
if (apply_filter_row) {
// Filter top horizontal edge.
apply_filter = 1;
vp8_loop_filter_mbh(
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
NULL, NULL, y_stride, uv_stride, &lfi);
}
}
if (apply_filter) {
// Update the signal block |x|. Pixel changes are only to top and/or
// left boundary pixels: can we avoid full block copy here.
vp8_copy_mem16x16(
denoiser->yv12_running_avg[INTRA_FRAME].y_buffer + recon_yoffset,
y_stride, x->thismb, 16);
}
}
}
......@@ -12,6 +12,7 @@
#define VP8_ENCODER_DENOISING_H_
#include "block.h"
#include "vp8/common/loopfilter.h"
#ifdef __cplusplus
extern "C" {
......@@ -27,13 +28,22 @@ enum vp8_denoiser_decision
FILTER_BLOCK
};
enum vp8_denoiser_filter_state {
kNoFilter,
kFilterZeroMV,
kFilterNonZeroMV
};
typedef struct vp8_denoiser
{
YV12_BUFFER_CONFIG yv12_running_avg[MAX_REF_FRAMES];
YV12_BUFFER_CONFIG yv12_mc_running_avg;
unsigned char* denoise_state;
int num_mb_cols;
} VP8_DENOISER;
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height);
int vp8_denoiser_allocate(VP8_DENOISER *denoiser, int width, int height,
int num_mb_rows, int num_mb_cols);
void vp8_denoiser_free(VP8_DENOISER *denoiser);
......@@ -42,7 +52,11 @@ void vp8_denoiser_denoise_mb(VP8_DENOISER *denoiser,
unsigned int best_sse,
unsigned int zero_mv_sse,
int recon_yoffset,
int recon_uvoffset);
int recon_uvoffset,
loop_filter_info_n *lfi_n,
int mb_row,
int mb_col,
int block_index);
#ifdef __cplusplus
} // extern "C"
......
......@@ -1246,7 +1246,7 @@ int vp8cx_encode_inter_macroblock
x->zbin_mode_boost_enabled = 0;
}
vp8_rd_pick_inter_mode(cpi, x, recon_yoffset, recon_uvoffset, &rate,
&distortion, &intra_error);
&distortion, &intra_error, mb_row, mb_col);
/* switch back to the regular quantizer for the encode */
if (cpi->sf.improved_quant)
......
......@@ -1751,7 +1751,8 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf)
{
int width = (cpi->oxcf.Width + 15) & ~15;
int height = (cpi->oxcf.Height + 15) & ~15;
vp8_denoiser_allocate(&cpi->denoiser, width, height);
vp8_denoiser_allocate(&cpi->denoiser, width, height,
cpi->common.mb_rows, cpi->common.mb_cols);
}
}
#endif
......
......@@ -1168,6 +1168,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#if CONFIG_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity)
{
int block_index = mb_row * cpi->common.mb_cols + mb_col;
if (x->best_sse_inter_mode == DC_PRED)
{
/* No best MV found. */
......@@ -1179,7 +1180,9 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
}
x->increase_denoising = 0;
vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
recon_yoffset, recon_uvoffset);
recon_yoffset, recon_uvoffset,
&cpi->common.lf_info, mb_row, mb_col,
block_index);
/* Reevaluate ZEROMV after denoising. */
......
......@@ -1935,7 +1935,8 @@ static void update_best_mode(BEST_MODE* best_mode, int this_rd,
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int recon_uvoffset, int *returnrate,
int *returndistortion, int *returnintra)
int *returndistortion, int *returnintra,
int mb_row, int mb_col)
{
BLOCK *b = &x->block[0];
BLOCKD *d = &x->e_mbd.block[0];
......@@ -2510,6 +2511,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
#if CONFIG_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity)
{
int block_index = mb_row * cpi->common.mb_cols + mb_col;
if (x->best_sse_inter_mode == DC_PRED)
{
/* No best MV found. */
......@@ -2520,7 +2522,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
best_sse = best_rd_sse;
}
vp8_denoiser_denoise_mb(&cpi->denoiser, x, best_sse, zero_mv_sse,
recon_yoffset, recon_uvoffset);
recon_yoffset, recon_uvoffset,
&cpi->common.lf_info, mb_row, mb_col,
block_index);
/* Reevaluate ZEROMV after denoising. */
......
......@@ -70,7 +70,10 @@ static void insertsortsad(int arr[],int idx[], int len)
}
extern void vp8_initialize_rd_consts(VP8_COMP *cpi, MACROBLOCK *x, int Qvalue);
extern void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra);
extern void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x,
int recon_yoffset, int recon_uvoffset,
int *returnrate, int *returndistortion,
int *returnintra, int mb_row, int mb_col);
extern void vp8_rd_pick_intra_mode(MACROBLOCK *x, int *rate);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment