[intra] Count fractional bits with get_coeff_cabac_cost

This commit is contained in:
Joose Sainio 2022-04-01 10:46:51 +03:00
parent 6d080b215c
commit 23fda23322
11 changed files with 107 additions and 91 deletions

View file

@ -315,15 +315,17 @@ void uvg_cabac_encode_bins_ep(cabac_data_t * const data, uint32_t bin_values, in
* \param remainder Value of remaining abs coeff * \param remainder Value of remaining abs coeff
* \param rice_param Reference to Rice parameter. * \param rice_param Reference to Rice parameter.
*/ */
void uvg_cabac_write_coeff_remain(cabac_data_t * const cabac, const uint32_t remainder, const uint32_t rice_param, const unsigned int cutoff) int uvg_cabac_write_coeff_remain(cabac_data_t * const cabac, const uint32_t remainder, const uint32_t rice_param, const unsigned int cutoff)
{ {
const unsigned threshold = cutoff << rice_param; const unsigned threshold = cutoff << rice_param;
uint32_t bins = remainder; uint32_t bins = remainder;
uint32_t bits = 0;
if (bins < threshold) { if (bins < threshold) {
uint32_t length = (bins >> rice_param) + 1; uint32_t length = (bins >> rice_param) + 1;
CABAC_BINS_EP(cabac, ((1 << (length)) - 2) , length, "coeff_abs_level_remaining"); CABAC_BINS_EP(cabac, ((1 << (length)) - 2) , length, "coeff_abs_level_remaining");
CABAC_BINS_EP(cabac, bins & ((1 << rice_param) - 1), rice_param, "coeff_abs_level_remaining"); CABAC_BINS_EP(cabac, bins & ((1 << rice_param) - 1), rice_param, "coeff_abs_level_remaining");
bits += length;
bits += rice_param;
} else { } else {
const unsigned max_prefix_length = 32 - cutoff - 15/*max_log2_tr_dynamic_range*/; const unsigned max_prefix_length = 32 - cutoff - 15/*max_log2_tr_dynamic_range*/;
unsigned prefix_length = 0; unsigned prefix_length = 0;
@ -344,8 +346,9 @@ void uvg_cabac_write_coeff_remain(cabac_data_t * const cabac, const uint32_t rem
const unsigned suffix = ((code_value - ((1 << prefix_length) - 1)) << rice_param) | (bins & bit_mask); const unsigned suffix = ((code_value - ((1 << prefix_length) - 1)) << rice_param) | (bins & bit_mask);
CABAC_BINS_EP(cabac, prefix, total_prefix_length, "coeff_abs_level_remaining"); CABAC_BINS_EP(cabac, prefix, total_prefix_length, "coeff_abs_level_remaining");
CABAC_BINS_EP(cabac, suffix, suffix_length, "coeff_abs_level_remaining"); CABAC_BINS_EP(cabac, suffix, suffix_length, "coeff_abs_level_remaining");
bits += total_prefix_length + suffix_length;
} }
return bits;
} }

View file

@ -140,7 +140,7 @@ void uvg_cabac_encode_bins_ep(cabac_data_t *data, uint32_t bin_values, int num_b
void uvg_cabac_encode_bin_trm(cabac_data_t *data, uint8_t bin_value); void uvg_cabac_encode_bin_trm(cabac_data_t *data, uint8_t bin_value);
void uvg_cabac_write(cabac_data_t *data); void uvg_cabac_write(cabac_data_t *data);
void uvg_cabac_finish(cabac_data_t *data); void uvg_cabac_finish(cabac_data_t *data);
void uvg_cabac_write_coeff_remain(cabac_data_t *cabac, uint32_t symbol, int uvg_cabac_write_coeff_remain(cabac_data_t *cabac, uint32_t symbol,
uint32_t r_param, const unsigned int cutoff); uint32_t r_param, const unsigned int cutoff);
uint32_t uvg_cabac_write_ep_ex_golomb(struct encoder_state_t * const state, cabac_data_t *data, uint32_t uvg_cabac_write_ep_ex_golomb(struct encoder_state_t * const state, cabac_data_t *data,
uint32_t symbol, uint32_t count); uint32_t symbol, uint32_t count);

View file

@ -256,7 +256,8 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
const coeff_t* coeff, const coeff_t* coeff,
uint32_t width, uint32_t width,
uint8_t type, uint8_t type,
int8_t scan_mode) { int8_t scan_mode,
double* bits_out) {
//const encoder_control_t * const encoder = state->encoder_control; //const encoder_control_t * const encoder = state->encoder_control;
//int c1 = 1; //int c1 = 1;
uint32_t i; uint32_t i;
@ -271,7 +272,7 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
const uint32_t log2_cg_size = uvg_g_log2_sbb_size[log2_block_size][log2_block_size][0] + uvg_g_log2_sbb_size[log2_block_size][log2_block_size][1]; const uint32_t log2_cg_size = uvg_g_log2_sbb_size[log2_block_size][log2_block_size][0] + uvg_g_log2_sbb_size[log2_block_size][log2_block_size][1];
const uint32_t* scan = uvg_g_sig_last_scan[scan_mode][log2_block_size - 1]; const uint32_t* scan = uvg_g_sig_last_scan[scan_mode][log2_block_size - 1];
const uint32_t* scan_cg = g_sig_last_scan_cg[log2_block_size - 1][scan_mode]; const uint32_t* scan_cg = g_sig_last_scan_cg[log2_block_size - 1][scan_mode];
double bits = 0;
// Init base contexts according to block type // Init base contexts according to block type
cabac_ctx_t* base_coeff_group_ctx = &(cabac->ctx.transform_skip_sig_coeff_group[0]); cabac_ctx_t* base_coeff_group_ctx = &(cabac->ctx.transform_skip_sig_coeff_group[0]);
@ -304,10 +305,10 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
cabac->cur_ctx = &base_coeff_group_ctx[ctx_sig]; cabac->cur_ctx = &base_coeff_group_ctx[ctx_sig];
if(!sig_coeffgroup_flag[scan_cg[i]]) { if(!sig_coeffgroup_flag[scan_cg[i]]) {
CABAC_BIN(cabac, 0, "ts_sigGroup"); CABAC_FBITS_UPDATE(cabac, &base_coeff_group_ctx[ctx_sig], 0, bits, "ts_sigGroup");
continue; continue;
} }
CABAC_BIN(cabac, 1, "ts_sigGroup"); CABAC_FBITS_UPDATE(cabac, &base_coeff_group_ctx[ctx_sig], 1, bits, "ts_sigGroup");
no_sig_group_before_last = false; no_sig_group_before_last = false;
} }
@ -333,10 +334,9 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
unsigned sigFlag = (curr_coeff != 0); unsigned sigFlag = (curr_coeff != 0);
if (numNonZero || nextSigPos != inferSigPos) if (numNonZero || nextSigPos != inferSigPos)
{ {
cabac->cur_ctx = &cabac->ctx.transform_skip_sig[ CABAC_FBITS_UPDATE(cabac, &cabac->ctx.transform_skip_sig[
uvg_context_get_sig_ctx_idx_abs_ts(coeff, pos_x, pos_y, width) uvg_context_get_sig_ctx_idx_abs_ts(coeff, pos_x, pos_y, width)
]; ], sigFlag, bits, "sig_coeff_flag");
CABAC_BIN(cabac, sigFlag, "sig_coeff_flag");
maxCtxBins--; maxCtxBins--;
} }
@ -344,10 +344,10 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
{ {
//===== encode sign's ===== //===== encode sign's =====
int sign = curr_coeff < 0; int sign = curr_coeff < 0;
cabac->cur_ctx = &cabac->ctx.transform_skip_res_sign[
uvg_sign_ctx_id_abs_ts(coeff, pos_x, pos_y, width, 0)
];
CABAC_BIN(cabac, sign, "coeff_sign_flag"); CABAC_BIN(cabac, sign, "coeff_sign_flag");
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.transform_skip_sig[
uvg_sign_ctx_id_abs_ts(coeff, pos_x, pos_y, width, 0)
], sign, bits, "coeff_sign_flag");
maxCtxBins--; maxCtxBins--;
numNonZero++; numNonZero++;
@ -359,17 +359,15 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
remAbsLevel = modAbsCoeff - 1; remAbsLevel = modAbsCoeff - 1;
unsigned gt1 = !!remAbsLevel; unsigned gt1 = !!remAbsLevel;
cabac->cur_ctx = &cabac->ctx.transform_skip_gt1[ CABAC_FBITS_UPDATE(cabac, &cabac->ctx.transform_skip_sig[
uvg_lrg1_ctx_id_abs_ts(coeff, pos_x, pos_y, width, 0) uvg_lrg1_ctx_id_abs_ts(coeff, pos_x, pos_y, width, 0)
]; ], remAbsLevel & 1, bits, "abs_level_gtx_flag");
CABAC_BIN(cabac, gt1, "abs_level_gtx_flag");
maxCtxBins--; maxCtxBins--;
if (gt1) if (gt1)
{ {
remAbsLevel -= 1; remAbsLevel -= 1;
cabac->cur_ctx = &cabac->ctx.transform_skip_par; CABAC_FBITS_UPDATE(cabac, &cabac->ctx.transform_skip_par, gt1, bits, "par_level_flag");
CABAC_BIN(cabac, remAbsLevel & 1, "par_level_flag");
maxCtxBins--; maxCtxBins--;
} }
} }
@ -396,6 +394,9 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
unsigned gt2 = (absLevel >= (cutoffVal + 2)); unsigned gt2 = (absLevel >= (cutoffVal + 2));
cabac->cur_ctx = &cabac->ctx.transform_skip_gt2[cutoffVal >> 1]; cabac->cur_ctx = &cabac->ctx.transform_skip_gt2[cutoffVal >> 1];
CABAC_BIN(cabac, gt2, "abs_level_gtx_flag"); CABAC_BIN(cabac, gt2, "abs_level_gtx_flag");
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.transform_skip_sig[
kvz_lrg1_ctx_id_abs_ts(coeff, pos_x, pos_y, width, 0)
], gt2, bits, "abs_level_gtx_flag");
maxCtxBins--; maxCtxBins--;
} }
cutoffVal += 2; cutoffVal += 2;
@ -419,16 +420,18 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
{ {
int rice = 1; int rice = 1;
unsigned rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel; unsigned rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
uvg_cabac_write_coeff_remain(cabac, rem, rice, 5); bits += uvg_cabac_write_coeff_remain(cabac, rem, rice, 5);
if (absLevel && scanPos > lastScanPosPass1) if (absLevel && scanPos > lastScanPosPass1)
{ {
int sign = coeff[blk_pos] < 0; int sign = coeff[blk_pos] < 0;
CABAC_BIN_EP(cabac, sign, "coeff_sign_flag"); CABAC_BIN_EP(cabac, sign, "coeff_sign_flag");
bits += 1;
} }
} }
} }
} }
if (bits_out && cabac->only_count) *bits_out += bits;
} }
/** /**
@ -447,7 +450,7 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
void uvg_encode_last_significant_xy(cabac_data_t * const cabac, void uvg_encode_last_significant_xy(cabac_data_t * const cabac,
uint8_t lastpos_x, uint8_t lastpos_y, uint8_t lastpos_x, uint8_t lastpos_y,
uint8_t width, uint8_t height, uint8_t width, uint8_t height,
uint8_t type, uint8_t scan) uint8_t type, uint8_t scan, double* bits_out)
{ {
const int index_x = uvg_math_floor_log2(width); const int index_x = uvg_math_floor_log2(width);
const int index_y = uvg_math_floor_log2(width); const int index_y = uvg_math_floor_log2(width);
@ -457,6 +460,7 @@ void uvg_encode_last_significant_xy(cabac_data_t * const cabac,
uint8_t ctx_offset_y = type ? 0 : prefix_ctx[index_y]; uint8_t ctx_offset_y = type ? 0 : prefix_ctx[index_y];
uint8_t shift_x = type ? CLIP(0, 2, width>>3) : (index_x+1)>>2; uint8_t shift_x = type ? CLIP(0, 2, width>>3) : (index_x+1)>>2;
uint8_t shift_y = type ? CLIP(0, 2, width >> 3) : (index_y + 1) >> 2; uint8_t shift_y = type ? CLIP(0, 2, width >> 3) : (index_y + 1) >> 2;
double bits = 0;
cabac_ctx_t *base_ctx_x = (type ? cabac->ctx.cu_ctx_last_x_chroma : cabac->ctx.cu_ctx_last_x_luma); cabac_ctx_t *base_ctx_x = (type ? cabac->ctx.cu_ctx_last_x_chroma : cabac->ctx.cu_ctx_last_x_luma);
cabac_ctx_t *base_ctx_y = (type ? cabac->ctx.cu_ctx_last_y_chroma : cabac->ctx.cu_ctx_last_y_luma); cabac_ctx_t *base_ctx_y = (type ? cabac->ctx.cu_ctx_last_y_chroma : cabac->ctx.cu_ctx_last_y_luma);
@ -466,39 +470,38 @@ void uvg_encode_last_significant_xy(cabac_data_t * const cabac,
// x prefix // x prefix
int last_x = 0; int last_x = 0;
for (last_x = 0; last_x < group_idx_x; last_x++) { for (; last_x < group_idx_x; last_x++) {
cabac->cur_ctx = &base_ctx_x[ctx_offset_x + (last_x >> shift_x)]; CABAC_FBITS_UPDATE(cabac, &base_ctx_x[ctx_offset_x + (last_x >> shift_x)], 1, bits, "last_sig_coeff_x_prefix");
CABAC_BIN(cabac, 1, "last_sig_coeff_x_prefix");
} }
if (group_idx_x < ( /*width == 32 ? g_group_idx[15] : */g_group_idx[MIN(32, (int32_t)width) - 1])) { if (group_idx_x < ( /*width == 32 ? g_group_idx[15] : */g_group_idx[MIN(32, (int32_t)width) - 1])) {
cabac->cur_ctx = &base_ctx_x[ctx_offset_x + (last_x >> shift_x)]; CABAC_FBITS_UPDATE(cabac, &base_ctx_x[ctx_offset_x + (last_x >> shift_x)], 0, bits, "last_sig_coeff_x_prefix");
CABAC_BIN(cabac, 0, "last_sig_coeff_x_prefix");
} }
// y prefix // y prefix
int last_y = 0; int last_y = 0;
for (last_y = 0; last_y < group_idx_y; last_y++) { for (; last_y < group_idx_y; last_y++) {
cabac->cur_ctx = &base_ctx_y[ctx_offset_y + (last_y >> shift_y)]; CABAC_FBITS_UPDATE(cabac, &base_ctx_y[ctx_offset_y + (last_y >> shift_y)], 1, bits, "last_sig_coeff_y_prefix");
CABAC_BIN(cabac, 1, "last_sig_coeff_y_prefix");
} }
if (group_idx_y < (/* height == 32 ? g_group_idx[15] : */g_group_idx[MIN(32, (int32_t)height) - 1])) { if (group_idx_y < (/* height == 32 ? g_group_idx[15] : */g_group_idx[MIN(32, (int32_t)height) - 1])) {
cabac->cur_ctx = &base_ctx_y[ctx_offset_y + (last_y >> shift_y)]; CABAC_FBITS_UPDATE(cabac, &base_ctx_y[ctx_offset_y + (last_y >> shift_y)], 0, bits, "last_sig_coeff_y_prefix");
CABAC_BIN(cabac, 0, "last_sig_coeff_y_prefix");
} }
// last_sig_coeff_x_suffix // last_sig_coeff_x_suffix
if (group_idx_x > 3) { if (group_idx_x > 3) {
const int suffix = lastpos_x - g_min_in_group[group_idx_x]; const int suffix = lastpos_x - g_min_in_group[group_idx_x];
const int bits = (group_idx_x - 2) / 2; const int write_bits = (group_idx_x - 2) / 2;
CABAC_BINS_EP(cabac, suffix, bits, "last_sig_coeff_x_suffix"); CABAC_BINS_EP(cabac, suffix, write_bits, "last_sig_coeff_x_suffix");
if (cabac->only_count) bits += write_bits;
} }
// last_sig_coeff_y_suffix // last_sig_coeff_y_suffix
if (group_idx_y > 3) { if (group_idx_y > 3) {
const int suffix = lastpos_y - g_min_in_group[group_idx_y]; const int suffix = lastpos_y - g_min_in_group[group_idx_y];
const int bits = (group_idx_y - 2) / 2; const int write_bits = (group_idx_y - 2) / 2;
CABAC_BINS_EP(cabac, suffix, bits, "last_sig_coeff_y_suffix"); CABAC_BINS_EP(cabac, suffix, write_bits, "last_sig_coeff_y_suffix");
if (cabac->only_count) bits += write_bits;
} }
if (cabac->only_count && bits_out) *bits_out += bits;
} }
static void encode_chroma_tu(encoder_state_t* const state, int x, int y, int depth, const uint8_t width_c, cu_info_t* cur_pu, int8_t* scan_idx, lcu_coeff_t* coeff, uint8_t joint_chroma) { static void encode_chroma_tu(encoder_state_t* const state, int x, int y, int depth, const uint8_t width_c, cu_info_t* cur_pu, int8_t* scan_idx, lcu_coeff_t* coeff, uint8_t joint_chroma) {
@ -517,7 +520,7 @@ static void encode_chroma_tu(encoder_state_t* const state, int x, int y, int dep
// TODO: transform skip for chroma blocks // TODO: transform skip for chroma blocks
CABAC_BIN(cabac, 0, "transform_skip_flag"); CABAC_BIN(cabac, 0, "transform_skip_flag");
} }
uvg_encode_coeff_nxn(state, &state->cabac, coeff_u, width_c, COLOR_U, *scan_idx, cur_pu); uvg_encode_coeff_nxn(state, &state->cabac, coeff_u, width_c, COLOR_U, *scan_idx, NULL, cur_pu);
} }
if (cbf_is_set(cur_pu->cbf, depth, COLOR_V)) { if (cbf_is_set(cur_pu->cbf, depth, COLOR_V)) {
@ -525,7 +528,7 @@ static void encode_chroma_tu(encoder_state_t* const state, int x, int y, int dep
cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma; cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma;
CABAC_BIN(cabac, 0, "transform_skip_flag"); CABAC_BIN(cabac, 0, "transform_skip_flag");
} }
uvg_encode_coeff_nxn(state, &state->cabac, coeff_v, width_c, COLOR_V, *scan_idx, cur_pu); uvg_encode_coeff_nxn(state, &state->cabac, coeff_v, width_c, COLOR_V, *scan_idx, NULL, cur_pu);
} }
} }
else { else {
@ -534,7 +537,7 @@ static void encode_chroma_tu(encoder_state_t* const state, int x, int y, int dep
cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma; cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma;
CABAC_BIN(cabac, 0, "transform_skip_flag"); CABAC_BIN(cabac, 0, "transform_skip_flag");
} }
uvg_encode_coeff_nxn(state, &state->cabac, coeff_uv, width_c, COLOR_V, *scan_idx, cur_pu); uvg_encode_coeff_nxn(state, &state->cabac, coeff_uv, width_c, COLOR_V, *scan_idx, NULL, cur_pu);
} }
} }
@ -569,7 +572,7 @@ static void encode_transform_unit(encoder_state_t * const state,
DBG_YUVIEW_VALUE(state->frame->poc, DBG_YUVIEW_TR_SKIP, x, y, width, width, (cur_pu->tr_idx == MTS_SKIP) ? 1 : 0); DBG_YUVIEW_VALUE(state->frame->poc, DBG_YUVIEW_TR_SKIP, x, y, width, width, (cur_pu->tr_idx == MTS_SKIP) ? 1 : 0);
} }
if(cur_pu->tr_idx == MTS_SKIP) { if(cur_pu->tr_idx == MTS_SKIP) {
uvg_encode_ts_residual(state, cabac, coeff_y, width, 0, scan_idx); uvg_encode_ts_residual(state, cabac, coeff_y, width, 0, scan_idx, NULL);
} }
else { else {
uvg_encode_coeff_nxn(state, uvg_encode_coeff_nxn(state,
@ -578,7 +581,8 @@ static void encode_transform_unit(encoder_state_t * const state,
width, width,
0, 0,
scan_idx, scan_idx,
(cu_info_t * )cur_pu); (cu_info_t * )cur_pu,
NULL);
} }
} }

