[mtt] Completely remove tr_depth

This commit is contained in:
Joose Sainio 2022-09-15 14:00:08 +03:00 committed by Marko Viitanen
parent 9a29d9ded3
commit b14f6f98ec
16 changed files with 42 additions and 171 deletions

View file

@ -80,7 +80,6 @@ int uvg_config_init(uvg_config *cfg)
cfg->trskip_max_size = 2; //Default to 4x4
cfg->mts = 0;
cfg->mts_implicit = 0;
cfg->tr_depth_intra = 0;
cfg->ime_algorithm = 0; /* hexbs */
cfg->fme_level = 4;
cfg->source_scan_type = 0; /* progressive */
@ -930,8 +929,6 @@ int uvg_config_parse(uvg_config *cfg, const char *name, const char *value)
cfg->mts = mts_type;
cfg->mts_implicit = (mts_type == UVG_MTS_IMPLICIT);
}
else if OPT("tr-depth-intra")
cfg->tr_depth_intra = atoi(value);
else if OPT("me") {
int8_t ime_algorithm = 0;
if (!parse_enum(value, me_names, &ime_algorithm)) return 0;
@ -1686,12 +1683,6 @@ int uvg_config_validate(const uvg_config *const cfg)
error = 1;
}
if (cfg->tr_depth_intra < 0 || cfg->tr_depth_intra > 4) {
// range is 0 .. CtbLog2SizeY - Log2MinTrafoSize
fprintf(stderr, "Input error: --tr-depth-intra is out of range [0..4]\n");
error = 1;
}
if (cfg->fme_level != 0 && cfg->fme_level > 4) {
fprintf(stderr, "Input error: invalid --subme parameter (must be in range 0-4)\n");
error = 1;

View file

@ -119,7 +119,6 @@ typedef struct
{
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 tr_depth : 3; //!< \brief transform depth
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 merge_idx : 3; //!< \brief merge index
@ -200,7 +199,7 @@ void uvg_cu_loc_ctor(cu_loc_t *loc, int x, int y, int width, int height);
} \
} while (0)
#define CHECKPOINT_CU(prefix_str, cu) CHECKPOINT(prefix_str " type=%d depth=%d part_size=%d tr_depth=%d coded=%d " \
#define CHECKPOINT_CU(prefix_str, cu) CHECKPOINT(prefix_str " type=%d depth=%d part_size=%d coded=%d " \
"skipped=%d merged=%d merge_idx=%d cbf.y=%d cbf.u=%d cbf.v=%d " \
"intra[0].cost=%u intra[0].bitcost=%u intra[0].mode=%d intra[0].mode_chroma=%d intra[0].tr_skip=%d " \
"intra[1].cost=%u intra[1].bitcost=%u intra[1].mode=%d intra[1].mode_chroma=%d intra[1].tr_skip=%d " \
@ -208,7 +207,7 @@ void uvg_cu_loc_ctor(cu_loc_t *loc, int x, int y, int width, int height);
"intra[3].cost=%u intra[3].bitcost=%u intra[3].mode=%d intra[3].mode_chroma=%d intra[3].tr_skip=%d " \
"inter.cost=%u inter.bitcost=%u inter.mv[0]=%d inter.mv[1]=%d inter.mvd[0]=%d inter.mvd[1]=%d " \
"inter.mv_cand=%d inter.mv_ref=%d inter.mv_dir=%d inter.mode=%d" \
, (cu).type, (cu).depth, (cu).part_size, (cu).tr_depth, (cu).coded, \
, (cu).type, (cu).depth, (cu).part_size, (cu).coded, \
(cu).skipped, (cu).merged, (cu).merge_idx, (cu).cbf.y, (cu).cbf.u, (cu).cbf.v, \
(cu).intra[0].cost, (cu).intra[0].bitcost, (cu).intra[0].mode, (cu).intra[0].mode_chroma, (cu).intra[0].tr_skip, \
(cu).intra[1].cost, (cu).intra[1].bitcost, (cu).intra[1].mode, (cu).intra[1].mode_chroma, (cu).intra[1].tr_skip, \

View file

