Add couple of missing bits to the calculation and get intra neighbours from lcu rather than cu_array

This commit is contained in:
Joose Sainio 2021-12-16 11:26:45 +02:00
parent aea1133e6a
commit 64b2806cc8
6 changed files with 47 additions and 86 deletions

View file

@ -491,26 +491,28 @@ void kvz_cabac_write_coeff_remain_encry(struct encoder_state_t * const state, ca
/**
* \brief
*/
void kvz_cabac_write_unary_max_symbol(cabac_data_t * const data, cabac_ctx_t * const ctx, uint32_t symbol, const int32_t offset, const uint32_t max_symbol)
void kvz_cabac_write_unary_max_symbol(cabac_data_t * const data,
cabac_ctx_t * const ctx,
uint32_t symbol,
const int32_t offset,
const uint32_t max_symbol,
double* bits_out)
{
int8_t code_last = max_symbol > symbol;
assert(symbol <= max_symbol);
if (!max_symbol) return;
data->cur_ctx = &ctx[0];
CABAC_BIN(data, symbol, "ums");
CABAC_FBITS_UPDATE(data, &ctx[0], symbol, *bits_out, "ums");
if (!symbol) return;
while (--symbol) {
data->cur_ctx = &ctx[offset];
CABAC_BIN(data, 1, "ums");
CABAC_FBITS_UPDATE(data, &ctx[offset], 1, *bits_out, "ums");
}
if (code_last) {
data->cur_ctx = &ctx[offset];
CABAC_BIN(data, 0, "ums");
CABAC_FBITS_UPDATE(data, &ctx[offset], 0,*bits_out, "ums");
}
}

View file

@ -125,8 +125,8 @@ void kvz_cabac_write_coeff_remain_encry(struct encoder_state_t * const state, ca
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,
uint32_t max_symbol);
uint32_t symbol, int32_t offset,
uint32_t max_symbol, double* bits_out);
void kvz_cabac_write_unary_max_symbol_ep(cabac_data_t *data, unsigned int symbol, unsigned int max_symbol);
extern const float kvz_f_entropy_bits[128];

View file

@ -290,7 +290,7 @@ static void encode_transform_coeff(encoder_state_t * const state,
// cu_qp_delta_abs prefix
cabac->cur_ctx = &cabac->ctx.cu_qp_delta_abs[0];
kvz_cabac_write_unary_max_symbol(cabac, cabac->ctx.cu_qp_delta_abs, MIN(qp_delta_abs, 5), 1, 5);
kvz_cabac_write_unary_max_symbol(cabac, cabac->ctx.cu_qp_delta_abs, MIN(qp_delta_abs, 5), 1, 5, NULL);
if (qp_delta_abs >= 5) {
// cu_qp_delta_abs suffix
@ -412,7 +412,7 @@ void kvz_encode_inter_prediction_unit(encoder_state_t * const state,
cabac->ctx.mvp_idx_model,
CU_GET_MV_CAND(cur_cu, ref_list_idx),
1,
AMVP_MAX_NUM_CANDS - 1);
AMVP_MAX_NUM_CANDS - 1, bits_out);
} // for ref_list
} // if !merge
@ -467,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, double* bits_out)
int x, int y, int depth, lcu_t* lcu, double* bits_out)
{
const videoframe_t * const frame = state->tile->frame;
uint8_t intra_pred_mode_actual[4];
@ -506,19 +506,19 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
for (int j = 0; j < num_pred_units; ++j) {
const int pu_x = PU_GET_X(cur_cu->part_size, cu_width, x, j);
const int pu_y = PU_GET_Y(cur_cu->part_size, cu_width, y, j);
const cu_info_t *cur_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
const cu_info_t *cur_pu = lcu ? LCU_GET_CU_AT_PX(lcu, SUB_SCU(pu_x), SUB_SCU(pu_y)) : kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y);
const cu_info_t *left_pu = NULL;
const cu_info_t *above_pu = NULL;
if (pu_x > 0) {
assert(pu_x >> 2 > 0);
left_pu = kvz_cu_array_at_const(frame->cu_array, pu_x - 1, pu_y);
left_pu = lcu ? LCU_GET_CU_AT_PX(lcu, SUB_SCU(pu_x -1), SUB_SCU(pu_y)) : kvz_cu_array_at_const(frame->cu_array, pu_x - 1, pu_y);
}
// Don't take the above PU across the LCU boundary.
if (pu_y % LCU_WIDTH > 0 && pu_y > 0) {
assert(pu_y >> 2 > 0);
above_pu = kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y - 1);
above_pu = lcu ? LCU_GET_CU_AT_PX(lcu, SUB_SCU(pu_x), SUB_SCU(pu_y - 1)) : kvz_cu_array_at_const(frame->cu_array, pu_x, pu_y - 1);
}
if (do_crypto) {
@ -893,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, NULL);
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth, NULL, NULL);
}
#if ENABLE_PCM
@ -952,11 +952,11 @@ end:
}
void kvz_mock_encode_coding_unit(
double kvz_mock_encode_coding_unit(
encoder_state_t* const state,
cabac_data_t* cabac,
int x, int y, int depth,
lcu_t* lcu) {
lcu_t* lcu, cu_info_t* cur_cu) {
double bits = 0;
const encoder_control_t* const ctrl = state->encoder_control;
@ -964,9 +964,7 @@ void kvz_mock_encode_coding_unit(
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);
@ -1037,7 +1035,7 @@ void kvz_mock_encode_coding_unit(
}
}
}
return;
return bits;
}
}
// Prediction mode
@ -1072,8 +1070,9 @@ void kvz_mock_encode_coding_unit(
}
}
else if (cur_cu->type == CU_INTRA) {
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth, NULL);
encode_intra_coding_unit(state, cabac, cur_cu, x, y, depth, lcu, &bits);
}
return bits;
}

