[mtt] remove all rest usages of deriving width and height from depth

This commit is contained in:
Joose Sainio 2022-09-07 16:11:36 +03:00 committed by Marko Viitanen
parent 26dcadc149
commit dcf879e5ed
13 changed files with 257 additions and 247 deletions

View file

@ -306,6 +306,8 @@ void uvg_cu_loc_ctor(cu_loc_t* loc, int x, int y, int width, int height)
loc->x = x; loc->x = x;
loc->y = y; loc->y = y;
loc->local_x = x % LCU_WIDTH;
loc->local_y = y % LCU_WIDTH;
loc->width = width; loc->width = width;
loc->height = height; loc->height = height;
// TODO: when MTT is implemented, chroma dimensions can be minimum 2. // TODO: when MTT is implemented, chroma dimensions can be minimum 2.

View file

@ -119,7 +119,7 @@ typedef struct
{ {
uint8_t type : 3; //!< \brief block type, one of cu_type_t values uint8_t type : 3; //!< \brief block type, one of cu_type_t values
uint8_t depth : 3; //!< \brief depth / size of this block uint8_t depth : 3; //!< \brief depth / size of this block
uint8_t tr_depth : 3; //!< \brief transform depth uint8_t tr_depth ; //!< \brief transform depth
uint8_t skipped : 1; //!< \brief flag to indicate this block is skipped uint8_t skipped : 1; //!< \brief flag to indicate this block is skipped
uint8_t merged : 1; //!< \brief flag to indicate this block is merged uint8_t merged : 1; //!< \brief flag to indicate this block is merged
uint8_t merge_idx : 3; //!< \brief merge index uint8_t merge_idx : 3; //!< \brief merge index
@ -129,6 +129,8 @@ typedef struct
uint16_t cbf; uint16_t cbf;
uint32_t split_tree : 3 * 9;
/** /**
* \brief QP used for the CU. * \brief QP used for the CU.
* *
@ -170,6 +172,8 @@ typedef struct
typedef struct { typedef struct {
int16_t x; int16_t x;
int16_t y; int16_t y;
uint8_t local_x;
uint8_t local_y;
int8_t width; int8_t width;
int8_t height; int8_t height;
int8_t chroma_width; int8_t chroma_width;

View file

@ -660,7 +660,7 @@ static void encode_transform_coeff(
bool last_split, bool last_split,
bool can_skip_last_cbf, bool can_skip_last_cbf,
int *luma_cbf_ctx, // Always true except when writing sub partition coeffs (ISP) int *luma_cbf_ctx, // Always true except when writing sub partition coeffs (ISP)
cu_loc_t *original_loc) // Original dimensions before ISP split const cu_loc_t * const original_loc) // Original dimensions before ISP split
{ {
cabac_data_t * const cabac = &state->cabac; cabac_data_t * const cabac = &state->cabac;
int x = cu_loc->x; int x = cu_loc->x;
@ -829,7 +829,6 @@ int uvg_encode_inter_prediction_unit(
encoder_state_t * const state, encoder_state_t * const state,
cabac_data_t * const cabac, cabac_data_t * const cabac,
const cu_info_t * const cur_cu, const cu_info_t * const cur_cu,
int depth,
lcu_t* lcu, lcu_t* lcu,
double* bits_out, double* bits_out,
const cu_loc_t* const cu_loc) const cu_loc_t* const cu_loc)
@ -867,7 +866,7 @@ int uvg_encode_inter_prediction_unit(
// Code Inter Dir // Code Inter Dir
uint8_t inter_dir = cur_cu->inter.mv_dir; uint8_t inter_dir = cur_cu->inter.mv_dir;
if ((LCU_WIDTH >> depth) != 4) { // ToDo: limit on 4x8/8x4 if (cu_loc->width + cu_loc->height > 12) { // ToDo: limit on 4x8/8x4
uint32_t inter_dir_ctx = (7 - ((uvg_math_floor_log2(cu_loc->width) + uvg_math_floor_log2(cu_loc->height) + 1) >> 1)); uint32_t inter_dir_ctx = (7 - ((uvg_math_floor_log2(cu_loc->width) + uvg_math_floor_log2(cu_loc->height) + 1) >> 1));
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.inter_dir[inter_dir_ctx]), (inter_dir == 3), bits, "inter_pred_idc"); CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.inter_dir[inter_dir_ctx]), (inter_dir == 3), bits, "inter_pred_idc");
@ -1038,10 +1037,13 @@ static void encode_chroma_intra_cu(
else if (cabac->only_count && bits_out)*bits_out += bits; else if (cabac->only_count && bits_out)*bits_out += bits;
} }
void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state, void uvg_encode_intra_luma_coding_unit(
cabac_data_t * const cabac, const encoder_state_t * const state,
const cu_info_t * const cur_cu, cabac_data_t * const cabac,
int x, int y, int depth, const lcu_t* lcu, double* bits_out) const cu_info_t * const cur_cu,
const cu_loc_t* const cu_loc,
const lcu_t* lcu,
double* bits_out)
{ {
const videoframe_t * const frame = state->tile->frame; const videoframe_t * const frame = state->tile->frame;
uint8_t intra_pred_mode_actual; uint8_t intra_pred_mode_actual;
@ -1053,6 +1055,9 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
uint32_t flag; uint32_t flag;
double bits = 0; double bits = 0;
const int x = cu_loc->x;
const int y = cu_loc->y;
/* /*
if ((cur_cu->type == CU_INTRA && (LCU_WIDTH >> cur_cu->depth <= 32))) { if ((cur_cu->type == CU_INTRA && (LCU_WIDTH >> cur_cu->depth <= 32))) {
cabac->cur_ctx = &(cabac->ctx.bdpcm_mode[0]); cabac->cur_ctx = &(cabac->ctx.bdpcm_mode[0]);
@ -1076,8 +1081,8 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
} }
*/ */
uint32_t width = (LCU_WIDTH >> depth); uint32_t width = cu_loc->width;
uint32_t height = (LCU_WIDTH >> depth); // TODO: height for non-square blocks uint32_t height = cu_loc->height; // TODO: height for non-square blocks
// Code MIP related bits // Code MIP related bits
bool enable_mip = state->encoder_control->cfg.mip; bool enable_mip = state->encoder_control->cfg.mip;
@ -1102,9 +1107,7 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
} }
if (cur_cu->type == CU_INTRA && !cur_cu->bdpcmMode && enable_mip) { if (cur_cu->type == CU_INTRA && !cur_cu->bdpcmMode && enable_mip) {
const int cu_width = LCU_WIDTH >> depth; uint8_t ctx_id = uvg_get_mip_flag_context(cu_loc, lcu, lcu ? NULL : frame->cu_array);
const int cu_height = cu_width; // TODO: height for non-square blocks
uint8_t ctx_id = uvg_get_mip_flag_context(x, y, cu_width, cu_height, lcu, lcu ? NULL : frame->cu_array);
// Write MIP flag // Write MIP flag
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.mip_flag[ctx_id]), mip_flag, bits, "mip_flag"); CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.mip_flag[ctx_id]), mip_flag, bits, "mip_flag");
@ -1149,8 +1152,7 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.intra_subpart_model[1]), isp_mode - 1, bits, "intra_subpartitions_split_type"); // Vertical or horizontal split CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.intra_subpart_model[1]), isp_mode - 1, bits, "intra_subpartitions_split_type"); // Vertical or horizontal split
} }
} }
const int cu_width = LCU_WIDTH >> depth;
// PREDINFO CODING // PREDINFO CODING
// If intra prediction mode is found from the predictors, // If intra prediction mode is found from the predictors,
// it can be signaled with two EP's. Otherwise we can send // it can be signaled with two EP's. Otherwise we can send
@ -1165,7 +1167,7 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
if (x > 0) { if (x > 0) {
assert(x >> 2 > 0); assert(x >> 2 > 0);
const int x_scu = SUB_SCU(x) - 1; const int x_scu = SUB_SCU(x) - 1;
const int y_scu = SUB_SCU(y + cu_width - 1); const int y_scu = SUB_SCU(y + height - 1);
left_pu = lcu ? left_pu = lcu ?
LCU_GET_CU_AT_PX( LCU_GET_CU_AT_PX(
lcu, lcu,
@ -1174,7 +1176,7 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
uvg_cu_array_at_const( uvg_cu_array_at_const(
frame->cu_array, frame->cu_array,
x - 1, x - 1,
y + cu_width - 1); y + height - 1);
} }
// Don't take the above PU across the LCU boundary. // Don't take the above PU across the LCU boundary.
if (y % LCU_WIDTH > 0 && y > 0) { if (y % LCU_WIDTH > 0 && y > 0) {
@ -1182,11 +1184,11 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
above_pu = lcu ? above_pu = lcu ?
LCU_GET_CU_AT_PX( LCU_GET_CU_AT_PX(
lcu, lcu,
SUB_SCU(x + cu_width - 1), SUB_SCU(x + width - 1),
SUB_SCU(y) - 1) : SUB_SCU(y) - 1) :
uvg_cu_array_at_const( uvg_cu_array_at_const(
frame->cu_array, frame->cu_array,
x + cu_width - 1, x + width - 1,
y - 1); y - 1);
} }
@ -1405,28 +1407,25 @@ bool uvg_write_split_flag(
void uvg_encode_coding_tree( void uvg_encode_coding_tree(
encoder_state_t * const state, encoder_state_t * const state,
uint16_t x,
uint16_t y,
uint8_t depth,
lcu_coeff_t *coeff, lcu_coeff_t *coeff,
enum uvg_tree_type tree_type) enum uvg_tree_type tree_type,
const cu_loc_t* const cu_loc,
const split_tree_t split_tree)
{ {
cabac_data_t * const cabac = &state->cabac; cabac_data_t * const cabac = &state->cabac;
const encoder_control_t * const ctrl = state->encoder_control; const encoder_control_t * const ctrl = state->encoder_control;
const videoframe_t * const frame = state->tile->frame; const videoframe_t * const frame = state->tile->frame;
const cu_array_t* used_array = tree_type != UVG_CHROMA_T ? frame->cu_array : frame->chroma_cu_array; const cu_array_t* used_array = tree_type != UVG_CHROMA_T ? frame->cu_array : frame->chroma_cu_array;
const cu_info_t *cur_cu = uvg_cu_array_at_const(used_array, x, y); const cu_info_t *cur_cu = uvg_cu_array_at_const(used_array, cu_loc->x, cu_loc->y);
const int width = LCU_WIDTH >> depth; const int cu_width = tree_type != UVG_CHROMA_T ? cu_loc->width : cu_loc->chroma_width;
const int height = width; // TODO: height for non-square blocks const int cu_height = tree_type != UVG_CHROMA_T ? cu_loc->height : cu_loc->chroma_height;
cu_loc_t cu_loc;
uvg_cu_loc_ctor(&cu_loc, x, y, width, height);
const int cu_width = tree_type != UVG_CHROMA_T ? cu_loc.width : cu_loc.chroma_width;
const int cu_height = tree_type != UVG_CHROMA_T ? cu_loc.height : cu_loc.chroma_height;
const int half_cu = cu_width >> 1; const int half_cu = cu_width >> 1;
const int x = cu_loc->x;
const int y = cu_loc->y;
const int depth = split_tree.current_depth;
const cu_info_t *left_cu = NULL; const cu_info_t *left_cu = NULL;
if (x > 0) { if (x > 0) {
@ -1458,33 +1457,33 @@ void uvg_encode_coding_tree(
// When not in MAX_DEPTH, insert split flag and split the blocks if needed // When not in MAX_DEPTH, insert split flag and split the blocks if needed
if (depth != MAX_DEPTH && !(tree_type == UVG_CHROMA_T && depth == MAX_DEPTH -1)) { if (depth != MAX_DEPTH && !(tree_type == UVG_CHROMA_T && depth == MAX_DEPTH -1)) {
const int split_flag = uvg_write_split_flag(state, cabac, left_cu, above_cu, GET_SPLITDATA(cur_cu, depth), depth, cu_width, x, y, tree_type,NULL); const int split_flag = uvg_write_split_flag(state, cabac, left_cu, above_cu, (cur_cu->split_tree >> (split_tree.current_depth * 3)) & 7, depth, cu_width, x, y, tree_type,NULL);
if (split_flag || border) { if (split_flag || border) {
const int half_luma = cu_loc->width / 2;
split_tree_t new_split_tree = { cur_cu->split_tree, split_tree.current_depth + 1 };
cu_loc_t new_cu_loc;
uvg_cu_loc_ctor(&new_cu_loc, x, y, half_luma, half_luma);
// Split blocks and remember to change x and y block positions // Split blocks and remember to change x and y block positions
uvg_encode_coding_tree(state, x, y, depth + 1, coeff, tree_type); uvg_encode_coding_tree(state, coeff, tree_type, &new_cu_loc, new_split_tree);
if (!border_x || border_split_x) { if (!border_x || border_split_x) {
uvg_encode_coding_tree(state, x + half_cu, y, depth + 1, coeff, tree_type); uvg_cu_loc_ctor(&new_cu_loc, x + half_cu, y, half_luma, half_luma);
uvg_encode_coding_tree(state, coeff, tree_type, &new_cu_loc, new_split_tree);
} }
if (!border_y || border_split_y) { if (!border_y || border_split_y) {
uvg_encode_coding_tree(state, x, y + half_cu, depth + 1, coeff, tree_type); uvg_cu_loc_ctor(&new_cu_loc, x, y + half_cu, half_luma, half_luma);
uvg_encode_coding_tree(state, coeff, tree_type, &new_cu_loc, new_split_tree);
} }
if (!border || (border_split_x && border_split_y)) { if (!border || (border_split_x && border_split_y)) {
uvg_encode_coding_tree(state, x + half_cu, y + half_cu, depth + 1, coeff, tree_type); uvg_cu_loc_ctor(&new_cu_loc, x + half_cu, y + half_cu, half_luma, half_luma);
uvg_encode_coding_tree(state, coeff, tree_type, &new_cu_loc, new_split_tree);
} }
return; return;
} }
} }
//ToDo: check if we can actually split
//ToDo: Implement MT split
if (depth < MAX_PU_DEPTH)
{
// cabac->cur_ctx = &(cabac->ctx.trans_subdiv_model[5 - ((uvg_g_convert_to_bit[LCU_WIDTH] + 2) - depth)]);
// CABAC_BIN(cabac, 0, "split_transform_flag");
}
DBG_YUVIEW_VALUE(state->frame->poc, DBG_YUVIEW_CU_TYPE, abs_x, abs_y, cu_width, cu_width, cur_cu->type-1); DBG_YUVIEW_VALUE(state->frame->poc, DBG_YUVIEW_CU_TYPE, abs_x, abs_y, cu_width, cu_width, cur_cu->type-1);
if (ctrl->cfg.lossless) { if (ctrl->cfg.lossless) {
@ -1519,8 +1518,8 @@ void uvg_encode_coding_tree(
cabac->cur_ctx = &(cabac->ctx.ibc_flag[ctx_ibc]); cabac->cur_ctx = &(cabac->ctx.ibc_flag[ctx_ibc]);
CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag"); 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); DBG_PRINT_MV(state, x, y, (uint32_t)cu_width, (uint32_t)cu_height, cur_cu);
uvg_hmvp_add_mv(state, x, y, (uint32_t)cu_width, (uint32_t)cu_width, cur_cu); uvg_hmvp_add_mv(state, x, y, cu_width, cu_height, cur_cu);
int16_t num_cand = state->encoder_control->cfg.max_merge; int16_t num_cand = state->encoder_control->cfg.max_merge;
if (num_cand > 1) { if (num_cand > 1) {
for (int ui = 0; ui < num_cand - 1; ui++) { for (int ui = 0; ui < num_cand - 1; ui++) {
@ -1555,7 +1554,7 @@ void uvg_encode_coding_tree(
CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag"); CABAC_BIN(cabac, (cur_cu->type == CU_IBC), "IBCFlag");
} }
if (state->frame->slicetype != UVG_SLICE_I && cu_width != 4) { if (state->frame->slicetype != UVG_SLICE_I && cu_width != 4 && cu_height != 4) {
int8_t ctx_predmode = 0; int8_t ctx_predmode = 0;
@ -1629,11 +1628,11 @@ void uvg_encode_coding_tree(
bool non_zero_mvd = false; bool non_zero_mvd = false;
// TODO: height for non-square blocks // TODO: height for non-square blocks
const cu_info_t *cur_pu = uvg_cu_array_at_const(used_array, cu_loc.x, cu_loc.y); const cu_info_t *cur_pu = uvg_cu_array_at_const(used_array, cu_loc->x, cu_loc->y);
non_zero_mvd |= uvg_encode_inter_prediction_unit(state, cabac, cur_pu, depth, NULL, NULL, &cu_loc); non_zero_mvd |= uvg_encode_inter_prediction_unit(state, cabac, cur_pu, NULL, NULL, cu_loc);
DBG_PRINT_MV(state, pu_x, pu_y, pu_w, pu_h, cur_pu); DBG_PRINT_MV(state, x, y, cu_width, cu_height, cur_pu);
uvg_hmvp_add_mv(state, x, y, width, height, cur_pu); uvg_hmvp_add_mv(state, x, y, cu_width, cu_height, cur_pu);
// imv mode, select between fullpel, half-pel and quarter-pel resolutions // imv mode, select between fullpel, half-pel and quarter-pel resolutions
@ -1662,7 +1661,7 @@ void uvg_encode_coding_tree(
// Code (possible) coeffs to bitstream // Code (possible) coeffs to bitstream
if (cbf) { if (cbf) {
int luma_cbf_ctx = 0; int luma_cbf_ctx = 0;
encode_transform_coeff(state, &cu_loc, depth, 0, 0, 0, 0, coeff, tree_type, true, false, &luma_cbf_ctx, &cu_loc); encode_transform_coeff(state, &cu_loc, depth, 0, 0, 0, 0, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
} }
encode_mts_idx(state, cabac, cur_cu); encode_mts_idx(state, cabac, cur_cu);
@ -1670,7 +1669,7 @@ void uvg_encode_coding_tree(
} }
} else if (cur_cu->type == CU_INTRA) { } else if (cur_cu->type == CU_INTRA) {
if(tree_type != UVG_CHROMA_T) { if(tree_type != UVG_CHROMA_T) {
uvg_encode_intra_luma_coding_unit(state, cabac, cur_cu, x, y, depth, NULL, NULL); uvg_encode_intra_luma_coding_unit(state, cabac, cur_cu, cu_loc, NULL, NULL);
} }
// Code chroma prediction mode. // Code chroma prediction mode.
@ -1694,7 +1693,7 @@ void uvg_encode_coding_tree(
// Check if last split to write chroma // Check if last split to write chroma
bool last_split = (i + 1) == split_limit; bool last_split = (i + 1) == split_limit;
encode_transform_coeff(state, &split_loc, depth, 0, 0, 0, 0, coeff, tree_type, last_split, can_skip_last_cbf, &luma_cbf_ctx, &cu_loc); encode_transform_coeff(state, &split_loc, depth, 0, 0, 0, 0, coeff, tree_type, last_split, can_skip_last_cbf, &luma_cbf_ctx, cu_loc);
can_skip_last_cbf &= luma_cbf_ctx == 2; can_skip_last_cbf &= luma_cbf_ctx == 2;
} }
} }
@ -1714,7 +1713,7 @@ void uvg_encode_coding_tree(
tmp->violates_lfnst_constrained_luma = false; tmp->violates_lfnst_constrained_luma = false;
tmp->violates_lfnst_constrained_chroma = false; tmp->violates_lfnst_constrained_chroma = false;
tmp->lfnst_last_scan_pos = false; tmp->lfnst_last_scan_pos = false;
encode_transform_coeff(state, &cu_loc, depth, 0, 0, 0, 1, coeff, tree_type, true, false, &luma_cbf_ctx, &cu_loc); encode_transform_coeff(state, &cu_loc, depth, 0, 0, 0, 1, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
// Write LFNST only once for single tree structure // Write LFNST only once for single tree structure
encode_lfnst_idx(state, cabac, tmp, x, y, depth, cu_width, cu_height, tree_type, COLOR_UV); encode_lfnst_idx(state, cabac, tmp, x, y, depth, cu_width, cu_height, tree_type, COLOR_UV);
} }
@ -1843,7 +1842,7 @@ double uvg_mock_encode_coding_unit(
if (cur_cu->type == CU_INTER || cur_cu->type == CU_IBC) { if (cur_cu->type == CU_INTER || cur_cu->type == CU_IBC) {
const uint8_t imv_mode = UVG_IMV_OFF; const uint8_t imv_mode = UVG_IMV_OFF;
const int non_zero_mvd = uvg_encode_inter_prediction_unit(state, cabac, cur_cu, depth, lcu, &bits, cu_loc); const int non_zero_mvd = uvg_encode_inter_prediction_unit(state, cabac, cur_cu, lcu, &bits, cu_loc);
if (ctrl->cfg.amvr && non_zero_mvd) { if (ctrl->cfg.amvr && non_zero_mvd) {
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.imv_flag[0]), imv_mode, bits, "imv_flag"); CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.imv_flag[0]), imv_mode, bits, "imv_flag");
if (imv_mode > UVG_IMV_OFF) { if (imv_mode > UVG_IMV_OFF) {
@ -1856,7 +1855,7 @@ double uvg_mock_encode_coding_unit(
} }
else if (cur_cu->type == CU_INTRA) { else if (cur_cu->type == CU_INTRA) {
if(tree_type != UVG_CHROMA_T) { if(tree_type != UVG_CHROMA_T) {
uvg_encode_intra_luma_coding_unit(state, cabac, cur_cu, x, y, depth, lcu, &bits); uvg_encode_intra_luma_coding_unit(state, cabac, cur_cu, cu_loc, lcu, &bits);
} }
if((depth != 4 || (x % 8 != 0 && y % 8 != 0)) && state->encoder_control->chroma_format != UVG_CSP_400 && tree_type != UVG_LUMA_T) { if((depth != 4 || (x % 8 != 0 && y % 8 != 0)) && state->encoder_control->chroma_format != UVG_CSP_400 && tree_type != UVG_LUMA_T) {
encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm, &bits); encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm, &bits);

View file

@ -54,11 +54,10 @@ bool uvg_is_lfnst_allowed(
void uvg_encode_coding_tree( void uvg_encode_coding_tree(
encoder_state_t * const state, encoder_state_t * const state,
uint16_t x_ctb,
uint16_t y_ctb,
uint8_t depth,
lcu_coeff_t *coeff, lcu_coeff_t *coeff,
enum uvg_tree_type tree_type); enum uvg_tree_type tree_type,
const cu_loc_t* const cu_loc,
const split_tree_t split_tree);
void uvg_encode_ts_residual(encoder_state_t* const state, void uvg_encode_ts_residual(encoder_state_t* const state,
cabac_data_t* const cabac, cabac_data_t* const cabac,
@ -87,15 +86,17 @@ int uvg_encode_inter_prediction_unit(
encoder_state_t* const state, encoder_state_t* const state,
cabac_data_t* const cabac, cabac_data_t* const cabac,
const cu_info_t* const cur_cu, const cu_info_t* const cur_cu,
int depth,
lcu_t* lcu, lcu_t* lcu,
double* bits_out, double* bits_out,
const cu_loc_t* const cu_loc); const cu_loc_t* const cu_loc);
void uvg_encode_intra_luma_coding_unit(const encoder_state_t* const state, void uvg_encode_intra_luma_coding_unit(
const encoder_state_t* const state,
cabac_data_t* const cabac, cabac_data_t* const cabac,
const cu_info_t* const cur_cu, const cu_info_t* const cur_cu,
int x, int y, int depth, const lcu_t* lcu, double* bits_out); const cu_loc_t* const cu_loc,
const lcu_t* lcu,
double* bits_out);
bool uvg_write_split_flag( bool uvg_write_split_flag(

View file

@ -870,10 +870,15 @@ static void encoder_state_worker_encode_lcu_bitstream(void * opaque)
enum uvg_tree_type tree_type = state->frame->slicetype == UVG_SLICE_I && state->encoder_control->cfg.dual_tree ? UVG_LUMA_T : UVG_BOTH_T; enum uvg_tree_type tree_type = state->frame->slicetype == UVG_SLICE_I && state->encoder_control->cfg.dual_tree ? UVG_LUMA_T : UVG_BOTH_T;
//Encode coding tree //Encode coding tree
uvg_encode_coding_tree(state, lcu->position.x * LCU_WIDTH, lcu->position.y * LCU_WIDTH, 0, lcu->coeff, tree_type); cu_loc_t start;
uvg_cu_loc_ctor(&start, lcu->position.x * LCU_WIDTH, lcu->position.y * LCU_WIDTH, LCU_WIDTH, LCU_WIDTH);
split_tree_t split_tree = { 0, 0 };
uvg_encode_coding_tree(state, lcu->coeff, tree_type, &start, split_tree);
if(tree_type == UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400) { if(tree_type == UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400) {
uvg_encode_coding_tree(state, lcu->position.x * LCU_WIDTH_C, lcu->position.y * LCU_WIDTH_C, 0, lcu->coeff, UVG_CHROMA_T); uvg_cu_loc_ctor(&start, lcu->position.x * LCU_WIDTH_C, lcu->position.y * LCU_WIDTH_C, LCU_WIDTH, LCU_WIDTH);
uvg_encode_coding_tree(state, lcu->coeff, UVG_CHROMA_T, &start, split_tree);
} }
if (!state->cabac.only_count) { if (!state->cabac.only_count) {

View file

@ -585,12 +585,18 @@ static void predict_cclm(
} }
int uvg_get_mip_flag_context(int x, int y, int width, int height, const lcu_t* lcu, cu_array_t* const cu_a) { uint8_t uvg_get_mip_flag_context(
const cu_loc_t* const cu_loc,
const lcu_t* lcu,
cu_array_t* const cu_a) {
assert(!(lcu && cu_a)); assert(!(lcu && cu_a));
if (width > 2 * height || height > 2 * width) { if (cu_loc->width > 2 * cu_loc->height || cu_loc->height > 2 * cu_loc->width) {
return 3; return 3;
} }
const int x = cu_loc->x;
const int y = cu_loc->y;
int context = 0; int context = 0;
const cu_info_t* left = NULL; const cu_info_t* left = NULL;
const cu_info_t* top = NULL; const cu_info_t* top = NULL;
@ -1761,26 +1767,26 @@ static void intra_recon_tb_leaf(
*/ */
void uvg_intra_recon_cu( void uvg_intra_recon_cu(
encoder_state_t* const state, encoder_state_t* const state,
int x,
int y,
int depth,
intra_search_data_t* search_data, intra_search_data_t* search_data,
const cu_loc_t* cu_loc,
cu_info_t *cur_cu, cu_info_t *cur_cu,
lcu_t *lcu, lcu_t *lcu,
enum uvg_tree_type tree_type, enum uvg_tree_type tree_type,
bool recon_luma, bool recon_luma,
bool recon_chroma) bool recon_chroma)
{ {
const vector2d_t lcu_px = { SUB_SCU(x) >> (tree_type == UVG_CHROMA_T), SUB_SCU(y) >> (tree_type == UVG_CHROMA_T) }; const uint8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int8_t width = LCU_WIDTH >> depth; const vector2d_t lcu_px = { cu_loc->local_x >> (tree_type == UVG_CHROMA_T), cu_loc->local_y >> (tree_type == UVG_CHROMA_T) };
const int8_t height = width; // TODO: height for non-square blocks. const int8_t width = cu_loc->width;
const int8_t height = cu_loc->height; // TODO: height for non-square blocks.
if (cur_cu == NULL) { if (cur_cu == NULL) {
cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y); cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
} }
cu_loc_t chroma_cu_loc;
if(!recon_luma && recon_chroma) { if(!recon_luma && recon_chroma) {
x &= ~7; uvg_cu_loc_ctor(&chroma_cu_loc, cu_loc->x & ~7, cu_loc->y & ~7, width, height);
y &= ~7; cu_loc = &chroma_cu_loc;
} }
// Reset CBFs because CBFs might have been set // Reset CBFs because CBFs might have been set
@ -1793,22 +1799,25 @@ void uvg_intra_recon_cu(
cbf_clear(&cur_cu->cbf, depth, COLOR_V); cbf_clear(&cur_cu->cbf, depth, COLOR_V);
} }
if (depth == 0 || cur_cu->tr_depth > depth) { if (width > TR_MAX_WIDTH || height > TR_MAX_WIDTH) {
cu_loc_t split_cu_loc;
const int offset = width / 2; const int half_width = width / 2;
const int32_t x2 = x + offset; const int half_height = height / 2;
const int32_t y2 = y + offset; uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x, cu_loc->y, half_width, half_height);
uvg_intra_recon_cu(state, search_data, &split_cu_loc, NULL, lcu, tree_type, recon_luma, recon_chroma);
uvg_intra_recon_cu(state, x, y, depth + 1, search_data, NULL, lcu, tree_type, recon_luma, recon_chroma); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x + half_width, cu_loc->y, half_width, half_height);
uvg_intra_recon_cu(state, x2, y, depth + 1, search_data, NULL, lcu, tree_type, recon_luma, recon_chroma); uvg_intra_recon_cu(state, search_data, &split_cu_loc, NULL, lcu, tree_type, recon_luma, recon_chroma);
uvg_intra_recon_cu(state, x, y2, depth + 1, search_data, NULL, lcu, tree_type, recon_luma, recon_chroma); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x, cu_loc->y + half_height, half_width, half_height);
uvg_intra_recon_cu(state, x2, y2, depth + 1, search_data, NULL, lcu, tree_type, recon_luma, recon_chroma); uvg_intra_recon_cu(state, search_data, &split_cu_loc, NULL, lcu, tree_type, recon_luma, recon_chroma);
uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x + half_width, cu_loc->y + half_height, half_width, half_height);
uvg_intra_recon_cu(state, search_data, &split_cu_loc, NULL, lcu, tree_type, recon_luma, recon_chroma);
// Propagate coded block flags from child CUs to parent CU. // Propagate coded block flags from child CUs to parent CU.
uint16_t child_cbfs[3] = { uint16_t child_cbfs[3] = {
LCU_GET_CU_AT_PX(lcu, (lcu_px.x + offset) >> (tree_type == UVG_CHROMA_T), lcu_px.y >> (tree_type == UVG_CHROMA_T))->cbf, LCU_GET_CU_AT_PX(lcu, (lcu_px.x + half_width) >> (tree_type == UVG_CHROMA_T), lcu_px.y >> (tree_type == UVG_CHROMA_T))->cbf,
LCU_GET_CU_AT_PX(lcu, lcu_px.x >> (tree_type == UVG_CHROMA_T), (lcu_px.y + offset) >> (tree_type == UVG_CHROMA_T))->cbf, LCU_GET_CU_AT_PX(lcu, lcu_px.x >> (tree_type == UVG_CHROMA_T), (lcu_px.y + half_height) >> (tree_type == UVG_CHROMA_T))->cbf,
LCU_GET_CU_AT_PX(lcu, (lcu_px.x + offset) >> (tree_type == UVG_CHROMA_T), (lcu_px.y + offset) >> (tree_type == UVG_CHROMA_T))->cbf, LCU_GET_CU_AT_PX(lcu, (lcu_px.x + half_width) >> (tree_type == UVG_CHROMA_T), (lcu_px.y + half_height) >> (tree_type == UVG_CHROMA_T))->cbf,
}; };
if (recon_luma && depth <= MAX_DEPTH) { if (recon_luma && depth <= MAX_DEPTH) {
@ -1826,8 +1835,6 @@ void uvg_intra_recon_cu(
// Small blocks are split only twice. // Small blocks are split only twice.
int split_type = search_data->pred_cu.intra.isp_mode; int split_type = search_data->pred_cu.intra.isp_mode;
int split_limit = uvg_get_isp_split_num(width, height, split_type, true); int split_limit = uvg_get_isp_split_num(width, height, split_type, true);
cu_loc_t origin_cu;
uvg_cu_loc_ctor(&origin_cu, x, y, width, height);
for (int i = 0; i < split_limit; ++i) { for (int i = 0; i < split_limit; ++i) {
cu_loc_t tu_loc; cu_loc_t tu_loc;
@ -1845,24 +1852,21 @@ void uvg_intra_recon_cu(
} }
} }
const bool has_luma = recon_luma && search_data->pred_cu.intra.isp_mode == ISP_MODE_NO_ISP; const bool has_luma = recon_luma && search_data->pred_cu.intra.isp_mode == ISP_MODE_NO_ISP;
const bool has_chroma = recon_chroma && (x % 8 == 0 && y % 8 == 0); const bool has_chroma = recon_chroma && (cu_loc->x % 8 == 0 && cu_loc->y % 8 == 0);
cu_loc_t loc;
uvg_cu_loc_ctor(&loc, x, y, width, height);
// Process a leaf TU. // Process a leaf TU.
if (has_luma) { if (has_luma) {
intra_recon_tb_leaf(state, &loc, &loc, lcu, COLOR_Y, search_data, tree_type); intra_recon_tb_leaf(state, cu_loc, cu_loc, lcu, COLOR_Y, search_data, tree_type);
} }
if (has_chroma) { if (has_chroma) {
intra_recon_tb_leaf(state, &loc, &loc, lcu, COLOR_U, search_data, tree_type); intra_recon_tb_leaf(state, cu_loc, cu_loc, lcu, COLOR_U, search_data, tree_type);
intra_recon_tb_leaf(state, &loc, &loc, lcu, COLOR_V, search_data, tree_type); intra_recon_tb_leaf(state, cu_loc, cu_loc, lcu, COLOR_V, search_data, tree_type);
} }
// TODO: not necessary to call if only luma and ISP is on // TODO: not necessary to call if only luma and ISP is on
uvg_quantize_lcu_residual(state, has_luma, has_chroma && !(search_data->pred_cu.joint_cb_cr & 3), uvg_quantize_lcu_residual(state, has_luma, has_chroma && !(search_data->pred_cu.joint_cb_cr & 3),
search_data->pred_cu.joint_cb_cr & 3 && state->encoder_control->cfg.jccr && has_chroma, search_data->pred_cu.joint_cb_cr & 3 && state->encoder_control->cfg.jccr && has_chroma,
&loc, depth, cur_cu, lcu, cu_loc, depth, cur_cu, lcu,
false, tree_type); false, tree_type);
} }

View file

@ -142,10 +142,8 @@ void uvg_intra_predict(
void uvg_intra_recon_cu( void uvg_intra_recon_cu(
encoder_state_t* const state, encoder_state_t* const state,
int x,
int y,
int depth,
intra_search_data_t* search_data, intra_search_data_t* search_data,
const cu_loc_t* cu_loc,
cu_info_t *cur_cu, cu_info_t *cur_cu,
lcu_t *lcu, lcu_t *lcu,
enum uvg_tree_type tree_type, enum uvg_tree_type tree_type,
@ -161,7 +159,10 @@ const cu_info_t* uvg_get_co_located_luma_cu(
const cu_array_t* const cu_array, const cu_array_t* const cu_array,
enum uvg_tree_type tree_type); enum uvg_tree_type tree_type);
int uvg_get_mip_flag_context(int x, int y, int width, int height, const lcu_t* lcu, cu_array_t* const cu_a); uint8_t uvg_get_mip_flag_context(
const cu_loc_t* const cu_loc,
const lcu_t* lcu,
cu_array_t* const cu_a);
// ISP related defines // ISP related defines
#define NUM_ISP_MODES 3 #define NUM_ISP_MODES 3

View file

@ -761,16 +761,17 @@ static double cu_rd_cost_tr_split_accurate(
// Return estimate of bits used to code prediction mode of cur_cu. // Return estimate of bits used to code prediction mode of cur_cu.
static double calc_mode_bits(const encoder_state_t *state, static double calc_mode_bits(
const lcu_t *lcu, const encoder_state_t *state,
const cu_info_t * cur_cu, const lcu_t *lcu,
int x, int y, int depth) const cu_info_t * cur_cu,
const cu_loc_t* const cu_loc)
{ {
assert(cur_cu->type == CU_INTRA); assert(cur_cu->type == CU_INTRA);
double mode_bits = uvg_luma_mode_bits(state, cur_cu, x, y, depth, lcu); double mode_bits = uvg_luma_mode_bits(state, cur_cu, cu_loc, lcu);
if (((depth == 4 && x % 8 && y % 8) || (depth != 4)) && state->encoder_control->chroma_format != UVG_CSP_400) { if (((cu_loc->width == 4 && cu_loc->x % 8 && cu_loc->y % 8) || (cu_loc->width != 4)) && state->encoder_control->chroma_format != UVG_CSP_400) {
mode_bits += uvg_chroma_mode_bits(state, cur_cu->intra.mode_chroma, cur_cu->intra.mode); mode_bits += uvg_chroma_mode_bits(state, cur_cu->intra.mode_chroma, cur_cu->intra.mode);
} }
@ -945,6 +946,7 @@ static double search_cu(
cur_cu->lfnst_last_scan_pos = 0; cur_cu->lfnst_last_scan_pos = 0;
cur_cu->lfnst_idx = 0; cur_cu->lfnst_idx = 0;
cur_cu->joint_cb_cr = 0; cur_cu->joint_cb_cr = 0;
cur_cu->split_tree = split_tree.split_tree;
// If the CU is completely inside the frame at this depth, search for // If the CU is completely inside the frame at this depth, search for
// prediction modes at this depth. // prediction modes at this depth.
@ -1001,9 +1003,7 @@ static double search_cu(
intra_search.pred_cu = *cur_cu; intra_search.pred_cu = *cur_cu;
if(tree_type != UVG_CHROMA_T) { if(tree_type != UVG_CHROMA_T) {
intra_search.pred_cu.joint_cb_cr = 4; intra_search.pred_cu.joint_cb_cr = 4;
uvg_search_cu_intra(state, x, y, depth, &intra_search, uvg_search_cu_intra(state, &intra_search, lcu, tree_type, cu_loc);
lcu,
tree_type);
} }
#ifdef COMPLETE_PRED_MODE_BITS #ifdef COMPLETE_PRED_MODE_BITS
// Technically counting these bits would be correct, however counting // Technically counting these bits would be correct, however counting
@ -1017,10 +1017,11 @@ static double search_cu(
#endif #endif
if (state->encoder_control->cfg.cclm && tree_type != UVG_CHROMA_T && state->encoder_control->chroma_format != UVG_CSP_400) { if (state->encoder_control->cfg.cclm && tree_type != UVG_CHROMA_T && state->encoder_control->chroma_format != UVG_CSP_400) {
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x, y, &intra_search, cu_loc,
depth, &intra_search, &intra_search.pred_cu, lcu,
&intra_search.pred_cu, tree_type,
lcu, tree_type, true, false); true,
false);
downsample_cclm_rec( downsample_cclm_rec(
state, x, y, cu_width / 2, cu_width / 2, lcu->rec.y, lcu->left_ref.y[64] state, x, y, cu_width / 2, cu_width / 2, lcu->rec.y, lcu->left_ref.y[64]
@ -1058,14 +1059,13 @@ static double search_cu(
else { else {
intra_search.pred_cu.intra.mode_chroma = 0; intra_search.pred_cu.intra.mode_chroma = 0;
} }
uvg_intra_recon_cu(state,
if(tree_type != UVG_CHROMA_T && ctrl->cfg.rdo >= 2) { &intra_search, cu_loc,
uvg_intra_recon_cu(state, &intra_search.pred_cu, lcu,
x, y, tree_type,
depth, &intra_search, false,
&intra_search.pred_cu, true);
lcu, if(tree_type != UVG_CHROMA_T) {
tree_type, false, true);
intra_cost += uvg_cu_rd_cost_chroma(state, x_local, y_local, depth, &intra_search.pred_cu, lcu); intra_cost += uvg_cu_rd_cost_chroma(state, x_local, y_local, depth, &intra_search.pred_cu, lcu);
} }
else { else {
@ -1128,20 +1128,20 @@ static double search_cu(
} }
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu); lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x, y, &intra_search, cu_loc,
depth, &intra_search, NULL, lcu,
NULL, tree_type,
lcu, tree_type,recon_luma,recon_chroma); recon_luma, recon_chroma);
if(split_tree.current_depth == 4 && x % 8 && y % 8 && tree_type != UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400) { if(split_tree.current_depth == 4 && x % 8 && y % 8 && tree_type != UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400) {
intra_search.pred_cu.intra.mode_chroma = cur_cu->intra.mode_chroma; intra_search.pred_cu.intra.mode_chroma = cur_cu->intra.mode_chroma;
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x, y, &intra_search, cu_loc,
depth, &intra_search, NULL, lcu,
NULL, tree_type,
lcu, false,
tree_type,false,true); true);
} }
if (cur_cu->joint_cb_cr == 4) cur_cu->joint_cb_cr = 0; if (cur_cu->joint_cb_cr == 4) cur_cu->joint_cb_cr = 0;
@ -1334,7 +1334,7 @@ static double search_cu(
// It is ok to interrupt the search as soon as it is known that // It is ok to interrupt the search as soon as it is known that
// the split costs at least as much as not splitting. // the split costs at least as much as not splitting.
if (cur_cu->type == CU_NOTSET || cbf || state->encoder_control->cfg.cu_split_termination == UVG_CU_SPLIT_TERMINATION_OFF) { if (cur_cu->type == CU_NOTSET || cbf || state->encoder_control->cfg.cu_split_termination == UVG_CU_SPLIT_TERMINATION_OFF) {
const split_tree_t new_split = { split_tree.split_tree | QT_SPLIT << split_tree.current_depth, split_tree.current_depth + 1}; const split_tree_t new_split = { split_tree.split_tree | QT_SPLIT << (split_tree.current_depth * 3), split_tree.current_depth + 1};
cu_loc_t new_cu_loc; cu_loc_t new_cu_loc;
if (split_cost < cost) { if (split_cost < cost) {
uvg_cu_loc_ctor(&new_cu_loc, x, y, half_cu, half_cu); uvg_cu_loc_ctor(&new_cu_loc, x, y, half_cu, half_cu);
@ -1399,14 +1399,14 @@ static double search_cu(
proxy.pred_cu = *cur_cu; proxy.pred_cu = *cur_cu;
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x, y, &proxy, cu_loc,
depth,
&proxy,
NULL, NULL,
lcu, lcu,
tree_type, true, state->encoder_control->chroma_format == UVG_CSP_400); tree_type,
true,
state->encoder_control->chroma_format == UVG_CSP_400);
double mode_bits = calc_mode_bits(state, lcu, cur_cu, x, y, depth) + bits; double mode_bits = calc_mode_bits(state, lcu, cur_cu, cu_loc) + bits;
cost += mode_bits * state->lambda; cost += mode_bits * state->lambda;
cost += cu_rd_cost_tr_split_accurate(state, x_local, y_local, depth, cur_cu, lcu, tree_type, 0); cost += cu_rd_cost_tr_split_accurate(state, x_local, y_local, depth, cur_cu, lcu, tree_type, 0);

View file

@ -265,23 +265,21 @@ static void derive_mts_constraints(cu_info_t *const pred_cu,
*/ */
static double search_intra_trdepth( static double search_intra_trdepth(
encoder_state_t * const state, encoder_state_t * const state,
int x_px, const cu_loc_t* const cu_loc,
int y_px,
int depth,
int max_depth, int max_depth,
double cost_treshold, double cost_treshold,
intra_search_data_t *const search_data, intra_search_data_t *const search_data,
lcu_t *const lcu, lcu_t *const lcu,
enum uvg_tree_type tree_type) enum uvg_tree_type tree_type)
{ {
assert(depth >= 0 && depth <= MAX_PU_DEPTH);
const int width = LCU_WIDTH >> depth; const uint8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int height = width; // TODO: height for non-square blocks const uint8_t width = cu_loc->width;
const int width_c = width > TR_MIN_WIDTH ? width / 2 : width; const uint8_t height = cu_loc->height; // TODO: height for non-square blocks
const uint8_t width_c = cu_loc->chroma_width;
const int offset = width / 2; const uint8_t height_c = cu_loc->chroma_height;
const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) };
const vector2d_t lcu_px = { cu_loc->local_x, cu_loc->local_y };
const bool reconstruct_chroma = false;// (depth != 4 || (depth == 4 && (x_px & 4 && y_px & 4))) && state->encoder_control->chroma_format != UVG_CSP_400; const bool reconstruct_chroma = false;// (depth != 4 || (depth == 4 && (x_px & 4 && y_px & 4))) && state->encoder_control->chroma_format != UVG_CSP_400;
cu_info_t* pred_cu = &search_data->pred_cu; cu_info_t* pred_cu = &search_data->pred_cu;
@ -297,7 +295,7 @@ static double search_intra_trdepth(
double split_cost = INT32_MAX; double split_cost = INT32_MAX;
double nosplit_cost = INT32_MAX; double nosplit_cost = INT32_MAX;
if (depth > 0) { if (width <= TR_MAX_WIDTH && height <= TR_MAX_WIDTH) {
tr_cu->tr_depth = depth; tr_cu->tr_depth = depth;
pred_cu->tr_depth = depth; pred_cu->tr_depth = depth;
@ -389,15 +387,14 @@ static double search_intra_trdepth(
uvg_intra_recon_cu( uvg_intra_recon_cu(
state, state,
x_px,
y_px,
depth,
search_data, search_data,
cu_loc,
pred_cu, pred_cu,
lcu, lcu,
UVG_LUMA_T, UVG_LUMA_T,
true, true,
false); false
);
if (pred_cu->intra.isp_mode != ISP_MODE_NO_ISP && search_data->best_isp_cbfs == 0) continue; if (pred_cu->intra.isp_mode != ISP_MODE_NO_ISP && search_data->best_isp_cbfs == 0) continue;
if (trafo != 0 && !cbf_is_set(pred_cu->cbf, depth, COLOR_Y)) continue; if (trafo != 0 && !cbf_is_set(pred_cu->cbf, depth, COLOR_Y)) continue;
@ -418,7 +415,6 @@ static double search_intra_trdepth(
if (trafo != MTS_SKIP && end_idx != 0) { if (trafo != MTS_SKIP && end_idx != 0) {
uvg_derive_lfnst_constraints( uvg_derive_lfnst_constraints(
pred_cu, pred_cu,
depth,
constraints, constraints,
lcu->coeff.y, lcu->coeff.y,
width, width,
@ -496,15 +492,14 @@ static double search_intra_trdepth(
// TODO: Maybe check the jccr mode here also but holy shit is the interface of search_intra_rdo bad currently // TODO: Maybe check the jccr mode here also but holy shit is the interface of search_intra_rdo bad currently
uvg_intra_recon_cu( uvg_intra_recon_cu(
state, state,
x_px,
y_px,
depth,
search_data, search_data,
cu_loc,
pred_cu, pred_cu,
lcu, lcu,
UVG_BOTH_T, UVG_BOTH_T,
false, false,
true); true
);
best_rd_cost += uvg_cu_rd_cost_chroma( best_rd_cost += uvg_cu_rd_cost_chroma(
state, state,
lcu_px.x, lcu_px.x,
@ -521,11 +516,10 @@ static double search_intra_trdepth(
pred_cu->lfnst_last_scan_pos}; pred_cu->lfnst_last_scan_pos};
uvg_derive_lfnst_constraints( uvg_derive_lfnst_constraints(
pred_cu, pred_cu,
depth,
constraints, constraints,
lcu->coeff.u, lcu->coeff.u,
width_c, width_c,
width_c, height_c,
&lcu_px, &lcu_px,
COLOR_U); COLOR_U);
if (constraints[0] || !constraints[1]) { if (constraints[0] || !constraints[1]) {
@ -534,11 +528,10 @@ static double search_intra_trdepth(
} }
uvg_derive_lfnst_constraints( uvg_derive_lfnst_constraints(
pred_cu, pred_cu,
depth,
constraints, constraints,
lcu->coeff.u, lcu->coeff.u,
width_c, width_c,
width_c, height_c,
&lcu_px, &lcu_px,
COLOR_U); COLOR_U);
if (constraints[0] || !constraints[1]) { if (constraints[0] || !constraints[1]) {
@ -554,11 +547,11 @@ static double search_intra_trdepth(
pred_cu->intra.mode_chroma = chroma_mode; pred_cu->intra.mode_chroma = chroma_mode;
pred_cu->joint_cb_cr= 4; // TODO: Maybe check the jccr mode here also but holy shit is the interface of search_intra_rdo bad currently pred_cu->joint_cb_cr= 4; // TODO: Maybe check the jccr mode here also but holy shit is the interface of search_intra_rdo bad currently
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x_px, y_px, search_data, cu_loc,
depth, search_data, pred_cu, lcu,
pred_cu, UVG_BOTH_T,
lcu, false,
UVG_BOTH_T,false,true); true);
best_rd_cost += uvg_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, pred_cu, lcu); best_rd_cost += uvg_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, pred_cu, lcu);
pred_cu->intra.mode = luma_mode; pred_cu->intra.mode = luma_mode;
} }
@ -610,17 +603,25 @@ static double search_intra_trdepth(
// max_depth. // max_depth.
// - Min transform size hasn't been reached (MAX_PU_DEPTH). // - Min transform size hasn't been reached (MAX_PU_DEPTH).
if (depth < max_depth && depth < MAX_PU_DEPTH) { if (depth < max_depth && depth < MAX_PU_DEPTH) {
cu_loc_t split_cu_loc;
const int half_width = width / 2;
const int half_height = height / 2;
split_cost = 0; split_cost = 0;
split_cost += search_intra_trdepth(state, x_px, y_px, depth + 1, max_depth, nosplit_cost, search_data, lcu, tree_type); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x, cu_loc->y, half_width, half_height);
split_cost += search_intra_trdepth(state, &split_cu_loc, max_depth, nosplit_cost, search_data, lcu, tree_type);
if (split_cost < nosplit_cost) { if (split_cost < nosplit_cost) {
split_cost += search_intra_trdepth(state, x_px + offset, y_px, depth + 1, max_depth, nosplit_cost, search_data, lcu, tree_type); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x + half_width, cu_loc->y, half_width, half_height);
split_cost += search_intra_trdepth(state, &split_cu_loc, max_depth, nosplit_cost, search_data, lcu, tree_type);
} }
if (split_cost < nosplit_cost) { if (split_cost < nosplit_cost) {
split_cost += search_intra_trdepth(state, x_px, y_px + offset, depth + 1, max_depth, nosplit_cost, search_data, lcu, tree_type); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x, cu_loc->y + half_height, half_width, half_height);
split_cost += search_intra_trdepth(state, &split_cu_loc, max_depth, nosplit_cost, search_data, lcu, tree_type);
} }
if (split_cost < nosplit_cost) { if (split_cost < nosplit_cost) {
split_cost += search_intra_trdepth(state, x_px + offset, y_px + offset, depth + 1, max_depth, nosplit_cost, search_data, lcu, tree_type); uvg_cu_loc_ctor(&split_cu_loc, cu_loc->x + half_width, cu_loc->y + half_height, half_width, half_height);
split_cost += search_intra_trdepth(state, &split_cu_loc, max_depth, nosplit_cost, search_data, lcu, tree_type);
} }
double cbf_bits = 0.0; double cbf_bits = 0.0;
@ -654,7 +655,7 @@ static double search_intra_trdepth(
if (depth == 0 || split_cost < nosplit_cost) { if (depth == 0 || split_cost < nosplit_cost) {
return split_cost; return split_cost;
} else { } else {
uvg_lcu_fill_trdepth(lcu, x_px, y_px, depth, depth, tree_type); uvg_lcu_fill_trdepth(lcu, cu_loc->x, cu_loc->y, depth, depth, tree_type);
pred_cu->cbf = nosplit_cbf; pred_cu->cbf = nosplit_cbf;
@ -1372,17 +1373,16 @@ static void get_rough_cost_for_2n_modes(
*/ */
static int8_t search_intra_rdo( static int8_t search_intra_rdo(
encoder_state_t * const state, encoder_state_t * const state,
int x_px,
int y_px,
int depth,
int modes_to_check, int modes_to_check,
intra_search_data_t *search_data, intra_search_data_t *search_data,
lcu_t *lcu, lcu_t *lcu,
enum uvg_tree_type tree_type) enum uvg_tree_type tree_type,
const cu_loc_t* const cu_loc)
{ {
const int8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int tr_depth = CLIP(1, MAX_PU_DEPTH, depth + state->encoder_control->cfg.tr_depth_intra); const int tr_depth = CLIP(1, MAX_PU_DEPTH, depth + state->encoder_control->cfg.tr_depth_intra);
const int width = LCU_WIDTH >> depth; const int width = cu_loc->width;
const int height = width; // TODO: height for non-square blocks const int height = cu_loc->height; // TODO: height for non-square blocks
for (int mode = 0; mode < modes_to_check; mode++) { for (int mode = 0; mode < modes_to_check; mode++) {
bool can_do_isp_search = search_data[mode].pred_cu.intra.mip_flag ? false : true; // Cannot use ISP with MIP bool can_do_isp_search = search_data[mode].pred_cu.intra.mip_flag ? false : true; // Cannot use ISP with MIP
@ -1399,12 +1399,12 @@ static int8_t search_intra_rdo(
search_data[mode].pred_cu.intra.isp_mode = isp_mode; search_data[mode].pred_cu.intra.isp_mode = isp_mode;
double rdo_bitcost = uvg_luma_mode_bits(state, &search_data[mode].pred_cu, x_px, y_px, depth, lcu); double rdo_bitcost = uvg_luma_mode_bits(state, &search_data[mode].pred_cu, cu_loc, lcu);
search_data[mode].pred_cu.tr_idx = MTS_TR_NUM; search_data[mode].pred_cu.tr_idx = MTS_TR_NUM;
search_data[mode].bits = rdo_bitcost; search_data[mode].bits = rdo_bitcost;
search_data[mode].cost = rdo_bitcost * state->lambda; search_data[mode].cost = rdo_bitcost * state->lambda;
double mode_cost = search_intra_trdepth(state, x_px, y_px, depth, tr_depth, MAX_INT, &search_data[mode], lcu, tree_type); double mode_cost = search_intra_trdepth(state, cu_loc, tr_depth, MAX_INT, &search_data[mode], lcu, tree_type);
best_mts_mode_for_isp[isp_mode] = search_data[mode].pred_cu.tr_idx; best_mts_mode_for_isp[isp_mode] = search_data[mode].pred_cu.tr_idx;
best_lfnst_mode_for_isp[isp_mode] = search_data[mode].pred_cu.lfnst_idx; best_lfnst_mode_for_isp[isp_mode] = search_data[mode].pred_cu.lfnst_idx;
search_data[mode].cost += mode_cost; search_data[mode].cost += mode_cost;
@ -1440,7 +1440,9 @@ static int8_t search_intra_rdo(
} }
double uvg_luma_mode_bits(const encoder_state_t *state, const cu_info_t* const cur_cu, int x, int y, int8_t depth, const lcu_t* lcu) double uvg_luma_mode_bits(const encoder_state_t *state, const cu_info_t* const cur_cu, const cu_loc_t*
const cu_loc,
const lcu_t* lcu)
{ {
cabac_data_t* cabac = (cabac_data_t *)&state->search_cabac; cabac_data_t* cabac = (cabac_data_t *)&state->search_cabac;
double mode_bits = 0; double mode_bits = 0;
@ -1449,8 +1451,8 @@ double uvg_luma_mode_bits(const encoder_state_t *state, const cu_info_t* const c
uvg_encode_intra_luma_coding_unit( uvg_encode_intra_luma_coding_unit(
state, state,
&cabac_copy, cur_cu, &cabac_copy, cur_cu,
x, y, depth, lcu, &mode_bits cu_loc, lcu, &mode_bits
); );
return mode_bits; return mode_bits;
} }
@ -1651,11 +1653,11 @@ int8_t uvg_search_intra_chroma_rdo(
state->search_cabac.update = 1; state->search_cabac.update = 1;
chroma_data[mode_i].cost = mode_bits * state->lambda; chroma_data[mode_i].cost = mode_bits * state->lambda;
uvg_intra_recon_cu(state, uvg_intra_recon_cu(state,
x_px, y_px, &chroma_data[mode_i], &loc,
depth, &chroma_data[mode_i], pred_cu, lcu,
pred_cu, tree_type,
lcu, false,
tree_type, false, true); true);
chroma_data[mode_i].cost += uvg_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, pred_cu, lcu); chroma_data[mode_i].cost += uvg_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, pred_cu, lcu);
memcpy(&state->search_cabac, &temp_cabac, sizeof(cabac_data_t)); memcpy(&state->search_cabac, &temp_cabac, sizeof(cabac_data_t));
} }
@ -1829,19 +1831,15 @@ static int select_candidates_for_further_search(const encoder_state_t * const st
*/ */
void uvg_search_cu_intra( void uvg_search_cu_intra(
encoder_state_t * const state, encoder_state_t * const state,
const int x_px,
const int y_px,
const int depth,
intra_search_data_t* mode_out, intra_search_data_t* mode_out,
lcu_t *lcu, lcu_t *lcu,
enum uvg_tree_type tree_type) enum uvg_tree_type tree_type,
const cu_loc_t* const cu_loc)
{ {
const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) }; const vector2d_t lcu_px = { cu_loc->local_x, cu_loc->local_y };
const int8_t cu_width = LCU_WIDTH >> depth; const int8_t log2_width = uvg_g_convert_to_log2[cu_loc->width];
const cu_loc_t cu_loc = { x_px, y_px, cu_width, cu_width, const int8_t log2_height = uvg_g_convert_to_log2[cu_loc->width];
MAX(cu_width >> 1, TR_MIN_WIDTH), MAX(cu_width >> 1, TR_MIN_WIDTH) }; const vector2d_t luma_px = { cu_loc->x, cu_loc->y};
const int_fast8_t log2_width = LOG2_LCU_WIDTH - depth;
const vector2d_t luma_px = { x_px, y_px };
const vector2d_t pic_px = { state->tile->frame->width, state->tile->frame->height }; const vector2d_t pic_px = { state->tile->frame->width, state->tile->frame->height };
cu_info_t *cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y); cu_info_t *cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
@ -1857,25 +1855,22 @@ void uvg_search_cu_intra(
// Select left and top CUs if they are available. // Select left and top CUs if they are available.
// Top CU is not available across LCU boundary. // Top CU is not available across LCU boundary.
if (x_px >= SCU_WIDTH) { if (cu_loc->x >= SCU_WIDTH) {
left_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x - 1, lcu_px.y+ cu_width-1); left_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x - 1, lcu_px.y+ cu_loc->height-1);
} }
if (y_px >= SCU_WIDTH && lcu_px.y > 0) { if (cu_loc->y >= SCU_WIDTH && lcu_px.y > 0) {
above_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x+ cu_width-1, lcu_px.y - 1); above_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x+ cu_loc->width-1, lcu_px.y - 1);
} }
int8_t num_cand = uvg_intra_get_dir_luma_predictor(x_px, y_px, candidate_modes, cur_cu, left_cu, above_cu); int8_t num_cand = uvg_intra_get_dir_luma_predictor(cu_loc->x, cu_loc->y, candidate_modes, cur_cu, left_cu, above_cu);
if (depth > 0) { bool is_large = cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH;
uvg_intra_build_reference(&cu_loc, &cu_loc, COLOR_Y, &luma_px, &pic_px, lcu, refs, state->encoder_control->cfg.wpp, NULL, 0, 0); if (!is_large) {
uvg_intra_build_reference(cu_loc, cu_loc, COLOR_Y, &luma_px, &pic_px, lcu, refs, state->encoder_control->cfg.wpp, NULL, 0, 0);
} }
// The maximum number of possible MIP modes depend on block size & shape
int width = LCU_WIDTH >> depth;
int height = width; // TODO: proper height for non-square blocks.
// This is needed for bit cost calculation and requires too many parameters to be // This is needed for bit cost calculation and requires too many parameters to be
// calculated inside the rough search functions // calculated inside the rough search functions
uint8_t mip_ctx = uvg_get_mip_flag_context(x_px, y_px, cu_width, cu_width, lcu, NULL); uint8_t mip_ctx = uvg_get_mip_flag_context(cu_loc, lcu, NULL);
// Find best intra mode for 2Nx2N. // Find best intra mode for 2Nx2N.
uvg_pixel *ref_pixels = &lcu->ref.y[lcu_px.x + lcu_px.y * LCU_WIDTH]; uvg_pixel *ref_pixels = &lcu->ref.y[lcu_px.x + lcu_px.y * LCU_WIDTH];
@ -1886,15 +1881,15 @@ void uvg_search_cu_intra(
temp_pred_cu.type = CU_INTRA; temp_pred_cu.type = CU_INTRA;
FILL(temp_pred_cu.intra, 0); FILL(temp_pred_cu.intra, 0);
// Find modes with multiple reference lines if in use. Do not use if CU in first row. // Find modes with multiple reference lines if in use. Do not use if CU in first row.
uint8_t lines = state->encoder_control->cfg.mrl && (y_px % LCU_WIDTH) != 0 ? MAX_REF_LINE_IDX : 1; uint8_t lines = state->encoder_control->cfg.mrl && lcu_px.y != 0 ? MAX_REF_LINE_IDX : 1;
uint8_t number_of_modes; uint8_t number_of_modes;
uint8_t num_regular_modes; uint8_t num_regular_modes;
bool skip_rough_search = (depth == 0 || state->encoder_control->cfg.rdo >= 4); bool skip_rough_search = (is_large || state->encoder_control->cfg.rdo >= 4);
if (!skip_rough_search) { if (!skip_rough_search) {
num_regular_modes = number_of_modes = search_intra_rough( num_regular_modes = number_of_modes = search_intra_rough(
state, state,
&cu_loc, cu_loc,
ref_pixels, ref_pixels,
LCU_WIDTH, LCU_WIDTH,
refs, refs,
@ -1903,7 +1898,7 @@ void uvg_search_cu_intra(
search_data, search_data,
&temp_pred_cu, &temp_pred_cu,
mip_ctx); mip_ctx);
// if(lines == 1) sort_modes(search_data, number_of_modes); // if(lines == 1) sort_modes(search_data, number_of_modes);
} else { } else {
for (int8_t i = 0; i < UVG_NUM_INTRA_MODES; i++) { for (int8_t i = 0; i < UVG_NUM_INTRA_MODES; i++) {
@ -1925,7 +1920,7 @@ void uvg_search_cu_intra(
// Copy extra ref lines, including ref line 1 and top left corner. // Copy extra ref lines, including ref line 1 and top left corner.
for (int i = 0; i < MAX_REF_LINE_IDX; ++i) { for (int i = 0; i < MAX_REF_LINE_IDX; ++i) {
int height = (LCU_WIDTH >> depth) * 2 + MAX_REF_LINE_IDX; int height = (cu_loc->height) * 2 + MAX_REF_LINE_IDX;
height = MIN(height, (LCU_WIDTH - lcu_px.y + MAX_REF_LINE_IDX)); // Cut short if on bottom LCU edge. Cannot take references from below since they don't exist. height = MIN(height, (LCU_WIDTH - lcu_px.y + MAX_REF_LINE_IDX)); // Cut short if on bottom LCU edge. Cannot take references from below since they don't exist.
height = MIN(height, pic_px.y - luma_px.y + MAX_REF_LINE_IDX); height = MIN(height, pic_px.y - luma_px.y + MAX_REF_LINE_IDX);
uvg_pixels_blit(&frame->rec->y[(luma_px.y - MAX_REF_LINE_IDX) * frame->rec->stride + luma_px.x - (1 + i)], uvg_pixels_blit(&frame->rec->y[(luma_px.y - MAX_REF_LINE_IDX) * frame->rec->stride + luma_px.x - (1 + i)],
@ -1934,7 +1929,7 @@ void uvg_search_cu_intra(
frame->rec->stride, 1); frame->rec->stride, 1);
} }
} }
uvg_intra_build_reference(&cu_loc, &cu_loc, COLOR_Y, &luma_px, &pic_px, lcu, &refs[line], state->encoder_control->cfg.wpp, extra_refs, line, 0); uvg_intra_build_reference(cu_loc, cu_loc, COLOR_Y, &luma_px, &pic_px, lcu, &refs[line], state->encoder_control->cfg.wpp, extra_refs, line, 0);
for(int i = 1; i < INTRA_MPM_COUNT; i++) { for(int i = 1; i < INTRA_MPM_COUNT; i++) {
num_mrl_modes++; num_mrl_modes++;
const int index = (i - 1) + (INTRA_MPM_COUNT -1)*(line-1) + number_of_modes; const int index = (i - 1) + (INTRA_MPM_COUNT -1)*(line-1) + number_of_modes;
@ -1946,7 +1941,7 @@ void uvg_search_cu_intra(
} }
} }
if (!skip_rough_search && lines != 1) { if (!skip_rough_search && lines != 1) {
get_rough_cost_for_2n_modes(state, refs, &cu_loc, get_rough_cost_for_2n_modes(state, refs, cu_loc,
ref_pixels, ref_pixels,
LCU_WIDTH, search_data + number_of_modes, num_mrl_modes, LCU_WIDTH, search_data + number_of_modes, num_mrl_modes,
mip_ctx); mip_ctx);
@ -1959,11 +1954,11 @@ void uvg_search_cu_intra(
int num_mip_modes = 0; int num_mip_modes = 0;
if (state->encoder_control->cfg.mip) { if (state->encoder_control->cfg.mip) {
// MIP is not allowed for 64 x 4 or 4 x 64 blocks // MIP is not allowed for 64 x 4 or 4 x 64 blocks
if (!((width == 64 && height == 4) || (width == 4 && height == 64))) { if (!((cu_loc->height == 64 && cu_loc->width== 4) || (cu_loc->height== 4 && cu_loc->width == 64))) {
num_mip_modes = NUM_MIP_MODES_FULL(width, height); num_mip_modes = NUM_MIP_MODES_FULL(cu_loc->width, cu_loc->height);
for (int transpose = 0; transpose < 2; transpose++) { for (int transpose = 0; transpose < 2; transpose++) {
const int half_mip_modes = NUM_MIP_MODES_HALF(width, height); const int half_mip_modes = num_mip_modes / 2;
for (int i = 0; i < half_mip_modes; ++i) { for (int i = 0; i < half_mip_modes; ++i) {
const int index = i + number_of_modes + transpose * half_mip_modes; const int index = i + number_of_modes + transpose * half_mip_modes;
search_data[index].pred_cu = temp_pred_cu; search_data[index].pred_cu = temp_pred_cu;
@ -1975,7 +1970,7 @@ void uvg_search_cu_intra(
} }
} }
if (!skip_rough_search) { if (!skip_rough_search) {
get_rough_cost_for_2n_modes(state, refs, &cu_loc, get_rough_cost_for_2n_modes(state, refs, cu_loc,
ref_pixels, ref_pixels,
LCU_WIDTH, search_data + number_of_modes, num_mip_modes, LCU_WIDTH, search_data + number_of_modes, num_mip_modes,
mip_ctx); mip_ctx);
@ -1986,7 +1981,10 @@ void uvg_search_cu_intra(
// Set transform depth to current depth, meaning no transform splits. // Set transform depth to current depth, meaning no transform splits.
uvg_lcu_fill_trdepth(lcu, x_px, y_px, depth, depth, tree_type); {
const int8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
uvg_lcu_fill_trdepth(lcu, cu_loc->x, cu_loc->y, depth, depth, tree_type);
}
// Refine results with slower search or get some results if rough search was skipped. // Refine results with slower search or get some results if rough search was skipped.
const int32_t rdo_level = state->encoder_control->cfg.rdo; const int32_t rdo_level = state->encoder_control->cfg.rdo;
if (rdo_level >= 2 || skip_rough_search) { if (rdo_level >= 2 || skip_rough_search) {
@ -2003,7 +2001,7 @@ void uvg_search_cu_intra(
{2, 3, 3, 3, 3, 2}, // 64x4, 64x8, 64x16, 64x32, 64x64, 64x128, {2, 3, 3, 3, 3, 2}, // 64x4, 64x8, 64x16, 64x32, 64x64, 64x128,
{2, 2, 2, 2, 2, 3}, // 128x4, 128x8, 128x16, 128x32, 128x64, 128x128, {2, 2, 2, 2, 2, 3}, // 128x4, 128x8, 128x16, 128x32, 128x64, 128x128,
}; };
number_of_modes_to_search = g_aucIntraModeNumFast_UseMPM_2D[7- depth - 3][7 - depth - 3]; number_of_modes_to_search = g_aucIntraModeNumFast_UseMPM_2D[log2_width - 2][log2_height - 2];
} else { } else {
// Check only the predicted modes. // Check only the predicted modes.
number_of_modes_to_search = 0; number_of_modes_to_search = 0;
@ -2015,8 +2013,8 @@ void uvg_search_cu_intra(
search_data, search_data,
num_regular_modes, num_regular_modes,
num_mip_modes, num_mip_modes,
width, cu_loc->width,
height cu_loc->height
); );
} }
} }
@ -2041,13 +2039,11 @@ void uvg_search_cu_intra(
search_intra_rdo( search_intra_rdo(
state, state,
x_px,
y_px,
depth,
number_of_modes_to_search, number_of_modes_to_search,
search_data, search_data,
lcu, lcu,
tree_type); tree_type,
cu_loc);
search_data[0].pred_cu.mts_last_scan_pos = false; search_data[0].pred_cu.mts_last_scan_pos = false;
search_data[0].pred_cu.violates_mts_coeff_constraint = false; search_data[0].pred_cu.violates_mts_coeff_constraint = false;
} }

View file

@ -43,7 +43,9 @@
#include "global.h" // IWYU pragma: keep #include "global.h" // IWYU pragma: keep
#include "intra.h" #include "intra.h"
double uvg_luma_mode_bits(const encoder_state_t *state, const cu_info_t* const cur_cu, int x, int y, int8_t depth, const lcu_t* lcu); double uvg_luma_mode_bits(const encoder_state_t *state, const cu_info_t* const cur_cu, const cu_loc_t*
const cu_loc,
const lcu_t* lcu);
double uvg_chroma_mode_bits(const encoder_state_t *state, double uvg_chroma_mode_bits(const encoder_state_t *state,
int8_t chroma_mode, int8_t luma_mode); int8_t chroma_mode, int8_t luma_mode);
@ -59,11 +61,9 @@ int8_t uvg_search_cu_intra_chroma(
void uvg_search_cu_intra( void uvg_search_cu_intra(
encoder_state_t * const state, encoder_state_t * const state,
const int x_px,
const int y_px,
const int depth,
intra_search_data_t* search_data, intra_search_data_t* search_data,
lcu_t *lcu, lcu_t *lcu,
enum uvg_tree_type tree_type); enum uvg_tree_type tree_type,
const cu_loc_t* const cu_loc);
#endif // SEARCH_INTRA_H_ #endif // SEARCH_INTRA_H_

View file

@ -2641,8 +2641,8 @@ static void mts_idct_generic(
if (tu->lfnst_idx || tu->cr_lfnst_idx) { if (tu->lfnst_idx || tu->cr_lfnst_idx) {
if ((width == 4 && height > 4) || (width > 4 && height == 4)) { if ((width == 4 && height > 4) || (width > 4 && height == 4)) {
skip_width == width - 4; skip_width = width - 4;
skip_height == height - 4; skip_height = height - 4;
} }
else if ((width >= 8 && height >= 8)) { else if ((width >= 8 && height >= 8)) {
skip_width = width - 8; skip_width = width - 8;

View file

@ -174,7 +174,6 @@ int32_t uvg_get_scaled_qp(color_t color, int8_t qp, int8_t qp_offset, int8_t con
*/ */
void uvg_derive_lfnst_constraints( void uvg_derive_lfnst_constraints(
cu_info_t* const pred_cu, cu_info_t* const pred_cu,
const int depth,
bool* constraints, bool* constraints,
const coeff_t* coeff, const coeff_t* coeff,
const int width, const int width,
@ -182,7 +181,7 @@ void uvg_derive_lfnst_constraints(
const vector2d_t * const lcu_px, const vector2d_t * const lcu_px,
color_t color) color_t color)
{ {
coeff_scan_order_t scan_idx = uvg_get_scan_order(pred_cu->type, pred_cu->intra.mode, depth); coeff_scan_order_t scan_idx = SCAN_DIAG;
// ToDo: large block support in VVC? // ToDo: large block support in VVC?
const uint32_t log2_block_size = uvg_g_convert_to_log2[width]; const uint32_t log2_block_size = uvg_g_convert_to_log2[width];
@ -584,9 +583,9 @@ void uvg_chroma_transform_search(
if(pred_cu->type == CU_INTRA && transforms[i] != CHROMA_TS && (depth == 4 || tree_type == UVG_CHROMA_T)) { if(pred_cu->type == CU_INTRA && transforms[i] != CHROMA_TS && (depth == 4 || tree_type == UVG_CHROMA_T)) {
bool constraints[2] = { false, false }; bool constraints[2] = { false, false };
uvg_derive_lfnst_constraints(pred_cu, depth, constraints, u_quant_coeff, width, height, NULL, COLOR_U); uvg_derive_lfnst_constraints(pred_cu, constraints, u_quant_coeff, width, height, NULL, COLOR_U);
if(!IS_JCCR_MODE(transforms[i])) { if(!IS_JCCR_MODE(transforms[i])) {
uvg_derive_lfnst_constraints(pred_cu, depth, constraints, v_quant_coeff, width, height, NULL, COLOR_V); uvg_derive_lfnst_constraints(pred_cu, constraints, v_quant_coeff, width, height, NULL, COLOR_V);
} }
if (!constraints[1] && (u_has_coeffs || v_has_coeffs) && pred_cu->cr_lfnst_idx != 0) continue; if (!constraints[1] && (u_has_coeffs || v_has_coeffs) && pred_cu->cr_lfnst_idx != 0) continue;
} }

View file

@ -74,7 +74,6 @@ int32_t uvg_get_scaled_qp(color_t color, int8_t qp, int8_t qp_offset, int8_t con
void uvg_derive_lfnst_constraints( void uvg_derive_lfnst_constraints(
cu_info_t* const pred_cu, cu_info_t* const pred_cu,
const int depth,
bool* constraints, bool* constraints,
const coeff_t* coeff, const coeff_t* coeff,
const int width, const int width,