diff --git a/src/encode_coding_tree.c b/src/encode_coding_tree.c index c908449d..2790932f 100644 --- a/src/encode_coding_tree.c +++ b/src/encode_coding_tree.c @@ -129,8 +129,7 @@ bool uvg_is_lfnst_allowed( } bool luma_flag = tree_type != UVG_CHROMA_T; bool chroma_flag = tree_type != UVG_LUMA_T; - bool non_zero_coeff_non_ts_corner_8x8 = false; - bool last_scan_pos = false; + bool non_zero_coeff_non_ts_corner_8x8 = (luma_flag && pred_cu->violates_lfnst_constrained_luma) || (chroma_flag && pred_cu->violates_lfnst_constrained_chroma); bool is_tr_skip = false; if (color == COLOR_Y && pred_cu->tr_idx == MTS_SKIP) { @@ -177,10 +176,10 @@ static bool encode_lfnst_idx( return true; } else { - if(depth != 4 || color == COLOR_Y) { + if(color == COLOR_Y) { assert(pred_cu->lfnst_idx == 0); } - if(depth == 4 && color != COLOR_Y) { + if(tree_type == UVG_CHROMA_T && color != COLOR_Y) { assert(pred_cu->cr_lfnst_idx == 0); } return false; @@ -612,7 +611,8 @@ static void encode_transform_coeff( cabac_data_t * const cabac = &state->cabac; bool isp_split = cu_loc->x != original_loc->x || cu_loc->y != original_loc->y; - + int x = cu_loc->x; + int y = cu_loc->y; if (isp_split) { uvg_get_isp_cu_arr_coords(&x, &y); } @@ -621,7 +621,7 @@ static void encode_transform_coeff( 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; if(cur_tu == NULL) { - cur_tu = uvg_cu_array_at_const(used_array, cu_loc->x, cu_loc->y); + cur_tu = uvg_cu_array_at_const(used_array, x, y); } const bool ver_split = cu_loc->height > TR_MAX_WIDTH; @@ -647,36 +647,25 @@ static void encode_transform_coeff( cu_loc_t split_cu_loc[4]; const int split_count = uvg_get_split_locs(cu_loc, split, split_cu_loc,NULL); for (int i = 0; i < split_count; ++i) { - encode_transform_coeff(state, &split_cu_loc[i], only_chroma, coeff, NULL, tree_type, true, luma_cbf_ctx, &split_cu_loc[i]); + encode_transform_coeff(state, &split_cu_loc[i], only_chroma, coeff, NULL, tree_type, true, false, luma_cbf_ctx, &split_cu_loc[i]); } return; } + + // Chroma cb flags are not signaled when one of the following: // No chroma. // Not the last CU for area of 64 pixels cowered by more than one luma CU. // Not the last ISP Split - if (state->encoder_control->chroma_format != UVG_CSP_400 + if (state->encoder_control->chroma_format != UVG_CSP_400 && (cur_tu->log2_height + cur_tu->log2_width >= 6 || only_chroma) - && tree_type != UVG_LUMA_T + && tree_type != UVG_LUMA_T && last_split) { cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_cb[0]); CABAC_BIN(cabac, cb_flag_u, "cbf_cb"); cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_cr[cb_flag_u ? 1 : 0]); - CABAC_BIN(cabac, cb_flag_v, "cbf_cr"); + CABAC_BIN(cabac, cb_flag_v, "cbf_cr"); } - - - for (int j = 0; j < 2; j++) { - for (int i = 0; i < 2; i++) { - cu_loc_t loc; - uvg_cu_loc_ctor(&loc, (x + i * split_width), (y + j * split_height), width >> 1, height >> 1); - - encode_transform_coeff(state, &loc, depth + 1, tr_depth + 1, cb_flag_u, cb_flag_v, only_chroma, coeff, tree_type, true, false, luma_cbf_ctx, &loc); - } - } - return; - } - // Luma coded block flag is signaled when one of the following: // - prediction mode is intra // - transform depth > 0 @@ -1417,7 +1406,7 @@ void uvg_encode_coding_tree( const int splits = uvg_get_split_locs(cu_loc, split_flag, new_cu_loc, &separate_chroma); for (int split = 0; split encoder_control->chroma_format != UVG_CSP_400 && - (has_chroma || tree_type == UVG_CHROMA_T) && + if (state->encoder_control->chroma_format != UVG_CSP_400 && + (((chroma_loc->width != cu_loc->width || chroma_loc->height != cu_loc->height)&& + has_chroma) || tree_type == UVG_CHROMA_T) && tree_type != UVG_LUMA_T) { encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm, NULL); // LFNST constraints must be reset here. Otherwise the left over values will interfere when calculating new constraints diff --git a/src/intra.c b/src/intra.c index 5db5abe5..bb696c0c 100644 --- a/src/intra.c +++ b/src/intra.c @@ -957,7 +957,7 @@ static void intra_predict_regular( // Wide angle correction int8_t pred_mode = uvg_wide_angle_correction(mode, - is_isp, + isp_mode, log2_width, log2_height, false); @@ -1859,15 +1859,15 @@ void uvg_intra_recon_cu( for (int i = 0; i < split_limit; ++i) { cu_loc_t tu_loc; - uvg_get_isp_split_loc(&tu_loc, x, y, width, height, i, split_type, true); + uvg_get_isp_split_loc(&tu_loc, cu_loc->x, cu_loc->y, width, height, i, split_type, true); cu_loc_t pu_loc; - uvg_get_isp_split_loc(&pu_loc, x, y, width, height, i, split_type, false); + uvg_get_isp_split_loc(&pu_loc, cu_loc->x, cu_loc->y, width, height, i, split_type, false); if(tu_loc.x % 4 == 0) { - intra_recon_tb_leaf(state, &pu_loc, &origin_cu, lcu, COLOR_Y, search_data, tree_type); + intra_recon_tb_leaf(state, &pu_loc, cu_loc, lcu, COLOR_Y, search_data, tree_type); } uvg_quantize_lcu_residual(state, true, false, false, - &tu_loc, depth, cur_cu, lcu, + &tu_loc, cur_cu, lcu, false, tree_type); search_data->best_isp_cbfs |= cbf_is_set(cur_cu->cbf, COLOR_Y) << i; } diff --git a/src/search.c b/src/search.c index e11d6d15..58c190d0 100644 --- a/src/search.c +++ b/src/search.c @@ -423,9 +423,9 @@ double uvg_cu_rd_cost_luma( } else { // TODO: 8x4 CUs - const int split_limit = uvg_get_isp_split_num(width, height, pred_cu->intra.isp_mode, true); + const int split_limit = uvg_get_isp_split_num(cu_loc->width, cu_loc->height, pred_cu->intra.isp_mode, true); + int luma_ctx = 2; for (int i = 0; i < split_limit; i++) { - int luma_ctx = 2; if (i != 3 && isp_cbf != 0x8) { const int flag = (isp_cbf >> i) & 1; CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.qt_cbf_model_luma[luma_ctx]), flag, tr_tree_bits, "cbf_y_search"); @@ -1338,7 +1338,7 @@ static double search_cu( // Recursively split all the way to max search depth. if (can_split_cu) { - const int split_type = depth == 2 ? TT_HOR_SPLIT : QT_SPLIT; + const int split_type = depth == 2 ? BT_HOR_SPLIT : QT_SPLIT; const split_tree_t new_split = { split_tree.split_tree | split_type << (split_tree.current_depth * 3), split_tree.current_depth + 1, @@ -1402,7 +1402,7 @@ static double search_cu( initialize_partial_work_tree(lcu, &split_lcu, cu_loc, tree_type); for (int split = 0; split < splits; ++split) { split_cost += search_cu(state, - &new_cu_loc[split], separate_chroma ? cu_loc : &new_cu_loc[split], + &new_cu_loc[split], separate_chroma ? chroma_loc : &new_cu_loc[split], &split_lcu, tree_type, new_split, !separate_chroma || split == splits - 1); diff --git a/src/strategies/generic/intra-generic.c b/src/strategies/generic/intra-generic.c index 01364ab1..9a3cbe26 100644 --- a/src/strategies/generic/intra-generic.c +++ b/src/strategies/generic/intra-generic.c @@ -192,7 +192,7 @@ static void uvg_angular_pred_generic( if (sample_disp != 0) { // The mode is not horizontal or vertical, we have to do interpolation. - for (int_fast32_t y = 0, delta_pos = sample_disp * (1 + multi_ref_index); y < tmp_height; ++y, delta_pos += sample_disp) { + for (int_fast32_t y = 0, delta_pos = sample_disp * (1 + multi_ref_index); y < height; ++y, delta_pos += sample_disp) { int_fast32_t delta_int = delta_pos >> 5; int_fast32_t delta_fract = delta_pos & (32 - 1); @@ -219,7 +219,7 @@ static void uvg_angular_pred_generic( const int16_t filter_coeff[4] = { 16 - (delta_fract >> 1), 32 - (delta_fract >> 1), 16 + (delta_fract >> 1), delta_fract >> 1 }; int16_t const * const f = use_cubic ? cubic_filter[delta_fract] : filter_coeff; // Do 4-tap intra interpolation filtering - for (int_fast32_t x = 0; x < tmp_width; x++, ref_main_index++) { + for (int_fast32_t x = 0; x < width; x++, ref_main_index++) { p[0] = ref_main[ref_main_index]; p[1] = ref_main[ref_main_index + 1]; p[2] = ref_main[ref_main_index + 2]; @@ -232,7 +232,7 @@ static void uvg_angular_pred_generic( else { // Do linear filtering - for (int_fast32_t x = 0; x < tmp_width; ++x) { + for (int_fast32_t x = 0; x < width; ++x) { uvg_pixel ref1 = ref_main[x + delta_int + 1]; uvg_pixel ref2 = ref_main[x + delta_int + 2]; work[y * width + x] = ref1 + ((delta_fract * (ref2-ref1) + 16) >> 5); @@ -248,7 +248,7 @@ static void uvg_angular_pred_generic( // PDPC - bool PDPC_filter = ((tmp_width >= TR_MIN_WIDTH && tmp_height >= TR_MIN_WIDTH) || channel_type != 0) && multi_ref_index == 0; + bool PDPC_filter = ((width >= TR_MIN_WIDTH && height >= TR_MIN_WIDTH) || channel_type != 0) && multi_ref_index == 0; if (pred_mode > 1 && pred_mode < 67) { if (mode_disp < 0 || multi_ref_index) { // Cannot be used with MRL. PDPC_filter = false; @@ -259,7 +259,7 @@ static void uvg_angular_pred_generic( } if(PDPC_filter) { int inv_angle_sum = 256; - for (int x = 0; x < MIN(3 << scale, tmp_width); x++) { + for (int x = 0; x < MIN(3 << scale, width); x++) { inv_angle_sum += modedisp2invsampledisp[abs(mode_disp)]; int wL = 32 >> (2 * x >> scale); @@ -274,7 +274,7 @@ static void uvg_angular_pred_generic( // Do not apply PDPC if multi ref line index is other than 0 // TODO: do not do PDPC if block is in BDPCM mode - bool do_pdpc = (((tmp_width >= 4 && tmp_height >= 4) || channel_type != 0) && sample_disp >= 0 && multi_ref_index == 0 /*&& !bdpcm*/); + bool do_pdpc = (((width >= 4 && height >= 4) || channel_type != 0) && sample_disp >= 0 && multi_ref_index == 0 /*&& !bdpcm*/); if (do_pdpc) { int scale = (log2_width + log2_height - 2) >> 2; @@ -282,7 +282,7 @@ static void uvg_angular_pred_generic( for (int_fast32_t y = 0; y < height; ++y) { memcpy(&work[y * width], &ref_main[1], width * sizeof(uvg_pixel)); const uvg_pixel left = ref_side[1 + y]; - for (int_fast32_t x = 0; x < MIN(3 << scale, tmp_width); ++x) { + for (int_fast32_t x = 0; x < MIN(3 << scale, width); ++x) { const int wL = 32 >> (2 * x >> scale); const uvg_pixel val = work[y * width + x]; work[y * width + x] = CLIP_TO_PIXEL(val + ((wL * (left - top_left) + 32) >> 6));