Simplify & fix potential bug in rd_pick_partition
Different partitionings were not being evaluated against best_rd and there were unnecessary calls to RDCOST. This could have resulted in a non-optimal partioning being selected. I simplified the variables used to track the rate, distortion and RD values throughout the function. Change-Id: Ifa7085ee80d824e86791432a5bc6d8fea5a3e313
This commit is contained in:
parent
6bfcce8c7a
commit
aae6a4c895
@ -570,8 +570,11 @@ static void pick_sb_modes(VP9_COMP *cpi, int mi_row, int mi_col,
|
||||
if (bsize < BLOCK_8X8) {
|
||||
// When ab_index = 0 all sub-blocks are handled, so for ab_index != 0
|
||||
// there is nothing to be done.
|
||||
if (xd->ab_index != 0)
|
||||
if (xd->ab_index != 0) {
|
||||
*totalrate = 0;
|
||||
*totaldist = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
set_offsets(cpi, mi_row, mi_col, bsize);
|
||||
@ -1518,8 +1521,9 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
|
||||
TOKENEXTRA *tp_orig = *tp;
|
||||
int i, pl;
|
||||
BLOCK_SIZE_TYPE subsize;
|
||||
int srate = INT_MAX;
|
||||
int64_t sdist = INT_MAX;
|
||||
int this_rate, sum_rate = 0, best_rate = INT_MAX;
|
||||
int64_t this_dist, sum_dist = 0, best_dist = INT_MAX;
|
||||
int64_t sum_rd = 0;
|
||||
|
||||
(void) *tp_orig;
|
||||
|
||||
@ -1540,42 +1544,38 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
|
||||
if (!cpi->sf.auto_min_max_partition_size ||
|
||||
bsize >= cpi->sf.min_partition_size) {
|
||||
if (bsize > BLOCK_8X8) {
|
||||
int r4 = 0;
|
||||
int64_t d4 = 0, sum_rd = 0;
|
||||
subsize = get_subsize(bsize, PARTITION_SPLIT);
|
||||
|
||||
for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
|
||||
int x_idx = (i & 1) * (ms >> 1);
|
||||
int y_idx = (i >> 1) * (ms >> 1);
|
||||
int r = 0;
|
||||
int64_t d = 0;
|
||||
|
||||
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
|
||||
continue;
|
||||
|
||||
*(get_sb_index(xd, subsize)) = i;
|
||||
rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, &r,
|
||||
&d, i != 3, best_rd - sum_rd);
|
||||
rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize,
|
||||
&this_rate, &this_dist, i != 3, best_rd - sum_rd);
|
||||
|
||||
if (r == INT_MAX) {
|
||||
r4 = INT_MAX;
|
||||
if (this_rate == INT_MAX) {
|
||||
sum_rd = INT64_MAX;
|
||||
} else {
|
||||
r4 += r;
|
||||
d4 += d;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, r4, d4);
|
||||
sum_rate += this_rate;
|
||||
sum_dist += this_dist;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
}
|
||||
}
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
if (r4 != INT_MAX && i == 4) {
|
||||
r4 += x->partition_cost[pl][PARTITION_SPLIT];
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
assert(r4 >= 0);
|
||||
assert(d4 >= 0);
|
||||
srate = r4;
|
||||
sdist = d4;
|
||||
best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r4, d4));
|
||||
if (sum_rd < best_rd && i == 4) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
if (sum_rd < best_rd) {
|
||||
best_rate = sum_rate;
|
||||
best_dist = sum_dist;
|
||||
best_rd = sum_rd;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
}
|
||||
}
|
||||
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
}
|
||||
@ -1685,169 +1685,162 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
|
||||
if (!cpi->sf.auto_min_max_partition_size ||
|
||||
bsize <= cpi->sf.max_partition_size) {
|
||||
int larger_is_better = 0;
|
||||
|
||||
// PARTITION_NONE
|
||||
if ((mi_row + (ms >> 1) < cm->mi_rows) &&
|
||||
(mi_col + (ms >> 1) < cm->mi_cols)) {
|
||||
int r;
|
||||
int64_t d;
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &r, &d, bsize,
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &this_rate, &this_dist, bsize,
|
||||
get_block_context(x, bsize), best_rd);
|
||||
if (r != INT_MAX && bsize >= BLOCK_8X8) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
r += x->partition_cost[pl][PARTITION_NONE];
|
||||
}
|
||||
|
||||
if (r != INT_MAX &&
|
||||
(bsize == BLOCK_8X8 ||
|
||||
RDCOST(x->rdmult, x->rddiv, r, d) <
|
||||
RDCOST(x->rdmult, x->rddiv, srate, sdist))) {
|
||||
best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r, d));
|
||||
srate = r;
|
||||
sdist = d;
|
||||
larger_is_better = 1;
|
||||
if (bsize >= BLOCK_8X8)
|
||||
*(get_sb_partitioning(x, bsize)) = bsize;
|
||||
if (this_rate != INT_MAX) {
|
||||
if (bsize >= BLOCK_8X8) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
this_rate += x->partition_cost[pl][PARTITION_NONE];
|
||||
}
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_dist);
|
||||
if (sum_rd < best_rd || bsize == BLOCK_8X8) {
|
||||
best_rate = this_rate;
|
||||
best_dist = this_dist;
|
||||
best_rd = sum_rd;
|
||||
larger_is_better = 1;
|
||||
if (bsize >= BLOCK_8X8)
|
||||
*(get_sb_partitioning(x, bsize)) = bsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bsize == BLOCK_8X8) {
|
||||
int r4 = 0;
|
||||
int64_t d4 = 0, sum_rd = 0;
|
||||
sum_rate = 0; sum_dist = 0; sum_rd = 0;
|
||||
|
||||
subsize = get_subsize(bsize, PARTITION_SPLIT);
|
||||
|
||||
for (i = 0; i < 4 && sum_rd < best_rd; ++i) {
|
||||
int x_idx = (i & 1) * (ms >> 1);
|
||||
int y_idx = (i >> 1) * (ms >> 1);
|
||||
int r = 0;
|
||||
int64_t d = 0;
|
||||
|
||||
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
|
||||
continue;
|
||||
|
||||
*(get_sb_index(xd, subsize)) = i;
|
||||
rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize, &r,
|
||||
&d, i != 3, best_rd - sum_rd);
|
||||
rd_pick_partition(cpi, tp, mi_row + y_idx, mi_col + x_idx, subsize,
|
||||
&this_rate, &this_dist, i != 3, best_rd - sum_rd);
|
||||
|
||||
if (r == INT_MAX) {
|
||||
r4 = INT_MAX;
|
||||
if (this_rate == INT_MAX) {
|
||||
sum_rd = INT64_MAX;
|
||||
} else {
|
||||
r4 += r;
|
||||
d4 += d;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, r4, d4);
|
||||
sum_rate += this_rate;
|
||||
sum_dist += this_dist;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
}
|
||||
}
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
if (r4 != INT_MAX && i == 4) {
|
||||
r4 += x->partition_cost[pl][PARTITION_SPLIT];
|
||||
if (RDCOST(x->rdmult, x->rddiv, r4, d4) <
|
||||
RDCOST(x->rdmult, x->rddiv, srate, sdist)) {
|
||||
srate = r4;
|
||||
sdist = d4;
|
||||
if (sum_rd < best_rd && i == 4) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
sum_rate += x->partition_cost[pl][PARTITION_SPLIT];
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
if (sum_rd < best_rd) {
|
||||
best_rate = sum_rate;
|
||||
best_dist = sum_dist;
|
||||
best_rd = sum_rd;
|
||||
larger_is_better = 0;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r4, d4));
|
||||
}
|
||||
}
|
||||
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
}
|
||||
|
||||
if (!cpi->sf.use_square_partition_only &&
|
||||
(!cpi->sf.less_rectangular_check ||!larger_is_better)) {
|
||||
(!cpi->sf.less_rectangular_check || !larger_is_better)) {
|
||||
// PARTITION_HORZ
|
||||
if (bsize >= BLOCK_8X8 && mi_col + (ms >> 1) < cm->mi_cols) {
|
||||
int r2, r = 0;
|
||||
int64_t d2, d = 0, h_rd;
|
||||
subsize = get_subsize(bsize, PARTITION_HORZ);
|
||||
*(get_sb_index(xd, subsize)) = 0;
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize,
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
|
||||
get_block_context(x, subsize), best_rd);
|
||||
h_rd = RDCOST(x->rdmult, x->rddiv, r2, d2);
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
|
||||
if (r2 != INT_MAX && h_rd < best_rd &&
|
||||
mi_row + (ms >> 1) < cm->mi_rows) {
|
||||
if (sum_rd < best_rd && mi_row + (ms >> 1) < cm->mi_rows) {
|
||||
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
||||
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
||||
|
||||
*(get_sb_index(xd, subsize)) = 1;
|
||||
pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &r, &d, subsize,
|
||||
get_block_context(x, subsize), best_rd - h_rd);
|
||||
if (r == INT_MAX) {
|
||||
r2 = INT_MAX;
|
||||
pick_sb_modes(cpi, mi_row + (ms >> 1), mi_col, &this_rate,
|
||||
&this_dist, subsize, get_block_context(x, subsize),
|
||||
best_rd - sum_rd);
|
||||
if (this_rate == INT_MAX) {
|
||||
sum_rd = INT64_MAX;
|
||||
} else {
|
||||
r2 += r;
|
||||
d2 += d;
|
||||
sum_rate += this_rate;
|
||||
sum_dist += this_dist;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
}
|
||||
}
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
if (r2 < INT_MAX)
|
||||
r2 += x->partition_cost[pl][PARTITION_HORZ];
|
||||
if (r2 != INT_MAX && RDCOST(x->rdmult, x->rddiv, r2, d2)
|
||||
< RDCOST(x->rdmult, x->rddiv, srate, sdist)) {
|
||||
best_rd = MIN(best_rd, RDCOST(x->rdmult, x->rddiv, r2, d2));
|
||||
srate = r2;
|
||||
sdist = d2;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
if (sum_rd < best_rd) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
sum_rate += x->partition_cost[pl][PARTITION_HORZ];
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
if (sum_rd < best_rd) {
|
||||
best_rd = sum_rd;
|
||||
best_rate = sum_rate;
|
||||
best_dist = sum_dist;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
}
|
||||
}
|
||||
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
}
|
||||
|
||||
// PARTITION_VERT
|
||||
if (bsize >= BLOCK_8X8 && mi_row + (ms >> 1) < cm->mi_rows) {
|
||||
int r2;
|
||||
int64_t d2, v_rd;
|
||||
subsize = get_subsize(bsize, PARTITION_VERT);
|
||||
*(get_sb_index(xd, subsize)) = 0;
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &r2, &d2, subsize,
|
||||
pick_sb_modes(cpi, mi_row, mi_col, &sum_rate, &sum_dist, subsize,
|
||||
get_block_context(x, subsize), best_rd);
|
||||
v_rd = RDCOST(x->rdmult, x->rddiv, r2, d2);
|
||||
if (r2 != INT_MAX && v_rd < best_rd &&
|
||||
mi_col + (ms >> 1) < cm->mi_cols) {
|
||||
int r = 0;
|
||||
int64_t d = 0;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
if (sum_rd < best_rd && mi_col + (ms >> 1) < cm->mi_cols) {
|
||||
update_state(cpi, get_block_context(x, subsize), subsize, 0);
|
||||
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize);
|
||||
|
||||
*(get_sb_index(xd, subsize)) = 1;
|
||||
pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &r, &d, subsize,
|
||||
get_block_context(x, subsize), best_rd - v_rd);
|
||||
if (r == INT_MAX) {
|
||||
r2 = INT_MAX;
|
||||
pick_sb_modes(cpi, mi_row, mi_col + (ms >> 1), &this_rate, &this_dist,
|
||||
subsize, get_block_context(x, subsize),
|
||||
best_rd - sum_rd);
|
||||
if (this_rate == INT_MAX) {
|
||||
sum_rd = INT64_MAX;
|
||||
} else {
|
||||
r2 += r;
|
||||
d2 += d;
|
||||
sum_rate += this_rate;
|
||||
sum_dist += this_dist;
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
}
|
||||
}
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
if (r2 < INT_MAX)
|
||||
r2 += x->partition_cost[pl][PARTITION_VERT];
|
||||
if (r2 != INT_MAX &&
|
||||
RDCOST(x->rdmult, x->rddiv, r2, d2)
|
||||
< RDCOST(x->rdmult, x->rddiv, srate, sdist)) {
|
||||
srate = r2;
|
||||
sdist = d2;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
if (sum_rd < best_rd) {
|
||||
set_partition_seg_context(cm, xd, mi_row, mi_col);
|
||||
pl = partition_plane_context(xd, bsize);
|
||||
sum_rate += x->partition_cost[pl][PARTITION_VERT];
|
||||
sum_rd = RDCOST(x->rdmult, x->rddiv, sum_rate, sum_dist);
|
||||
if (sum_rd < best_rd) {
|
||||
best_rate = sum_rate;
|
||||
best_dist = sum_dist;
|
||||
best_rd = sum_rd;
|
||||
*(get_sb_partitioning(x, bsize)) = subsize;
|
||||
}
|
||||
}
|
||||
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
*rate = srate;
|
||||
*dist = sdist;
|
||||
*rate = best_rate;
|
||||
*dist = best_dist;
|
||||
|
||||
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
|
||||
|
||||
if (srate < INT_MAX && sdist < INT_MAX && do_recon)
|
||||
if (best_rate < INT_MAX && best_dist < INT_MAX && do_recon)
|
||||
encode_sb(cpi, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize);
|
||||
|
||||
if (bsize == BLOCK_64X64) {
|
||||
assert(tp_orig < *tp);
|
||||
assert(srate < INT_MAX);
|
||||
assert(sdist < INT_MAX);
|
||||
assert(best_rate < INT_MAX);
|
||||
assert(best_dist < INT_MAX);
|
||||
} else {
|
||||
assert(tp_orig == *tp);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user