View file

@ -51,7 +51,8 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
const coeff_t* coeff, const coeff_t* coeff,
uint32_t width, uint32_t width,
uint8_t type, uint8_t type,
int8_t scan_mode); int8_t scan_mode,
double* bits);
void uvg_encode_mvd(encoder_state_t * const state, void uvg_encode_mvd(encoder_state_t * const state,
cabac_data_t *cabac, cabac_data_t *cabac,
@ -87,4 +88,4 @@ bool uvg_write_split_flag(const encoder_state_t* const state, cabac_data_t* caba
void uvg_encode_last_significant_xy(cabac_data_t * const cabac, void uvg_encode_last_significant_xy(cabac_data_t * const cabac,
uint8_t lastpos_x, uint8_t lastpos_y, uint8_t lastpos_x, uint8_t lastpos_y,
uint8_t width, uint8_t height, uint8_t width, uint8_t height,
uint8_t type, uint8_t scan); uint8_t type, uint8_t scan, double* bits_out);

View file

@ -294,7 +294,7 @@ out:
* *
* \returns bits needed to code input coefficients * \returns bits needed to code input coefficients
*/ */
static INLINE uint32_t get_coeff_cabac_cost( static INLINE double get_coeff_cabac_cost(
const encoder_state_t * const state, const encoder_state_t * const state,
const coeff_t *coeff, const coeff_t *coeff,
int32_t width, int32_t width,
@ -319,8 +319,8 @@ static INLINE uint32_t get_coeff_cabac_cost(
// Clear bytes and bits and set mode to "count" // Clear bytes and bits and set mode to "count"
cabac_copy.only_count = 1; cabac_copy.only_count = 1;
int num_buffered_bytes = cabac_copy.num_buffered_bytes; cabac_copy.update = 1;
int bits_left = cabac_copy.bits_left; double bits = 0;
// Execute the coding function. // Execute the coding function.
// It is safe to drop the const modifier since state won't be modified // It is safe to drop the const modifier since state won't be modified
@ -332,7 +332,8 @@ static INLINE uint32_t get_coeff_cabac_cost(
width, width,
type, type,
scan_mode, scan_mode,
NULL); NULL,
&bits);
} }
else { else {
uvg_encode_ts_residual((encoder_state_t* const)state, uvg_encode_ts_residual((encoder_state_t* const)state,
@ -340,15 +341,16 @@ static INLINE uint32_t get_coeff_cabac_cost(
coeff, coeff,
width, width,
type, type,
scan_mode); scan_mode,
&bits);
} }
if(cabac_copy.update) { if(state->search_cabac.update) {
memcpy((cabac_data_t *)&state->search_cabac, &cabac_copy, sizeof(cabac_copy)); memcpy((cabac_data_t *)&state->search_cabac, &cabac_copy, sizeof(cabac_copy));
} }
return (bits_left - cabac_copy.bits_left) + ((cabac_copy.num_buffered_bytes - num_buffered_bytes) << 3); return bits;
} }
static INLINE void save_ccc(int qp, const coeff_t *coeff, int32_t size, uint32_t ccc) static INLINE void save_ccc(int qp, const coeff_t *coeff, int32_t size, double ccc)
{ {
pthread_mutex_t *mtx = outfile_mutex + qp; pthread_mutex_t *mtx = outfile_mutex + qp;
@ -364,14 +366,14 @@ static INLINE void save_ccc(int qp, const coeff_t *coeff, int32_t size, uint32_t
pthread_mutex_unlock(mtx); pthread_mutex_unlock(mtx);
} }
static INLINE void save_accuracy(int qp, uint32_t ccc, uint32_t fast_cost) static INLINE void save_accuracy(int qp, double ccc, uint32_t fast_cost)
{ {
pthread_mutex_t *mtx = outfile_mutex + qp; pthread_mutex_t *mtx = outfile_mutex + qp;
assert(qp <= RD_SAMPLING_MAX_LAST_QP); assert(qp <= RD_SAMPLING_MAX_LAST_QP);
pthread_mutex_lock(mtx); pthread_mutex_lock(mtx);
fprintf(fastrd_learning_outfile[qp], "%u %u\n", fast_cost, ccc); fprintf(fastrd_learning_outfile[qp], "%u %f\n", fast_cost, ccc);
pthread_mutex_unlock(mtx); pthread_mutex_unlock(mtx);
} }
@ -384,7 +386,7 @@ static INLINE void save_accuracy(int qp, uint32_t ccc, uint32_t fast_cost)
* *
* \returns number of bits needed to code coefficients * \returns number of bits needed to code coefficients
*/ */
uint32_t uvg_get_coeff_cost(const encoder_state_t * const state, double uvg_get_coeff_cost(const encoder_state_t * const state,
const coeff_t *coeff, const coeff_t *coeff,
int32_t width, int32_t width,
int32_t type, int32_t type,
@ -406,13 +408,13 @@ uint32_t uvg_get_coeff_cost(const encoder_state_t * const state,
uint64_t weights = uvg_fast_coeff_get_weights(state); uint64_t weights = uvg_fast_coeff_get_weights(state);
uint32_t fast_cost = uvg_fast_coeff_cost(coeff, width, weights); uint32_t fast_cost = uvg_fast_coeff_cost(coeff, width, weights);
if (check_accuracy) { if (check_accuracy) {
uint32_t ccc = get_coeff_cabac_cost(state, coeff, width, type, scan_mode, tr_skip); double ccc = get_coeff_cabac_cost(state, coeff, width, type, scan_mode, tr_skip);
save_accuracy(state->qp, ccc, fast_cost); save_accuracy(state->qp, ccc, fast_cost);
} }
return fast_cost; return fast_cost;
} }
} else { } else {
uint32_t ccc = get_coeff_cabac_cost(state, coeff, width, type, scan_mode, tr_skip); double ccc = get_coeff_cabac_cost(state, coeff, width, type, scan_mode, tr_skip);
if (save_cccs) { if (save_cccs) {
save_ccc(state->qp, coeff, width * width, ccc); save_ccc(state->qp, coeff, width * width, ccc);
} }

View file

@ -59,7 +59,7 @@ int uvg_ts_rdoq(encoder_state_t* const state, coeff_t* src_coeff, coeff_t* dest_
int32_t height, int8_t type, int8_t scan_mode); int32_t height, int8_t type, int8_t scan_mode);
uint32_t uvg_get_coeff_cost(const encoder_state_t * const state, double uvg_get_coeff_cost(const encoder_state_t * const state,
const coeff_t *coeff, const coeff_t *coeff,
int32_t width, int32_t width,
int32_t type, int32_t type,

View file

@ -252,7 +252,8 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
uint8_t width, uint8_t width,
uint8_t type, uint8_t type,
int8_t scan_mode, int8_t scan_mode,
int8_t tr_skip) int8_t tr_skip,
double* bits_out)
{ {
const encoder_control_t * const encoder = state->encoder_control; const encoder_control_t * const encoder = state->encoder_control;
int c1 = 1; int c1 = 1;
@ -260,6 +261,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
uint8_t last_coeff_y = 0; uint8_t last_coeff_y = 0;
int32_t i; int32_t i;
uint32_t sig_coeffgroup_nzs[8 * 8] = { 0 }; uint32_t sig_coeffgroup_nzs[8 * 8] = { 0 };
double bits = 0;
int8_t be_valid = encoder->cfg.signhide_enable; int8_t be_valid = encoder->cfg.signhide_enable;
int32_t scan_pos_sig; int32_t scan_pos_sig;
@ -361,7 +363,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
// transform skip flag // transform skip flag
if(width == 4 && encoder->cfg.trskip_enable) { if(width == 4 && encoder->cfg.trskip_enable) {
cabac->cur_ctx = (type == 0) ? &(cabac->ctx.cu_sig_model_luma) : &(cabac->ctx.cu_sig_model_chroma); cabac->cur_ctx = (type == 0) ? &(cabac->ctx.cu_sig_model_luma) : &(cabac->ctx.cu_sig_model_chroma);
CABAC_BIN(cabac, tr_skip, "transform_skip_flag"); CABAC_FBITS_UPDATE(cabac, cabac->cur_ctx, tr_skip, bits, "transform_skip_flag");
} }
last_coeff_x = pos_last & (width - 1); last_coeff_x = pos_last & (width - 1);
@ -374,7 +376,8 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
width, width,
width, width,
type, type,
scan_mode); scan_mode,
bits_out);
scan_pos_sig = scan_pos_last; scan_pos_sig = scan_pos_last;
@ -406,8 +409,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
uint32_t sig_coeff_group = (sig_coeffgroup_nzs[cg_blk_pos] != 0); uint32_t sig_coeff_group = (sig_coeffgroup_nzs[cg_blk_pos] != 0);
uint32_t ctx_sig = uvg_context_get_sig_coeff_group(sig_coeffgroup_nzs, cg_pos_x, uint32_t ctx_sig = uvg_context_get_sig_coeff_group(sig_coeffgroup_nzs, cg_pos_x,
cg_pos_y, width); cg_pos_y, width);
cabac->cur_ctx = &base_coeff_group_ctx[ctx_sig]; CABAC_FBITS_UPDATE(cabac, &base_coeff_group_ctx[ctx_sig], sig_coeff_group, bits, "coded_sub_block_flag");
CABAC_BIN(cabac, sig_coeff_group, "coded_sub_block_flag");
} }
if (sig_coeffgroup_nzs[cg_blk_pos]) { if (sig_coeffgroup_nzs[cg_blk_pos]) {
@ -464,8 +466,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
if (curr_esc_flag | num_non_zero) { if (curr_esc_flag | num_non_zero) {
ctx_sig = ctx_sig_buf[id]; ctx_sig = ctx_sig_buf[id];
cabac->cur_ctx = &baseCtx[ctx_sig]; CABAC_FBITS_UPDATE(cabac, &baseCtx[ctx_sig], curr_sig, bits, "sig_coeff_flag");
CABAC_BIN(cabac, curr_sig, "sig_coeff_flag");
} }
if (curr_sig) { if (curr_sig) {
@ -519,8 +520,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
uint32_t shift = idx << 1; uint32_t shift = idx << 1;
uint32_t symbol = (coeffs_gt1_bits >> shift) & 1; uint32_t symbol = (coeffs_gt1_bits >> shift) & 1;
cabac->cur_ctx = &base_ctx_mod[c1]; CABAC_FBITS_UPDATE(cabac, &base_ctx_mod[c1], symbol, bits, "coeff_abs_level_greater1_flag");
CABAC_BIN(cabac, symbol, "coeff_abs_level_greater1_flag");
c1 = (c1s_nextiter >> shift) & 3; c1 = (c1s_nextiter >> shift) & 3;
} }
@ -532,9 +532,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
if (first_c2_flag_idx != -1) { if (first_c2_flag_idx != -1) {
uint32_t shift = (first_c2_flag_idx << 1) + 1; uint32_t shift = (first_c2_flag_idx << 1) + 1;
uint8_t symbol = (coeffs_gt2_bits >> shift) & 1; uint8_t symbol = (coeffs_gt2_bits >> shift) & 1;
cabac->cur_ctx = &base_ctx_mod[0]; CABAC_FBITS_UPDATE(cabac, &base_ctx_mod[0], symbol, bits, "coeff_abs_level_greater2_flag");
CABAC_BIN(cabac, symbol, "coeff_abs_level_greater2_flag");
} }
} }
int32_t shiftamt = (be_valid && sign_hidden) ? 1 : 0; int32_t shiftamt = (be_valid && sign_hidden) ? 1 : 0;
@ -546,6 +544,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
} }
} }
CABAC_BINS_EP(cabac, coeff_signs, nnz, "coeff_sign_flag"); CABAC_BINS_EP(cabac, coeff_signs, nnz, "coeff_sign_flag");
if (cabac->only_count) bits += nnz;
if (c1 == 0 || num_non_zero > C1FLAG_NUMBER) { if (c1 == 0 || num_non_zero > C1FLAG_NUMBER) {
@ -586,7 +585,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
if (!cabac->only_count && (encoder->cfg.crypto_features & UVG_CRYPTO_TRANSF_COEFFS)) { if (!cabac->only_count && (encoder->cfg.crypto_features & UVG_CRYPTO_TRANSF_COEFFS)) {
uvg_cabac_write_coeff_remain_encry(state, cabac, level_diff, go_rice_param, base_level); uvg_cabac_write_coeff_remain_encry(state, cabac, level_diff, go_rice_param, base_level);
} else { } else {
uvg_cabac_write_coeff_remain(cabac, level_diff, go_rice_param); bits += uvg_cabac_write_coeff_remain(cabac, level_diff, go_rice_param);
} }
if (curr_abs_coeff > 3 * (1 << go_rice_param)) { if (curr_abs_coeff > 3 * (1 << go_rice_param)) {
@ -602,6 +601,7 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
num_non_zero = 0; num_non_zero = 0;
coeff_signs = 0; coeff_signs = 0;
} }
if (cabac->only_count) *bits_out += bits;
} }
#endif // COMPILE_INTEL_AVX2 #endif // COMPILE_INTEL_AVX2

