From 90d13337daa6ab282ef4f2492ab069d440f600f2 Mon Sep 17 00:00:00 2001 From: Deb Mukherjee Date: Tue, 25 Feb 2014 17:22:34 -0800 Subject: [PATCH] Refines variance based partitioning search Instead of using source variance, this patch uses variance of the frame difference between the source and the current frame to make fixed size partition decisions. Also disables adjusting partitioning if variance based or fixed size partitioning is used. The latter change improves the speed substantially for speed 6, so that speed 7 is now less than 3x the speed of speed 6. But speed 6 is 48% better in psnr on the rtc set compared to speed 7. As compared to speed 5, speed 6 is -37% in psnr at about 2.5x the speed, speed 7 is -55% in psnr at about 7x the speed. Change-Id: If61d80431d3e04ed304ac05832e773cdb2c0a578 --- vp9/encoder/vp9_encodeframe.c | 59 ++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index a9b51e0d4..b77af8c90 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -94,7 +94,8 @@ static const uint8_t VP9_VAR_OFFS[64] = { 128, 128, 128, 128, 128, 128, 128, 128 }; -static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x, +static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, + MACROBLOCK *x, BLOCK_SIZE bs) { unsigned int var, sse; var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, x->plane[0].src.stride, @@ -102,19 +103,49 @@ static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x, return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]); } -static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi) { - unsigned int var = get_sby_perpixel_variance(cpi, &cpi->mb, BLOCK_64X64); - if (var < 256) +static unsigned int get_sby_perpixel_diff_variance(VP9_COMP *cpi, + MACROBLOCK *x, + int mi_row, + int mi_col, + BLOCK_SIZE bs) { + const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME); + int offset = (mi_row * MI_SIZE) * yv12->y_stride + (mi_col * MI_SIZE); + unsigned int var, sse; + var = cpi->fn_ptr[bs].vf(x->plane[0].src.buf, + x->plane[0].src.stride, + yv12->y_buffer + offset, + yv12->y_stride, + &sse); + return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]); +} + +static BLOCK_SIZE get_rd_var_based_fixed_partition(VP9_COMP *cpi, + int mi_row, + int mi_col) { + unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb, + mi_row, mi_col, + BLOCK_64X64); + if (var < 8) return BLOCK_64X64; - else + else if (var < 128) return BLOCK_32X32; + else if (var < 2048) + return BLOCK_16X16; + else + return BLOCK_8X8; } -static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi) { - unsigned int var = get_sby_perpixel_variance(cpi, &cpi->mb, BLOCK_64X64); - if (var < 1024) +static BLOCK_SIZE get_nonrd_var_based_fixed_partition(VP9_COMP *cpi, + int mi_row, + int mi_col) { + unsigned int var = get_sby_perpixel_diff_variance(cpi, &cpi->mb, + mi_row, mi_col, + BLOCK_64X64); + if (var < 8) + return BLOCK_64X64; + else if (var < 64) return BLOCK_32X32; - else if (var < 4096) + else if (var < 2048) return BLOCK_16X16; else return BLOCK_8X8; @@ -1262,7 +1293,8 @@ static void rd_use_partition(VP9_COMP *cpi, x->mb_energy = vp9_block_energy(cpi, x, bsize); } - if (cpi->sf.adjust_partitioning_from_last_frame) { + if (cpi->sf.partition_search_type == SEARCH_PARTITION && + cpi->sf.adjust_partitioning_from_last_frame) { // Check if any of the sub blocks are further split. if (partition == PARTITION_SPLIT && subsize > BLOCK_8X8) { sub_subsize = get_subsize(subsize, PARTITION_SPLIT); @@ -1387,6 +1419,7 @@ static void rd_use_partition(VP9_COMP *cpi, last_part_rate += x->partition_cost[pl][partition]; if (cpi->sf.adjust_partitioning_from_last_frame + && cpi->sf.partition_search_type == SEARCH_PARTITION && partition != PARTITION_SPLIT && bsize > BLOCK_8X8 && (mi_row + ms < cm->mi_rows || mi_row + (ms >> 1) == cm->mi_rows) && (mi_col + ms < cm->mi_cols || mi_col + (ms >> 1) == cm->mi_cols)) { @@ -1986,7 +2019,7 @@ static void encode_rd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, // map to the same thing. BLOCK_SIZE bsize; set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); - bsize = get_rd_var_based_fixed_partition(cpi); + bsize = get_rd_var_based_fixed_partition(cpi, mi_row, mi_col); set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize); rd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, &dummy_rate, &dummy_dist, 1); @@ -2368,7 +2401,9 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile, // TODO(debargha): Implement VAR_BASED_PARTITION as a separate case. // Currently both VAR_BASED_FIXED_PARTITION/VAR_BASED_PARTITION // map to the same thing. - BLOCK_SIZE bsize = get_nonrd_var_based_fixed_partition(cpi); + BLOCK_SIZE bsize = get_nonrd_var_based_fixed_partition(cpi, + mi_row, + mi_col); nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, bsize, &dummy_rate, &dummy_dist, 1); } else { -- 2.40.0