diff --git a/src/cabac.h b/src/cabac.h index 6f7aaa78..be249ba2 100644 --- a/src/cabac.h +++ b/src/cabac.h @@ -122,6 +122,7 @@ typedef struct cabac_ctx_t transform_skip_gt2[5]; cabac_ctx_t cclm_flag; cabac_ctx_t cclm_model; + cabac_ctx_t ibc_flag[3]; } ctx; } cabac_data_t; diff --git a/src/context.c b/src/context.c index 8e042cc2..83bd5502 100644 --- a/src/context.c +++ b/src/context.c @@ -423,6 +423,13 @@ static const uint8_t INIT_CCLM_MODEL[4] = { 9, }; +static const uint8_t INIT_IBC_FLAG[4][3] = { + { 0, 43, 45, }, + { 0, 57, 44, }, + { 17, 42, 36, }, + { 1, 5, 8, }, +}; + /* static const uint16_t g_inistateToCount[128] = { 614, 647, 681, 718, 756, 797, 839, 884, 932, 982, 1034, 1089, 1148, 1209, 1274, 1342, @@ -514,6 +521,7 @@ void uvg_init_contexts(encoder_state_t *state, int8_t QP, int8_t slice) uvg_ctx_init(&cabac->ctx.lfnst_idx_model[i], QP, INIT_LFNST_IDX[slice][i], INIT_LFNST_IDX[3][i]); uvg_ctx_init(&cabac->ctx.transform_skip_sig_coeff_group[i], QP, INIT_TRANSFORM_SKIP_SIG_COEFF_GROUP[slice][i], INIT_TRANSFORM_SKIP_SIG_COEFF_GROUP[3][i]); uvg_ctx_init(&cabac->ctx.transform_skip_sig[i], QP, INIT_TRANSFORM_SKIP_SIG[slice][i], INIT_TRANSFORM_SKIP_SIG[3][i]); + uvg_ctx_init(&cabac->ctx.ibc_flag[i], QP, INIT_IBC_FLAG[slice][i], INIT_IBC_FLAG[3][i]); } for (i = 0; i < 4; i++) { diff --git a/src/encode_coding_tree.c b/src/encode_coding_tree.c index 0552e211..cb27099b 100644 --- a/src/encode_coding_tree.c +++ b/src/encode_coding_tree.c @@ -1555,7 +1555,7 @@ void uvg_encode_coding_tree( } // Encode skip flag - if (state->frame->slicetype != UVG_SLICE_I && cu_width != 4) { + if ((state->frame->slicetype != UVG_SLICE_I || state->encoder_control->cfg.ibc) && cu_width != 4) { int8_t ctx_skip = 0; @@ -1570,6 +1570,15 @@ void uvg_encode_coding_tree( CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag"); if (cur_cu->skipped) { + + if (state->encoder_control->cfg.ibc) { // ToDo: Only for luma channel + // ToDo: Disable for blocks over 64x64 pixels + int8_t ctx_ibc = 0; + if (left_cu && left_cu->type == CU_IBC) ctx_ibc++; + if (above_cu && above_cu->type == CU_IBC) ctx_ibc++; + cabac->cur_ctx = &(cabac->ctx.ibc_flag[ctx_ibc]); + CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag"); + } DBG_PRINT_MV(state, x, y, (uint32_t)cu_width, (uint32_t)cu_width, cur_cu); uvg_hmvp_add_mv(state, x, y, (uint32_t)cu_width, (uint32_t)cu_width, cur_cu); int16_t num_cand = state->encoder_control->cfg.max_merge; @@ -1597,6 +1606,15 @@ void uvg_encode_coding_tree( } // Prediction mode + if (state->frame->slicetype == UVG_SLICE_I && state->encoder_control->cfg.ibc) { // ToDo: Only for luma channel + // ToDo: Disable for blocks over 64x64 pixels + int8_t ctx_ibc = 0; + if (left_cu && left_cu->type == CU_IBC) ctx_ibc++; + if (above_cu && above_cu->type == CU_IBC) ctx_ibc++; + cabac->cur_ctx = &(cabac->ctx.ibc_flag[ctx_ibc]); + CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag"); + } + if (state->frame->slicetype != UVG_SLICE_I && cu_width != 4) { int8_t ctx_predmode = 0; @@ -1607,6 +1625,15 @@ void uvg_encode_coding_tree( cabac->cur_ctx = &(cabac->ctx.cu_pred_mode_model[ctx_predmode]); CABAC_BIN(cabac, (cur_cu->type == CU_INTRA), "PredMode"); + + // We need IBC flag if the mode is signalled as Inter + if (state->encoder_control->cfg.ibc && cur_cu->type != CU_INTRA) { + int8_t ctx_ibc = 0; + if (left_cu && left_cu->type == CU_IBC) ctx_ibc++; + if (above_cu && above_cu->type == CU_IBC) ctx_ibc++; + cabac->cur_ctx = &(cabac->ctx.ibc_flag[ctx_ibc]); + CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag"); + } } // part_mode