Adjustments to vp9-denoising.
Adjust variance threshold, delta-qp, and intra penalty cost, based on estimated noise level in source. Replace denoising_on with a level value=L/M/H. Change-Id: I0c017dae75a5d897367d2c42dec26f2f37e447c1
This commit is contained in:
parent
dc9d36c0a6
commit
8a2fc54508
@ -486,10 +486,17 @@ void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) {
|
||||
// Account for larger interval on base layer for temporal layers.
|
||||
if (cr->percent_refresh > 0 &&
|
||||
rc->frames_since_key < (4 * cpi->svc.number_temporal_layers) *
|
||||
(100 / cr->percent_refresh))
|
||||
(100 / cr->percent_refresh)) {
|
||||
cr->rate_ratio_qdelta = 3.0;
|
||||
else
|
||||
} else {
|
||||
cr->rate_ratio_qdelta = 2.0;
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
if (cpi->oxcf.noise_sensitivity > 0 &&
|
||||
cpi->denoiser.denoising_level >= kMedium)
|
||||
// Reduce the delta-qp if the estimated source noise is above threshold.
|
||||
cr->rate_ratio_qdelta = 1.5;
|
||||
#endif
|
||||
}
|
||||
// Adjust some parameters for low resolutions at low bitrates.
|
||||
if (cm->width <= 352 &&
|
||||
cm->height <= 288 &&
|
||||
|
@ -323,7 +323,7 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
|
||||
struct buf_2d src = mb->plane[0].src;
|
||||
int is_skin = 0;
|
||||
|
||||
if (bs <= BLOCK_16X16 && denoiser->denoising_on) {
|
||||
if (bs <= BLOCK_16X16 && denoiser->denoising_level >= kMedium) {
|
||||
// Take center pixel in block to determine is_skin.
|
||||
const int y_width_shift = (4 << b_width_log2_lookup[bs]) >> 1;
|
||||
const int y_height_shift = (4 << b_height_log2_lookup[bs]) >> 1;
|
||||
@ -340,7 +340,7 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
|
||||
is_skin = vp9_skin_pixel(ysource, usource, vsource);
|
||||
}
|
||||
|
||||
if (denoiser->denoising_on)
|
||||
if (denoiser->denoising_level >= kMedium)
|
||||
decision = perform_motion_compensation(denoiser, mb, bs,
|
||||
denoiser->increase_denoising,
|
||||
mi_row, mi_col, ctx,
|
||||
@ -523,8 +523,8 @@ void vp9_denoiser_init_noise_estimate(VP9_DENOISER *denoiser,
|
||||
int height) {
|
||||
// Denoiser is off by default, i.e., no denoising is performed.
|
||||
// Noise level is measured periodically, and if observed to be above
|
||||
// thresh_noise_estimate, then denoising is performed, i.e., denoising_on = 1.
|
||||
denoiser->denoising_on = 0;
|
||||
// thresh_noise_estimate, then denoising is performed.
|
||||
denoiser->denoising_level = kLow;
|
||||
denoiser->noise_estimate = 0;
|
||||
denoiser->noise_estimate_count = 0;
|
||||
denoiser->thresh_noise_estimate = 20;
|
||||
@ -651,10 +651,15 @@ void vp9_denoiser_update_noise_estimate(VP9_COMP *const cpi) {
|
||||
if (cpi->denoiser.noise_estimate_count == num_frames_estimate) {
|
||||
// Reset counter and check noise level condition.
|
||||
cpi->denoiser.noise_estimate_count = 0;
|
||||
if (cpi->denoiser.noise_estimate > cpi->denoiser.thresh_noise_estimate)
|
||||
cpi->denoiser.denoising_on = 1;
|
||||
else
|
||||
cpi->denoiser.denoising_on = 0;
|
||||
if (cpi->denoiser.noise_estimate >
|
||||
(cpi->denoiser.thresh_noise_estimate << 1))
|
||||
cpi->denoiser.denoising_level = kHigh;
|
||||
else
|
||||
if (cpi->denoiser.noise_estimate >
|
||||
cpi->denoiser.thresh_noise_estimate)
|
||||
cpi->denoiser.denoising_level = kMedium;
|
||||
else
|
||||
cpi->denoiser.denoising_level = kLow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,13 +26,19 @@ typedef enum vp9_denoiser_decision {
|
||||
FILTER_BLOCK
|
||||
} VP9_DENOISER_DECISION;
|
||||
|
||||
typedef enum vp9_denoiser_level {
|
||||
kLow,
|
||||
kMedium,
|
||||
kHigh
|
||||
} VP9_DENOISER_LEVEL;
|
||||
|
||||
typedef struct vp9_denoiser {
|
||||
YV12_BUFFER_CONFIG running_avg_y[MAX_REF_FRAMES];
|
||||
YV12_BUFFER_CONFIG mc_running_avg_y;
|
||||
YV12_BUFFER_CONFIG last_source;
|
||||
int increase_denoising;
|
||||
int frame_buffer_initialized;
|
||||
int denoising_on;
|
||||
VP9_DENOISER_LEVEL denoising_level;
|
||||
int noise_estimate;
|
||||
int thresh_noise_estimate;
|
||||
int noise_estimate_count;
|
||||
|
@ -481,7 +481,7 @@ static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) {
|
||||
VP9_COMMON *const cm = &cpi->common;
|
||||
const int is_key_frame = (cm->frame_type == KEY_FRAME);
|
||||
const int threshold_multiplier = is_key_frame ? 20 : 1;
|
||||
const int64_t threshold_base = (int64_t)(threshold_multiplier *
|
||||
int64_t threshold_base = (int64_t)(threshold_multiplier *
|
||||
cpi->y_dequant[q][1]);
|
||||
if (is_key_frame) {
|
||||
thresholds[0] = threshold_base;
|
||||
@ -489,6 +489,16 @@ static void set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) {
|
||||
thresholds[2] = threshold_base >> 2;
|
||||
thresholds[3] = threshold_base << 2;
|
||||
} else {
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
if (cpi->oxcf.noise_sensitivity > 0) {
|
||||
// Increase base variance threshold is estimated noise level is high.
|
||||
if (cpi->denoiser.denoising_level == kHigh)
|
||||
threshold_base = threshold_base << 2;
|
||||
else
|
||||
if (cpi->denoiser.denoising_level == kMedium)
|
||||
threshold_base = threshold_base << 1;
|
||||
}
|
||||
#endif
|
||||
thresholds[1] = threshold_base;
|
||||
if (cm->width <= 352 && cm->height <= 288) {
|
||||
thresholds[0] = threshold_base >> 2;
|
||||
|
@ -1068,6 +1068,21 @@ static const REF_MODE ref_mode_set_svc[RT_INTER_MODES] = {
|
||||
{GOLDEN_FRAME, NEWMV}
|
||||
};
|
||||
|
||||
int set_intra_cost_penalty(const VP9_COMP *const cpi, BLOCK_SIZE bsize) {
|
||||
const VP9_COMMON *const cm = &cpi->common;
|
||||
// Reduce the intra cost penalty for small blocks (<=16x16).
|
||||
int reduction_fac =
|
||||
(bsize <= BLOCK_16X16) ? ((bsize <= BLOCK_8X8) ? 4 : 2) : 0;
|
||||
#if CONFIG_VP9_TEMPORAL_DENOISING
|
||||
if (cpi->oxcf.noise_sensitivity > 0 &&
|
||||
cpi->denoiser.denoising_level == kHigh)
|
||||
// Don't reduce intra cost penalty if estimated noise level is high.
|
||||
reduction_fac = 0;
|
||||
#endif
|
||||
return vp9_get_intra_cost_penalty(
|
||||
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth) >> reduction_fac;
|
||||
}
|
||||
|
||||
// TODO(jingning) placeholder for inter-frame non-RD mode decision.
|
||||
// this needs various further optimizations. to be continued..
|
||||
void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
@ -1094,11 +1109,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
||||
// var_y and sse_y are saved to be used in skipping checking
|
||||
unsigned int var_y = UINT_MAX;
|
||||
unsigned int sse_y = UINT_MAX;
|
||||
// Reduce the intra cost penalty for small blocks (<=16x16).
|
||||
const int reduction_fac = (bsize <= BLOCK_16X16) ?
|
||||
((bsize <= BLOCK_8X8) ? 4 : 2) : 0;
|
||||
const int intra_cost_penalty = vp9_get_intra_cost_penalty(
|
||||
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth) >> reduction_fac;
|
||||
const int intra_cost_penalty = set_intra_cost_penalty(cpi, bsize);
|
||||
const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
|
||||
intra_cost_penalty, 0);
|
||||
const int *const rd_threshes = cpi->rd.threshes[mbmi->segment_id][bsize];
|
||||
|
Loading…
x
Reference in New Issue
Block a user