Skip to content

Commit

Permalink
Merge branch 'intra-fix-up' into 'master'
Browse files Browse the repository at this point in the history
Intra fix up

See merge request cs/ultravideo/vvc/uvg266!12
  • Loading branch information
Jovasa committed Jul 8, 2022
2 parents 456f69f + ea32ef3 commit 98322c9
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 78 deletions.
16 changes: 8 additions & 8 deletions src/encode_coding_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ static bool can_use_lfnst_with_isp(const int width, const int height, const int
const int x,
const int y,
enum uvg_tree_type tree_type,
const color_t color)
const color_t color,
const lcu_t* lcu)
{
if (state->encoder_control->cfg.lfnst && pred_cu->type == CU_INTRA) {
const int isp_mode = 0; // ISP_TODO: assign proper ISP mode when ISP is implemented
Expand Down Expand Up @@ -201,12 +202,12 @@ static bool can_use_lfnst_with_isp(const int width, const int height, const int
const int tu_height = tu_width; // TODO: height for non-square blocks

// TODO: chroma transform skip
if (tree_type != UVG_BOTH_T) {
if (color == COLOR_Y) {
for (int i = 0; i < num_transform_units; i++) {
// TODO: this works only for square blocks
const int pu_x = x + ((i % tu_row_length) * tu_width);
const int pu_y = y + ((i / tu_row_length) * tu_height);
const cu_info_t* cur_tu = uvg_cu_array_at_const(frame->cu_array, pu_x, pu_y);
const int tu_x = x + ((i % tu_row_length) * tu_width);
const int tu_y = y + ((i / tu_row_length) * tu_height);
const cu_info_t* cur_tu = lcu ? LCU_GET_CU_AT_PX(lcu, tu_x, tu_y) : uvg_cu_array_at_const(frame->cu_array, tu_x, tu_y);
assert(cur_tu != NULL && "NULL transform unit.");
bool cbf_set = cbf_is_set(cur_tu->cbf, tr_depth, COLOR_Y);

Expand Down Expand Up @@ -239,7 +240,7 @@ static bool encode_lfnst_idx(
const color_t color)
{

if (uvg_is_lfnst_allowed(state, pred_cu, width, height, x, y, tree_type, color)) {
if (uvg_is_lfnst_allowed(state, pred_cu, width, height, x, y, tree_type, color, NULL)) {
// Getting separate tree bool from block size is a temporary fix until a proper dual tree check is possible (there is no dual tree structure at time of writing this).
// VTM seems to force explicit dual tree structure for small 4x4 blocks
bool is_separate_tree = depth == 4 || tree_type != UVG_BOTH_T;
Expand Down Expand Up @@ -399,7 +400,7 @@ void uvg_encode_ts_residual(encoder_state_t* const state,
belowPixel = pos_y > 0 ? coeff[pos_x + (pos_y - 1) * width] : 0;
absLevel = uvg_derive_mod_coeff(rightPixel, belowPixel, abs(coeff[blk_pos]), 0);
cutoffVal = 2;
for (i = 0; i < numGtBins; i++)
for (int j = 0; j < numGtBins; j++)
{
if (absLevel >= cutoffVal)
{
Expand Down Expand Up @@ -1738,7 +1739,6 @@ void uvg_encode_coding_tree(
encode_transform_coeff(state, x, y, depth, 0, 0, 0, 1, coeff, tree_type);
// 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);

}
}

Expand Down
3 changes: 2 additions & 1 deletion src/encode_coding_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ bool uvg_is_lfnst_allowed(
const int x,
const int y,
enum uvg_tree_type tree_type,
const color_t color);
const color_t color,
const lcu_t* lcu);

void uvg_encode_coding_tree(
encoder_state_t * const state,
Expand Down
47 changes: 26 additions & 21 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ double uvg_cu_rd_cost_chroma(const encoder_state_t *const state,
// block and return 0 cost for all others.
return 0;
}
int u_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 2) >> 1 : cbf_is_set(pred_cu->cbf, depth, COLOR_U);
int v_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 1) : cbf_is_set(pred_cu->cbf, depth, COLOR_V);

// See luma for why the second condition
if (!skip_residual_coding) {
Expand All @@ -401,13 +403,10 @@ double uvg_cu_rd_cost_chroma(const encoder_state_t *const state,
cabac_ctx_t *ctx = &(cabac->ctx.qt_cbf_model_cb[0]);
cabac->cur_ctx = ctx;
if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, depth - 1, COLOR_U)) {
int u_is_set = cbf_is_set(pred_cu->cbf, depth, COLOR_U);
CABAC_FBITS_UPDATE(cabac, ctx, u_is_set, tr_tree_bits, "cbf_cb_search");
}
int is_set = cbf_is_set(pred_cu->cbf, depth, COLOR_U);
ctx = &(cabac->ctx.qt_cbf_model_cr[is_set]);
ctx = &(cabac->ctx.qt_cbf_model_cr[u_is_set]);
if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, depth - 1, COLOR_V)) {
int v_is_set = cbf_is_set(pred_cu->cbf, depth, COLOR_V);
CABAC_FBITS_UPDATE(cabac, ctx, v_is_set, tr_tree_bits, "cbf_cb_search");
}
}
Expand All @@ -426,7 +425,7 @@ double uvg_cu_rd_cost_chroma(const encoder_state_t *const state,
}

if (state->encoder_control->cfg.jccr) {
int cbf_mask = cbf_is_set(pred_cu->cbf, depth, COLOR_U) * 2 + cbf_is_set(pred_cu->cbf, depth, COLOR_V) - 1;
int cbf_mask = u_is_set * 2 + v_is_set - 1;
cabac_ctx_t* ctx = NULL;
if (cbf_mask != -1) {
cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac;
Expand All @@ -448,13 +447,18 @@ double uvg_cu_rd_cost_chroma(const encoder_state_t *const state,
ssd = ssd_u + ssd_v;
}

if (!skip_residual_coding)
{
if (!skip_residual_coding) {
int8_t scan_order = uvg_get_scan_order(pred_cu->type, pred_cu->intra.mode_chroma, depth);
const int index = xy_to_zorder(LCU_WIDTH_C, lcu_px.x, lcu_px.y);

coeff_bits += uvg_get_coeff_cost(state, &lcu->coeff.u[index], NULL, width, 2, scan_order, 0);
coeff_bits += uvg_get_coeff_cost(state, &lcu->coeff.v[index], NULL, width, 2, scan_order, 0);
if((pred_cu->joint_cb_cr & 3) == 0){
coeff_bits += uvg_get_coeff_cost(state, &lcu->coeff.u[index], NULL, width, 2, scan_order, 0);
coeff_bits += uvg_get_coeff_cost(state, &lcu->coeff.v[index], NULL, width, 2, scan_order, 0);
}
else {
coeff_bits += uvg_get_coeff_cost(state, &lcu->coeff.joint_uv[index], NULL, width, 2, scan_order, 0);

}
}


Expand Down Expand Up @@ -568,7 +572,7 @@ static double cu_rd_cost_tr_split_accurate(
}

if(depth == 4 || tree_type == UVG_LUMA_T) {
if (uvg_is_lfnst_allowed(state, tr_cu, width, width, x_px, y_px, tree_type, COLOR_Y)) {
if (uvg_is_lfnst_allowed(state, tr_cu, width, width, x_px, y_px, tree_type, COLOR_Y, lcu)) {
const int lfnst_idx = tr_cu->lfnst_idx;
CABAC_FBITS_UPDATE(
cabac,
Expand Down Expand Up @@ -620,10 +624,10 @@ static double cu_rd_cost_tr_split_accurate(
else {
{
int index = lcu_px.y * LCU_WIDTH_C + lcu_px.x;
int ssd_u_joint = uvg_pixels_calc_ssd(&lcu->ref.u[index], &lcu->rec.joint_u[index],
int ssd_u_joint = uvg_pixels_calc_ssd(&lcu->ref.u[index], &lcu->rec.u[index],
LCU_WIDTH_C, LCU_WIDTH_C,
chroma_width);
int ssd_v_joint = uvg_pixels_calc_ssd(&lcu->ref.v[index], &lcu->rec.joint_v[index],
int ssd_v_joint = uvg_pixels_calc_ssd(&lcu->ref.v[index], &lcu->rec.v[index],
LCU_WIDTH_C, LCU_WIDTH_C,
chroma_width);
chroma_ssd = ssd_u_joint + ssd_v_joint;
Expand All @@ -635,7 +639,7 @@ static double cu_rd_cost_tr_split_accurate(
}
}

if (uvg_is_lfnst_allowed(state, tr_cu, width, width, x_px, y_px, tree_type, depth == 4 || tree_type == UVG_CHROMA_T ? COLOR_UV : COLOR_Y)) {
if (uvg_is_lfnst_allowed(state, tr_cu, width, width, x_px, y_px, tree_type, depth == 4 || tree_type == UVG_CHROMA_T ? COLOR_UV : COLOR_Y, lcu)) {
const int lfnst_idx = (depth != 4 && tree_type != UVG_CHROMA_T) ? tr_cu->lfnst_idx : tr_cu->cr_lfnst_idx;
CABAC_FBITS_UPDATE(
cabac,
Expand Down Expand Up @@ -956,7 +960,7 @@ static double search_cu(
intra_search.pred_cu.type = CU_INTRA;
}
intra_search.pred_cu.intra.mode_chroma = intra_search.pred_cu.intra.mode;
if (ctrl->cfg.rdo >= 3 || ctrl->cfg.jccr || ctrl->cfg.lfnst) {
if (ctrl->cfg.rdo >= 2 || ctrl->cfg.jccr || ctrl->cfg.lfnst) {
uvg_search_cu_intra_chroma(state, x, y, depth, lcu, &intra_search, tree_type);

if (intra_search.pred_cu.joint_cb_cr == 0) {
Expand Down Expand Up @@ -1150,11 +1154,11 @@ static double search_cu(
memcpy(&state->search_cabac, &pre_search_cabac, sizeof(post_seach_cabac));


state->search_cabac.update = 1;

double split_bits = 0;

if (depth < MAX_DEPTH) {

state->search_cabac.update = 1;
// Add cost of cu_split_flag.
const cu_info_t* left_cu = NULL, * above_cu = NULL;
if (x) {
Expand Down Expand Up @@ -1197,14 +1201,13 @@ static double search_cu(
// 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 (split_cost < cost) split_cost += search_cu(state, x, y, depth + 1, work_tree, tree_type);
if (split_cost < cost) split_cost += search_cu(state, x + half_cu, y, depth + 1, work_tree, tree_type);
if (split_cost < cost) split_cost += search_cu(state, x, y + half_cu, depth + 1, work_tree, tree_type);
if (split_cost < cost) split_cost += search_cu(state, x + half_cu, y + half_cu, depth + 1, work_tree, tree_type);
if (split_cost < cost || 1) split_cost += search_cu(state, x + half_cu, y, depth + 1, work_tree, tree_type);
if (split_cost < cost || 1) split_cost += search_cu(state, x, y + half_cu, depth + 1, work_tree, tree_type);
if (split_cost < cost || 1) split_cost += search_cu(state, x + half_cu, y + half_cu, depth + 1, work_tree, tree_type);
} else {
split_cost = INT_MAX;
}


// If no search is not performed for this depth, try just the best mode
// of the top left CU from the next depth. This should ensure that 64x64
// gets used, at least in the most obvious cases, while avoiding any
Expand All @@ -1230,14 +1233,16 @@ static double search_cu(
x > 0 ? LCU_GET_CU_AT_PX(lcu, SUB_SCU(x) - 1, SUB_SCU(y)) : NULL,
y > 0 ? LCU_GET_CU_AT_PX(lcu, SUB_SCU(x), SUB_SCU(y) - 1) : NULL,
0, depth, cu_width, x, y, tree_type,
& split_bits);
&bits);

cur_cu->intra = cu_d1->intra;
cur_cu->type = CU_INTRA;
cur_cu->part_size = SIZE_2Nx2N;

// Disable MRL in this case
cur_cu->intra.multi_ref_idx = 0;
cur_cu->lfnst_idx = 0;
cur_cu->cr_lfnst_idx = 0;

uvg_lcu_fill_trdepth(lcu, x, y, depth, cur_cu->tr_depth, tree_type);
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
Expand Down
Loading

0 comments on commit 98322c9

Please sign in to comment.