mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Refactor inter MVD cost functions
Moves duplicate code for writing the MVD of a single motion vector from kvz_get_mvd_coding_cost_cabac and encoder_inter_prediction_unit to a new function.
This commit is contained in:
parent
c1cca1ad7f
commit
405b8c1069
|
@ -559,122 +559,76 @@ static void encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
uint32_t ref_list_idx;
|
||||
|
||||
// Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
|
||||
if (state->frame->slicetype == KVZ_SLICE_B)
|
||||
{
|
||||
if (state->frame->slicetype == KVZ_SLICE_B) {
|
||||
// Code Inter Dir
|
||||
uint8_t inter_dir = cur_cu->inter.mv_dir-1;
|
||||
uint8_t ctx = depth;
|
||||
|
||||
|
||||
if (cur_cu->part_size == SIZE_2Nx2N || (LCU_WIDTH >> depth) != 8)
|
||||
{
|
||||
cabac->cur_ctx = &(cabac->ctx.inter_dir[ctx]);
|
||||
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");
|
||||
}
|
||||
if (inter_dir < 2)
|
||||
{
|
||||
if (inter_dir < 2) {
|
||||
cabac->cur_ctx = &(cabac->ctx.inter_dir[4]);
|
||||
CABAC_BIN(cabac, inter_dir, "inter_pred_idc");
|
||||
}
|
||||
}
|
||||
|
||||
for (ref_list_idx = 0; ref_list_idx < 2; ref_list_idx++) {
|
||||
if (cur_cu->inter.mv_dir & (1 << ref_list_idx)) {
|
||||
|
||||
// size of the current reference index list (L0/L1)
|
||||
uint8_t ref_LX_size = state->frame->ref_LX_size[ref_list_idx];
|
||||
|
||||
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");
|
||||
|
||||
if (ref_frame > 0) {
|
||||
int32_t i;
|
||||
int32_t ref_num = ref_LX_size - 2;
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_ref_pic_model[1]);
|
||||
ref_frame--;
|
||||
|
||||
for (i = 0; i < ref_num; ++i) {
|
||||
const uint32_t symbol = (i == ref_frame) ? 0 : 1;
|
||||
|
||||
if (i == 0) {
|
||||
CABAC_BIN(cabac, symbol, "ref_idx_lX");
|
||||
} else {
|
||||
CABAC_BIN_EP(cabac, symbol, "ref_idx_lX");
|
||||
}
|
||||
if (symbol == 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(/*pcCU->getSlice()->getMvdL1ZeroFlag() &&*/ state->frame->ref_list == REF_PIC_LIST_1 && cur_cu->inter.mv_dir == 3)) {
|
||||
|
||||
int16_t mv_cand[2][2];
|
||||
kvz_inter_get_mv_cand_cua(
|
||||
state,
|
||||
x, y, width, height,
|
||||
mv_cand, cur_cu, ref_list_idx);
|
||||
|
||||
uint8_t cu_mv_cand = CU_GET_MV_CAND(cur_cu, ref_list_idx);
|
||||
|
||||
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];
|
||||
const int8_t hor_abs_gr0 = mvd_hor != 0;
|
||||
const int8_t ver_abs_gr0 = mvd_ver != 0;
|
||||
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
||||
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->cur_ctx = &(cabac->ctx.cu_mvd_model[1]);
|
||||
|
||||
if (hor_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_hor_abs>1), "abs_mvd_greater1_flag_hor");
|
||||
}
|
||||
|
||||
if (ver_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_ver_abs>1), "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 mvd_hor_sign = (mvd_hor>0)?0:1;
|
||||
if(!state->cabac.only_count)
|
||||
if (state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
|
||||
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 (ver_abs_gr0) {
|
||||
if (mvd_ver_abs > 1) {
|
||||
kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_ver_abs-2, 1);
|
||||
}
|
||||
uint32_t mvd_ver_sign = (mvd_ver>0)?0:1;
|
||||
if(!state->cabac.only_count)
|
||||
if (state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
// Signal which candidate MV to use
|
||||
kvz_cabac_write_unary_max_symbol(cabac,
|
||||
cabac->ctx.mvp_idx_model,
|
||||
CU_GET_MV_CAND(cur_cu, ref_list_idx),
|
||||
1,
|
||||
AMVP_MAX_NUM_CANDS - 1);
|
||||
for (uint32_t ref_list_idx = 0; ref_list_idx < 2; ref_list_idx++) {
|
||||
if (!(cur_cu->inter.mv_dir & (1 << ref_list_idx))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// size of the current reference index list (L0/L1)
|
||||
uint8_t ref_LX_size = state->frame->ref_LX_size[ref_list_idx];
|
||||
|
||||
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");
|
||||
|
||||
if (ref_frame > 0) {
|
||||
ref_frame--;
|
||||
|
||||
int32_t ref_num = ref_LX_size - 2;
|
||||
|
||||
for (int32_t i = 0; i < ref_num; ++i) {
|
||||
const uint32_t symbol = (i == ref_frame) ? 0 : 1;
|
||||
|
||||
if (i == 0) {
|
||||
cabac->cur_ctx = &cabac->ctx.cu_ref_pic_model[1];
|
||||
CABAC_BIN(cabac, symbol, "ref_idx_lX");
|
||||
} else {
|
||||
CABAC_BIN_EP(cabac, symbol, "ref_idx_lX");
|
||||
}
|
||||
if (symbol == 0) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state->frame->ref_list != REF_PIC_LIST_1 || cur_cu->inter.mv_dir != 3) {
|
||||
|
||||
int16_t mv_cand[2][2];
|
||||
kvz_inter_get_mv_cand_cua(
|
||||
state,
|
||||
x, y, width, height,
|
||||
mv_cand, cur_cu, ref_list_idx);
|
||||
|
||||
uint8_t cu_mv_cand = CU_GET_MV_CAND(cur_cu, ref_list_idx);
|
||||
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);
|
||||
}
|
||||
|
||||
// Signal which candidate MV to use
|
||||
kvz_cabac_write_unary_max_symbol(cabac,
|
||||
cabac->ctx.mvp_idx_model,
|
||||
CU_GET_MV_CAND(cur_cu, ref_list_idx),
|
||||
1,
|
||||
AMVP_MAX_NUM_CANDS - 1);
|
||||
|
||||
} // for ref_list
|
||||
} // if !merge
|
||||
}
|
||||
|
@ -1186,3 +1140,52 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void kvz_encode_mvd(encoder_state_t * const state,
|
||||
cabac_data_t *cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver)
|
||||
{
|
||||
const int8_t hor_abs_gr0 = mvd_hor != 0;
|
||||
const int8_t ver_abs_gr0 = mvd_ver != 0;
|
||||
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
||||
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->cur_ctx = &cabac->ctx.cu_mvd_model[1];
|
||||
if (hor_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_hor_abs>1), "abs_mvd_greater1_flag_hor");
|
||||
}
|
||||
if (ver_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_ver_abs>1), "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 mvd_hor_sign = (mvd_hor > 0) ? 0 : 1;
|
||||
if (!state->cabac.only_count &&
|
||||
state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
|
||||
{
|
||||
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 (ver_abs_gr0) {
|
||||
if (mvd_ver_abs > 1) {
|
||||
kvz_cabac_write_ep_ex_golomb(state, cabac, mvd_ver_abs - 2, 1);
|
||||
}
|
||||
uint32_t mvd_ver_sign = mvd_ver > 0 ? 0 : 1;
|
||||
if (!state->cabac.only_count &&
|
||||
state->encoder_control->cfg.crypto_features & KVZ_CRYPTO_MV_SIGNS)
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,4 +42,9 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
|
|||
int8_t scan_mode,
|
||||
int8_t tr_skip);
|
||||
|
||||
void kvz_encode_mvd(encoder_state_t * const state,
|
||||
cabac_data_t *cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver);
|
||||
|
||||
#endif // ENCODE_CODING_TREE_H_
|
||||
|
|
96
src/rdo.c
96
src/rdo.c
|
@ -856,46 +856,19 @@ 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* real_cabac,
|
||||
int32_t mvd_hor,
|
||||
int32_t mvd_ver)
|
||||
const cabac_data_t* cabac,
|
||||
const int32_t mvd_hor,
|
||||
const int32_t mvd_ver)
|
||||
{
|
||||
uint32_t bitcost = 0;
|
||||
const int8_t hor_abs_gr0 = mvd_hor != 0;
|
||||
const int8_t ver_abs_gr0 = mvd_ver != 0;
|
||||
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
||||
const uint32_t mvd_ver_abs = abs(mvd_ver);
|
||||
cabac_data_t cabac_copy = *cabac;
|
||||
cabac_copy.only_count = 1;
|
||||
|
||||
cabac_data_t cabac_copy;
|
||||
memcpy(&cabac_copy, real_cabac, sizeof(cabac_data_t));
|
||||
cabac_data_t *cabac = &cabac_copy;
|
||||
cabac->only_count = 1;
|
||||
// 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);
|
||||
|
||||
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->cur_ctx = &(cabac->ctx.cu_mvd_model[1]);
|
||||
if (hor_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_hor_abs > 1), "abs_mvd_greater1_flag_hor");
|
||||
}
|
||||
if (ver_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_ver_abs > 1), "abs_mvd_greater1_flag_ver");
|
||||
}
|
||||
if (hor_abs_gr0) {
|
||||
if (mvd_hor_abs > 1) {
|
||||
// It is safe to drop const here because cabac->only_count is set.
|
||||
kvz_cabac_write_ep_ex_golomb((encoder_state_t*)state, cabac, mvd_hor_abs - 2, 1);
|
||||
}
|
||||
CABAC_BIN_EP(cabac, (mvd_hor > 0) ? 0 : 1, "mvd_sign_flag_hor");
|
||||
}
|
||||
if (ver_abs_gr0) {
|
||||
if (mvd_ver_abs > 1) {
|
||||
// It is safe to drop const here because cabac->only_count is set.
|
||||
kvz_cabac_write_ep_ex_golomb((encoder_state_t*)state, cabac, mvd_ver_abs - 2, 1);
|
||||
}
|
||||
CABAC_BIN_EP(cabac, (mvd_ver > 0) ? 0 : 1, "mvd_sign_flag_ver");
|
||||
}
|
||||
bitcost = ((23 - cabac->bits_left) + (cabac->num_buffered_bytes << 3)) - ((23 - real_cabac->bits_left) + (real_cabac->num_buffered_bytes << 3));
|
||||
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;
|
||||
}
|
||||
|
@ -1031,51 +1004,18 @@ uint32_t 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)) {
|
||||
const int32_t mvd_hor = mvd.x;
|
||||
const int32_t mvd_ver = mvd.y;
|
||||
const int8_t hor_abs_gr0 = mvd_hor != 0;
|
||||
const int8_t ver_abs_gr0 = mvd_ver != 0;
|
||||
const uint32_t mvd_hor_abs = abs(mvd_hor);
|
||||
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->cur_ctx = &(cabac->ctx.cu_mvd_model[1]);
|
||||
|
||||
if (hor_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_hor_abs > 1), "abs_mvd_greater1_flag_hor");
|
||||
}
|
||||
|
||||
if (ver_abs_gr0) {
|
||||
CABAC_BIN(cabac, (mvd_ver_abs > 1), "abs_mvd_greater1_flag_ver");
|
||||
}
|
||||
|
||||
if (hor_abs_gr0) {
|
||||
if (mvd_hor_abs > 1) {
|
||||
// It is safe to drop const because cabac->only_count is set.
|
||||
kvz_cabac_write_ep_ex_golomb((encoder_state_t*)state, cabac, mvd_hor_abs - 2, 1);
|
||||
}
|
||||
|
||||
CABAC_BIN_EP(cabac, (mvd_hor > 0) ? 0 : 1, "mvd_sign_flag_hor");
|
||||
}
|
||||
|
||||
if (ver_abs_gr0) {
|
||||
if (mvd_ver_abs > 1) {
|
||||
// It is safe to drop const because cabac->only_count is set.
|
||||
kvz_cabac_write_ep_ex_golomb((encoder_state_t*)state, cabac, mvd_ver_abs - 2, 1);
|
||||
}
|
||||
|
||||
CABAC_BIN_EP(cabac, (mvd_ver > 0) ? 0 : 1, "mvd_sign_flag_ver");
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Signal which candidate MV to use
|
||||
kvz_cabac_write_unary_max_symbol(cabac, cabac->ctx.mvp_idx_model, cur_mv_cand, 1,
|
||||
AMVP_MAX_NUM_CANDS - 1);
|
||||
kvz_cabac_write_unary_max_symbol(
|
||||
cabac,
|
||||
cabac->ctx.mvp_idx_model,
|
||||
cur_mv_cand,
|
||||
1,
|
||||
AMVP_MAX_NUM_CANDS - 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue