mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
Function for mock coding a CU and counting the bits
This commit is contained in:
parent
4b8d217f2d
commit
aea1133e6a
|
@ -547,7 +547,7 @@ void kvz_cabac_write_unary_max_symbol_ep(cabac_data_t * const data, unsigned int
|
|||
/**
|
||||
* \brief
|
||||
*/
|
||||
void kvz_cabac_write_ep_ex_golomb(encoder_state_t * const state,
|
||||
uint32_t kvz_cabac_write_ep_ex_golomb(encoder_state_t * const state,
|
||||
cabac_data_t * const data,
|
||||
uint32_t symbol,
|
||||
uint32_t count)
|
||||
|
@ -576,4 +576,5 @@ void kvz_cabac_write_ep_ex_golomb(encoder_state_t * const state,
|
|||
}
|
||||
}
|
||||
kvz_cabac_encode_bins_ep(data, bins, num_bins);
|
||||
return num_bins;
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ void kvz_cabac_write_coeff_remain(cabac_data_t *cabac, uint32_t symbol,
|
|||
uint32_t r_param);
|
||||
void kvz_cabac_write_coeff_remain_encry(struct encoder_state_t * const state, cabac_data_t * const cabac, const uint32_t symbol,
|
||||
const uint32_t r_param, int32_t base_level);
|
||||
void kvz_cabac_write_ep_ex_golomb(struct encoder_state_t * const state, cabac_data_t *data,
|
||||
uint32_t kvz_cabac_write_ep_ex_golomb(struct encoder_state_t * const state, cabac_data_t *data,
|
||||
uint32_t symbol, uint32_t count);
|
||||
void kvz_cabac_write_unary_max_symbol(cabac_data_t *data, cabac_ctx_t *ctx,
|
||||
uint32_t symbol, int32_t offset,
|
||||
|
@ -133,7 +133,7 @@ extern const float kvz_f_entropy_bits[128];
|
|||
#define CTX_ENTROPY_FBITS(ctx, val) kvz_f_entropy_bits[(ctx)->uc_state ^ (val)]
|
||||
|
||||
#define CABAC_FBITS_UPDATE(cabac, ctx, val, bits, name) do { \
|
||||
(bits) += kvz_f_entropy_bits[(ctx)->uc_state ^ (val)]; \
|
||||
if((cabac)->only_count) (bits) += kvz_f_entropy_bits[(ctx)->uc_state ^ (val)]; \
|
||||
if((cabac)->update) {\
|
||||
(cabac)->cur_ctx = ctx;\
|
||||
CABAC_BIN((cabac), (val), (name));\
|
||||
|
|
|
@ -309,15 +309,17 @@ static void encode_transform_coeff(encoder_state_t * const state,
|
|||
}
|
||||
|
||||
void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
||||
cabac_data_t * const cabac,
|
||||
const cu_info_t * const cur_cu,
|
||||
int x, int y, int width, int height,
|
||||
int depth, lcu_t* lcu)
|
||||
cabac_data_t * const cabac,
|
||||
const cu_info_t * const cur_cu,
|
||||
int x, int y, int width, int height,
|
||||
int depth, lcu_t* lcu, double* bits_out)
|
||||
{
|
||||
// Mergeflag
|
||||
int16_t num_cand = 0;
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
|
||||
CABAC_BIN(cabac, cur_cu->merged, "MergeFlag");
|
||||
double bits = 0;
|
||||
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_merge_flag_ext_model), cur_cu->merged, bits, "MergeFlag");
|
||||
|
||||
num_cand = state->encoder_control->cfg.max_merge;
|
||||
if (cur_cu->merged) { //merge
|
||||
if (num_cand > 1) {
|
||||
|
@ -325,10 +327,10 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
for (ui = 0; ui < num_cand - 1; ui++) {
|
||||
int32_t symbol = (ui != cur_cu->merge_idx);
|
||||
if (ui == 0) {
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_merge_idx_ext_model);
|
||||
CABAC_BIN(cabac, symbol, "MergeIndex");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_merge_idx_ext_model), symbol, bits, "MergeIndex");
|
||||
} else {
|
||||
CABAC_BIN_EP(cabac,symbol,"MergeIndex");
|
||||
if(cabac->only_count) bits += 1;
|
||||
}
|
||||
if (symbol == 0) break;
|
||||
}
|
||||
|
@ -339,12 +341,10 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
uint8_t inter_dir = cur_cu->inter.mv_dir-1;
|
||||
|
||||
if (cur_cu->part_size == SIZE_2Nx2N || (LCU_WIDTH >> depth) != 8) {
|
||||
cabac->cur_ctx = &(cabac->ctx.inter_dir[depth]);
|
||||
CABAC_BIN(cabac, (inter_dir == 2), "inter_pred_idc");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.inter_dir[depth]), inter_dir == 2, bits, "inter_pred_idc");
|
||||
}
|
||||
if (inter_dir < 2) {
|
||||
cabac->cur_ctx = &(cabac->ctx.inter_dir[4]);
|
||||
CABAC_BIN(cabac, inter_dir, "inter_pred_idc");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.inter_dir[4]), inter_dir, bits, "inter_pred_idc");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,9 +359,8 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
if (ref_LX_size > 1) {
|
||||
// parseRefFrmIdx
|
||||
int32_t ref_frame = cur_cu->inter.mv_ref[ref_list_idx];
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_ref_pic_model[0]);
|
||||
CABAC_BIN(cabac, (ref_frame != 0), "ref_idx_lX");
|
||||
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_ref_pic_model[0]), (ref_frame != 0), bits, "ref_idx_lX");
|
||||
|
||||
if (ref_frame > 0) {
|
||||
ref_frame--;
|
||||
|
@ -373,9 +372,10 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
|
||||
if (i == 0) {
|
||||
cabac->cur_ctx = &cabac->ctx.cu_ref_pic_model[1];
|
||||
CABAC_BIN(cabac, symbol, "ref_idx_lX");
|
||||
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.cu_ref_pic_model[1], symbol, bits, "ref_idx_lX");
|
||||
} else {
|
||||
CABAC_BIN_EP(cabac, symbol, "ref_idx_lX");
|
||||
if (cabac->only_count) bits += 1;
|
||||
}
|
||||
if (symbol == 0) break;
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
const int32_t mvd_hor = cur_cu->inter.mv[ref_list_idx][0] - mv_cand[cu_mv_cand][0];
|
||||
const int32_t mvd_ver = cur_cu->inter.mv[ref_list_idx][1] - mv_cand[cu_mv_cand][1];
|
||||
|
||||
kvz_encode_mvd(state, cabac, mvd_hor, mvd_ver);
|
||||
kvz_encode_mvd(state, cabac, mvd_hor, mvd_ver, bits_out);
|
||||
}
|
||||
|
||||
// Signal which candidate MV to use
|
||||
|
@ -416,6 +416,7 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
|
||||
} // for ref_list
|
||||
} // if !merge
|
||||
if(bits_out) *bits_out += bits;
|
||||
}
|
||||
|
||||
|
||||
|
@ -466,7 +467,7 @@ static INLINE uint8_t intra_mode_encryption(encoder_state_t * const state,
|
|||
static void encode_intra_coding_unit(encoder_state_t * const state,
|
||||
cabac_data_t * const cabac,
|
||||
const cu_info_t * const cur_cu,
|
||||
int x, int y, int depth)
|
||||
int x, int y, int depth, double* bits_out)
|
||||
{
|
||||
const videoframe_t * const frame = state->tile->frame;
|
||||
uint8_t intra_pred_mode_actual[4];
|
||||
|
@ -569,18 +570,19 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.intra_mode_model);
|
||||
|
||||
for (int j = 0; j < num_pred_units; ++j) {
|
||||
CABAC_BIN(cabac, flag[j], "prev_intra_luma_pred_flag");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.intra_mode_model),flag[j], *bits_out, "prev_intra_luma_pred_flag");
|
||||
}
|
||||
|
||||
for (int j = 0; j < num_pred_units; ++j) {
|
||||
// Signal index of the prediction mode in the prediction list.
|
||||
if (flag[j]) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] == 0 ? 0 : 1), "mpm_idx");
|
||||
if (cabac->only_count) *bits_out += 1;
|
||||
if (mpm_preds[j] != 0) {
|
||||
CABAC_BIN_EP(cabac, (mpm_preds[j] == 1 ? 0 : 1), "mpm_idx");
|
||||
if (cabac->only_count) *bits_out += 1;
|
||||
}
|
||||
} else {
|
||||
// Signal the actual prediction mode.
|
||||
|
@ -599,6 +601,7 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
}
|
||||
|
||||
CABAC_BINS_EP(cabac, tmp_pred, 5, "rem_intra_luma_pred_mode");
|
||||
if (cabac->only_count) *bits_out += 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,17 +642,21 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
|
|||
*/
|
||||
cabac->cur_ctx = &(cabac->ctx.chroma_pred_model[0]);
|
||||
if (pred_mode == 4) {
|
||||
CABAC_BIN(cabac, 0, "intra_chroma_pred_mode");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.chroma_pred_model[0]), 0, *bits_out,"intra_chroma_pred_mode");
|
||||
} else {
|
||||
CABAC_BIN(cabac, 1, "intra_chroma_pred_mode");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.chroma_pred_model[0]), 1, *bits_out,"intra_chroma_pred_mode");
|
||||
CABAC_BINS_EP(cabac, pred_mode, 2, "intra_chroma_pred_mode");
|
||||
if (cabac->only_count) *bits_out += 2;
|
||||
}
|
||||
}
|
||||
|
||||
encode_transform_coeff(state, x, y, depth, 0, 0, 0);
|
||||
// if we are counting bits, the cost for transform coeffs is done separately
|
||||
// To get the distortion at the same time
|
||||
if(!cabac->only_count)
|
||||
encode_transform_coeff(state, x, y, depth, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void encode_part_mode(encoder_state_t * const state,
|
||||
static double encode_part_mode(encoder_state_t * const state,
|
||||
cabac_data_t * const cabac,
|
||||
const cu_info_t * const cur_cu,
|
||||
int depth)
|
||||
|
@ -684,32 +691,32 @@ static void encode_part_mode(encoder_state_t * const state,
|
|||
// log2CbSize == MinCbLog2SizeY | 0 1 2 bypass
|
||||
// log2CbSize > MinCbLog2SizeY | 0 1 3 bypass
|
||||
// ------------------------------+------------------
|
||||
|
||||
double bits = 0;
|
||||
if (cur_cu->type == CU_INTRA) {
|
||||
if (depth == MAX_DEPTH) {
|
||||
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
||||
if (cur_cu->part_size == SIZE_2Nx2N) {
|
||||
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[0]), 1, bits, "part_mode 2Nx2N");
|
||||
} else {
|
||||
CABAC_BIN(cabac, 0, "part_mode NxN");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[0]), 0, bits, "part_mode NxN");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.part_size_model[0]);
|
||||
if (cur_cu->part_size == SIZE_2Nx2N) {
|
||||
CABAC_BIN(cabac, 1, "part_mode 2Nx2N");
|
||||
return;
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[0]), 1, bits, "part_mode 2Nx2N");
|
||||
return bits;
|
||||
}
|
||||
CABAC_BIN(cabac, 0, "part_mode split");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[0]), 0, bits, "part_mode split");
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.part_size_model[1]);
|
||||
if (cur_cu->part_size == SIZE_2NxN ||
|
||||
cur_cu->part_size == SIZE_2NxnU ||
|
||||
cur_cu->part_size == SIZE_2NxnD) {
|
||||
CABAC_BIN(cabac, 1, "part_mode vertical");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[1]), 1, bits, "part_mode vertical");
|
||||
} else {
|
||||
CABAC_BIN(cabac, 0, "part_mode horizontal");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[1]), 0, bits, "part_mode horizontal");
|
||||
}
|
||||
|
||||
if (state->encoder_control->cfg.amp_enable && depth < MAX_DEPTH) {
|
||||
|
@ -717,19 +724,22 @@ static void encode_part_mode(encoder_state_t * const state,
|
|||
|
||||
if (cur_cu->part_size == SIZE_2NxN ||
|
||||
cur_cu->part_size == SIZE_Nx2N) {
|
||||
CABAC_BIN(cabac, 1, "part_mode SMP");
|
||||
return;
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[3]), 1, bits, "part_mode SMP");
|
||||
return bits;
|
||||
}
|
||||
CABAC_BIN(cabac, 0, "part_mode AMP");
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.part_size_model[3]), 0, bits, "part_mode AMP");
|
||||
|
||||
if (cur_cu->part_size == SIZE_2NxnU ||
|
||||
cur_cu->part_size == SIZE_nLx2N) {
|
||||
CABAC_BINS_EP(cabac, 0, 1, "part_mode AMP");
|
||||
if(cabac->only_count) bits += 1;
|
||||
} else {
|
||||
CABAC_BINS_EP(cabac, 1, 1, "part_mode AMP");
|
||||
if(cabac->only_count) bits += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
void kvz_encode_coding_tree(encoder_state_t * const state,
|
||||
|
@ -865,7 +875,7 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
const int pu_h = PU_GET_H(cur_cu->part_size, cu_width, i);
|
||||
const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
|
||||
|
||||
kvz_encode_inter_prediction_unit(state, cabac, cur_pu, pu_x, pu_y, pu_w, pu_h, depth, NULL);
|
||||
kvz_encode_inter_prediction_unit(state, cabac, cur_pu, pu_x, pu_y, pu_w, pu_h, depth, NULL, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -883,7 +893,7 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
}
|
||||
}
|
||||
} else if (cur_cu->type == CU_INTRA) {
|
||||
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth);
|
||||
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth, NULL);
|
||||
}
|
||||
|
||||
#if ENABLE_PCM
|
||||
|
@ -942,11 +952,135 @@ end:
|
|||
|
||||
}
|
||||
|
||||
void kvz_mock_encode_coding_unit(
|
||||
encoder_state_t* const state,
|
||||
cabac_data_t* cabac,
|
||||
int x, int y, int depth,
|
||||
lcu_t* lcu) {
|
||||
double bits = 0;
|
||||
const encoder_control_t* const ctrl = state->encoder_control;
|
||||
|
||||
int x_local = SUB_SCU(x);
|
||||
int y_local = SUB_SCU(y);
|
||||
|
||||
const int cu_width = LCU_WIDTH >> depth;
|
||||
const int half_cu = cu_width >> 1;
|
||||
|
||||
const cu_info_t* cur_cu = LCU_GET_CU_AT_PX(lcu, x_local, y_local);
|
||||
const cu_info_t* left_cu = NULL, *above_cu = NULL;
|
||||
if (x) {
|
||||
left_cu = LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local);
|
||||
}
|
||||
if (y) {
|
||||
above_cu = LCU_GET_CU_AT_PX(lcu, x_local, y_local-1);
|
||||
}
|
||||
uint8_t split_model = 0;
|
||||
|
||||
// Absolute coordinates
|
||||
uint16_t abs_x = x + state->tile->offset_x;
|
||||
uint16_t abs_y = y + state->tile->offset_y;
|
||||
|
||||
// Check for slice border
|
||||
bool border_x = ctrl->in.width < abs_x + cu_width;
|
||||
bool border_y = ctrl->in.height < abs_y + cu_width;
|
||||
bool border = border_x || border_y; /*!< are we in any border CU */
|
||||
|
||||
if (depth <= state->frame->max_qp_delta_depth) {
|
||||
state->must_code_qp_delta = true;
|
||||
}
|
||||
|
||||
// When not in MAX_DEPTH, insert split flag and split the blocks if needed
|
||||
if (depth != MAX_DEPTH) {
|
||||
// Implicit split flag when on border
|
||||
if (!border) {
|
||||
// Get left and top block split_flags and if they are present and true, increase model number
|
||||
if (left_cu && GET_SPLITDATA(left_cu, depth) == 1) {
|
||||
split_model++;
|
||||
}
|
||||
|
||||
if (above_cu && GET_SPLITDATA(above_cu, depth) == 1) {
|
||||
split_model++;
|
||||
}
|
||||
|
||||
// This mocks encoding the current CU so it should be never split
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.split_flag_model[split_model]), 0, bits, "SplitFlag");
|
||||
}
|
||||
}
|
||||
|
||||
// Encode skip flag
|
||||
if (state->frame->slicetype != KVZ_SLICE_I) {
|
||||
int8_t ctx_skip = 0;
|
||||
|
||||
if (left_cu && left_cu->skipped) {
|
||||
ctx_skip++;
|
||||
}
|
||||
if (above_cu && above_cu->skipped) {
|
||||
ctx_skip++;
|
||||
}
|
||||
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_skip_flag_model[ctx_skip]), cur_cu->skipped, bits, "SkipFlag");
|
||||
|
||||
if (cur_cu->skipped) {
|
||||
int16_t num_cand = state->encoder_control->cfg.max_merge;
|
||||
if (num_cand > 1) {
|
||||
for (int ui = 0; ui < num_cand - 1; ui++) {
|
||||
int32_t symbol = (ui != cur_cu->merge_idx);
|
||||
if (ui == 0) {
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_merge_idx_ext_model), symbol, bits, "MergeIndex");
|
||||
}
|
||||
else {
|
||||
CABAC_BIN_EP(cabac, symbol, "MergeIndex");
|
||||
if(cabac->only_count) bits += 1;
|
||||
}
|
||||
if (symbol == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Prediction mode
|
||||
if (state->frame->slicetype != KVZ_SLICE_I) {
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_pred_mode_model), (cur_cu->type == CU_INTRA), bits, "PredMode");
|
||||
}
|
||||
|
||||
// part_mode
|
||||
bits += encode_part_mode(state, cabac, cur_cu, depth);
|
||||
|
||||
if (cur_cu->type == CU_INTER) {
|
||||
const int num_pu = kvz_part_mode_num_parts[cur_cu->part_size];
|
||||
|
||||
for (int i = 0; i < num_pu; ++i) {
|
||||
const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, i);
|
||||
const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, i);
|
||||
const int pu_w = PU_GET_W(cur_cu->part_size, cu_width, i);
|
||||
const int pu_h = PU_GET_H(cur_cu->part_size, cu_width, i);
|
||||
const cu_info_t* cur_pu = LCU_GET_CU_AT_PX(lcu, SUB_SCU(pu_x), SUB_SCU(pu_y));
|
||||
|
||||
kvz_encode_inter_prediction_unit(state, cabac, cur_pu, pu_x, pu_y, pu_w, pu_h, depth, lcu, &bits);
|
||||
}
|
||||
|
||||
{
|
||||
int cbf = cbf_is_set_any(cur_cu->cbf, depth);
|
||||
// Only need to signal coded block flag if not skipped or merged
|
||||
// skip = no coded residual, merge = coded residual
|
||||
if (cur_cu->part_size != SIZE_2Nx2N || !cur_cu->merged) {
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_qt_root_cbf_model), cbf, bits, "rqt_root_cbf");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (cur_cu->type == CU_INTRA) {
|
||||
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void kvz_encode_mvd(encoder_state_t * const state,
|
||||
cabac_data_t *cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver)
|
||||
int32_t mvd_ver, double* bits_out)
|
||||
{
|
||||
const int8_t hor_abs_gr0 = mvd_hor != 0;
|
||||
const int8_t ver_abs_gr0 = mvd_ver != 0;
|
||||
|
@ -954,20 +1088,21 @@ void kvz_encode_mvd(encoder_state_t * const state,
|
|||
const uint32_t mvd_ver_abs = abs(mvd_ver);
|
||||
|
||||
cabac->cur_ctx = &cabac->ctx.cu_mvd_model[0];
|
||||
CABAC_BIN(cabac, (mvd_hor != 0), "abs_mvd_greater0_flag_hor");
|
||||
CABAC_BIN(cabac, (mvd_ver != 0), "abs_mvd_greater0_flag_ver");
|
||||
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.cu_mvd_model[0], (mvd_hor != 0), *bits_out, "abs_mvd_greater0_flag_hor");
|
||||
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.cu_mvd_model[0], (mvd_ver != 0), *bits_out, "abs_mvd_greater0_flag_ver");
|
||||
|
||||
cabac->cur_ctx = &cabac->ctx.cu_mvd_model[1];
|
||||
if (hor_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_hor_abs>1), "abs_mvd_greater1_flag_hor");
|
||||
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.cu_mvd_model[1], (mvd_hor_abs>1), *bits_out,"abs_mvd_greater1_flag_hor");
|
||||
}
|
||||
if (ver_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_ver_abs>1), "abs_mvd_greater1_flag_ver");
|
||||
CABAC_FBITS_UPDATE(cabac, &cabac->ctx.cu_mvd_model[1], (mvd_ver_abs>1), *bits_out, "abs_mvd_greater1_flag_ver");
|
||||
}
|
||||
|
||||
if (hor_abs_gr0) {
|
||||
if (mvd_hor_abs > 1) {
|
||||
kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_hor_abs - 2, 1);
|
||||
uint32_t bits = kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_hor_abs - 2, 1);
|
||||
if(cabac->only_count) *bits_out += bits;
|
||||
}
|
||||
uint32_t mvd_hor_sign = (mvd_hor > 0) ? 0 : 1;
|
||||
if (!state->cabac.only_count &&
|
||||
|
@ -976,10 +1111,12 @@ void kvz_encode_mvd(encoder_state_t * const state,
|
|||
mvd_hor_sign = mvd_hor_sign ^ kvz_crypto_get_key(state->crypto_hdl, 1);
|
||||
}
|
||||
CABAC_BIN_EP(cabac, mvd_hor_sign, "mvd_sign_flag_hor");
|
||||
if (cabac->only_count) *bits_out += 1;
|
||||
}
|
||||
if (ver_abs_gr0) {
|
||||
if (mvd_ver_abs > 1) {
|
||||
kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_ver_abs - 2, 1);
|
||||
uint32_t bits = kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_ver_abs - 2, 1);
|
||||
if (cabac->only_count) *bits_out += bits;
|
||||
}
|
||||
uint32_t mvd_ver_sign = mvd_ver > 0 ? 0 : 1;
|
||||
if (!state->cabac.only_count &&
|
||||
|
@ -988,5 +1125,6 @@ void kvz_encode_mvd(encoder_state_t * const state,
|
|||
mvd_ver_sign = mvd_ver_sign^kvz_crypto_get_key(state->crypto_hdl, 1);
|
||||
}
|
||||
CABAC_BIN_EP(cabac, mvd_ver_sign, "mvd_sign_flag_ver");
|
||||
if (cabac->only_count) *bits_out += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,13 +49,22 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
void kvz_encode_mvd(encoder_state_t * const state,
|
||||
cabac_data_t *cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver);
|
||||
int32_t mvd_ver,
|
||||
double* bits_out);
|
||||
|
||||
void kvz_mock_encode_coding_unit(
|
||||
encoder_state_t* const state,
|
||||
cabac_data_t* cabac,
|
||||
int x, int y, int depth,
|
||||
lcu_t* lcu);
|
||||
|
||||
void kvz_encode_inter_prediction_unit(encoder_state_t* const state,
|
||||
cabac_data_t* const cabac,
|
||||
const cu_info_t* const cur_cu,
|
||||
int x, int y, int width, int height,
|
||||
int depth, lcu_t* lcu);
|
||||
cabac_data_t* const cabac,
|
||||
const cu_info_t* const cur_cu,
|
||||
int x, int y, int width, int height,
|
||||
int depth,
|
||||
lcu_t* lcu,
|
||||
double* bits_out);
|
||||
|
||||
void kvz_encode_last_significant_xy(cabac_data_t * const cabac,
|
||||
uint8_t lastpos_x, uint8_t lastpos_y,
|
||||
|
|
20
src/rdo.c
20
src/rdo.c
|
@ -1010,22 +1010,18 @@ void kvz_rdoq(encoder_state_t * const state, coeff_t *coef, coeff_t *dest_coeff,
|
|||
/**
|
||||
* Calculate cost of actual motion vectors using CABAC coding
|
||||
*/
|
||||
uint32_t kvz_get_mvd_coding_cost_cabac(const encoder_state_t *state,
|
||||
const cabac_data_t* cabac,
|
||||
const int32_t mvd_hor,
|
||||
const int32_t mvd_ver)
|
||||
double kvz_get_mvd_coding_cost_cabac(const encoder_state_t* state,
|
||||
const cabac_data_t* cabac,
|
||||
const int32_t mvd_hor,
|
||||
const int32_t mvd_ver)
|
||||
{
|
||||
cabac_data_t cabac_copy = *cabac;
|
||||
cabac_copy.only_count = 1;
|
||||
|
||||
double bits = 0;
|
||||
// It is safe to drop const here because cabac->only_count is set.
|
||||
kvz_encode_mvd((encoder_state_t*) state, &cabac_copy, mvd_hor, mvd_ver);
|
||||
kvz_encode_mvd((encoder_state_t*) state, &cabac_copy, mvd_hor, mvd_ver, &bits);
|
||||
|
||||
uint32_t bitcost =
|
||||
((23 - cabac_copy.bits_left) + (cabac_copy.num_buffered_bytes << 3)) -
|
||||
((23 - cabac->bits_left) + (cabac->num_buffered_bytes << 3));
|
||||
|
||||
return bitcost;
|
||||
return bits;
|
||||
}
|
||||
|
||||
/** MVD cost calculation with CABAC
|
||||
|
@ -1160,7 +1156,7 @@ double kvz_calc_mvd_cost_cabac(const encoder_state_t * state,
|
|||
// ToDo: Bidir vector support
|
||||
if (!(state->frame->ref_list == REF_PIC_LIST_1 && /*cur_cu->inter.mv_dir == 3*/ 0)) {
|
||||
// It is safe to drop const here because cabac->only_count is set.
|
||||
kvz_encode_mvd((encoder_state_t*) state, cabac, mvd.x, mvd.y);
|
||||
kvz_encode_mvd((encoder_state_t*) state, cabac, mvd.x, mvd.y, NULL);
|
||||
}
|
||||
|
||||
// Signal which candidate MV to use
|
||||
|
|
|
@ -71,10 +71,10 @@ uint32_t kvz_get_coded_level(encoder_state_t * state, double* coded_cost, double
|
|||
|
||||
kvz_mvd_cost_func kvz_calc_mvd_cost_cabac;
|
||||
|
||||
uint32_t kvz_get_mvd_coding_cost_cabac(const encoder_state_t *state,
|
||||
const cabac_data_t* cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver);
|
||||
double kvz_get_mvd_coding_cost_cabac(const encoder_state_t* state,
|
||||
const cabac_data_t* cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver);
|
||||
|
||||
// Number of fixed point fractional bits used in the fractional bit table.
|
||||
#define CTX_FRAC_BITS 15
|
||||
|
|
56
src/search.c
56
src/search.c
|
@ -740,29 +740,61 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
|
|||
|
||||
if (cur_cu->type == CU_INTRA || cur_cu->type == CU_INTER) {
|
||||
double bits = 0;
|
||||
state->search_cabac.update = 1;
|
||||
cabac_data_t* cabac = &state->search_cabac;
|
||||
cabac->update = 1;
|
||||
|
||||
if(depth < MAX_DEPTH) {
|
||||
uint8_t split_model = get_ctx_cu_split_model(lcu, x, y, depth);
|
||||
cabac_ctx_t* ctx = &(state->search_cabac.ctx.split_flag_model[split_model]);
|
||||
CABAC_FBITS_UPDATE(&state->search_cabac, ctx, 0, bits, "no_split_search");
|
||||
cabac_ctx_t* ctx = &(cabac->ctx.split_flag_model[split_model]);
|
||||
CABAC_FBITS_UPDATE(cabac, ctx, 0, bits, "no_split_search");
|
||||
}
|
||||
else if(depth == MAX_DEPTH && cur_cu->type == CU_INTRA) {
|
||||
// Add cost of intra part_size.
|
||||
cabac_ctx_t* ctx = &(state->search_cabac.ctx.part_size_model[0]);
|
||||
CABAC_FBITS_UPDATE(&state->search_cabac, ctx, 0, bits, "no_split_search");
|
||||
cabac_ctx_t* ctx = &(cabac->ctx.part_size_model[0]);
|
||||
CABAC_FBITS_UPDATE(cabac, ctx, 0, bits, "no_split_search");
|
||||
}
|
||||
|
||||
double mode_bits;
|
||||
double mode_bits = 0;
|
||||
if (state->frame->slicetype != KVZ_SLICE_I) {
|
||||
int ctx_skip = 0;
|
||||
if (x > 0) {
|
||||
ctx_skip += LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local)->skipped;
|
||||
}
|
||||
if (y > 0) {
|
||||
ctx_skip += LCU_GET_CU_AT_PX(lcu, x_local, y_local - 1)->skipped;
|
||||
}
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_skip_flag_model[ctx_skip]), cur_cu->skipped, mode_bits, "skip_flag");
|
||||
if (cur_cu->skipped) {
|
||||
int16_t num_cand = state->encoder_control->cfg.max_merge;
|
||||
if (num_cand > 1) {
|
||||
for (int ui = 0; ui < num_cand - 1; ui++) {
|
||||
int32_t symbol = (ui != cur_cu->merge_idx);
|
||||
if (ui == 0) {
|
||||
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.cu_merge_idx_ext_model), symbol, mode_bits, "MergeIndex");
|
||||
}
|
||||
else {
|
||||
CABAC_BIN_EP(cabac, symbol, "MergeIndex");
|
||||
mode_bits += 1;
|
||||
}
|
||||
if (symbol == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (cur_cu->type == CU_INTRA) {
|
||||
if(state->frame->slicetype != KVZ_SLICE_I) {
|
||||
cabac_ctx_t* ctx = &(state->search_cabac.ctx.cu_pred_mode_model);
|
||||
CABAC_FBITS_UPDATE(&state->search_cabac, &state->search_cabac.ctx.cu_pred_mode_model, 1, bits, "pred_mode_flag");
|
||||
cabac_ctx_t* ctx = &(cabac->ctx.cu_pred_mode_model);
|
||||
CABAC_FBITS_UPDATE(cabac, ctx, 1, mode_bits, "pred_mode_flag");
|
||||
}
|
||||
mode_bits = calc_mode_bits(state, lcu, cur_cu, x, y);
|
||||
mode_bits += calc_mode_bits(state, lcu, cur_cu, x, y);
|
||||
}
|
||||
else {
|
||||
mode_bits = inter_bitcost;
|
||||
else if (!cur_cu->skipped) {
|
||||
cabac_ctx_t* ctx = &(cabac->ctx.cu_pred_mode_model);
|
||||
CABAC_FBITS_UPDATE(cabac, ctx, 0, mode_bits, "pred_mode_flag");
|
||||
mode_bits += inter_bitcost;
|
||||
}
|
||||
bits += mode_bits;
|
||||
cost = mode_bits * state->lambda;
|
||||
|
@ -795,7 +827,7 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
|
|||
cur_cu->cbf = 0;
|
||||
lcu_fill_cbf(lcu, x_local, y_local, cu_width, cur_cu);
|
||||
}
|
||||
state->search_cabac.update = 0;
|
||||
cabac->update = 0;
|
||||
}
|
||||
|
||||
bool can_split_cu =
|
||||
|
|
|
@ -323,19 +323,19 @@ static void select_starting_point(inter_search_info_t *info,
|
|||
}
|
||||
|
||||
|
||||
static uint32_t get_mvd_coding_cost(const encoder_state_t *state,
|
||||
static double get_mvd_coding_cost(const encoder_state_t *state,
|
||||
const cabac_data_t* cabac,
|
||||
const int32_t mvd_hor,
|
||||
const int32_t mvd_ver)
|
||||
{
|
||||
unsigned bitcost = 0;
|
||||
double bitcost = 0;
|
||||
const vector2d_t abs_mvd = { abs(mvd_hor), abs(mvd_ver) };
|
||||
|
||||
bitcost += get_ep_ex_golomb_bitcost(abs_mvd.x) << CTX_FRAC_BITS;
|
||||
bitcost += get_ep_ex_golomb_bitcost(abs_mvd.y) << CTX_FRAC_BITS;
|
||||
|
||||
// Round and shift back to integer bits.
|
||||
return (bitcost + CTX_FRAC_HALF_BIT) >> CTX_FRAC_BITS;
|
||||
return bitcost / (1 << CTX_FRAC_BITS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,7 +353,7 @@ static int select_mv_cand(const encoder_state_t *state,
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t (*mvd_coding_cost)(const encoder_state_t * const state,
|
||||
double (*mvd_coding_cost)(const encoder_state_t * const state,
|
||||
const cabac_data_t*,
|
||||
int32_t, int32_t);
|
||||
if (state->encoder_control->cfg.mv_rdo) {
|
||||
|
|
Loading…
Reference in a new issue