mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-30 12:44:07 +00:00
[mtt] remove all rest usages of deriving width and height from depth
This commit is contained in:
parent
26dcadc149
commit
dcf879e5ed
2
src/cu.c
2
src/cu.c
|
@ -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.
|
||||||
|
|
6
src/cu.h
6
src/cu.h
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
@ -1150,7 +1153,6 @@ void uvg_encode_intra_luma_coding_unit(const encoder_state_t * const state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
68
src/intra.c
68
src/intra.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
72
src/search.c
72
src/search.c
|
@ -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);
|
||||||
|
|
|
@ -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 uint8_t height_c = cu_loc->chroma_height;
|
||||||
|
|
||||||
const int offset = width / 2;
|
const vector2d_t lcu_px = { cu_loc->local_x, cu_loc->local_y };
|
||||||
const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) };
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue