diff options
Diffstat (limited to 'vp9/encoder/vp9_encodeframe.c')
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 129 |
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) |