View file

@ -47,7 +47,8 @@ void uvg_encode_coeff_nxn_avx2(encoder_state_t * const state,
uint8_t width, uint8_t width,
uint8_t type, uint8_t type,
int8_t scan_mode, int8_t scan_mode,
int8_t tr_skip); int8_t tr_skip,
double* bits_out);
int uvg_strategy_register_encode_avx2(void* opaque, uint8_t bitdepth); int uvg_strategy_register_encode_avx2(void* opaque, uint8_t bitdepth);

View file

@ -57,7 +57,8 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
uint8_t width, uint8_t width,
uint8_t color, uint8_t color,
int8_t scan_mode, int8_t scan_mode,
cu_info_t* cur_cu) { cu_info_t* cur_cu,
double* bits_out) {
//const encoder_control_t * const encoder = state->encoder_control; //const encoder_control_t * const encoder = state->encoder_control;
//int c1 = 1; //int c1 = 1;
@ -70,6 +71,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
int32_t scan_pos; int32_t scan_pos;
//int32_t next_sig_pos; //int32_t next_sig_pos;
uint32_t blk_pos, pos_y, pos_x, sig, ctx_sig; uint32_t blk_pos, pos_y, pos_x, sig, ctx_sig;
double bits = 0;
// CONSTANTS // CONSTANTS
@ -115,7 +117,8 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
width, width,
width, width,
color, color,
scan_mode); scan_mode,
bits_out);
@ -144,8 +147,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
uint32_t sig_coeff_group = (sig_coeffgroup_flag[cg_blk_pos] != 0); uint32_t sig_coeff_group = (sig_coeffgroup_flag[cg_blk_pos] != 0);
uint32_t ctx_sig = uvg_context_get_sig_coeff_group(sig_coeffgroup_flag, cg_pos_x, uint32_t ctx_sig = uvg_context_get_sig_coeff_group(sig_coeffgroup_flag, cg_pos_x,
cg_pos_y, (MIN((uint8_t)32, width) >> (log2_cg_size / 2))); cg_pos_y, (MIN((uint8_t)32, width) >> (log2_cg_size / 2)));
cabac->cur_ctx = &base_coeff_group_ctx[ctx_sig]; CABAC_FBITS_UPDATE(cabac, &base_coeff_group_ctx[ctx_sig], sig_coeff_group, bits, "significant_coeffgroup_flag");
CABAC_BIN(cabac, sig_coeff_group, "significant_coeffgroup_flag");
} }
@ -178,9 +180,8 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
ctx_sig = uvg_context_get_sig_ctx_idx_abs(coeff, pos_x, pos_y, width, width, color, &temp_diag, &temp_sum); ctx_sig = uvg_context_get_sig_ctx_idx_abs(coeff, pos_x, pos_y, width, width, color, &temp_diag, &temp_sum);
cabac_ctx_t* sig_ctx_luma = &(cabac->ctx.cu_sig_model_luma[MAX(0, (quant_state - 1))][ctx_sig]); cabac_ctx_t* sig_ctx_luma = &(cabac->ctx.cu_sig_model_luma[MAX(0, (quant_state - 1))][ctx_sig]);
cabac_ctx_t* sig_ctx_chroma = &(cabac->ctx.cu_sig_model_chroma[MAX(0, (quant_state - 1))][MIN(ctx_sig,7)]); cabac_ctx_t* sig_ctx_chroma = &(cabac->ctx.cu_sig_model_chroma[MAX(0, (quant_state - 1))][MIN(ctx_sig,7)]);
cabac->cur_ctx = (color == COLOR_Y ? sig_ctx_luma : sig_ctx_chroma);
CABAC_BIN(cabac, sig, "sig_coeff_flag"); CABAC_FBITS_UPDATE(cabac, (color == 0 ? sig_ctx_luma : sig_ctx_chroma), sig, bits, "sig_coeff_flag");
reg_bins--; reg_bins--;
} else if (next_sig_pos != scan_pos_last) { } else if (next_sig_pos != scan_pos_last) {
@ -214,25 +215,25 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
// Code "greater than 1" flag // Code "greater than 1" flag
uint8_t gt1 = remainder_abs_coeff ? 1 : 0; uint8_t gt1 = remainder_abs_coeff ? 1 : 0;
cabac->cur_ctx = (color == COLOR_Y) ? &(cabac->ctx.cu_gtx_flag_model_luma[1][*offset]) : CABAC_FBITS_UPDATE(cabac, (color == 0) ? &(cabac->ctx.cu_gtx_flag_model_luma[1][*offset]) :
&(cabac->ctx.cu_gtx_flag_model_chroma[1][*offset]); &(cabac->ctx.cu_gtx_flag_model_chroma[1][*offset]),
CABAC_BIN(cabac, gt1, "gt1_flag"); gt1, bits, "abs_level_gtx_flag");
reg_bins--; reg_bins--;
if (gt1) { if (gt1) {
remainder_abs_coeff -= 1; remainder_abs_coeff -= 1;
// Code coeff parity // Code coeff parity
cabac->cur_ctx = (color == COLOR_Y) ? &(cabac->ctx.cu_parity_flag_model_luma[*offset]) : CABAC_FBITS_UPDATE(cabac, (color == 0) ? &(cabac->ctx.cu_parity_flag_model_luma[*offset]) :
&(cabac->ctx.cu_parity_flag_model_chroma[*offset]); &(cabac->ctx.cu_parity_flag_model_chroma[*offset]),
CABAC_BIN(cabac, remainder_abs_coeff & 1, "par_flag"); remainder_abs_coeff & 1, bits, "par_flag");
remainder_abs_coeff >>= 1; remainder_abs_coeff >>= 1;
reg_bins--; reg_bins--;
uint8_t gt2 = remainder_abs_coeff ? 1 : 0; uint8_t gt2 = remainder_abs_coeff ? 1 : 0;
cabac->cur_ctx = (color == COLOR_Y) ? &(cabac->ctx.cu_gtx_flag_model_luma[0][*offset]) : CABAC_FBITS_UPDATE(cabac, (color == 0) ? &(cabac->ctx.cu_gtx_flag_model_luma[0][*offset]) :
&(cabac->ctx.cu_gtx_flag_model_chroma[0][*offset]); &(cabac->ctx.cu_gtx_flag_model_chroma[0][*offset]),
CABAC_BIN(cabac, gt2, "gt2_flag"); gt2, bits, "gt2_flag");
reg_bins--; reg_bins--;
} }
} }
@ -256,7 +257,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
uint32_t second_pass_abs_coeff = abs(coeff[blk_pos]); uint32_t second_pass_abs_coeff = abs(coeff[blk_pos]);
if (second_pass_abs_coeff >= 4) { if (second_pass_abs_coeff >= 4) {
uint32_t remainder = (second_pass_abs_coeff - 4) >> 1; uint32_t remainder = (second_pass_abs_coeff - 4) >> 1;
uvg_cabac_write_coeff_remain(cabac, remainder, rice_param, 5); bits += uvg_cabac_write_coeff_remain(cabac, remainder, rice_param, 5);
} }
} }
@ -272,7 +273,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
rice_param = g_go_rice_pars[abs_sum]; rice_param = g_go_rice_pars[abs_sum];
pos0 = ((quant_state<2)?1:2) << rice_param; pos0 = ((quant_state<2)?1:2) << rice_param;
uint32_t remainder = (coeff_abs == 0 ? pos0 : coeff_abs <= pos0 ? coeff_abs - 1 : coeff_abs); uint32_t remainder = (coeff_abs == 0 ? pos0 : coeff_abs <= pos0 ? coeff_abs - 1 : coeff_abs);
uvg_cabac_write_coeff_remain(cabac, remainder, rice_param, 5); bits += uvg_cabac_write_coeff_remain(cabac, remainder, rice_param, 5);
quant_state = (quant_state_transition_table >> ((quant_state << 2) + ((coeff_abs & 1) << 1))) & 3; quant_state = (quant_state_transition_table >> ((quant_state << 2) + ((coeff_abs & 1) << 1))) & 3;
if (coeff_abs) { if (coeff_abs) {
num_non_zero++; num_non_zero++;
@ -296,6 +297,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
} }
CABAC_BINS_EP(cabac, coeff_signs, num_signs, "coeff_signs"); CABAC_BINS_EP(cabac, coeff_signs, num_signs, "coeff_signs");
if (cabac->only_count) bits += num_signs;
} }
if (color == COLOR_Y && cur_cu != NULL && (cg_pos_y > 3 || cg_pos_x > 3) && sig_coeffgroup_flag[cg_blk_pos] != 0) if (color == COLOR_Y && cur_cu != NULL && (cg_pos_y > 3 || cg_pos_x > 3) && sig_coeffgroup_flag[cg_blk_pos] != 0)
@ -303,6 +305,7 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
cur_cu->violates_mts_coeff_constraint = true; cur_cu->violates_mts_coeff_constraint = true;
} }
} }
if (cabac->only_count) *bits_out += bits;
} }

View file

@ -47,7 +47,8 @@ void uvg_encode_coeff_nxn_generic(encoder_state_t * const state,
uint8_t width, uint8_t width,
uint8_t color, uint8_t color,
int8_t scan_mode, int8_t scan_mode,
cu_info_t* cur_cu); cu_info_t* cur_cu,
double* bits_out);
int uvg_strategy_register_encode_generic(void* opaque, uint8_t bitdepth); int uvg_strategy_register_encode_generic(void* opaque, uint8_t bitdepth);

View file

@ -52,7 +52,8 @@ typedef unsigned (encode_coeff_nxn_func)(encoder_state_t * const state,
uint8_t width, uint8_t width,
uint8_t color, uint8_t color,
int8_t scan_mode, int8_t scan_mode,
cu_info_t* cur_cu); cu_info_t* cur_cu,
double *bits_out);
// Declare function pointers. // Declare function pointers.
extern encode_coeff_nxn_func *uvg_encode_coeff_nxn; extern encode_coeff_nxn_func *uvg_encode_coeff_nxn;