View file

@ -52,11 +52,11 @@ void kvz_encode_mvd(encoder_state_t * const state,
int32_t mvd_ver,
double* bits_out);
void kvz_mock_encode_coding_unit(
double kvz_mock_encode_coding_unit(
encoder_state_t* const state,
cabac_data_t* cabac,
int x, int y, int depth,
lcu_t* lcu);
lcu_t* lcu, cu_info_t* cur_cu);
void kvz_encode_inter_prediction_unit(encoder_state_t* const state,
cabac_data_t* const cabac,

View file

@ -1081,8 +1081,8 @@ double kvz_calc_mvd_cost_cabac(const encoder_state_t * state,
x - mv_cand[1][0],
y - mv_cand[1][1],
};
uint32_t cand1_cost = kvz_get_mvd_coding_cost_cabac(state, cabac, mvd1.x, mvd1.y);
uint32_t cand2_cost = kvz_get_mvd_coding_cost_cabac(state, cabac, mvd2.x, mvd2.y);
double cand1_cost = kvz_get_mvd_coding_cost_cabac(state, cabac, mvd1.x, mvd1.y);
double cand2_cost = kvz_get_mvd_coding_cost_cabac(state, cabac, mvd2.x, mvd2.y);
// Select candidate 1 if it has lower cost
if (cand2_cost < cand1_cost) {
@ -1161,11 +1161,12 @@ double kvz_calc_mvd_cost_cabac(const encoder_state_t * state,
// 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);
cabac,
cabac->ctx.mvp_idx_model,
cur_mv_cand,
1,
AMVP_MAX_NUM_CANDS - 1,
NULL);
}
}
}

View file

@ -37,6 +37,7 @@
#include "cabac.h"
#include "encoder.h"
#include "encode_coding_tree.h"
#include "imagelist.h"
#include "inter.h"
#include "intra.h"
@ -743,61 +744,19 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
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 = &(cabac->ctx.split_flag_model[split_model]);
CABAC_FBITS_UPDATE(cabac, ctx, 0, bits, "no_split_search");
if(cur_cu->type != CU_INTRA || cur_cu->part_size == SIZE_2Nx2N) {
bits += kvz_mock_encode_coding_unit(
state,
cabac,
x, y, depth,
lcu,
cur_cu);
}
else if(depth == MAX_DEPTH && cur_cu->type == CU_INTRA) {
// Add cost of intra part_size.
cabac_ctx_t* ctx = &(cabac->ctx.part_size_model[0]);
CABAC_FBITS_UPDATE(cabac, ctx, 0, bits, "no_split_search");
else {
// Intra 4×4 PUs
}
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 = &(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);
}
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;
cost = bits * state->lambda;
cost += kvz_cu_rd_cost_luma(state, x_local, y_local, depth, cur_cu, lcu, &bits);
if (state->encoder_control->chroma_format != KVZ_CSP_400) {