mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
[mtt] fix dual tree
This commit is contained in:
parent
8fbefc0de3
commit
d5d9afb1e2
|
@ -229,7 +229,7 @@ int uvg_config_init(uvg_config *cfg)
|
|||
|
||||
cfg->max_btt_depth[0] = 1;
|
||||
cfg->max_btt_depth[1] = 0;
|
||||
cfg->max_btt_depth[2] = 0;
|
||||
cfg->max_btt_depth[2] = 1;
|
||||
|
||||
cfg->max_tt_size[0] = 64;
|
||||
cfg->max_bt_size[0] = 64;
|
||||
|
|
28
src/cu.c
28
src/cu.c
|
@ -407,11 +407,7 @@ int uvg_get_possible_splits(const encoder_state_t * const state,
|
|||
if (width <= min_qt_size) splits[QT_SPLIT] = false;
|
||||
|
||||
if (tree_type == UVG_CHROMA_T && width <= 4) splits[QT_SPLIT] = false;
|
||||
if (tree_type == UVG_CHROMA_T)
|
||||
{
|
||||
splits[QT_SPLIT] = splits[BT_VER_SPLIT] = splits[TT_HOR_SPLIT] = splits[BT_VER_SPLIT] = splits[TT_VER_SPLIT] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (implicitSplit != NO_SPLIT)
|
||||
{
|
||||
splits[NO_SPLIT] = splits[TT_HOR_SPLIT] = splits[TT_VER_SPLIT] = false;
|
||||
|
@ -499,3 +495,25 @@ int uvg_count_available_edge_cus(const cu_loc_t* const cu_loc, const lcu_t* cons
|
|||
}
|
||||
return MAX(amount / TR_MIN_WIDTH, cu_loc->width / TR_MIN_WIDTH);
|
||||
}
|
||||
|
||||
int uvg_count_chroma_tree_available_edge_cus(int x, int y, int width, int height, const lcu_t* const lcu, bool left)
|
||||
{
|
||||
if (left && x == 0 || !left && y == 0) return 0;
|
||||
const int local_x = x % LCU_WIDTH_C;
|
||||
const int local_y = y % LCU_WIDTH_C;
|
||||
if (left && local_x == 0) return (LCU_WIDTH_C - local_y) / 4;
|
||||
if (!left && local_y == 0) return width / 2;
|
||||
|
||||
int amount = 0;
|
||||
if(left) {
|
||||
while (LCU_GET_CU_AT_PX(lcu, local_x - TR_MIN_WIDTH, local_y + amount)->type != CU_NOTSET && (local_y + amount) < LCU_WIDTH_C) {
|
||||
amount += TR_MIN_WIDTH;
|
||||
}
|
||||
return MAX(amount / TR_MIN_WIDTH, height / TR_MIN_WIDTH);
|
||||
}
|
||||
while (LCU_GET_CU_AT_PX(lcu, local_x + amount, local_y - TR_MIN_WIDTH)->type != CU_NOTSET && local_x + amount < LCU_WIDTH_C) {
|
||||
amount += TR_MIN_WIDTH;
|
||||
}
|
||||
return MAX(amount / TR_MIN_WIDTH, width / TR_MIN_WIDTH);
|
||||
|
||||
}
|
1
src/cu.h
1
src/cu.h
|
@ -377,6 +377,7 @@ void uvg_cu_array_copy_from_lcu(cu_array_t* dst, int dst_x, int dst_y, const lcu
|
|||
tree_type);
|
||||
|
||||
int uvg_count_available_edge_cus(const cu_loc_t* const cu_loc, const lcu_t* const lcu, bool left);
|
||||
int uvg_count_chroma_tree_available_edge_cus(int x, int y, int width, int height, const lcu_t* const lcu, bool left);
|
||||
|
||||
/**
|
||||
* \brief Return pointer to the top right reference CU.
|
||||
|
|
|
@ -1352,13 +1352,14 @@ void uvg_encode_coding_tree(
|
|||
const encoder_control_t * const ctrl = state->encoder_control;
|
||||
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;
|
||||
const cu_info_t *cur_cu = uvg_cu_array_at_const(used_array, cu_loc->x, cu_loc->y);
|
||||
|
||||
const int cu_width = tree_type != UVG_CHROMA_T ? cu_loc->width : cu_loc->chroma_width;
|
||||
const int cu_height = tree_type != UVG_CHROMA_T ? cu_loc->height : cu_loc->chroma_height;
|
||||
|
||||
const int x = cu_loc->x;
|
||||
const int y = cu_loc->y;
|
||||
const int x = tree_type != UVG_CHROMA_T ? cu_loc->x : chroma_loc->x;
|
||||
const int y = tree_type != UVG_CHROMA_T ? cu_loc->y : chroma_loc->y;
|
||||
|
||||
const cu_info_t* cur_cu = uvg_cu_array_at_const(used_array, x, y);
|
||||
|
||||
const int depth = split_tree.current_depth;
|
||||
|
||||
|
@ -1397,7 +1398,7 @@ void uvg_encode_coding_tree(
|
|||
cabac,
|
||||
left_cu,
|
||||
above_cu,
|
||||
cu_loc,
|
||||
tree_type != UVG_CHROMA_T ? cu_loc : chroma_loc,
|
||||
split_tree,
|
||||
tree_type,
|
||||
NULL);
|
||||
|
@ -1406,12 +1407,24 @@ void uvg_encode_coding_tree(
|
|||
split_tree_t new_split_tree = { cur_cu->split_tree, split_tree.current_depth + 1, split_tree.mtt_depth + (split_flag != QT_SPLIT), 0};
|
||||
|
||||
cu_loc_t new_cu_loc[4];
|
||||
cu_loc_t chroma_tree_loc;
|
||||
uint8_t separate_chroma = 0;
|
||||
const int splits = uvg_get_split_locs(cu_loc, split_flag, new_cu_loc, &separate_chroma);
|
||||
for (int split = 0; split <splits; ++split) {
|
||||
new_split_tree.part_index = split;
|
||||
if (tree_type == UVG_CHROMA_T) {
|
||||
chroma_tree_loc = new_cu_loc[split];
|
||||
chroma_tree_loc.x >>= 1;
|
||||
chroma_tree_loc.y >>= 1;
|
||||
chroma_tree_loc.local_x = chroma_tree_loc.x & LCU_WIDTH_C;
|
||||
chroma_tree_loc.local_y = chroma_tree_loc.y & LCU_WIDTH_C;
|
||||
chroma_tree_loc.width >>= 1;
|
||||
chroma_tree_loc.height >>= 1;
|
||||
assert(!separate_chroma);
|
||||
}
|
||||
uvg_encode_coding_tree(state, coeff, tree_type,
|
||||
&new_cu_loc[split], separate_chroma ? chroma_loc : &new_cu_loc[split],
|
||||
&new_cu_loc[split],
|
||||
separate_chroma ? chroma_loc :(tree_type == UVG_CHROMA_T ? &chroma_tree_loc : &new_cu_loc[split]),
|
||||
new_split_tree, !separate_chroma || split == splits - 1);
|
||||
}
|
||||
return;
|
||||
|
@ -1420,6 +1433,9 @@ void uvg_encode_coding_tree(
|
|||
|
||||
DBG_YUVIEW_VALUE(state->frame->poc, DBG_YUVIEW_CU_TYPE, abs_x, abs_y, cu_width, cu_height, cur_cu->type-1);
|
||||
|
||||
if(tree_type==UVG_CHROMA_T)
|
||||
fprintf(stderr, "%d %d %d %d\n", x * 2, y * 2, cu_width * 2, cu_height*2);
|
||||
|
||||
if (ctrl->cfg.lossless) {
|
||||
cabac->cur_ctx = &cabac->ctx.cu_transquant_bypass;
|
||||
CABAC_BIN(cabac, 1, "cu_transquant_bypass_flag");
|
||||
|
@ -1643,7 +1659,7 @@ void uvg_encode_coding_tree(
|
|||
((is_local_dual_tree &&
|
||||
has_chroma) || tree_type == UVG_CHROMA_T) &&
|
||||
tree_type != UVG_LUMA_T) {
|
||||
int8_t luma_dir = uvg_get_co_located_luma_mode(chroma_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);
|
||||
// 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;
|
||||
|
|
|
@ -883,13 +883,20 @@ static void encoder_state_worker_encode_lcu_bitstream(void * opaque)
|
|||
//Encode coding tree
|
||||
cu_loc_t start;
|
||||
uvg_cu_loc_ctor(&start, lcu->position.x * LCU_WIDTH, lcu->position.y * LCU_WIDTH, LCU_WIDTH, LCU_WIDTH);
|
||||
split_tree_t split_tree = { 0, 0, 0, 0 };
|
||||
split_tree_t split_tree = { 0, 0, 0 };
|
||||
|
||||
uvg_encode_coding_tree(state, lcu->coeff, tree_type, &start, &start, split_tree, true);
|
||||
|
||||
if(tree_type == UVG_LUMA_T && state->encoder_control->chroma_format != UVG_CSP_400) {
|
||||
uvg_cu_loc_ctor(&start, lcu->position.x * LCU_WIDTH_C, lcu->position.y * LCU_WIDTH_C, LCU_WIDTH, LCU_WIDTH);
|
||||
uvg_encode_coding_tree(state, lcu->coeff, UVG_CHROMA_T, &start, &start, split_tree, true);
|
||||
uvg_cu_loc_ctor(&start, lcu->position.x * LCU_WIDTH, lcu->position.y * LCU_WIDTH, LCU_WIDTH, LCU_WIDTH);
|
||||
cu_loc_t chroma_tree_loc = start;
|
||||
chroma_tree_loc.x >>= 1;
|
||||
chroma_tree_loc.y >>= 1;
|
||||
chroma_tree_loc.local_x = chroma_tree_loc.x & LCU_WIDTH_C;
|
||||
chroma_tree_loc.local_y = chroma_tree_loc.y & LCU_WIDTH_C;
|
||||
chroma_tree_loc.width >>= 1;
|
||||
chroma_tree_loc.height >>= 1;
|
||||
uvg_encode_coding_tree(state, lcu->coeff, UVG_CHROMA_T, &start, &chroma_tree_loc, split_tree, true);
|
||||
}
|
||||
|
||||
if (!state->cabac.only_count) {
|
||||
|
|
26
src/intra.c
26
src/intra.c
|
@ -1119,9 +1119,14 @@ void uvg_intra_build_reference_any(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!is_dual_tree) {
|
||||
const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, true);
|
||||
px_available_left = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus *2;
|
||||
px_available_left -= px.x % 4;
|
||||
px_available_left = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus * 2;
|
||||
}
|
||||
else {
|
||||
const int num_cus = uvg_count_chroma_tree_available_edge_cus(cu_loc->x >> 1, cu_loc->y >> 1, width, height, lcu, true);
|
||||
px_available_left = num_cus * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the number of available pixels based on block size and dimensions
|
||||
|
@ -1242,9 +1247,15 @@ void uvg_intra_build_reference_any(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!is_dual_tree) {
|
||||
const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, false);
|
||||
px_available_top = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus * 2;
|
||||
}
|
||||
else {
|
||||
const int num_cus = uvg_count_chroma_tree_available_edge_cus(cu_loc->x >> 1, cu_loc->y >> 1, width, height, lcu, false);
|
||||
px_available_top = num_cus * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the number of available pixels based on block size and dimensions
|
||||
// of the picture.
|
||||
|
@ -1428,8 +1439,13 @@ void uvg_intra_build_reference_inner(
|
|||
|
||||
}
|
||||
else {
|
||||
if(!is_dual_tree) {
|
||||
const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, true);
|
||||
px_available_left = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus * 2;
|
||||
} else {
|
||||
const int num_cus = uvg_count_chroma_tree_available_edge_cus(cu_loc->x >> 1, cu_loc->y >> 1, width, height, lcu, true);
|
||||
px_available_left = num_cus * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the number of available pixels based on block size and dimensions
|
||||
|
@ -1490,9 +1506,15 @@ void uvg_intra_build_reference_inner(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!is_dual_tree) {
|
||||
const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, false);
|
||||
px_available_top = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus * 2;
|
||||
}
|
||||
else {
|
||||
const int num_cus = uvg_count_chroma_tree_available_edge_cus(cu_loc->x >> 1, cu_loc->y >> 1, width, height, lcu, false);
|
||||
px_available_top = num_cus * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Limit the number of available pixels based on block size and dimensions
|
||||
// of the picture.
|
||||
|
|
Loading…
Reference in a new issue