mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
[intra] Fix various issues with cclm, mip, dual-tree, and lfnst
This commit is contained in:
parent
f0be187396
commit
6ef532775b
|
@ -178,7 +178,7 @@ static bool can_use_lfnst_with_isp(const int width, const int height, const int
|
||||||
const int cu_height = tree_type != UVG_LUMA_T || depth == 4 ? height : chroma_height;
|
const int cu_height = tree_type != UVG_LUMA_T || depth == 4 ? height : chroma_height;
|
||||||
bool can_use_lfnst_with_mip = (width >= 16 && height >= 16);
|
bool can_use_lfnst_with_mip = (width >= 16 && height >= 16);
|
||||||
bool is_sep_tree = depth == 4 || tree_type != UVG_BOTH_T;
|
bool is_sep_tree = depth == 4 || tree_type != UVG_BOTH_T;
|
||||||
bool mip_flag = pred_cu->type == CU_INTRA ? pred_cu->intra.mip_flag : false;
|
bool mip_flag = pred_cu->type == CU_INTRA && color == COLOR_Y ? pred_cu->intra.mip_flag : false;
|
||||||
|
|
||||||
if ((isp_mode && !can_use_lfnst_with_isp(width, height, isp_split_type, tree_type)) ||
|
if ((isp_mode && !can_use_lfnst_with_isp(width, height, isp_split_type, tree_type)) ||
|
||||||
(pred_cu->type == CU_INTRA && mip_flag && !can_use_lfnst_with_mip) ||
|
(pred_cu->type == CU_INTRA && mip_flag && !can_use_lfnst_with_mip) ||
|
||||||
|
@ -1720,8 +1720,9 @@ void uvg_encode_coding_tree(
|
||||||
encode_transform_coeff(state, x, y, depth, 0, 0, 0, 0, coeff, tree_type);
|
encode_transform_coeff(state, x, y, depth, 0, 0, 0, 0, coeff, tree_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lfnst_written = encode_lfnst_idx(state, cabac, cur_cu, x, y, depth, cu_width, cu_height, tree_type, COLOR_Y);
|
if (tree_type != UVG_CHROMA_T) {
|
||||||
|
bool lfnst_written = encode_lfnst_idx(state, cabac, cur_cu, x, y, depth, cu_width, cu_height, tree_type, COLOR_Y);
|
||||||
|
}
|
||||||
encode_mts_idx(state, cabac, cur_cu);
|
encode_mts_idx(state, cabac, cur_cu);
|
||||||
|
|
||||||
// For 4x4 the chroma PU/TU is coded after the last
|
// For 4x4 the chroma PU/TU is coded after the last
|
||||||
|
@ -1736,9 +1737,8 @@ void uvg_encode_coding_tree(
|
||||||
tmp->lfnst_last_scan_pos = false;
|
tmp->lfnst_last_scan_pos = false;
|
||||||
encode_transform_coeff(state, x, y, depth, 0, 0, 0, 1, coeff, tree_type);
|
encode_transform_coeff(state, x, y, depth, 0, 0, 0, 1, coeff, tree_type);
|
||||||
// Write LFNST only once for single tree structure
|
// Write LFNST only once for single tree structure
|
||||||
if (!lfnst_written || tree_type == UVG_CHROMA_T || depth == 4) {
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1118,6 +1118,9 @@ static void encoder_state_encode(encoder_state_t * const main_state) {
|
||||||
sub_state->tile->frame->rec = NULL;
|
sub_state->tile->frame->rec = NULL;
|
||||||
|
|
||||||
uvg_cu_array_free(&sub_state->tile->frame->cu_array);
|
uvg_cu_array_free(&sub_state->tile->frame->cu_array);
|
||||||
|
if(sub_state->tile->frame->chroma_cu_array) {
|
||||||
|
uvg_cu_array_free(&sub_state->tile->frame->chroma_cu_array);
|
||||||
|
}
|
||||||
|
|
||||||
sub_state->tile->frame->source = uvg_image_make_subimage(
|
sub_state->tile->frame->source = uvg_image_make_subimage(
|
||||||
main_state->tile->frame->source,
|
main_state->tile->frame->source,
|
||||||
|
@ -1989,6 +1992,9 @@ void uvg_encoder_prepare(encoder_state_t *state)
|
||||||
|
|
||||||
if (state->previous_encoder_state != state) {
|
if (state->previous_encoder_state != state) {
|
||||||
uvg_cu_array_free(&state->tile->frame->cu_array);
|
uvg_cu_array_free(&state->tile->frame->cu_array);
|
||||||
|
if (state->tile->frame->chroma_cu_array) {
|
||||||
|
uvg_cu_array_free(&state->tile->frame->chroma_cu_array);
|
||||||
|
}
|
||||||
unsigned width = state->tile->frame->width_in_lcu * LCU_WIDTH;
|
unsigned width = state->tile->frame->width_in_lcu * LCU_WIDTH;
|
||||||
unsigned height = state->tile->frame->height_in_lcu * LCU_WIDTH;
|
unsigned height = state->tile->frame->height_in_lcu * LCU_WIDTH;
|
||||||
state->tile->frame->cu_array = uvg_cu_array_alloc(width, height);
|
state->tile->frame->cu_array = uvg_cu_array_alloc(width, height);
|
||||||
|
@ -2011,6 +2017,9 @@ void uvg_encoder_prepare(encoder_state_t *state)
|
||||||
prev_state->frame->poc,
|
prev_state->frame->poc,
|
||||||
prev_state->frame->ref_LX);
|
prev_state->frame->ref_LX);
|
||||||
uvg_cu_array_free(&state->tile->frame->cu_array);
|
uvg_cu_array_free(&state->tile->frame->cu_array);
|
||||||
|
if (state->tile->frame->chroma_cu_array) {
|
||||||
|
uvg_cu_array_free(&state->tile->frame->chroma_cu_array);
|
||||||
|
}
|
||||||
unsigned height = state->tile->frame->height_in_lcu * LCU_WIDTH;
|
unsigned height = state->tile->frame->height_in_lcu * LCU_WIDTH;
|
||||||
unsigned width = state->tile->frame->width_in_lcu * LCU_WIDTH;
|
unsigned width = state->tile->frame->width_in_lcu * LCU_WIDTH;
|
||||||
state->tile->frame->cu_array = uvg_cu_array_alloc(width, height);
|
state->tile->frame->cu_array = uvg_cu_array_alloc(width, height);
|
||||||
|
@ -2032,6 +2041,9 @@ void uvg_encoder_prepare(encoder_state_t *state)
|
||||||
state->tile->frame->rec = NULL;
|
state->tile->frame->rec = NULL;
|
||||||
|
|
||||||
uvg_cu_array_free(&state->tile->frame->cu_array);
|
uvg_cu_array_free(&state->tile->frame->cu_array);
|
||||||
|
if (state->tile->frame->chroma_cu_array) {
|
||||||
|
uvg_cu_array_free(&state->tile->frame->chroma_cu_array);
|
||||||
|
}
|
||||||
|
|
||||||
// Update POC and frame count.
|
// Update POC and frame count.
|
||||||
state->frame->num = prev_state->frame->num + 1;
|
state->frame->num = prev_state->frame->num + 1;
|
||||||
|
|
25
src/search.c
25
src/search.c
|
@ -833,8 +833,8 @@ static double search_cu(
|
||||||
pu_depth_intra.max = ctrl->cfg.pu_depth_intra.max[gop_layer] >= 0 ? ctrl->cfg.pu_depth_intra.max[gop_layer] : ctrl->cfg.pu_depth_intra.max[0];
|
pu_depth_intra.max = ctrl->cfg.pu_depth_intra.max[gop_layer] >= 0 ? ctrl->cfg.pu_depth_intra.max[gop_layer] : ctrl->cfg.pu_depth_intra.max[0];
|
||||||
}
|
}
|
||||||
if(tree_type == UVG_CHROMA_T) {
|
if(tree_type == UVG_CHROMA_T) {
|
||||||
pu_depth_intra.max = MIN(3, pu_depth_intra.max);
|
pu_depth_intra.max = CLIP(1, 3, pu_depth_intra.max);
|
||||||
pu_depth_intra.min = MIN(3, pu_depth_intra.min);
|
pu_depth_intra.min = CLIP(1, 3, pu_depth_intra.min);
|
||||||
}
|
}
|
||||||
pu_depth_inter.min = ctrl->cfg.pu_depth_inter.min[gop_layer] >= 0 ? ctrl->cfg.pu_depth_inter.min[gop_layer] : ctrl->cfg.pu_depth_inter.min[0];
|
pu_depth_inter.min = ctrl->cfg.pu_depth_inter.min[gop_layer] >= 0 ? ctrl->cfg.pu_depth_inter.min[gop_layer] : ctrl->cfg.pu_depth_inter.min[0];
|
||||||
pu_depth_inter.max = ctrl->cfg.pu_depth_inter.max[gop_layer] >= 0 ? ctrl->cfg.pu_depth_inter.max[gop_layer] : ctrl->cfg.pu_depth_inter.max[0];
|
pu_depth_inter.max = ctrl->cfg.pu_depth_inter.max[gop_layer] >= 0 ? ctrl->cfg.pu_depth_inter.max[gop_layer] : ctrl->cfg.pu_depth_inter.max[0];
|
||||||
|
@ -926,20 +926,21 @@ static double search_cu(
|
||||||
intra_cost += pred_mode_type_bits * state->lambda;
|
intra_cost += pred_mode_type_bits * state->lambda;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (state->encoder_control->cfg.cclm && tree_type != UVG_CHROMA_T && state->encoder_control->chroma_format != UVG_CSP_400) {
|
||||||
|
uvg_intra_recon_cu(state,
|
||||||
|
x, y,
|
||||||
|
depth, &intra_search,
|
||||||
|
&intra_search.pred_cu,
|
||||||
|
lcu, tree_type, true, false);
|
||||||
|
|
||||||
|
downsample_cclm_rec(
|
||||||
|
state, x, y, cu_width / 2, cu_width / 2, lcu->rec.y, lcu->left_ref.y[64]
|
||||||
|
);
|
||||||
|
}
|
||||||
double intra_cost = intra_search.cost;
|
double intra_cost = intra_search.cost;
|
||||||
if (intra_cost < cost && tree_type != UVG_LUMA_T) {
|
if (intra_cost < cost && tree_type != UVG_LUMA_T) {
|
||||||
int8_t intra_mode = intra_search.pred_cu.intra.mode;
|
int8_t intra_mode = intra_search.pred_cu.intra.mode;
|
||||||
if (state->encoder_control->cfg.cclm && tree_type == UVG_BOTH_T) {
|
|
||||||
uvg_intra_recon_cu(state,
|
|
||||||
x, y,
|
|
||||||
depth, &intra_search,
|
|
||||||
&intra_search.pred_cu,
|
|
||||||
lcu, tree_type, true, false);
|
|
||||||
|
|
||||||
downsample_cclm_rec(
|
|
||||||
state, x, y, cu_width / 2, cu_width / 2, lcu->rec.y, lcu->left_ref.y[64]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// TODO: This heavily relies to square CUs
|
// TODO: This heavily relies to square CUs
|
||||||
if ((depth != 4 || (x % 8 && y % 8)) && state->encoder_control->chroma_format != UVG_CSP_400 && tree_type != UVG_LUMA_T) {
|
if ((depth != 4 || (x % 8 && y % 8)) && state->encoder_control->chroma_format != UVG_CSP_400 && tree_type != UVG_LUMA_T) {
|
||||||
|
|
||||||
|
|
|
@ -336,9 +336,12 @@ static double search_intra_trdepth(
|
||||||
|
|
||||||
const int max_tb_size = TR_MAX_WIDTH;
|
const int max_tb_size = TR_MAX_WIDTH;
|
||||||
// LFNST search params
|
// LFNST search params
|
||||||
const int max_lfnst_idx = width > max_tb_size || height > max_tb_size ?
|
int max_lfnst_idx = width > max_tb_size || height > max_tb_size ?
|
||||||
0 :
|
0 :
|
||||||
2;
|
2;
|
||||||
|
if(pred_cu->intra.mip_flag && (width < 16 || height < 16)) {
|
||||||
|
max_lfnst_idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int start_idx = 0;
|
int start_idx = 0;
|
||||||
int end_idx = state->encoder_control->cfg.lfnst && depth == pred_cu->
|
int end_idx = state->encoder_control->cfg.lfnst && depth == pred_cu->
|
||||||
|
@ -989,7 +992,7 @@ static double count_bits(
|
||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t search_intra_rough(
|
static uint8_t search_intra_rough(
|
||||||
encoder_state_t * const state,
|
encoder_state_t * const state,
|
||||||
const cu_loc_t* const cu_loc,
|
const cu_loc_t* const cu_loc,
|
||||||
uvg_pixel *orig,
|
uvg_pixel *orig,
|
||||||
|
@ -1041,7 +1044,7 @@ static int16_t search_intra_rough(
|
||||||
const double planar_mode_flag = CTX_ENTROPY_FBITS(&(state->search_cabac.ctx.luma_planar_model[1]), 0);
|
const double planar_mode_flag = CTX_ENTROPY_FBITS(&(state->search_cabac.ctx.luma_planar_model[1]), 0);
|
||||||
const double not_planar_mode_flag = CTX_ENTROPY_FBITS(&(state->search_cabac.ctx.luma_planar_model[1]), 1);
|
const double not_planar_mode_flag = CTX_ENTROPY_FBITS(&(state->search_cabac.ctx.luma_planar_model[1]), 1);
|
||||||
|
|
||||||
const int mode_list_size = state->encoder_control->cfg.mip ? 6 : 3;
|
const uint8_t mode_list_size = state->encoder_control->cfg.mip ? 6 : 3;
|
||||||
struct mode_cost best_six_modes[6];
|
struct mode_cost best_six_modes[6];
|
||||||
// Initial offset decides how many modes are tried before moving on to the
|
// Initial offset decides how many modes are tried before moving on to the
|
||||||
// recursive search.
|
// recursive search.
|
||||||
|
|
|
@ -943,7 +943,7 @@ void uvg_inv_lfnst(
|
||||||
bool is_separate_tree = depth == 4 || tree_type != UVG_BOTH_T;
|
bool is_separate_tree = depth == 4 || tree_type != UVG_BOTH_T;
|
||||||
bool is_cclm_mode = (intra_mode >= 81 && intra_mode <= 83); // CCLM modes are in [81, 83]
|
bool is_cclm_mode = (intra_mode >= 81 && intra_mode <= 83); // CCLM modes are in [81, 83]
|
||||||
|
|
||||||
bool is_mip = cur_cu->type == CU_INTRA ? cur_cu->intra.mip_flag : false;
|
bool is_mip = cur_cu->type == CU_INTRA && tree_type != UVG_CHROMA_T ? cur_cu->intra.mip_flag : false;
|
||||||
bool is_wide_angle = false; // TODO: get wide angle mode when implemented
|
bool is_wide_angle = false; // TODO: get wide angle mode when implemented
|
||||||
|
|
||||||
const int cu_type = cur_cu->type;
|
const int cu_type = cur_cu->type;
|
||||||
|
@ -956,7 +956,7 @@ void uvg_inv_lfnst(
|
||||||
const uint32_t* scan = whge3 ? uvg_coef_top_left_diag_scan_8x8[log2_block_size] : uvg_g_sig_last_scan[scan_order][log2_block_size - 1];
|
const uint32_t* scan = whge3 ? uvg_coef_top_left_diag_scan_8x8[log2_block_size] : uvg_g_sig_last_scan[scan_order][log2_block_size - 1];
|
||||||
|
|
||||||
if (is_cclm_mode) {
|
if (is_cclm_mode) {
|
||||||
intra_mode = cur_cu->intra.mode;
|
intra_mode = cur_cu->intra.mip_flag ? 0 : cur_cu->intra.mode;
|
||||||
}
|
}
|
||||||
if (is_mip) {
|
if (is_mip) {
|
||||||
intra_mode = 0; // Set to planar mode
|
intra_mode = 0; // Set to planar mode
|
||||||
|
|
Loading…
Reference in a new issue