[mtt] Only consider termination if the cu is completely inside the frame

This commit is contained in:
Joose Sainio 2023-01-04 09:55:22 +02:00 committed by Marko Viitanen
parent 0c63743fc0
commit d3f42949a7

View file

@ -1159,7 +1159,12 @@ static void mark_deblocking(const cu_loc_t* const cu_loc, const cu_loc_t* const
} }
} }
static bool check_for_early_termission(const int cu_width, const int cu_height, cu_info_t* cur_cu, int x_local, int y_local, bool improved[6], int cbf, lcu_t* split_lcu, int split_type) static bool check_for_early_termission(const int cu_width, const int cu_height, const cu_info_t* const cur_cu, int x_local, int y_local, const
bool* improved,
int cbf,
lcu_t* split_lcu,
int split_type,
const bool* can_split)
{ {
// Best no split has no residual and same direction bt didn't improve so don't try tt // Best no split has no residual and same direction bt didn't improve so don't try tt
// 3.11 // 3.11
@ -1170,7 +1175,7 @@ static bool check_for_early_termission(const int cu_width, const int cu_height,
// 3.8 // 3.8
if (split_type == TT_HOR_SPLIT) { if (split_type == TT_HOR_SPLIT && can_split[BT_HOR_SPLIT]) {
bool can_skip = true; bool can_skip = true;
for (int x_scu = x_local; x_scu < x_local + cu_width; x_scu += 4) { for (int x_scu = x_local; x_scu < x_local + cu_width; x_scu += 4) {
can_skip &= can_skip &=
@ -1179,7 +1184,7 @@ static bool check_for_early_termission(const int cu_width, const int cu_height,
} }
if (can_skip) return true; if (can_skip) return true;
} }
if (split_type == TT_VER_SPLIT) { if (split_type == TT_VER_SPLIT && can_split[BT_VER_SPLIT]) {
bool can_skip = true; bool can_skip = true;
for (int y_scu = y_local; y_scu < y_local + cu_height; y_scu += 4) { for (int y_scu = y_local; y_scu < y_local + cu_height; y_scu += 4) {
can_skip &= can_skip &=
@ -1292,9 +1297,10 @@ static double search_cu(
intra_search_data_t intra_search; intra_search_data_t intra_search;
const bool completely_inside = x + luma_width <= frame_width && y + luma_height <= frame_height;
// If the CU is completely inside the frame at this depth, search for // If the CU is completely inside the frame at this depth, search for
// prediction modes at this depth. // prediction modes at this depth.
if ( x + luma_width <= frame_width && y + luma_height <= frame_height) if ( completely_inside)
{ {
int cu_width_inter_min = LCU_WIDTH >> pu_depth_inter.max; int cu_width_inter_min = LCU_WIDTH >> pu_depth_inter.max;
bool can_use_inter = bool can_use_inter =
@ -1707,16 +1713,20 @@ static double search_cu(
|| (tree_type == UVG_CHROMA_T && split_type == BT_HOR_SPLIT && cu_loc->chroma_height == 4)) || (tree_type == UVG_CHROMA_T && split_type == BT_HOR_SPLIT && cu_loc->chroma_height == 4))
continue; continue;
if (check_for_early_termission( if (completely_inside && check_for_early_termission(
cu_width, cu_width,
cu_height, cu_height,
cur_cu, cur_cu,
x_local, x_local,
y_local, y_local,
improved, improved,
cbf, cbf,
split_lcu, split_lcu,
split_type)) continue; split_type,
can_split)) {
can_split[split_type] = false;
continue;
}
double split_cost = 0.0; double split_cost = 0.0;
memcpy(&state->search_cabac, &pre_search_cabac, sizeof(post_seach_cabac)); memcpy(&state->search_cabac, &pre_search_cabac, sizeof(post_seach_cabac));
@ -1762,7 +1772,10 @@ static double search_cu(
// 3.9 // 3.9
const double factor = state->qp > 30 ? 1.1 : 1.075; const double factor = state->qp > 30 ? 1.1 : 1.075;
if (split_bits * state->frame->lambda + cost / factor > cost) continue; if (split_bits * state->frame->lambda + cost / factor > cost) {
can_split[split_type] = false;
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),
@ -1792,12 +1805,13 @@ static double search_cu(
!separate_chroma || (split == splits - 1 && has_chroma)); !separate_chroma || (split == splits - 1 && has_chroma));
// If there is no separate chroma the block will always have chroma, otherwise it is the last block of the split that has the chroma // If there is no separate chroma the block will always have chroma, otherwise it is the last block of the split that has the chroma
if (split_type == QT_SPLIT) { if (split_type == QT_SPLIT && completely_inside) {
const cu_info_t * const t = LCU_GET_CU_AT_PX(&split_lcu[0], new_cu_loc[split].local_x, new_cu_loc[split].local_y); const cu_info_t * const t = LCU_GET_CU_AT_PX(&split_lcu[0], new_cu_loc[split].local_x, new_cu_loc[split].local_y);
stop_to_qt |= GET_SPLITDATA(t, depth + 1) == QT_SPLIT; stop_to_qt |= GET_SPLITDATA(t, depth + 1) == QT_SPLIT;
} }
if (split_cost > cost || split_cost > best_split_cost) { if (split_cost > cost || split_cost > best_split_cost) {
can_split[split_type] = false;
break; break;
} }
} }