@ -587,7 +587,6 @@ static void encode_transform_unit(
* \param x_pu Prediction units' x coordinate.
* \param y_pu Prediction units' y coordinate.
* \param depth Depth from LCU.
* \param tr_depth Depth from last CU.
* \param parent_coeff_u What was signaled at previous level for cbf_cb.
* \param parent_coeff_v What was signlaed at previous level for cbf_cr.
*/
@ -595,7 +594,6 @@ static void encode_transform_coeff(
encoder_state_t * const state,
const cu_loc_t * cu_loc,
int8_t depth,
int8_t tr_depth,
bool only_chroma,
lcu_coeff_t* coeff,
enum uvg_tree_type tree_type,
@ -626,45 +624,13 @@ static void encode_transform_coeff(
const int x_cu = 8 * (x / 8);
const int y_cu = 8 * (y / 8);
const cu_info_t *cur_cu = uvg_cu_array_at_const(used_array, x, y); // TODO: very suspect, chroma cbfs stored in upper left corner, everything else in bottom right for depth 4
// NxN signifies implicit transform split at the first transform level.
// There is a similar implicit split for inter, but it is only used when
// transform hierarchy is not in use.
//int intra_split_flag = (cur_cu->type == CU_INTRA && cur_cu->part_size == SIZE_NxN);
// The implicit split by intra NxN is not counted towards max_tr_depth.
/*
int max_tr_depth;
if (cur_cu->type == CU_INTRA) {
max_tr_depth = ctrl->cfg.tr_depth_intra + intra_split_flag;
} else {
max_tr_depth = ctrl->tr_depth_inter;
}
*/
int8_t split = (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH);
const int cb_flag_y = tree_type != UVG_CHROMA_T ? cbf_is_set(cur_pu->cbf, COLOR_Y) : 0;
const int cb_flag_u = tree_type != UVG_LUMA_T ?( cur_pu->joint_cb_cr ? (cur_pu->joint_cb_cr >> 1) & 1 : cbf_is_set(cur_cu->cbf, COLOR_U)) : 0;
const int cb_flag_v = tree_type != UVG_LUMA_T ? (cur_pu->joint_cb_cr ? cur_pu->joint_cb_cr & 1 : cbf_is_set(cur_cu->cbf, COLOR_V)) : 0;
// The split_transform_flag is not signaled when:
// - transform size is greater than 32 (depth == 0)
// - transform size is 4 (depth == MAX_PU_DEPTH)
// - transform depth is max
// - cu is intra NxN and it's the first split
//ToDo: check BMS transform split in QTBT
/*
if (depth > 0 &&
depth < MAX_PU_DEPTH &&
tr_depth < max_tr_depth &&
!(intra_split_flag && tr_depth == 0))
{
cabac->cur_ctx = &(cabac->ctx.trans_subdiv_model[5 - ((uvg_g_convert_to_bit[LCU_WIDTH] + 2) - depth)]);
CABAC_BIN(cabac, split, "split_transform_flag");
}
*/
if (split) {
int split_width = width >> 1;
@ -675,29 +641,20 @@ static void encode_transform_coeff(
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, only_chroma, coeff, tree_type, true, luma_cbf_ctx, &loc);
encode_transform_coeff(state, &loc, depth + 1, only_chroma, coeff, tree_type, true, luma_cbf_ctx, &loc);
}
}
return;
}
// Chroma cb flags are not signaled when one of the following:
// - transform size is 4 (2x2 chroma transform doesn't exist)
// - they have already been signaled to 0 previously
// When they are not present they are inferred to be 0, except for size 4
// when the flags from previous level are used.
// 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 && (depth != 4 || only_chroma) && tree_type != UVG_LUMA_T && last_split) {
if (!split) {
if (true) {
assert(tr_depth < 5);
cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_cb[0]);
CABAC_BIN(cabac, cb_flag_u, "cbf_cb");
}
if (true) {
cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_cr[cb_flag_u ? 1 : 0]);
CABAC_BIN(cabac, cb_flag_v, "cbf_cr");
}
}
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");
}
@ -717,13 +674,13 @@ static void encode_transform_coeff(
// - transform depth > 0
// - we have chroma coefficients at this level
// When it is not present, it is inferred to be 1.
if ((cur_cu->type == CU_INTRA || tr_depth > 0 || cb_flag_u || cb_flag_v) && !only_chroma && tree_type != UVG_CHROMA_T) {
if ((cur_cu->type == CU_INTRA || !PU_IS_TU(cur_cu) || cb_flag_u || cb_flag_v) && !only_chroma && tree_type != UVG_CHROMA_T) {
if (can_skip_last_cbf && isp_split && last_split) {
// Do not write luma cbf if first three isp splits have luma cbf 0
} else {
cabac->cur_ctx = &(cabac->ctx.qt_cbf_model_luma[*luma_cbf_ctx]);
CABAC_BIN(cabac, cb_flag_y, "cbf_luma");
if (tr_depth == 0) {
if (PU_IS_TU(cur_cu)) {
*luma_cbf_ctx = 2 + cb_flag_y;
}
}
@ -1620,7 +1577,7 @@ void uvg_encode_coding_tree(
// Code (possible) coeffs to bitstream
if (has_coeffs) {
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, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
}
encode_mts_idx(state, cabac, cur_cu, cu_loc);
@ -1654,7 +1611,7 @@ void uvg_encode_coding_tree(
// Check if last split to write chroma
bool last_split = (i + 1) == split_limit;
encode_transform_coeff(state, &split_loc, depth, 0, 0, coeff, tree_type, last_split, can_skip_last_cbf, &luma_cbf_ctx, cu_loc);
encode_transform_coeff(state, &split_loc, depth, 0, coeff, tree_type, last_split, can_skip_last_cbf, &luma_cbf_ctx, cu_loc);
can_skip_last_cbf &= luma_cbf_ctx == 2;
}
}
@ -1674,7 +1631,7 @@ void uvg_encode_coding_tree(
tmp->violates_lfnst_constrained_luma = false;
tmp->violates_lfnst_constrained_chroma = false;
tmp->lfnst_last_scan_pos = false;
encode_transform_coeff(state, &cu_loc, depth, 0, 1, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
encode_transform_coeff(state, cu_loc, depth, 1, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
// Write LFNST only once for single tree structure
encode_lfnst_idx(state, cabac, tmp, is_local_dual_tree ? UVG_CHROMA_T : tree_type, COLOR_UV, cu_loc);
}

View file

@ -378,11 +378,7 @@ encoder_control_t* uvg_encoder_control_init(const uvg_config *const cfg)
{
goto init_failed;
}
// NOTE: When tr_depth_inter is equal to 0, the transform is still split
// for SMP and AMP partition units.
encoder->tr_depth_inter = 0;
//Tiles
encoder->tiles_enable = encoder->cfg.tiles_width_count > 1 ||
encoder->cfg.tiles_height_count > 1;

View file

@ -132,8 +132,6 @@ typedef struct encoder_control_t
FILE *roi_file;
int tr_depth_inter;
//! pic_parameter_set
struct {
uint8_t dependent_slice_segments_enabled_flag;

View file

@ -660,10 +660,10 @@ static void set_cu_qps(encoder_state_t *state, const cu_loc_t* const cu_loc, int
int y_limit = cu_loc->y + cu_loc->height;
int x_limit = cu_loc->x + cu_loc->width;
if (cu->tr_depth > depth) {
if (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH) {
// The CU is split into smaller transform units. Check whether coded
// block flag is set for any of the TUs.
const int tu_width = LCU_WIDTH >> cu->tr_depth;
const int tu_width = MIN(TR_MAX_WIDTH, 1 << cu->log2_width);
for (int y_scu = cu_loc->y; !cbf_found && y_scu < y_limit; y_scu += tu_width) {
for (int x_scu = cu_loc->x; !cbf_found && x_scu < x_limit; x_scu += tu_width) {
cu_info_t *tu = uvg_cu_array_at(state->tile->frame->cu_array, x_scu, y_scu);

View file

@ -767,7 +767,6 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
}
else if (tu_boundary && nonzero_coeffs) {
// Non-zero residual/coeffs and transform boundary
// Neither CU is intra so tr_depth <= MAX_DEPTH.
strength = 1;
}
else if(cu_p->inter.mv_dir == 3 || cu_q->inter.mv_dir == 3 || state->frame->slicetype == UVG_SLICE_B) { // B-slice related checks. TODO: Need to account for cu_p being in another slice?

View file

@ -1553,7 +1553,7 @@ void uvg_intra_predict(
}
else {
uvg_pixels_blit(&state->tile->frame->cclm_luma_rec[x / 2 + (y * stride) / 4], dst, width, width, stride / 2, width);
if (data->pred_cu.depth != data->pred_cu.tr_depth || data->cclm_parameters[color == COLOR_U ? 0 : 1].b <= 0) {
if (!PU_IS_TU(&data->pred_cu) || data->cclm_parameters[color == COLOR_U ? 0 : 1].b <= 0) {
predict_cclm(
state, color, width, height, x, y, stride, intra_mode, lcu, refs, dst,
(cclm_parameters_t*)&data->cclm_parameters[color == COLOR_U ? 0 : 1],

View file

@ -158,25 +158,6 @@ static void work_tree_copy_down(
}
}
void uvg_lcu_fill_trdepth(
lcu_t *lcu,
const cu_loc_t* const cu_loc,
uint8_t tr_depth,
enum uvg_tree_type
tree_type)
{
const int x_local = cu_loc->local_x >> (tree_type == UVG_CHROMA_T);
const int y_local = cu_loc->local_y >> (tree_type == UVG_CHROMA_T);
const unsigned width = tree_type != UVG_CHROMA_T ? cu_loc->width : cu_loc->chroma_width;
const unsigned height = tree_type != UVG_CHROMA_T ? cu_loc->height : cu_loc->chroma_height;
for (unsigned y = 0; y < height; y += SCU_WIDTH) {
for (unsigned x = 0; x < width; x += SCU_WIDTH) {
LCU_GET_CU_AT_PX(lcu, x_local + x, y_local + y)->tr_depth = tr_depth;
}
}
}
static void lcu_fill_cu_info(lcu_t *lcu, int x_local, int y_local, int width, int height, const cu_info_t *cu)
{
// Set mode in every CU covered by part_mode in this depth.
@ -216,8 +197,7 @@ static void lcu_fill_cu_info(lcu_t *lcu, int x_local, int y_local, int width, in
static void lcu_fill_cbf(lcu_t *lcu, int x_local, unsigned y_local, unsigned width, const cu_info_t *cur_cu)
{
const uint32_t tr_split = cur_cu->tr_depth - cur_cu->depth;
const uint32_t mask = ~((width >> tr_split)-1);
const uint32_t mask = ~((MIN(width, TR_MAX_WIDTH))-1);
// Set coeff flags in every CU covered by part_mode in this depth.
for (uint32_t y = y_local; y < y_local + width; y += SCU_WIDTH) {
@ -360,10 +340,9 @@ double uvg_cu_rd_cost_luma(
// Add transform_tree cbf_luma bit cost.
if (pred_cu->type == CU_INTER || pred_cu->intra.isp_mode == ISP_MODE_NO_ISP) {
const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int is_tr_split = tr_cu->tr_depth - tr_cu->depth;
int is_set = cbf_is_set(pred_cu->cbf, COLOR_Y);
if (pred_cu->type == CU_INTRA ||
is_tr_split ||
!PU_IS_TU(pred_cu) ||
cbf_is_set(tr_cu->cbf, COLOR_U) ||
cbf_is_set(tr_cu->cbf, COLOR_V))
{
@ -482,13 +461,11 @@ double uvg_cu_rd_cost_chroma(
cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac;
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, COLOR_U)) {
CABAC_FBITS_UPDATE(cabac, ctx, u_is_set, tr_tree_bits, "cbf_cb_search");
}
CABAC_FBITS_UPDATE(cabac, ctx, u_is_set, tr_tree_bits, "cbf_cb_search");
ctx = &(cabac->ctx.qt_cbf_model_cr[u_is_set]);
if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, COLOR_V)) {
CABAC_FBITS_UPDATE(cabac, ctx, v_is_set, tr_tree_bits, "cbf_cb_search");
}
CABAC_FBITS_UPDATE(cabac, ctx, v_is_set, tr_tree_bits, "cbf_cb_search");
}
@ -969,7 +946,6 @@ static double search_cu(
cur_cu = LCU_GET_CU_AT_PX(lcu, x_local, y_local);
// Assign correct depth
cur_cu->depth = (split_tree.current_depth > MAX_DEPTH) ? MAX_DEPTH : split_tree.current_depth;
cur_cu->tr_depth = cu_width > TR_MAX_WIDTH || cu_height > TR_MAX_WIDTH ? 1 : split_tree.current_depth;
cur_cu->type = CU_NOTSET;
cur_cu->qp = state->qp;
cur_cu->bdpcmMode = 0;
@ -1112,9 +1088,6 @@ static double search_cu(
intra_search.pred_cu.intra.mode_chroma = intra_mode;
}
intra_search.pred_cu.intra.mode = intra_mode;
if(tree_type == UVG_CHROMA_T) {
uvg_lcu_fill_trdepth(lcu, cu_loc, split_tree.current_depth, tree_type);
}
}
if (intra_cost < cost) {
cost = intra_cost;
@ -1216,11 +1189,6 @@ static double search_cu(
if (cur_cu->inter.mv_dir & 1) uvg_round_precision(INTERNAL_MV_PREC, 2, &cur_cu->inter.mv[0][0], &cur_cu->inter.mv[0][1]);
if (cur_cu->inter.mv_dir & 2) uvg_round_precision(INTERNAL_MV_PREC, 2, &cur_cu->inter.mv[1][0], &cur_cu->inter.mv[1][1]);
}
// Reset transform depth because intra messes with them.
// This will no longer be necessary if the transform depths are not shared.
int tr_depth = MAX(1, split_tree.current_depth);
uvg_lcu_fill_trdepth(lcu, cu_loc, tr_depth, tree_type);
const bool has_chroma = state->encoder_control->chroma_format != UVG_CSP_400;
uvg_inter_recon_cu(state, lcu, true, has_chroma, cu_loc);
@ -1296,12 +1264,6 @@ static double search_cu(
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
}
if (cur_cu->tr_depth != 0) {
// Reset transform depth since there are no coefficients. This
// ensures that CBF is cleared for the whole area of the CU.
uvg_lcu_fill_trdepth(lcu, cu_loc, depth, tree_type);
}
cur_cu->cbf = 0;
lcu_fill_cbf(lcu, x_local, y_local, cu_width, cur_cu);
}
@ -1430,8 +1392,7 @@ static double search_cu(
cur_cu->intra.multi_ref_idx = 0;
cur_cu->lfnst_idx = 0;
cur_cu->cr_lfnst_idx = 0;
uvg_lcu_fill_trdepth(lcu, cu_loc, cur_cu->tr_depth, tree_type);
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
intra_search_data_t proxy;

View file

@ -96,13 +96,6 @@ double uvg_cu_rd_cost_chroma(
lcu_t *const lcu,
const cu_loc_t * const);
void uvg_lcu_fill_trdepth(
lcu_t *lcu,
const cu_loc_t* const cu_loc,
uint8_t tr_depth,
enum uvg_tree_type
tree_type);
void uvg_intra_recon_lcu_luma(encoder_state_t * const state, int x, int y, int depth, int8_t intra_mode, cu_info_t *cur_cu, lcu_t *lcu);
void uvg_intra_recon_lcu_chroma(encoder_state_t * const state, int x, int y, int depth, int8_t intra_mode, cu_info_t *cur_cu, lcu_t *lcu);

View file

@ -1811,7 +1811,6 @@ static void search_pu_inter(
cur_pu->inter.mv[0][1] = info->merge_cand[merge_idx].mv[0][1];
cur_pu->inter.mv[1][0] = info->merge_cand[merge_idx].mv[1][0];
cur_pu->inter.mv[1][1] = info->merge_cand[merge_idx].mv[1][1];
uvg_lcu_fill_trdepth(lcu, cu_loc, MAX(1, depth), UVG_BOTH_T);
uvg_inter_recon_cu(state, lcu, true, false, cu_loc);
uvg_quantize_lcu_residual(state, true, false, false, cu_loc, depth, cur_pu, lcu, true, UVG_BOTH_T);
@ -2127,9 +2126,6 @@ void uvg_cu_cost_inter_rd2(
const cu_loc_t* const cu_loc){
const uint8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
int tr_depth = MAX(1, depth);
uvg_lcu_fill_trdepth(lcu, cu_loc, tr_depth, UVG_BOTH_T);
const int x_px = SUB_SCU(cu_loc->x);
const int y_px = SUB_SCU(cu_loc->y);
@ -2179,7 +2175,7 @@ void uvg_cu_cost_inter_rd2(
state->encoder_control->cfg.chroma_trskip_enable;
double chroma_cost = 0;
if((state->encoder_control->cfg.jccr || can_use_chroma_tr_skip) && cur_cu->depth == cur_cu->tr_depth && reconstruct_chroma) {
if((state->encoder_control->cfg.jccr || can_use_chroma_tr_skip) && PU_IS_TU(cur_cu) && reconstruct_chroma) {
uvg_quantize_lcu_residual(state,
true,
false,
@ -2262,7 +2258,7 @@ void uvg_cu_cost_inter_rd2(
if(cbf) {
*inter_cost = uvg_cu_rd_cost_luma(state, cu_loc, cur_cu, lcu, 0);
if (reconstruct_chroma) {
if (cur_cu->depth != cur_cu->tr_depth || !state->encoder_control->cfg.jccr) {
if (!PU_IS_TU(cur_cu) || !state->encoder_control->cfg.jccr) {
*inter_cost += uvg_cu_rd_cost_chroma(state, cur_cu, lcu, cu_loc);
}
else {

View file

@ -266,7 +266,6 @@ static void derive_mts_constraints(cu_info_t *const pred_cu,
static double search_intra_trdepth(
encoder_state_t * const state,
const cu_loc_t* const cu_loc,
int max_depth,
double cost_treshold,
intra_search_data_t *const search_data,
lcu_t *const lcu,
@ -296,8 +295,6 @@ static double search_intra_trdepth(
double nosplit_cost = INT32_MAX;
if (width <= TR_MAX_WIDTH && height <= TR_MAX_WIDTH) {
tr_cu->tr_depth = depth;
pred_cu->tr_depth = depth;
const bool mts_enabled = (state->encoder_control->cfg.mts == UVG_MTS_INTRA || state->encoder_control->cfg.mts == UVG_MTS_BOTH)
&& PU_IS_TU(pred_cu);
@ -575,7 +572,7 @@ static double search_intra_trdepth(
// - Maximum transform hierarchy depth is constrained by clipping
// max_depth.
// - Min transform size hasn't been reached (MAX_PU_DEPTH).
if (depth < max_depth && depth < MAX_PU_DEPTH) {
else {
cu_loc_t split_cu_loc;
const int half_width = width / 2;
@ -583,28 +580,24 @@ static double search_intra_trdepth(
split_cost = 0;
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);
split_cost += search_intra_trdepth(state, &split_cu_loc, nosplit_cost, search_data, lcu, tree_type);
if (split_cost < nosplit_cost) {
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);
split_cost += search_intra_trdepth(state, &split_cu_loc, nosplit_cost, search_data, lcu, tree_type);
}
if (split_cost < nosplit_cost) {
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);
split_cost += search_intra_trdepth(state, &split_cu_loc, nosplit_cost, search_data, lcu, tree_type);
}
if (split_cost < nosplit_cost) {
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);
split_cost += search_intra_trdepth(state, &split_cu_loc, nosplit_cost, search_data, lcu, tree_type);
}
} else {
assert(width <= TR_MAX_WIDTH);
}
if (depth == 0 || split_cost < nosplit_cost) {
return split_cost;
} else {
uvg_lcu_fill_trdepth(lcu, cu_loc, depth, tree_type);
return nosplit_cost;
}
}
@ -1314,7 +1307,6 @@ static int8_t search_intra_rdo(
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 width = cu_loc->width;
const int height = cu_loc->height; // TODO: height for non-square blocks
@ -1338,7 +1330,7 @@ static int8_t search_intra_rdo(
search_data[mode].bits = rdo_bitcost;
search_data[mode].cost = rdo_bitcost * state->lambda;
double mode_cost = search_intra_trdepth(state, cu_loc, tr_depth, MAX_INT, &search_data[mode], lcu, tree_type);
double mode_cost = search_intra_trdepth(state, cu_loc, MAX_INT, &search_data[mode], lcu, tree_type);
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;
search_data[mode].cost += mode_cost;
@ -1492,7 +1484,7 @@ int8_t uvg_search_intra_chroma_rdo(
}
pred_cu->cr_lfnst_idx = lfnst;
chroma_data[mode_i].lfnst_costs[lfnst] += mode_bits * state->lambda;
if (pred_cu->tr_depth == pred_cu->depth) {
if (PU_IS_TU(pred_cu)) {
uvg_intra_predict(
state,
&refs[COLOR_U - 1],
@ -1898,12 +1890,6 @@ void uvg_search_cu_intra(
number_of_modes += num_mip_modes;
}
// Set transform depth to current depth, meaning no transform splits.
{
const int8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
uvg_lcu_fill_trdepth(lcu, cu_loc, depth, tree_type);
}
// Refine results with slower search or get some results if rough search was skipped.
const int32_t rdo_level = state->encoder_control->cfg.rdo;
if (rdo_level >= 2 || skip_rough_search) {

View file

@ -707,7 +707,6 @@ int uvg_quantize_residual_avx2(encoder_state_t *const state,
if (state->encoder_control->cfg.rdoq_enable &&
(width > 4 || !state->encoder_control->cfg.rdoq_skip) && !use_trskip)
{
int8_t tr_depth = cur_cu->tr_depth - cur_cu->depth;
uvg_rdoq(state, coeff, coeff_out, width, height, color,
scan_order, cur_cu->type, cur_cu->cbf, lfnst_index);
}

View file

@ -315,7 +315,6 @@ int uvg_quant_cbcr_residual_generic(
if (state->encoder_control->cfg.rdoq_enable &&
(width > 4 || !state->encoder_control->cfg.rdoq_skip))
{
int8_t tr_depth = cur_cu->tr_depth - cur_cu->depth;
uvg_rdoq(state, coeff, coeff_out, width, width, cur_cu->joint_cb_cr == 1 ? COLOR_V : COLOR_U,
scan_order, cur_cu->type, cur_cu->cbf, cur_cu->cr_lfnst_idx);
}
@ -496,7 +495,6 @@ int uvg_quantize_residual_generic(encoder_state_t *const state,
if (state->encoder_control->cfg.rdoq_enable &&
(width > 4 || !state->encoder_control->cfg.rdoq_skip) && !use_trskip)
{
int8_t tr_depth = cur_cu->tr_depth - cur_cu->depth;
uvg_rdoq(state, coeff, coeff_out, width, height, color,
scan_order, cur_cu->type, cur_cu->cbf, lfnst_index);
} else if(state->encoder_control->cfg.rdoq_enable && use_trskip) {

View file

@ -1393,7 +1393,7 @@ void uvg_quantize_lcu_residual(
cbf_clear(&cur_pu->cbf, COLOR_V);
}
if (depth == 0 || cur_pu->tr_depth > depth) {
if (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH) {
// Split transform and increase depth
const int offset = width / 2;
@ -1420,13 +1420,12 @@ void uvg_quantize_lcu_residual(
LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y + offset)->cbf,
LCU_GET_CU_AT_PX(lcu, lcu_px.x + offset, lcu_px.y + offset)->cbf,
};
if (depth <= MAX_DEPTH) {
cur_pu->root_cbf = cbf_is_set_any(cur_pu->cbf)
cur_pu->root_cbf = cbf_is_set_any(cur_pu->cbf)
|| cbf_is_set_any(child_cbfs[0])
|| cbf_is_set_any(child_cbfs[1])
|| cbf_is_set_any(child_cbfs[2]);
}
} else {
// Process a leaf TU.
@ -1440,10 +1439,10 @@ void uvg_quantize_lcu_residual(
quantize_tr_residual(state, COLOR_U, &loc, depth, cur_pu, lcu, early_skip, tree_type);
quantize_tr_residual(state, COLOR_V, &loc, depth, cur_pu, lcu, early_skip, tree_type);
}
if (jccr && cur_pu->tr_depth == cur_pu->depth) {
if (jccr && PU_IS_TU(cur_pu)) {
quantize_tr_residual(state, COLOR_UV, &loc, depth, cur_pu, lcu, early_skip, tree_type);
}
if(chroma && jccr && cur_pu->tr_depth == cur_pu->depth) {
if(chroma && jccr && PU_IS_TU(cur_pu)) {
assert( 0 && "Trying to quantize both jccr and regular at the same time.\n");
}
}

View file

@ -338,7 +338,6 @@ typedef struct uvg_config
int32_t trskip_max_size; /*!< \brief Transform skip max block size. */
enum uvg_mts mts; /*< \brief flag to enable multiple transform selection*/
int32_t mts_implicit; /*< \brief flag to enable implicit multiple transform selection*/
int32_t tr_depth_intra; /*!< \brief Maximum transform depth for intra. */
enum uvg_ime_algorithm ime_algorithm; /*!< \brief Integer motion estimation algorithm. */
int32_t fme_level; /*!< \brief Fractional pixel motion estimation level (0: disabled, 1: enabled). */
int8_t source_scan_type; /*!< \brief Source scan type (0: progressive, 1: top field first, 2: bottom field first).*/