Merge "Some minor improvements in bilateral filter expt." into nextgen
This commit is contained in:
commit
96213ac5e7
@ -1279,6 +1279,10 @@ void vp9_setup_past_independence(VP9_COMMON *cm) {
|
|||||||
|
|
||||||
// To force update of the sharpness
|
// To force update of the sharpness
|
||||||
lf->last_sharpness_level = -1;
|
lf->last_sharpness_level = -1;
|
||||||
|
#if CONFIG_LOOP_POSTFILTER
|
||||||
|
lf->bilateral_level = 0;
|
||||||
|
lf->last_bilateral_level = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
vp9_default_coef_probs(cm);
|
vp9_default_coef_probs(cm);
|
||||||
vp9_init_mode_probs(&cm->fc);
|
vp9_init_mode_probs(&cm->fc);
|
||||||
|
@ -242,7 +242,7 @@ int vp9_bilateral_level_bits(const VP9_COMMON *const cm) {
|
|||||||
|
|
||||||
int vp9_loop_bilateral_used(int level, int kf) {
|
int vp9_loop_bilateral_used(int level, int kf) {
|
||||||
const bilateral_params_t param = vp9_bilateral_level_to_params(level, kf);
|
const bilateral_params_t param = vp9_bilateral_level_to_params(level, kf);
|
||||||
return (param.sigma_x && param.sigma_r);
|
return (param.sigma_x && param.sigma_y && param.sigma_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vp9_loop_bilateral_init(loop_filter_info_n *lfi, int level, int kf) {
|
void vp9_loop_bilateral_init(loop_filter_info_n *lfi, int level, int kf) {
|
||||||
@ -250,11 +250,14 @@ void vp9_loop_bilateral_init(loop_filter_info_n *lfi, int level, int kf) {
|
|||||||
lfi->bilateral_used = vp9_loop_bilateral_used(level, kf);
|
lfi->bilateral_used = vp9_loop_bilateral_used(level, kf);
|
||||||
if (lfi->bilateral_used) {
|
if (lfi->bilateral_used) {
|
||||||
if (param.sigma_x != lfi->bilateral_sigma_x_set ||
|
if (param.sigma_x != lfi->bilateral_sigma_x_set ||
|
||||||
|
param.sigma_y != lfi->bilateral_sigma_y_set ||
|
||||||
param.sigma_r != lfi->bilateral_sigma_r_set) {
|
param.sigma_r != lfi->bilateral_sigma_r_set) {
|
||||||
const int sigma_x = param.sigma_x;
|
const int sigma_x = param.sigma_x;
|
||||||
|
const int sigma_y = param.sigma_y;
|
||||||
const int sigma_r = param.sigma_r;
|
const int sigma_r = param.sigma_r;
|
||||||
const double sigma_r_d = (double)sigma_r / BILATERAL_PRECISION;
|
const double sigma_r_d = (double)sigma_r / BILATERAL_PRECISION;
|
||||||
const double sigma_x_d = (double)sigma_x / BILATERAL_PRECISION;
|
const double sigma_x_d = (double)sigma_x / BILATERAL_PRECISION;
|
||||||
|
const double sigma_y_d = (double)sigma_y / BILATERAL_PRECISION;
|
||||||
double *wr_lut_ = lfi->wr_lut + 255;
|
double *wr_lut_ = lfi->wr_lut + 255;
|
||||||
double *wx_lut_ = lfi->wx_lut + BILATERAL_HALFWIN * (1 + BILATERAL_WIN);
|
double *wx_lut_ = lfi->wx_lut + BILATERAL_HALFWIN * (1 + BILATERAL_WIN);
|
||||||
int i, x, y;
|
int i, x, y;
|
||||||
@ -265,9 +268,11 @@ void vp9_loop_bilateral_init(loop_filter_info_n *lfi, int level, int kf) {
|
|||||||
for (y = -BILATERAL_HALFWIN; y <= BILATERAL_HALFWIN; y++)
|
for (y = -BILATERAL_HALFWIN; y <= BILATERAL_HALFWIN; y++)
|
||||||
for (x = -BILATERAL_HALFWIN; x <= BILATERAL_HALFWIN; x++) {
|
for (x = -BILATERAL_HALFWIN; x <= BILATERAL_HALFWIN; x++) {
|
||||||
wx_lut_[y * BILATERAL_WIN + x] =
|
wx_lut_[y * BILATERAL_WIN + x] =
|
||||||
exp(-(x * x + y * y) / (2 * sigma_x_d * sigma_x_d));
|
exp(-(x * x) / (2 * sigma_x_d * sigma_x_d) -
|
||||||
|
(y * y) / (2 * sigma_y_d * sigma_y_d));
|
||||||
}
|
}
|
||||||
lfi->bilateral_sigma_x_set = sigma_x;
|
lfi->bilateral_sigma_x_set = sigma_x;
|
||||||
|
lfi->bilateral_sigma_y_set = sigma_y;
|
||||||
lfi->bilateral_sigma_r_set = sigma_r;
|
lfi->bilateral_sigma_r_set = sigma_r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,49 +38,50 @@ struct VP9Common;
|
|||||||
#define BILATERAL_LEVELS (1 << BILATERAL_LEVEL_BITS)
|
#define BILATERAL_LEVELS (1 << BILATERAL_LEVEL_BITS)
|
||||||
#define DEF_BILATERAL_LEVEL 2
|
#define DEF_BILATERAL_LEVEL 2
|
||||||
|
|
||||||
#define BILATERAL_PRECISION 8
|
#define BILATERAL_PRECISION 16
|
||||||
#define BILATERAL_HALFWIN 3
|
#define BILATERAL_HALFWIN 3
|
||||||
#define BILATERAL_WIN (2 * BILATERAL_HALFWIN + 1)
|
#define BILATERAL_WIN (2 * BILATERAL_HALFWIN + 1)
|
||||||
|
|
||||||
typedef struct bilateral_params {
|
typedef struct bilateral_params {
|
||||||
int sigma_x; // spatial variance
|
int sigma_x; // spatial variance x
|
||||||
|
int sigma_y; // spatial variance y
|
||||||
int sigma_r; // range variance
|
int sigma_r; // range variance
|
||||||
} bilateral_params_t;
|
} bilateral_params_t;
|
||||||
|
|
||||||
static bilateral_params_t
|
static bilateral_params_t
|
||||||
bilateral_level_to_params_arr[BILATERAL_LEVELS + 1] = {
|
bilateral_level_to_params_arr[BILATERAL_LEVELS + 1] = {
|
||||||
// Values are rounded to 1/8 th precision
|
// Values are rounded to 1/16 th precision
|
||||||
{0, 0}, // 0 - default
|
{0, 0, 0}, // 0 - default
|
||||||
{4, 16},
|
{8, 9, 30},
|
||||||
{5, 16},
|
{9, 8, 30},
|
||||||
{6, 16},
|
{9, 11, 32},
|
||||||
{7, 16},
|
{11, 9, 32},
|
||||||
{9, 18},
|
{14, 14, 32},
|
||||||
{12, 20},
|
{18, 18, 36},
|
||||||
{16, 20},
|
{24, 24, 40},
|
||||||
{20, 20},
|
{32, 32, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bilateral_params_t
|
static bilateral_params_t
|
||||||
bilateral_level_to_params_arr_kf[BILATERAL_LEVELS_KF + 1] = {
|
bilateral_level_to_params_arr_kf[BILATERAL_LEVELS_KF + 1] = {
|
||||||
// Values are rounded to 1/8 th precision
|
// Values are rounded to 1/16 th precision
|
||||||
{0, 0}, // 0 - default
|
{0, 0, 0}, // 0 - default
|
||||||
{4, 16},
|
{8, 8, 30},
|
||||||
{5, 16},
|
{9, 9, 32},
|
||||||
{6, 16},
|
{10, 10, 32},
|
||||||
{7, 16},
|
{12, 12, 32},
|
||||||
{9, 18},
|
{14, 14, 32},
|
||||||
{12, 20},
|
{18, 18, 36},
|
||||||
{15, 22},
|
{24, 24, 40},
|
||||||
{18, 24},
|
{30, 30, 44},
|
||||||
{21, 24},
|
{36, 36, 48},
|
||||||
{24, 24},
|
{42, 42, 48},
|
||||||
{24, 28},
|
{48, 48, 48},
|
||||||
{28, 24},
|
{48, 48, 56},
|
||||||
{28, 28},
|
{56, 56, 48},
|
||||||
{28, 32},
|
{56, 56, 56},
|
||||||
{32, 24},
|
{56, 56, 64},
|
||||||
{32, 28},
|
{64, 64, 48},
|
||||||
};
|
};
|
||||||
|
|
||||||
int vp9_bilateral_level_bits(const struct VP9Common *const cm);
|
int vp9_bilateral_level_bits(const struct VP9Common *const cm);
|
||||||
@ -112,6 +113,7 @@ struct loopfilter {
|
|||||||
|
|
||||||
#if CONFIG_LOOP_POSTFILTER
|
#if CONFIG_LOOP_POSTFILTER
|
||||||
int bilateral_level;
|
int bilateral_level;
|
||||||
|
int last_bilateral_level;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,6 +132,7 @@ typedef struct {
|
|||||||
double wx_lut[BILATERAL_WIN * BILATERAL_WIN];
|
double wx_lut[BILATERAL_WIN * BILATERAL_WIN];
|
||||||
double wr_lut[512];
|
double wr_lut[512];
|
||||||
int bilateral_sigma_x_set;
|
int bilateral_sigma_x_set;
|
||||||
|
int bilateral_sigma_y_set;
|
||||||
int bilateral_sigma_r_set;
|
int bilateral_sigma_r_set;
|
||||||
int bilateral_used;
|
int bilateral_used;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1631,9 +1631,15 @@ static void setup_loopfilter(VP9_COMMON *cm,
|
|||||||
#if CONFIG_LOOP_POSTFILTER
|
#if CONFIG_LOOP_POSTFILTER
|
||||||
lf->bilateral_level = vp9_rb_read_bit(rb);
|
lf->bilateral_level = vp9_rb_read_bit(rb);
|
||||||
if (lf->bilateral_level) {
|
if (lf->bilateral_level) {
|
||||||
lf->bilateral_level += vp9_rb_read_literal(
|
int level = vp9_rb_read_literal(rb, vp9_bilateral_level_bits(cm));
|
||||||
rb, vp9_bilateral_level_bits(cm));
|
lf->bilateral_level = level + (level >= lf->last_bilateral_level);
|
||||||
|
} else {
|
||||||
|
lf->bilateral_level = lf->last_bilateral_level;
|
||||||
}
|
}
|
||||||
|
if (cm->frame_type != KEY_FRAME)
|
||||||
|
cm->lf.last_bilateral_level = cm->lf.bilateral_level;
|
||||||
|
else
|
||||||
|
cm->lf.last_bilateral_level = 0;
|
||||||
#endif // CONFIG_LOOP_POSTFILTER
|
#endif // CONFIG_LOOP_POSTFILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2377,6 +2383,7 @@ static size_t read_uncompressed_header(VP9Decoder *pbi,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_VP9_HIGHBITDEPTH
|
#if CONFIG_VP9_HIGHBITDEPTH
|
||||||
get_frame_new_buffer(cm)->bit_depth = cm->bit_depth;
|
get_frame_new_buffer(cm)->bit_depth = cm->bit_depth;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1527,10 +1527,13 @@ static void encode_loopfilter(VP9_COMMON *cm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if CONFIG_LOOP_POSTFILTER
|
#if CONFIG_LOOP_POSTFILTER
|
||||||
vp9_wb_write_bit(wb, lf->bilateral_level > 0);
|
vp9_wb_write_bit(wb, lf->bilateral_level != lf->last_bilateral_level);
|
||||||
if (lf->bilateral_level > 0)
|
if (lf->bilateral_level != lf->last_bilateral_level) {
|
||||||
vp9_wb_write_literal(wb, lf->bilateral_level - 1,
|
int level = lf->bilateral_level -
|
||||||
|
(lf->bilateral_level > lf->last_bilateral_level);
|
||||||
|
vp9_wb_write_literal(wb, level,
|
||||||
vp9_bilateral_level_bits(cm));
|
vp9_bilateral_level_bits(cm));
|
||||||
|
}
|
||||||
#endif // CONFIG_LOOP_POSTFILTER
|
#endif // CONFIG_LOOP_POSTFILTER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3423,6 +3423,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
// Pick the loop filter level for the frame.
|
// Pick the loop filter level for the frame.
|
||||||
loopfilter_frame(cpi, cm);
|
loopfilter_frame(cpi, cm);
|
||||||
|
|
||||||
|
// printf("Bilateral level: %d\n", cm->lf.bilateral_level);
|
||||||
|
|
||||||
// build the bitstream
|
// build the bitstream
|
||||||
vp9_pack_bitstream(cpi, dest, size);
|
vp9_pack_bitstream(cpi, dest, size);
|
||||||
|
|
||||||
@ -3463,6 +3465,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
|
|||||||
|
|
||||||
cm->last_frame_type = cm->frame_type;
|
cm->last_frame_type = cm->frame_type;
|
||||||
|
|
||||||
|
#if CONFIG_LOOP_POSTFILTER
|
||||||
|
if (cm->frame_type != KEY_FRAME)
|
||||||
|
cm->lf.last_bilateral_level = cm->lf.bilateral_level;
|
||||||
|
else
|
||||||
|
cm->lf.last_bilateral_level = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING))
|
if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING))
|
||||||
vp9_rc_postencode_update(cpi, *size);
|
vp9_rc_postencode_update(cpi, *size);
|
||||||
|
|
||||||
|
@ -87,15 +87,16 @@ static int try_bilateral_frame(const YV12_BUFFER_CONFIG *sd,
|
|||||||
static int64_t search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
static int64_t search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
||||||
VP9_COMP *cpi,
|
VP9_COMP *cpi,
|
||||||
int filter_level, int partial_frame,
|
int filter_level, int partial_frame,
|
||||||
int64_t *best_cost_ret) {
|
double *best_cost_ret) {
|
||||||
VP9_COMMON *const cm = &cpi->common;
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
int i, bilateral_best, err;
|
int i, bilateral_best, err;
|
||||||
int64_t best_cost;
|
double best_cost;
|
||||||
int64_t cost[BILATERAL_LEVELS_KF];
|
double cost[BILATERAL_LEVELS_KF];
|
||||||
const int bilateral_level_bits = vp9_bilateral_level_bits(&cpi->common);
|
const int bilateral_level_bits = vp9_bilateral_level_bits(&cpi->common);
|
||||||
const int bilateral_levels = 1 << bilateral_level_bits;
|
const int bilateral_levels = 1 << bilateral_level_bits;
|
||||||
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
|
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
|
||||||
MACROBLOCK *x = &cpi->mb;
|
MACROBLOCK *x = &cpi->mb;
|
||||||
|
int bits;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make a copy of the unfiltered / processed recon buffer
|
// Make a copy of the unfiltered / processed recon buffer
|
||||||
@ -107,9 +108,10 @@ static int64_t search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
|||||||
bilateral_best = 0;
|
bilateral_best = 0;
|
||||||
err = try_bilateral_frame(sd, cpi, 0, partial_frame);
|
err = try_bilateral_frame(sd, cpi, 0, partial_frame);
|
||||||
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
|
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
|
||||||
cost[0] = RDCOST(x->rdmult, x->rddiv, 0, err);
|
bits = cm->lf.last_bilateral_level == 0 ? 0 : bilateral_level_bits;
|
||||||
|
cost[0] = RDCOST_DBL(x->rdmult, x->rddiv, (bits << 2), err);
|
||||||
#else
|
#else
|
||||||
cost[0] = err;
|
cost[0] = (double)err;
|
||||||
#endif
|
#endif
|
||||||
best_cost = cost[0];
|
best_cost = cost[0];
|
||||||
for (i = 1; i <= bilateral_levels; ++i) {
|
for (i = 1; i <= bilateral_levels; ++i) {
|
||||||
@ -118,10 +120,10 @@ static int64_t search_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
|||||||
// Normally the rate is rate in bits * 256 and dist is sum sq err * 64
|
// Normally the rate is rate in bits * 256 and dist is sum sq err * 64
|
||||||
// when RDCOST is used. However below we just scale both in the correct
|
// when RDCOST is used. However below we just scale both in the correct
|
||||||
// ratios appropriately but not exactly by these values.
|
// ratios appropriately but not exactly by these values.
|
||||||
cost[i] = RDCOST(x->rdmult, x->rddiv,
|
bits = cm->lf.last_bilateral_level == i ? 0 : bilateral_level_bits;
|
||||||
bilateral_level_bits << 2, err);
|
cost[i] = RDCOST_DBL(x->rdmult, x->rddiv, (bits << 2), err);
|
||||||
#else
|
#else
|
||||||
cost[i] = err;
|
cost[i] = (double)err;
|
||||||
#endif
|
#endif
|
||||||
if (cost[i] < best_cost) {
|
if (cost[i] < best_cost) {
|
||||||
bilateral_best = i;
|
bilateral_best = i;
|
||||||
@ -144,18 +146,19 @@ static int search_filter_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
|||||||
const int max_filter_level = get_max_filter_level(cpi);
|
const int max_filter_level = get_max_filter_level(cpi);
|
||||||
int filt_direction = 0;
|
int filt_direction = 0;
|
||||||
int filt_best, bilateral_best;
|
int filt_best, bilateral_best;
|
||||||
int64_t best_err;
|
double best_err;
|
||||||
|
int i;
|
||||||
|
|
||||||
// Start the search at the previous frame filter level unless it is now out of
|
// Start the search at the previous frame filter level unless it is now out of
|
||||||
// range.
|
// range.
|
||||||
int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
|
int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
|
||||||
int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
|
int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
|
||||||
// Sum squared error at each filter level
|
double ss_err[MAX_LOOP_FILTER + 1];
|
||||||
int64_t ss_err[MAX_LOOP_FILTER + 1];
|
|
||||||
int bilateral;
|
int bilateral;
|
||||||
|
|
||||||
// Set each entry to -1
|
// Set each entry to -1
|
||||||
vpx_memset(ss_err, 0xFF, sizeof(ss_err));
|
for (i = 0; i <= MAX_LOOP_FILTER; ++i)
|
||||||
|
ss_err[i] = -1.0;
|
||||||
|
|
||||||
bilateral = search_bilateral_level(sd, cpi, filt_mid,
|
bilateral = search_bilateral_level(sd, cpi, filt_mid,
|
||||||
partial_frame, &best_err);
|
partial_frame, &best_err);
|
||||||
@ -168,14 +171,14 @@ static int search_filter_bilateral_level(const YV12_BUFFER_CONFIG *sd,
|
|||||||
const int filt_low = MAX(filt_mid - filter_step, min_filter_level);
|
const int filt_low = MAX(filt_mid - filter_step, min_filter_level);
|
||||||
|
|
||||||
// Bias against raising loop filter in favor of lowering it.
|
// Bias against raising loop filter in favor of lowering it.
|
||||||
int64_t bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;
|
double bias = (best_err / (1 << (15 - (filt_mid / 8)))) * filter_step;
|
||||||
|
|
||||||
if ((cpi->oxcf.pass == 2) && (cpi->twopass.section_intra_rating < 20))
|
if ((cpi->oxcf.pass == 2) && (cpi->twopass.section_intra_rating < 20))
|
||||||
bias = (bias * cpi->twopass.section_intra_rating) / 20;
|
bias = (bias * cpi->twopass.section_intra_rating) / 20;
|
||||||
|
|
||||||
// yx, bias less for large block size
|
// yx, bias less for large block size
|
||||||
if (cm->tx_mode != ONLY_4X4)
|
if (cm->tx_mode != ONLY_4X4)
|
||||||
bias >>= 1;
|
bias /= 2;
|
||||||
|
|
||||||
if (filt_direction <= 0 && filt_low != filt_mid) {
|
if (filt_direction <= 0 && filt_low != filt_mid) {
|
||||||
// Get Low filter error score
|
// Get Low filter error score
|
||||||
|
@ -25,10 +25,10 @@ extern "C" {
|
|||||||
#define RDDIV_BITS 7
|
#define RDDIV_BITS 7
|
||||||
|
|
||||||
#define RDCOST(RM, DM, R, D) \
|
#define RDCOST(RM, DM, R, D) \
|
||||||
(((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM))
|
(((128 + ((int64_t)R) * (RM)) >> 8) + ((D) << (DM)))
|
||||||
|
|
||||||
#define RDCOST_DBL(RM, DM, R, D) \
|
#define RDCOST_DBL(RM, DM, R, D) \
|
||||||
(((((double)R) * (RM)) / 256.0) + ((double)D * (1 << DM)))
|
(((((double)(R)) * (RM)) / 256.0) + ((double)(D) * (1 << (DM))))
|
||||||
|
|
||||||
#define QIDX_SKIP_THRESH 115
|
#define QIDX_SKIP_THRESH 115
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user