Commit eb7b5f66 authored by Yaowu Xu's avatar Yaowu Xu

Merge branch 'master' into nextgenv2

Change-Id: I63dc39d1ec9ad2e2454da6f5956dcd4367b87190
parents f847a16a 823a47ee
......@@ -403,7 +403,6 @@ const vpx_prob vp10_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES] = {
{255, 241, 243, 255, 236, 255, 252, 254},
{255, 243, 245, 255, 237, 255, 252, 254},
{255, 246, 247, 255, 239, 255, 253, 255},
{255, 246, 247, 255, 239, 255, 253, 255},
};
static const vp10_coeff_probs_model default_coef_probs_4x4[PLANE_TYPES] = {
......@@ -743,14 +742,16 @@ static const vp10_coeff_probs_model default_coef_probs_32x32[PLANE_TYPES] = {
};
static void extend_to_full_distribution(vpx_prob *probs, vpx_prob p) {
memcpy(probs, vp10_pareto8_full[p = 0 ? 0 : p - 1],
MODEL_NODES * sizeof(vpx_prob));
memcpy(probs, vp10_pareto8_full[p - 1], MODEL_NODES * sizeof(vpx_prob));
}
void vp10_model_to_full_probs(const vpx_prob *model, vpx_prob *full) {
if (full != model)
memcpy(full, model, sizeof(vpx_prob) * UNCONSTRAINED_NODES);
extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
// TODO(aconverse): model[PIVOT_NODE] should never be zero.
// https://code.google.com/p/webm/issues/detail?id=1089
if (model[PIVOT_NODE] != 0)
extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
}
void vp10_default_coef_probs(VP10_COMMON *cm) {
......
......@@ -154,7 +154,7 @@ static INLINE const uint8_t *get_band_translate(TX_SIZE tx_size) {
// 1, 3, 5, 7, ..., 253, 255
// In between probabilities are interpolated linearly
#define COEFF_PROB_MODELS 256
#define COEFF_PROB_MODELS 255
#define UNCONSTRAINED_NODES 3
......
......@@ -49,7 +49,7 @@ static void calc_centroids(const double *data, double *centroids,
const uint8_t *indices, int n, int k, int dim) {
int i, j, index;
int count[PALETTE_MAX_SIZE];
unsigned int rand_state = data[0];
unsigned int rand_state = (unsigned int)data[0];
assert(n <= 32768);
......
......@@ -403,7 +403,6 @@ const vpx_prob vp9_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES] = {
{255, 241, 243, 255, 236, 255, 252, 254},
{255, 243, 245, 255, 237, 255, 252, 254},
{255, 246, 247, 255, 239, 255, 253, 255},
{255, 246, 247, 255, 239, 255, 253, 255},
};
static const vp9_coeff_probs_model default_coef_probs_4x4[PLANE_TYPES] = {
......@@ -743,14 +742,16 @@ static const vp9_coeff_probs_model default_coef_probs_32x32[PLANE_TYPES] = {
};
static void extend_to_full_distribution(vpx_prob *probs, vpx_prob p) {
memcpy(probs, vp9_pareto8_full[p = 0 ? 0 : p - 1],
MODEL_NODES * sizeof(vpx_prob));
memcpy(probs, vp9_pareto8_full[p - 1], MODEL_NODES * sizeof(vpx_prob));
}
void vp9_model_to_full_probs(const vpx_prob *model, vpx_prob *full) {
if (full != model)
memcpy(full, model, sizeof(vpx_prob) * UNCONSTRAINED_NODES);
extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
// TODO(aconverse): model[PIVOT_NODE] should never be zero.
// https://code.google.com/p/webm/issues/detail?id=1089
if (model[PIVOT_NODE] != 0)
extend_to_full_distribution(&full[UNCONSTRAINED_NODES], model[PIVOT_NODE]);
}
void vp9_default_coef_probs(VP9_COMMON *cm) {
......
......@@ -138,7 +138,7 @@ static INLINE const uint8_t *get_band_translate(TX_SIZE tx_size) {
// 1, 3, 5, 7, ..., 253, 255
// In between probabilities are interpolated linearly
#define COEFF_PROB_MODELS 256
#define COEFF_PROB_MODELS 255
#define UNCONSTRAINED_NODES 3
......
......@@ -485,10 +485,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 &&
......
......@@ -193,7 +193,7 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
int mi_row,
int mi_col,
PICK_MODE_CONTEXT *ctx,
int *motion_magnitude,
int motion_magnitude,
int is_skin) {
int mv_col, mv_row;
int sse_diff = ctx->zeromv_sse - ctx->newmv_sse;
......@@ -207,18 +207,17 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
mv_col = ctx->best_sse_mv.as_mv.col;
mv_row = ctx->best_sse_mv.as_mv.row;
*motion_magnitude = mv_row * mv_row + mv_col * mv_col;
frame = ctx->best_reference_frame;
saved_mbmi = *mbmi;
if (is_skin && *motion_magnitude > 16)
if (is_skin && motion_magnitude > 16)
return COPY_BLOCK;
// If the best reference frame uses inter-prediction and there is enough of a
// difference in sum-squared-error, use it.
if (frame != INTRA_FRAME &&
sse_diff > sse_diff_thresh(bs, increase_denoising, *motion_magnitude)) {
sse_diff > sse_diff_thresh(bs, increase_denoising, motion_magnitude)) {
mbmi->ref_frame[0] = ctx->best_reference_frame;
mbmi->mode = ctx->best_sse_inter_mode;
mbmi->mv[0] = ctx->best_sse_mv;
......@@ -240,7 +239,7 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
*mbmi = saved_mbmi;
return COPY_BLOCK;
}
if (*motion_magnitude >
if (motion_magnitude >
(noise_motion_thresh(bs, increase_denoising) << 3)) {
// Restore everything to its original state
*mbmi = saved_mbmi;
......@@ -313,6 +312,7 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
int mi_row, int mi_col, BLOCK_SIZE bs,
PICK_MODE_CONTEXT *ctx) {
int mv_col, mv_row;
int motion_magnitude = 0;
VP9_DENOISER_DECISION decision = COPY_BLOCK;
YV12_BUFFER_CONFIG avg = denoiser->running_avg_y[INTRA_FRAME];
......@@ -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,18 +340,28 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
is_skin = vp9_skin_pixel(ysource, usource, vsource);
}
if (denoiser->denoising_on)
mv_col = ctx->best_sse_mv.as_mv.col;
mv_row = ctx->best_sse_mv.as_mv.row;
motion_magnitude = mv_row * mv_row + mv_col * mv_col;
if (denoiser->denoising_level == kHigh && motion_magnitude < 16) {
denoiser->increase_denoising = 1;
} else {
denoiser->increase_denoising = 0;
}
if (denoiser->denoising_level >= kMedium)
decision = perform_motion_compensation(denoiser, mb, bs,
denoiser->increase_denoising,
mi_row, mi_col, ctx,
&motion_magnitude,
motion_magnitude,
is_skin);
if (decision == FILTER_BLOCK) {
decision = vp9_denoiser_filter(src.buf, src.stride,
mc_avg_start, mc_avg.y_stride,
avg_start, avg.y_stride,
0, bs, motion_magnitude);
denoiser->increase_denoising,
bs, motion_magnitude);
}
if (decision == FILTER_BLOCK) {
......@@ -523,8 +533,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 +661,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];
......
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