mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
[mtt] search with mtt depth 2 and dual tree works without lfnst
This commit is contained in:
parent
fb146cb6ed
commit
9e644fafd0
|
@ -227,7 +227,7 @@ int uvg_config_init(uvg_config *cfg)
|
||||||
cfg->min_qt_size[1] = 4;
|
cfg->min_qt_size[1] = 4;
|
||||||
cfg->min_qt_size[2] = 4;
|
cfg->min_qt_size[2] = 4;
|
||||||
|
|
||||||
cfg->max_btt_depth[0] = 1;
|
cfg->max_btt_depth[0] = 2;
|
||||||
cfg->max_btt_depth[1] = 0;
|
cfg->max_btt_depth[1] = 0;
|
||||||
cfg->max_btt_depth[2] = 1;
|
cfg->max_btt_depth[2] = 1;
|
||||||
|
|
||||||
|
|
6
src/cu.c
6
src/cu.c
|
@ -400,7 +400,7 @@ int uvg_get_possible_splits(const encoder_state_t * const state,
|
||||||
bool can_btt = split_tree.mtt_depth < max_btd;
|
bool can_btt = split_tree.mtt_depth < max_btd;
|
||||||
|
|
||||||
const enum split_type last_split = (split_tree.split_tree >> (split_tree.current_depth * 3 - 3)) & 7;
|
const enum split_type last_split = (split_tree.split_tree >> (split_tree.current_depth * 3 - 3)) & 7;
|
||||||
const enum split_type parl_split = last_split == BT_HOR_SPLIT ? BT_HOR_SPLIT : BT_VER_SPLIT;
|
const enum split_type parl_split = last_split == TT_HOR_SPLIT ? BT_HOR_SPLIT : BT_VER_SPLIT;
|
||||||
|
|
||||||
// don't allow QT-splitting below a BT split
|
// don't allow QT-splitting below a BT split
|
||||||
if (split_tree.current_depth != 0 && last_split != QT_SPLIT /* && !(width > 64 || height > 64)*/) splits[QT_SPLIT] = false;
|
if (split_tree.current_depth != 0 && last_split != QT_SPLIT /* && !(width > 64 || height > 64)*/) splits[QT_SPLIT] = false;
|
||||||
|
@ -459,12 +459,12 @@ int uvg_get_possible_splits(const encoder_state_t * const state,
|
||||||
|
|
||||||
//if (modeType == MODE_TYPE_INTER && width * height == 32) splits[BT_VER_SPLIT] = splits[BT_HOR_SPLIT] = false;
|
//if (modeType == MODE_TYPE_INTER && width * height == 32) splits[BT_VER_SPLIT] = splits[BT_HOR_SPLIT] = false;
|
||||||
|
|
||||||
if (height <= 2 * min_tt_size || height > max_tt_size || width > max_tt_size)
|
if (cu_loc->chroma_height <= min_tt_size || height > max_tt_size || width > max_tt_size)
|
||||||
splits[TT_HOR_SPLIT] = false;
|
splits[TT_HOR_SPLIT] = false;
|
||||||
if (width > 64 || height > 64) splits[TT_HOR_SPLIT] = false;
|
if (width > 64 || height > 64) splits[TT_HOR_SPLIT] = false;
|
||||||
if (tree_type == UVG_CHROMA_T && width * height <= 16 * 2) splits[TT_HOR_SPLIT] = false;
|
if (tree_type == UVG_CHROMA_T && width * height <= 16 * 2) splits[TT_HOR_SPLIT] = false;
|
||||||
|
|
||||||
if (width <= 2 * min_tt_size || width > max_tt_size || height > max_tt_size)
|
if (cu_loc->chroma_width <= min_tt_size || width > max_tt_size || height > max_tt_size)
|
||||||
splits[TT_VER_SPLIT] = false;
|
splits[TT_VER_SPLIT] = false;
|
||||||
if (width > 64 || height > 64) splits[TT_VER_SPLIT] = false;
|
if (width > 64 || height > 64) splits[TT_VER_SPLIT] = false;
|
||||||
if (tree_type == UVG_CHROMA_T && (width * height <= 16 * 2 || width == 8)) splits[TT_VER_SPLIT] = false;
|
if (tree_type == UVG_CHROMA_T && (width * height <= 16 * 2 || width == 8)) splits[TT_VER_SPLIT] = false;
|
||||||
|
|
2
src/cu.h
2
src/cu.h
|
@ -607,7 +607,7 @@ static INLINE void cbf_copy(uint16_t *cbf, uint16_t src, color_t plane)
|
||||||
*cbf |= src & (1 << plane);
|
*cbf |= src & (1 << plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_SPLITDATA(CU,curDepth) (((CU)->split_tree >> (curDepth)) & 7)
|
#define GET_SPLITDATA(CU,curDepth) (((CU)->split_tree >> ((curDepth) * 3)) & 7)
|
||||||
#define PU_IS_TU(cu) ((cu)->log2_width <= TR_MAX_LOG2_SIZE && (cu)->log2_height <= TR_MAX_LOG2_SIZE)
|
#define PU_IS_TU(cu) ((cu)->log2_width <= TR_MAX_LOG2_SIZE && (cu)->log2_height <= TR_MAX_LOG2_SIZE)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -563,6 +563,7 @@ static void encode_transform_unit(
|
||||||
(cu_info_t * )cur_pu,
|
(cu_info_t * )cur_pu,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
if (tree_type == UVG_LUMA_T) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool joint_chroma = cur_pu->joint_cb_cr != 0;
|
bool joint_chroma = cur_pu->joint_cb_cr != 0;
|
||||||
|
@ -627,8 +628,9 @@ static void encode_transform_coeff(
|
||||||
cur_tu = uvg_cu_array_at_const(used_array, x, y);
|
cur_tu = uvg_cu_array_at_const(used_array, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool ver_split = cu_loc->height > TR_MAX_WIDTH;
|
const int tr_limit = (TR_MAX_WIDTH >> (tree_type == UVG_CHROMA_T));
|
||||||
const bool hor_split = cu_loc->width > TR_MAX_WIDTH;
|
const bool ver_split = cu_loc->height > tr_limit;
|
||||||
|
const bool hor_split = cu_loc->width > tr_limit;
|
||||||
|
|
||||||
const int cb_flag_y = tree_type != UVG_CHROMA_T ? cbf_is_set(cur_tu->cbf, COLOR_Y) : 0;
|
const int cb_flag_y = tree_type != UVG_CHROMA_T ? cbf_is_set(cur_tu->cbf, COLOR_Y) : 0;
|
||||||
const int cb_flag_u = tree_type != UVG_LUMA_T ?(cur_tu->joint_cb_cr ? (cur_tu->joint_cb_cr >> 1) & 1 : cbf_is_set(cur_tu->cbf, COLOR_U)) : 0;
|
const int cb_flag_u = tree_type != UVG_LUMA_T ?(cur_tu->joint_cb_cr ? (cur_tu->joint_cb_cr >> 1) & 1 : cbf_is_set(cur_tu->cbf, COLOR_U)) : 0;
|
||||||
|
@ -637,10 +639,10 @@ static void encode_transform_coeff(
|
||||||
|
|
||||||
if (hor_split || ver_split) {
|
if (hor_split || ver_split) {
|
||||||
enum split_type split;
|
enum split_type split;
|
||||||
if (cu_loc->width > TR_MAX_WIDTH && cu_loc->height > TR_MAX_WIDTH) {
|
if (cu_loc->width > tr_limit && cu_loc->height > tr_limit) {
|
||||||
split = QT_SPLIT;
|
split = QT_SPLIT;
|
||||||
}
|
}
|
||||||
else if (cu_loc->width > TR_MAX_WIDTH) {
|
else if (cu_loc->width > tr_limit) {
|
||||||
split = BT_VER_SPLIT;
|
split = BT_VER_SPLIT;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -650,6 +652,10 @@ static void encode_transform_coeff(
|
||||||
cu_loc_t split_cu_loc[4];
|
cu_loc_t split_cu_loc[4];
|
||||||
const int split_count = uvg_get_split_locs(cu_loc, split, split_cu_loc,NULL);
|
const int split_count = uvg_get_split_locs(cu_loc, split, split_cu_loc,NULL);
|
||||||
for (int i = 0; i < split_count; ++i) {
|
for (int i = 0; i < split_count; ++i) {
|
||||||
|
if(tree_type == UVG_CHROMA_T) {
|
||||||
|
split_cu_loc[i].chroma_width = split_cu_loc[i].width;
|
||||||
|
split_cu_loc[i].chroma_height = split_cu_loc[i].height;
|
||||||
|
}
|
||||||
encode_transform_coeff(state, &split_cu_loc[i], only_chroma,
|
encode_transform_coeff(state, &split_cu_loc[i], only_chroma,
|
||||||
coeff, NULL, tree_type, true, false, luma_cbf_ctx, &split_cu_loc[i], &split_cu_loc[i]);
|
coeff, NULL, tree_type, true, false, luma_cbf_ctx, &split_cu_loc[i], &split_cu_loc[i]);
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1258,7 @@ uint8_t uvg_write_split_flag(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!is_implicit && can_split[QT_SPLIT] && (can_split[BT_HOR_SPLIT] || can_split[BT_VER_SPLIT] || can_split[TT_HOR_SPLIT] || can_split[TT_VER_SPLIT]) && split_flag != NO_SPLIT) {
|
if (!is_implicit && (can_split[BT_HOR_SPLIT] || can_split[BT_VER_SPLIT] || can_split[TT_HOR_SPLIT] || can_split[TT_VER_SPLIT]) && split_flag != NO_SPLIT) {
|
||||||
bool qt_split = split_flag == QT_SPLIT;
|
bool qt_split = split_flag == QT_SPLIT;
|
||||||
if((can_split[BT_VER_SPLIT] || can_split[BT_HOR_SPLIT] || can_split[TT_VER_SPLIT] || can_split[TT_HOR_SPLIT]) && can_split[QT_SPLIT]) {
|
if((can_split[BT_VER_SPLIT] || can_split[BT_HOR_SPLIT] || can_split[TT_VER_SPLIT] || can_split[TT_HOR_SPLIT]) && can_split[QT_SPLIT]) {
|
||||||
unsigned left_qt_depth = 0;
|
unsigned left_qt_depth = 0;
|
||||||
|
@ -1617,7 +1623,7 @@ void uvg_encode_coding_tree(
|
||||||
has_chroma) || tree_type == UVG_CHROMA_T) &&
|
has_chroma) || tree_type == UVG_CHROMA_T) &&
|
||||||
tree_type != UVG_LUMA_T) {
|
tree_type != UVG_LUMA_T) {
|
||||||
int8_t luma_dir = uvg_get_co_located_luma_mode(tree_type != UVG_CHROMA_T ? chroma_loc : cu_loc, cu_loc, cur_cu, NULL, frame->cu_array, UVG_CHROMA_T);
|
int8_t luma_dir = uvg_get_co_located_luma_mode(tree_type != UVG_CHROMA_T ? chroma_loc : cu_loc, cu_loc, cur_cu, NULL, frame->cu_array, UVG_CHROMA_T);
|
||||||
encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm, luma_dir,NULL);
|
encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm && uvg_cclm_is_allowed(state, cu_loc, cur_cu, tree_type), luma_dir,NULL);
|
||||||
// LFNST constraints must be reset here. Otherwise the left over values will interfere when calculating new constraints
|
// LFNST constraints must be reset here. Otherwise the left over values will interfere when calculating new constraints
|
||||||
cu_info_t* tmp = (cu_info_t*)cur_cu;
|
cu_info_t* tmp = (cu_info_t*)cur_cu;
|
||||||
tmp->violates_lfnst_constrained_luma = false;
|
tmp->violates_lfnst_constrained_luma = false;
|
||||||
|
@ -1769,7 +1775,7 @@ double uvg_mock_encode_coding_unit(
|
||||||
int8_t luma_dir = uvg_get_co_located_luma_mode(chroma_loc,cu_loc , cur_cu, tree_type != UVG_CHROMA_T ? lcu : NULL,
|
int8_t luma_dir = uvg_get_co_located_luma_mode(chroma_loc,cu_loc , cur_cu, tree_type != UVG_CHROMA_T ? lcu : NULL,
|
||||||
tree_type == UVG_CHROMA_T ? state->tile->frame->cu_array : NULL,
|
tree_type == UVG_CHROMA_T ? state->tile->frame->cu_array : NULL,
|
||||||
is_separate_tree ? UVG_CHROMA_T : tree_type);
|
is_separate_tree ? UVG_CHROMA_T : tree_type);
|
||||||
encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm, luma_dir, &bits);
|
encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm && uvg_cclm_is_allowed(state, cu_loc, cur_cu, tree_type), luma_dir, &bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
22
src/intra.c
22
src/intra.c
|
@ -283,6 +283,26 @@ static void intra_pred_dc(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool uvg_cclm_is_allowed(const encoder_state_t* const state, const cu_loc_t * const luma_loc, cu_info_t const * const cur_cu, enum
|
||||||
|
uvg_tree_type tree_type)
|
||||||
|
{
|
||||||
|
if (tree_type != UVG_CHROMA_T) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
uint32_t chroma_split = GET_SPLITDATA(cur_cu, 0);
|
||||||
|
if((chroma_split == BT_VER_SPLIT || chroma_split == TT_VER_SPLIT || chroma_split == TT_HOR_SPLIT) && GET_SPLITDATA(cur_cu, 1) == NO_SPLIT) return false;
|
||||||
|
const cu_info_t* const luma_cu = uvg_cu_array_at_const(state->tile->frame->cu_array, luma_loc->x, luma_loc->y);
|
||||||
|
uint32_t split = GET_SPLITDATA(luma_cu, 0);
|
||||||
|
if (split != QT_SPLIT && split != NO_SPLIT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (split != NO_SPLIT && luma_cu->intra.isp_mode != ISP_MODE_NO_ISP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum lm_mode
|
enum lm_mode
|
||||||
{
|
{
|
||||||
LM_CHROMA_IDX = 81,
|
LM_CHROMA_IDX = 81,
|
||||||
|
@ -1846,7 +1866,7 @@ void uvg_intra_recon_cu(
|
||||||
const uint8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
|
const uint8_t depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
|
||||||
const vector2d_t lcu_px = { cu_loc->local_x >> (tree_type == UVG_CHROMA_T), cu_loc->local_y >> (tree_type == UVG_CHROMA_T) };
|
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 width = cu_loc->width;
|
const int8_t width = cu_loc->width;
|
||||||
const int8_t height = cu_loc->height; // TODO: height for non-square blocks.
|
const int8_t height = cu_loc->height;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,8 @@ int8_t uvg_get_co_located_luma_mode(
|
||||||
const lcu_t* const lcu,
|
const lcu_t* const lcu,
|
||||||
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);
|
||||||
|
bool uvg_cclm_is_allowed(const encoder_state_t* const state, const cu_loc_t* const luma_loc, cu_info_t const* const cur_cu, enum
|
||||||
|
uvg_tree_type tree_type);
|
||||||
|
|
||||||
uint8_t uvg_get_mip_flag_context(
|
uint8_t uvg_get_mip_flag_context(
|
||||||
const cu_loc_t* const cu_loc,
|
const cu_loc_t* const cu_loc,
|
||||||
|
|
|
@ -215,7 +215,7 @@ static void work_tree_copy_up(
|
||||||
copy_cu_info (from, to, cu_loc, tree_type);
|
copy_cu_info (from, to, cu_loc, tree_type);
|
||||||
copy_cu_pixels(from, to, cu_loc, cu_loc != chroma_loc && tree_type == UVG_LUMA_T ? UVG_LUMA_T : tree_type);
|
copy_cu_pixels(from, to, cu_loc, cu_loc != chroma_loc && tree_type == UVG_LUMA_T ? UVG_LUMA_T : tree_type);
|
||||||
copy_cu_coeffs(cu_loc, from, to, joint, cu_loc != chroma_loc && tree_type == UVG_LUMA_T ? UVG_LUMA_T : tree_type);
|
copy_cu_coeffs(cu_loc, from, to, joint, cu_loc != chroma_loc && tree_type == UVG_LUMA_T ? UVG_LUMA_T : tree_type);
|
||||||
if (cu_loc != chroma_loc && tree_type == UVG_LUMA_T) {
|
if (cu_loc != chroma_loc && tree_type != UVG_LUMA_T) {
|
||||||
copy_cu_pixels(from, to, chroma_loc, UVG_CHROMA_T);
|
copy_cu_pixels(from, to, chroma_loc, UVG_CHROMA_T);
|
||||||
copy_cu_coeffs(chroma_loc, from, to, joint, UVG_CHROMA_T);
|
copy_cu_coeffs(chroma_loc, from, to, joint, UVG_CHROMA_T);
|
||||||
}
|
}
|
||||||
|
@ -1189,7 +1189,7 @@ static double search_cu(
|
||||||
|
|
||||||
bool recon_chroma = true;
|
bool recon_chroma = true;
|
||||||
bool recon_luma = tree_type != UVG_CHROMA_T;
|
bool recon_luma = tree_type != UVG_CHROMA_T;
|
||||||
if (is_separate_tree || !has_chroma || state->encoder_control->chroma_format == UVG_CSP_400 || tree_type == UVG_LUMA_T) {
|
if (is_separate_tree || !has_chroma || state->encoder_control->chroma_format == UVG_CSP_400 || tree_type == UVG_LUMA_T || cu_loc->chroma_height % 4 == 2) {
|
||||||
recon_chroma = false;
|
recon_chroma = false;
|
||||||
}
|
}
|
||||||
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_height, cur_cu);
|
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_height, cur_cu);
|
||||||
|
@ -1200,7 +1200,7 @@ static double search_cu(
|
||||||
recon_luma, recon_chroma);
|
recon_luma, recon_chroma);
|
||||||
|
|
||||||
|
|
||||||
if((is_separate_tree && has_chroma && tree_type != UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400 )
|
if((!recon_chroma && state->encoder_control->chroma_format != UVG_CSP_400 )
|
||||||
|| tree_type == UVG_CHROMA_T) {
|
|| tree_type == UVG_CHROMA_T) {
|
||||||
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,
|
||||||
|
@ -1360,7 +1360,7 @@ static double search_cu(
|
||||||
cabac_data_t best_split_cabac;
|
cabac_data_t best_split_cabac;
|
||||||
memcpy(&post_seach_cabac, &state->search_cabac, sizeof(post_seach_cabac));
|
memcpy(&post_seach_cabac, &state->search_cabac, sizeof(post_seach_cabac));
|
||||||
for (int split_type = QT_SPLIT; split_type <= TT_VER_SPLIT; ++split_type) {
|
for (int split_type = QT_SPLIT; split_type <= TT_VER_SPLIT; ++split_type) {
|
||||||
if (!can_split[split_type] || (split_type != QT_SPLIT && depth == 0) || (split_type == QT_SPLIT && depth == 1)) continue;
|
if (!can_split[split_type] || (tree_type == UVG_CHROMA_T && split_type == TT_HOR_SPLIT && cu_loc->chroma_height == 8)) continue;
|
||||||
split_tree_t new_split = {
|
split_tree_t new_split = {
|
||||||
split_tree.split_tree | split_type << (split_tree.current_depth * 3),
|
split_tree.split_tree | split_type << (split_tree.current_depth * 3),
|
||||||
split_tree.current_depth + 1,
|
split_tree.current_depth + 1,
|
||||||
|
|
|
@ -1476,7 +1476,7 @@ int8_t uvg_search_intra_chroma_rdo(
|
||||||
}
|
}
|
||||||
pred_cu->cr_lfnst_idx = lfnst;
|
pred_cu->cr_lfnst_idx = lfnst;
|
||||||
chroma_data[mode_i].lfnst_costs[lfnst] += mode_bits * state->lambda;
|
chroma_data[mode_i].lfnst_costs[lfnst] += mode_bits * state->lambda;
|
||||||
if (PU_IS_TU(pred_cu)) {
|
if (PU_IS_TU(pred_cu) && (tree_type != UVG_CHROMA_T || (pred_cu->log2_width < 5 && pred_cu->log2_height < 5))) {
|
||||||
uvg_intra_predict(
|
uvg_intra_predict(
|
||||||
state,
|
state,
|
||||||
&refs[COLOR_U - 1],
|
&refs[COLOR_U - 1],
|
||||||
|
@ -1594,7 +1594,7 @@ int8_t uvg_search_cu_intra_chroma(
|
||||||
const cu_info_t *cur_pu = &search_data->pred_cu;
|
const cu_info_t *cur_pu = &search_data->pred_cu;
|
||||||
|
|
||||||
int8_t modes[8] = { 0, 50, 18, 1, luma_mode, 81, 82, 83 };
|
int8_t modes[8] = { 0, 50, 18, 1, luma_mode, 81, 82, 83 };
|
||||||
uint8_t total_modes = (state->encoder_control->cfg.cclm ? 8 : 5);
|
uint8_t total_modes = (state->encoder_control->cfg.cclm && uvg_cclm_is_allowed(state, cu_loc, cur_pu, tree_type) ? 8 : 5);
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
if (modes[i] == luma_mode) {
|
if (modes[i] == luma_mode) {
|
||||||
modes[i] = 66;
|
modes[i] = 66;
|
||||||
|
|
Loading…
Reference in a new issue