Replace simple coefficient cost estimation with CABAC. Substantial improvement.

Approximation proved to be too inaccurate while not giving actually that much speedup.
This commit is contained in:
Ari Lemmetti 2017-12-10 01:23:48 +02:00 committed by Ari Lemmetti
parent ea79069dc8
commit 14892fda00
4 changed files with 12 additions and 38 deletions

View file

@ -41,8 +41,6 @@
#define LOG2_SCAN_SET_SIZE 4
#define SBH_THRESHOLD 4
static const double COEFF_SUM_MULTIPLIER = 1.9;
const uint32_t kvz_g_go_rice_range[5] = { 7, 14, 26, 46, 78 };
const uint32_t kvz_g_go_rice_prefix_len[5] = { 8, 7, 6, 5, 4 };
@ -154,7 +152,7 @@ struct sh_rates_t {
*
* \returns bits needed to code input coefficients
*/
static INLINE uint32_t get_coeff_cabac_cost(
uint32_t kvz_get_coeff_cabac_cost(
const encoder_state_t * const state,
const coeff_t *coeff,
int32_t width,
@ -195,31 +193,6 @@ static INLINE uint32_t get_coeff_cabac_cost(
return (23 - cabac_copy.bits_left) + (cabac_copy.num_buffered_bytes << 3);
}
/**
* \brief Estimate bitcost for coding coefficients.
*
* \param coeff coefficient array
* \param width coeff block width
* \param type data type (0 == luma)
*
* \returns number of bits needed to code coefficients
*/
uint32_t kvz_get_coeff_cost(const encoder_state_t * const state,
const coeff_t *coeff,
int32_t width,
int32_t type,
int8_t scan_mode)
{
if (state->encoder_control->cfg.rdo > 0) {
return get_coeff_cabac_cost(state, coeff, width, type, scan_mode);
} else {
return COEFF_SUM_MULTIPLIER * kvz_coeff_abs_sum(coeff, width * width) + 0.5;
}
}
#define COEF_REMAIN_BIN_REDUCTION 3
/** Calculates the cost for specific absolute transform level
* \param abs_level scaled quantized level

View file

@ -39,11 +39,12 @@ extern const uint32_t kvz_g_go_rice_prefix_len[5];
void kvz_rdoq(encoder_state_t *state, coeff_t *coef, coeff_t *dest_coeff, int32_t width,
int32_t height, int8_t type, int8_t scan_mode, int8_t block_type, int8_t tr_depth);
uint32_t kvz_get_coeff_cost(const encoder_state_t *state,
const coeff_t *coeff,
int32_t width,
int32_t type,
int8_t scan_mode);
uint32_t kvz_get_coeff_cabac_cost(
const encoder_state_t * const state,
const coeff_t *coeff,
int32_t width,
int32_t type,
int8_t scan_mode);
int32_t kvz_get_ic_rate(encoder_state_t *state, uint32_t abs_level, uint16_t ctx_num_one, uint16_t ctx_num_abs,
uint16_t abs_go_rice, uint32_t c1_idx, uint32_t c2_idx, int8_t type);

View file

@ -262,7 +262,7 @@ double kvz_cu_rd_cost_luma(const encoder_state_t *const state,
int8_t luma_scan_mode = kvz_get_scan_order(pred_cu->type, pred_cu->intra.mode, depth);
const coeff_t *coeffs = &lcu->coeff.y[xy_to_zorder(LCU_WIDTH, x_px, y_px)];
coeff_bits += kvz_get_coeff_cost(state, coeffs, width, 0, luma_scan_mode);
coeff_bits += kvz_get_coeff_cabac_cost(state, coeffs, width, 0, luma_scan_mode);
}
double bits = tr_tree_bits + coeff_bits;
@ -331,8 +331,8 @@ double kvz_cu_rd_cost_chroma(const encoder_state_t *const state,
int8_t scan_order = kvz_get_scan_order(pred_cu->type, pred_cu->intra.mode_chroma, depth);
const int index = xy_to_zorder(LCU_WIDTH_C, lcu_px.x, lcu_px.y);
coeff_bits += kvz_get_coeff_cost(state, &lcu->coeff.u[index], width, 2, scan_order);
coeff_bits += kvz_get_coeff_cost(state, &lcu->coeff.v[index], width, 2, scan_order);
coeff_bits += kvz_get_coeff_cabac_cost(state, &lcu->coeff.u[index], width, 2, scan_order);
coeff_bits += kvz_get_coeff_cabac_cost(state, &lcu->coeff.v[index], width, 2, scan_order);
}
double bits = tr_tree_bits + coeff_bits;

View file

@ -238,14 +238,14 @@ int kvz_quantize_residual_trskip(
0, in_stride, 4,
ref_in, pred_in, noskip.rec, noskip.coeff);
noskip.cost = kvz_pixels_calc_ssd(ref_in, noskip.rec, in_stride, 4, 4);
noskip.cost += kvz_get_coeff_cost(state, noskip.coeff, 4, 0, scan_order) * bit_cost;
noskip.cost += kvz_get_coeff_cabac_cost(state, noskip.coeff, 4, 0, scan_order) * bit_cost;
skip.has_coeffs = kvz_quantize_residual(
state, cur_cu, width, color, scan_order,
1, in_stride, 4,
ref_in, pred_in, skip.rec, skip.coeff);
skip.cost = kvz_pixels_calc_ssd(ref_in, skip.rec, in_stride, 4, 4);
skip.cost += kvz_get_coeff_cost(state, skip.coeff, 4, 0, scan_order) * bit_cost;
skip.cost += kvz_get_coeff_cabac_cost(state, skip.coeff, 4, 0, scan_order) * bit_cost;
if (noskip.cost <= skip.cost) {
*trskip_out = 0;