| Index: source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_encodeframe.c b/source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| index 186c6e0f4e091765265b0b0d3c505e3e2cf7ba99..ac9de21cce2696102348c0d595b1296d36d5c90b 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_encodeframe.c
|
| @@ -44,12 +44,6 @@
|
| #include "vp9/encoder/vp9_segmentation.h"
|
| #include "vp9/encoder/vp9_tokenize.h"
|
|
|
| -#define GF_ZEROMV_ZBIN_BOOST 0
|
| -#define LF_ZEROMV_ZBIN_BOOST 0
|
| -#define MV_ZBIN_BOOST 0
|
| -#define SPLIT_MV_ZBIN_BOOST 0
|
| -#define INTRA_ZBIN_BOOST 0
|
| -
|
| static void encode_superblock(VP9_COMP *cpi, ThreadData * td,
|
| TOKENEXTRA **t, int output_enabled,
|
| int mi_row, int mi_col, BLOCK_SIZE bsize,
|
| @@ -406,7 +400,7 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
| int mi_col,
|
| int64_t threshold,
|
| BLOCK_SIZE bsize_min,
|
| - int segment_id) {
|
| + int force_split) {
|
| VP9_COMMON * const cm = &cpi->common;
|
| variance_node vt;
|
| const int block_width = num_8x8_blocks_wide_lookup[bsize];
|
| @@ -415,8 +409,7 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
| assert(block_height == block_width);
|
| tree_to_node(data, bsize, &vt);
|
|
|
| - // No 64x64 blocks on segments other than base (un-boosted) segment.
|
| - if (cyclic_refresh_segment_id_boosted(segment_id) && bsize == BLOCK_64X64)
|
| + if (force_split)
|
| return 0;
|
|
|
| // For bsize=bsize_min (16x16/8x8 for 8x8/4x4 downsampling), select if
|
| @@ -432,7 +425,9 @@ static int set_vt_partitioning(VP9_COMP *cpi,
|
| }
|
| return 0;
|
| } else if (bsize > bsize_min) {
|
| - get_variance(&vt.part_variances->none);
|
| + // Variance is already computed for 32x32 blocks to set the force_split.
|
| + if (bsize != BLOCK_32X32)
|
| + get_variance(&vt.part_variances->none);
|
| // For key frame or low_res: for bsize above 32X32 or very high variance,
|
| // take split.
|
| if (cm->frame_type == KEY_FRAME &&
|
| @@ -486,32 +481,34 @@ void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) {
|
| return;
|
| } else {
|
| VP9_COMMON *const cm = &cpi->common;
|
| - const VP9EncoderConfig *const oxcf = &cpi->oxcf;
|
| const int is_key_frame = (cm->frame_type == KEY_FRAME);
|
| - const int use_4x4_partition = is_key_frame;
|
| - const int low_res = (cm->width <= 352 && cm->height <= 288);
|
| const int threshold_multiplier = is_key_frame ? 80 : 4;
|
| const int64_t threshold_base = (int64_t)(threshold_multiplier *
|
| vp9_convert_qindex_to_q(q, cm->bit_depth));
|
| - cpi->vbp_threshold = threshold_base;
|
| - cpi->vbp_threshold_bsize_min = threshold_base << oxcf->speed;
|
| - cpi->vbp_threshold_bsize_max = threshold_base;
|
|
|
| - if (is_key_frame) {
|
| - cpi->vbp_threshold = threshold_base >> 2;
|
| - cpi->vbp_threshold_bsize_min = threshold_base << 2;
|
| - } else if (low_res) {
|
| - cpi->vbp_threshold_bsize_min = threshold_base << 3;
|
| - cpi->vbp_threshold_bsize_max = threshold_base >> 2;
|
| - }
|
| // TODO(marpan): Allow 4x4 partitions for inter-frames.
|
| // use_4x4_partition = (variance4x4downsample[i2 + j] == 1);
|
| // If 4x4 partition is not used, then 8x8 partition will be selected
|
| // if variance of 16x16 block is very high, so use larger threshold
|
| // for 16x16 (threshold_bsize_min) in that case.
|
| - cpi->vbp_threshold_16x16 = (use_4x4_partition) ?
|
| - cpi->vbp_threshold : cpi->vbp_threshold_bsize_min;
|
| - cpi->vbp_bsize_min = (use_4x4_partition) ? BLOCK_8X8 : BLOCK_16X16;
|
| + if (is_key_frame) {
|
| + cpi->vbp_threshold = threshold_base >> 2;
|
| + cpi->vbp_threshold_bsize_max = threshold_base;
|
| + cpi->vbp_threshold_bsize_min = threshold_base << 2;
|
| + cpi->vbp_threshold_16x16 = cpi->vbp_threshold;
|
| + cpi->vbp_bsize_min = BLOCK_8X8;
|
| + } else {
|
| + cpi->vbp_threshold = threshold_base;
|
| + if (cm->width <= 352 && cm->height <= 288) {
|
| + cpi->vbp_threshold_bsize_max = threshold_base >> 2;
|
| + cpi->vbp_threshold_bsize_min = threshold_base << 3;
|
| + } else {
|
| + cpi->vbp_threshold_bsize_max = threshold_base;
|
| + cpi->vbp_threshold_bsize_min = threshold_base << cpi->oxcf.speed;
|
| + }
|
| + cpi->vbp_threshold_16x16 = cpi->vbp_threshold_bsize_min;
|
| + cpi->vbp_bsize_min = BLOCK_16X16;
|
| + }
|
| }
|
| }
|
|
|
| @@ -526,6 +523,7 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| int i, j, k, m;
|
| v64x64 vt;
|
| v16x16 vt2[16];
|
| + int force_split[5];
|
| uint8_t *s;
|
| const uint8_t *d;
|
| int sp;
|
| @@ -643,12 +641,15 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| #endif // CONFIG_VP9_HIGHBITDEPTH
|
| }
|
|
|
| + // Index for force_split: 0 for 64x64, 1-4 for 32x32 blocks,
|
| + force_split[0] = 0;
|
| // Fill in the entire tree of 8x8 (or 4x4 under some conditions) variances
|
| // for splits.
|
| for (i = 0; i < 4; i++) {
|
| const int x32_idx = ((i & 1) << 5);
|
| const int y32_idx = ((i >> 1) << 5);
|
| const int i2 = i << 2;
|
| + force_split[i + 1] = 0;
|
| for (j = 0; j < 4; j++) {
|
| const int x16_idx = x32_idx + ((j & 1) << 4);
|
| const int y16_idx = y32_idx + ((j >> 1) << 4);
|
| @@ -658,29 +659,29 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| for (k = 0; k < 4; k++) {
|
| int x8_idx = x16_idx + ((k & 1) << 3);
|
| int y8_idx = y16_idx + ((k >> 1) << 3);
|
| - unsigned int sse = 0;
|
| - int sum = 0;
|
| - if (x8_idx < pixels_wide && y8_idx < pixels_high) {
|
| - int s_avg, d_avg;
|
| + unsigned int sse = 0;
|
| + int sum = 0;
|
| + if (x8_idx < pixels_wide && y8_idx < pixels_high) {
|
| + int s_avg, d_avg;
|
| #if CONFIG_VP9_HIGHBITDEPTH
|
| - if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| - s_avg = vp9_highbd_avg_8x8(s + y8_idx * sp + x8_idx, sp);
|
| - d_avg = vp9_highbd_avg_8x8(d + y8_idx * dp + x8_idx, dp);
|
| - } else {
|
| - s_avg = vp9_avg_8x8(s + y8_idx * sp + x8_idx, sp);
|
| - d_avg = vp9_avg_8x8(d + y8_idx * dp + x8_idx, dp);
|
| - }
|
| -#else
|
| + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| + s_avg = vp9_highbd_avg_8x8(s + y8_idx * sp + x8_idx, sp);
|
| + d_avg = vp9_highbd_avg_8x8(d + y8_idx * dp + x8_idx, dp);
|
| + } else {
|
| s_avg = vp9_avg_8x8(s + y8_idx * sp + x8_idx, sp);
|
| d_avg = vp9_avg_8x8(d + y8_idx * dp + x8_idx, dp);
|
| -#endif
|
| - sum = s_avg - d_avg;
|
| - sse = sum * sum;
|
| }
|
| - // If variance is based on 8x8 downsampling, we stop here and have
|
| - // one sample for 8x8 block (so use 1 for count in fill_variance),
|
| - // which of course means variance = 0 for 8x8 block.
|
| - fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
|
| +#else
|
| + s_avg = vp9_avg_8x8(s + y8_idx * sp + x8_idx, sp);
|
| + d_avg = vp9_avg_8x8(d + y8_idx * dp + x8_idx, dp);
|
| +#endif
|
| + sum = s_avg - d_avg;
|
| + sse = sum * sum;
|
| + }
|
| + // If variance is based on 8x8 downsampling, we stop here and have
|
| + // one sample for 8x8 block (so use 1 for count in fill_variance),
|
| + // which of course means variance = 0 for 8x8 block.
|
| + fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
|
| }
|
| fill_variance_tree(&vt.split[i].split[j], BLOCK_16X16);
|
| // For low-resolution, compute the variance based on 8x8 down-sampling,
|
| @@ -735,6 +736,11 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| }
|
| }
|
|
|
| + // No 64x64 blocks on segments other than base (un-boosted) segment,
|
| + // so force split.
|
| + if (cyclic_refresh_segment_id_boosted(segment_id))
|
| + force_split[0] = 1;
|
| +
|
| // Fill the rest of the variance tree by summing split partition values.
|
| for (i = 0; i < 4; i++) {
|
| const int i2 = i << 2;
|
| @@ -742,22 +748,29 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| if (variance4x4downsample[i2 + j] == 1) {
|
| v16x16 *vtemp = (!is_key_frame) ? &vt2[i2 + j] :
|
| &vt.split[i].split[j];
|
| - for (m = 0; m < 4; m++) {
|
| + for (m = 0; m < 4; m++)
|
| fill_variance_tree(&vtemp->split[m], BLOCK_8X8);
|
| - }
|
| fill_variance_tree(vtemp, BLOCK_16X16);
|
| }
|
| }
|
| fill_variance_tree(&vt.split[i], BLOCK_32X32);
|
| + // If variance of this 32x32 block is above the threshold, force the block
|
| + // to split. This also forces a split on the upper (64x64) level.
|
| + get_variance(&vt.split[i].part_variances.none);
|
| + if (vt.split[i].part_variances.none.variance > cpi->vbp_threshold) {
|
| + force_split[i + 1] = 1;
|
| + force_split[0] = 1;
|
| + }
|
| }
|
| - fill_variance_tree(&vt, BLOCK_64X64);
|
| + if (!force_split[0])
|
| + fill_variance_tree(&vt, BLOCK_64X64);
|
|
|
| // Now go through the entire structure, splitting every block size until
|
| // we get to one that's got a variance lower than our threshold.
|
| if ( mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows ||
|
| !set_vt_partitioning(cpi, xd, &vt, BLOCK_64X64, mi_row, mi_col,
|
| cpi->vbp_threshold_bsize_max, BLOCK_16X16,
|
| - segment_id)) {
|
| + force_split[0])) {
|
| for (i = 0; i < 4; ++i) {
|
| const int x32_idx = ((i & 1) << 2);
|
| const int y32_idx = ((i >> 1) << 2);
|
| @@ -765,7 +778,7 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32,
|
| (mi_row + y32_idx), (mi_col + x32_idx),
|
| cpi->vbp_threshold,
|
| - BLOCK_16X16, segment_id)) {
|
| + BLOCK_16X16, force_split[i + 1])) {
|
| for (j = 0; j < 4; ++j) {
|
| const int x16_idx = ((j & 1) << 1);
|
| const int y16_idx = ((j >> 1) << 1);
|
| @@ -779,7 +792,7 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| mi_row + y32_idx + y16_idx,
|
| mi_col + x32_idx + x16_idx,
|
| cpi->vbp_threshold_16x16,
|
| - cpi->vbp_bsize_min, segment_id)) {
|
| + cpi->vbp_bsize_min, 0)) {
|
| for (k = 0; k < 4; ++k) {
|
| const int x8_idx = (k & 1);
|
| const int y8_idx = (k >> 1);
|
| @@ -789,7 +802,7 @@ static void choose_partitioning(VP9_COMP *cpi,
|
| mi_row + y32_idx + y16_idx + y8_idx,
|
| mi_col + x32_idx + x16_idx + x8_idx,
|
| cpi->vbp_threshold_bsize_min,
|
| - BLOCK_8X8, segment_id)) {
|
| + BLOCK_8X8, 0)) {
|
| set_block_size(cpi, xd,
|
| (mi_row + y32_idx + y16_idx + y8_idx),
|
| (mi_col + x32_idx + x16_idx + x8_idx),
|
|
|