summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r--vp9/encoder/vp9_encodeframe.c129
1 files changed, 64 insertions, 65 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index a4e4fa325..87114f1bd 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -412,29 +412,47 @@ static int set_vt_partitioning(VP9_COMP *cpi,
return 1;
}
- // Vertical split is available on all but the bottom border.
- if (mi_row + block_height / 2 < cm->mi_rows &&
- vt.part_variances->vert[0].variance < threshold &&
- vt.part_variances->vert[1].variance < threshold) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
- set_block_size(cpi, mi_row, mi_col, subsize);
- set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
- return 1;
- }
-
- // Horizontal split is available on all but the right border.
- if (mi_col + block_width / 2 < cm->mi_cols &&
- vt.part_variances->horz[0].variance < threshold &&
- vt.part_variances->horz[1].variance < threshold) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
- set_block_size(cpi, mi_row, mi_col, subsize);
- set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
- return 1;
+ // Only allow split for blocks above 16x16.
+ if (bsize > BLOCK_16X16) {
+ // Vertical split is available on all but the bottom border.
+ if (mi_row + block_height / 2 < cm->mi_rows &&
+ vt.part_variances->vert[0].variance < threshold &&
+ vt.part_variances->vert[1].variance < threshold) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
+ set_block_size(cpi, mi_row, mi_col, subsize);
+ set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
+ return 1;
+ }
+
+ // Horizontal split is available on all but the right border.
+ if (mi_col + block_width / 2 < cm->mi_cols &&
+ vt.part_variances->horz[0].variance < threshold &&
+ vt.part_variances->horz[1].variance < threshold) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
+ set_block_size(cpi, mi_row, mi_col, subsize);
+ set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
+ return 1;
+ }
+ }
+
+ // This will only allow 8x8 if the 16x16 variance is very large.
+ if (bsize == BLOCK_16X16) {
+ if (mi_col + block_width / 2 < cm->mi_cols &&
+ mi_row + block_height / 2 < cm->mi_rows &&
+ vt.part_variances->none.variance < (threshold << 6)) {
+ set_block_size(cpi, mi_row, mi_col, bsize);
+ return 1;
+ }
}
return 0;
}
-// TODO(debargha): Fix this function and make it work as expected.
+// This function chooses partitioning based on the variance
+// between source and reconstructed last, where variance is
+// computed for 8x8 downsampled inputs. Some things to check:
+// using the last source rather than reconstructed last, and
+// allowing for small downsampling (4x4 or 2x2) for selection
+// of smaller block sizes (i.e., < 16x16).
static void choose_partitioning(VP9_COMP *cpi,
const TileInfo *const tile,
int mi_row, int mi_col) {
@@ -549,27 +567,11 @@ static void choose_partitioning(VP9_COMP *cpi,
for (j = 0; j < 4; ++j) {
const int x16_idx = ((j & 1) << 1);
const int y16_idx = ((j >> 1) << 1);
- // NOTE: This is a temporary hack to disable 8x8 partitions,
- // since it works really bad - possibly due to a bug
-#define DISABLE_8X8_VAR_BASED_PARTITION
-#ifdef DISABLE_8X8_VAR_BASED_PARTITION
- if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
- mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
- set_block_size(cpi,
- (mi_row + y32_idx + y16_idx),
- (mi_col + x32_idx + x16_idx),
- BLOCK_16X16);
- } else {
- for (k = 0; k < 4; ++k) {
- const int x8_idx = (k & 1);
- const int y8_idx = (k >> 1);
- set_block_size(cpi,
- (mi_row + y32_idx + y16_idx + y8_idx),
- (mi_col + x32_idx + x16_idx + x8_idx),
- BLOCK_8X8);
- }
- }
-#else
+ // NOTE: Since this uses 8x8 downsampling for variance calculation
+ // we cannot really select block size 8x8 (or even 8x16/16x8),
+ // since we do not sufficient samples for variance.
+ // For now, 8x8 partition is only set if the variance of the 16x16
+ // block is very high. This is controlled in set_vt_partitioning.
if (!set_vt_partitioning(cpi, &vt.split[i].split[j],
BLOCK_16X16,
mi_row + y32_idx + y16_idx,
@@ -583,7 +585,6 @@ static void choose_partitioning(VP9_COMP *cpi,
BLOCK_8X8);
}
}
-#endif
}
}
}
@@ -1521,9 +1522,7 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
BLOCK_SIZE subsize;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
- RD_COST last_part_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
- RD_COST none_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
- RD_COST chosen_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
+ RD_COST last_part_rdc, none_rdc, chosen_rdc;
BLOCK_SIZE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0].src_mi->mbmi.sb_type;
@@ -1536,6 +1535,10 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
assert(num_4x4_blocks_wide_lookup[bsize] ==
num_4x4_blocks_high_lookup[bsize]);
+ vp9_rd_cost_reset(&last_part_rdc);
+ vp9_rd_cost_reset(&none_rdc);
+ vp9_rd_cost_reset(&chosen_rdc);
+
partition = partition_lookup[bsl][bs_type];
subsize = get_subsize(bsize, partition);
@@ -1597,16 +1600,15 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
INT64_MAX);
if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
- RD_COST tmp_rdc = {0, 0, 0};
+ RD_COST tmp_rdc;
PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
+ vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
subsize, &pc_tree->horizontal[1], INT64_MAX);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1619,17 +1621,16 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
subsize, &pc_tree->vertical[0], INT64_MAX);
if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
- RD_COST tmp_rdc = {0, 0, 0};
+ RD_COST tmp_rdc;
PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
+ vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
INT64_MAX);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1650,19 +1651,17 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
int x_idx = (i & 1) * (mi_step >> 1);
int y_idx = (i >> 1) * (mi_step >> 1);
int jj = i >> 1, ii = i & 0x01;
- RD_COST tmp_rdc = {0, 0, 0};
-
+ RD_COST tmp_rdc;
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
+ vp9_rd_cost_init(&tmp_rdc);
rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
mi_row + y_idx, mi_col + x_idx, subsize,
&tmp_rdc.rate, &tmp_rdc.dist,
i != 3, pc_tree->split[i]);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1709,15 +1708,12 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
pc_tree->split[i]->partitioning = PARTITION_NONE;
rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
- split_subsize, &pc_tree->split[i]->none,
- INT64_MAX);
+ split_subsize, &pc_tree->split[i]->none, INT64_MAX);
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- chosen_rdc.rate = INT_MAX;
- chosen_rdc.dist = INT64_MAX;
- chosen_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&chosen_rdc);
break;
}
@@ -2122,9 +2118,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i, pl;
BLOCK_SIZE subsize;
- RD_COST this_rdc = {0, 0, 0};
- RD_COST sum_rdc = {0, 0, 0};
- RD_COST best_rdc = {INT_MAX, INT64_MAX, best_rd};
+ RD_COST this_rdc, sum_rdc, best_rdc;
int do_split = bsize >= BLOCK_8X8;
int do_rect = 1;
@@ -2152,6 +2146,11 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
assert(num_8x8_blocks_wide_lookup[bsize] ==
num_8x8_blocks_high_lookup[bsize]);
+ vp9_rd_cost_init(&this_rdc);
+ vp9_rd_cost_init(&sum_rdc);
+ vp9_rd_cost_reset(&best_rdc);
+ best_rdc.rdcost = best_rd;
+
set_offsets(cpi, tile, mi_row, mi_col, bsize);
if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode)