Merge "Allow for deblocking temporal-denoised signal."
This commit is contained in:
Коммит
c153903660
|
@ -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);
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче