Refactor choose_partitioning computing scheme
This commit refactors the choose_partitioning function. It removes redundant memset calls and makes the encoder to calculate variance value per block only when it is needed. It reduces the average runtime cost of choose_partitioning by 60%. Overall it reduces speed -6 runtime by 2-5%. Change-Id: I951922c50d901d0fff77a3bafc45992179bacef9
This commit is contained in:
Родитель
0cac834b5a
Коммит
377d2f027a
|
@ -327,7 +327,6 @@ typedef enum {
|
||||||
static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
|
static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
|
||||||
int i;
|
int i;
|
||||||
node->part_variances = NULL;
|
node->part_variances = NULL;
|
||||||
vpx_memset(node->split, 0, sizeof(node->split));
|
|
||||||
switch (bsize) {
|
switch (bsize) {
|
||||||
case BLOCK_64X64: {
|
case BLOCK_64X64: {
|
||||||
v64x64 *vt = (v64x64 *) data;
|
v64x64 *vt = (v64x64 *) data;
|
||||||
|
@ -376,7 +375,10 @@ static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
|
||||||
v->sum_square_error = s2;
|
v->sum_square_error = s2;
|
||||||
v->sum_error = s;
|
v->sum_error = s;
|
||||||
v->count = c;
|
v->count = c;
|
||||||
if (c > 0)
|
}
|
||||||
|
|
||||||
|
static void get_variance(var *v) {
|
||||||
|
if (v->count > 0)
|
||||||
v->variance = (int)(256 *
|
v->variance = (int)(256 *
|
||||||
(v->sum_square_error - v->sum_error * v->sum_error /
|
(v->sum_square_error - v->sum_error * v->sum_error /
|
||||||
v->count) / v->count);
|
v->count) / v->count);
|
||||||
|
@ -433,6 +435,7 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
||||||
// variance is below threshold, otherwise split will be selected.
|
// variance is below threshold, otherwise split will be selected.
|
||||||
// No check for vert/horiz split as too few samples for variance.
|
// No check for vert/horiz split as too few samples for variance.
|
||||||
if (bsize == bsize_ref) {
|
if (bsize == bsize_ref) {
|
||||||
|
get_variance(&vt.part_variances->none);
|
||||||
if (mi_col + block_width / 2 < cm->mi_cols &&
|
if (mi_col + block_width / 2 < cm->mi_cols &&
|
||||||
mi_row + block_height / 2 < cm->mi_rows &&
|
mi_row + block_height / 2 < cm->mi_rows &&
|
||||||
vt.part_variances->none.variance < threshold_bsize_ref) {
|
vt.part_variances->none.variance < threshold_bsize_ref) {
|
||||||
|
@ -441,6 +444,7 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (bsize > bsize_ref) {
|
} else if (bsize > bsize_ref) {
|
||||||
|
get_variance(&vt.part_variances->none);
|
||||||
// For key frame, for bsize above 32X32, or very high variance, take split.
|
// For key frame, for bsize above 32X32, or very high variance, take split.
|
||||||
if (cm->frame_type == KEY_FRAME &&
|
if (cm->frame_type == KEY_FRAME &&
|
||||||
(bsize > BLOCK_32X32 ||
|
(bsize > BLOCK_32X32 ||
|
||||||
|
@ -454,24 +458,32 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
||||||
set_block_size(cpi, xd, mi_row, mi_col, bsize);
|
set_block_size(cpi, xd, mi_row, mi_col, bsize);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check vertical split.
|
// Check vertical split.
|
||||||
if (mi_row + block_height / 2 < cm->mi_rows &&
|
if (mi_row + block_height / 2 < cm->mi_rows) {
|
||||||
vt.part_variances->vert[0].variance < threshold_low &&
|
get_variance(&vt.part_variances->vert[0]);
|
||||||
vt.part_variances->vert[1].variance < threshold_low) {
|
get_variance(&vt.part_variances->vert[1]);
|
||||||
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
|
if (vt.part_variances->vert[0].variance < threshold_low &&
|
||||||
set_block_size(cpi, xd, mi_row, mi_col, subsize);
|
vt.part_variances->vert[1].variance < threshold_low) {
|
||||||
set_block_size(cpi, xd, mi_row, mi_col + block_width / 2, subsize);
|
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
|
||||||
return 1;
|
set_block_size(cpi, xd, mi_row, mi_col, subsize);
|
||||||
|
set_block_size(cpi, xd, mi_row, mi_col + block_width / 2, subsize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check horizontal split.
|
// Check horizontal split.
|
||||||
if (mi_col + block_width / 2 < cm->mi_cols &&
|
if (mi_col + block_width / 2 < cm->mi_cols) {
|
||||||
vt.part_variances->horz[0].variance < threshold_low &&
|
get_variance(&vt.part_variances->horz[0]);
|
||||||
vt.part_variances->horz[1].variance < threshold_low) {
|
get_variance(&vt.part_variances->horz[1]);
|
||||||
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
|
if (vt.part_variances->horz[0].variance < threshold_low &&
|
||||||
set_block_size(cpi, xd, mi_row, mi_col, subsize);
|
vt.part_variances->horz[1].variance < threshold_low) {
|
||||||
set_block_size(cpi, xd, mi_row + block_height / 2, mi_col, subsize);
|
BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
|
||||||
return 1;
|
set_block_size(cpi, xd, mi_row, mi_col, subsize);
|
||||||
|
set_block_size(cpi, xd, mi_row + block_height / 2, mi_col, subsize);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче