Commit cae03a7e authored by Yunqing Wang's avatar Yunqing Wang
Browse files

Set vbp thresholds for aq3 boosted blocks

The vbp thresholds are set seperately for boosted/non-boosted
superblocks according to their segment_id. This way we don't
have to force the boosted blocks to split to 32x32.

Speed 6 RTC set borg test result showed some quality gains.
Overall PSNR: +0.199%; Avg PSNR: +0.245%; SSIM: +0.802%.
No speed change was observed.

Change-Id: I37c6643a3e2da59c4b7dc10ebe05abc8abf4026a
parent a0043c6d
...@@ -474,7 +474,7 @@ static int set_vt_partitioning(VP9_COMP *cpi, ...@@ -474,7 +474,7 @@ static int set_vt_partitioning(VP9_COMP *cpi,
} }
void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) { void vp9_set_vbp_thresholds(VP9_COMP *cpi, int64_t thresholds[], int q) {
SPEED_FEATURES *const sf = &cpi->sf; SPEED_FEATURES *const sf = &cpi->sf;
if (sf->partition_search_type != VAR_BASED_PARTITION && if (sf->partition_search_type != VAR_BASED_PARTITION &&
sf->partition_search_type != REFERENCE_PARTITION) { sf->partition_search_type != REFERENCE_PARTITION) {
...@@ -491,20 +491,23 @@ void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) { ...@@ -491,20 +491,23 @@ void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) {
// If 4x4 partition is not used, then 8x8 partition will be selected // If 4x4 partition is not used, then 8x8 partition will be selected
// if variance of 16x16 block is very high, so use larger threshold // if variance of 16x16 block is very high, so use larger threshold
// for 16x16 (threshold_bsize_min) in that case. // for 16x16 (threshold_bsize_min) in that case.
// Array index: 0 - threshold_64x64; 1 - threshold_32x32;
// 2 - threshold_16x16; 3 - vbp_threshold_8x8;
if (is_key_frame) { if (is_key_frame) {
cpi->vbp_threshold_64x64 = threshold_base; thresholds[0] = threshold_base;
cpi->vbp_threshold_32x32 = threshold_base >> 2; thresholds[1] = threshold_base >> 2;
cpi->vbp_threshold_16x16 = threshold_base >> 2; thresholds[2] = threshold_base >> 2;
cpi->vbp_threshold_8x8 = threshold_base << 2; thresholds[3] = threshold_base << 2;
cpi->vbp_bsize_min = BLOCK_8X8; cpi->vbp_bsize_min = BLOCK_8X8;
} else { } else {
cpi->vbp_threshold_32x32 = threshold_base; thresholds[1] = threshold_base;
if (cm->width <= 352 && cm->height <= 288) { if (cm->width <= 352 && cm->height <= 288) {
cpi->vbp_threshold_64x64 = threshold_base >> 2; thresholds[0] = threshold_base >> 2;
cpi->vbp_threshold_16x16 = threshold_base << 3; thresholds[2] = threshold_base << 3;
} else { } else {
cpi->vbp_threshold_64x64 = threshold_base; thresholds[0] = threshold_base;
cpi->vbp_threshold_16x16 = threshold_base << cpi->oxcf.speed; thresholds[2] = threshold_base << cpi->oxcf.speed;
} }
cpi->vbp_bsize_min = BLOCK_16X16; cpi->vbp_bsize_min = BLOCK_16X16;
} }
...@@ -528,6 +531,8 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -528,6 +531,8 @@ static void choose_partitioning(VP9_COMP *cpi,
int sp; int sp;
int dp; int dp;
int pixels_wide = 64, pixels_high = 64; int pixels_wide = 64, pixels_high = 64;
int64_t thresholds[4] = {cpi->vbp_thresholds[0], cpi->vbp_thresholds[1],
cpi->vbp_thresholds[2], cpi->vbp_thresholds[3]};
// Always use 4x4 partition for key frame. // Always use 4x4 partition for key frame.
const int is_key_frame = (cm->frame_type == KEY_FRAME); const int is_key_frame = (cm->frame_type == KEY_FRAME);
...@@ -540,6 +545,11 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -540,6 +545,11 @@ static void choose_partitioning(VP9_COMP *cpi,
const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map : const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map :
cm->last_frame_seg_map; cm->last_frame_seg_map;
segment_id = vp9_get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col); segment_id = vp9_get_segment_id(cm, map, BLOCK_64X64, mi_row, mi_col);
if (cyclic_refresh_segment_id_boosted(segment_id)) {
int q = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
vp9_set_vbp_thresholds(cpi, thresholds, q);
}
} }
set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64); set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
...@@ -691,7 +701,7 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -691,7 +701,7 @@ static void choose_partitioning(VP9_COMP *cpi,
} }
if (is_key_frame || (low_res && if (is_key_frame || (low_res &&
vt.split[i].split[j].part_variances.none.variance > vt.split[i].split[j].part_variances.none.variance >
(cpi->vbp_threshold_32x32 << 1))) { (thresholds[1] << 1))) {
// Go down to 4x4 down-sampling for variance. // Go down to 4x4 down-sampling for variance.
variance4x4downsample[i2 + j] = 1; variance4x4downsample[i2 + j] = 1;
for (k = 0; k < 4; k++) { for (k = 0; k < 4; k++) {
...@@ -735,11 +745,6 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -735,11 +745,6 @@ 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. // Fill the rest of the variance tree by summing split partition values.
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
const int i2 = i << 2; const int i2 = i << 2;
...@@ -756,7 +761,7 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -756,7 +761,7 @@ static void choose_partitioning(VP9_COMP *cpi,
// If variance of this 32x32 block is above the threshold, force the block // 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. // to split. This also forces a split on the upper (64x64) level.
get_variance(&vt.split[i].part_variances.none); get_variance(&vt.split[i].part_variances.none);
if (vt.split[i].part_variances.none.variance > cpi->vbp_threshold_32x32) { if (vt.split[i].part_variances.none.variance > thresholds[1]) {
force_split[i + 1] = 1; force_split[i + 1] = 1;
force_split[0] = 1; force_split[0] = 1;
} }
...@@ -768,16 +773,15 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -768,16 +773,15 @@ static void choose_partitioning(VP9_COMP *cpi,
// we get to one that's got a variance lower than our threshold. // 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 || 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, !set_vt_partitioning(cpi, xd, &vt, BLOCK_64X64, mi_row, mi_col,
cpi->vbp_threshold_64x64, BLOCK_16X16, thresholds[0], BLOCK_16X16, force_split[0])) {
force_split[0])) {
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
const int x32_idx = ((i & 1) << 2); const int x32_idx = ((i & 1) << 2);
const int y32_idx = ((i >> 1) << 2); const int y32_idx = ((i >> 1) << 2);
const int i2 = i << 2; const int i2 = i << 2;
if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32, if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32,
(mi_row + y32_idx), (mi_col + x32_idx), (mi_row + y32_idx), (mi_col + x32_idx),
cpi->vbp_threshold_32x32, thresholds[1], BLOCK_16X16,
BLOCK_16X16, force_split[i + 1])) { force_split[i + 1])) {
for (j = 0; j < 4; ++j) { for (j = 0; j < 4; ++j) {
const int x16_idx = ((j & 1) << 1); const int x16_idx = ((j & 1) << 1);
const int y16_idx = ((j >> 1) << 1); const int y16_idx = ((j >> 1) << 1);
...@@ -790,8 +794,7 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -790,8 +794,7 @@ static void choose_partitioning(VP9_COMP *cpi,
if (!set_vt_partitioning(cpi, xd, vtemp, BLOCK_16X16, if (!set_vt_partitioning(cpi, xd, vtemp, BLOCK_16X16,
mi_row + y32_idx + y16_idx, mi_row + y32_idx + y16_idx,
mi_col + x32_idx + x16_idx, mi_col + x32_idx + x16_idx,
cpi->vbp_threshold_16x16, thresholds[2], cpi->vbp_bsize_min, 0)) {
cpi->vbp_bsize_min, 0)) {
for (k = 0; k < 4; ++k) { for (k = 0; k < 4; ++k) {
const int x8_idx = (k & 1); const int x8_idx = (k & 1);
const int y8_idx = (k >> 1); const int y8_idx = (k >> 1);
...@@ -800,8 +803,7 @@ static void choose_partitioning(VP9_COMP *cpi, ...@@ -800,8 +803,7 @@ static void choose_partitioning(VP9_COMP *cpi,
BLOCK_8X8, BLOCK_8X8,
mi_row + y32_idx + y16_idx + y8_idx, mi_row + y32_idx + y16_idx + y8_idx,
mi_col + x32_idx + x16_idx + x8_idx, mi_col + x32_idx + x16_idx + x8_idx,
cpi->vbp_threshold_8x8, thresholds[3], BLOCK_8X8, 0)) {
BLOCK_8X8, 0)) {
set_block_size(cpi, xd, set_block_size(cpi, xd,
(mi_row + y32_idx + y16_idx + y8_idx), (mi_row + y32_idx + y16_idx + y8_idx),
(mi_col + x32_idx + x16_idx + x8_idx), (mi_col + x32_idx + x16_idx + x8_idx),
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#ifndef VP9_ENCODER_VP9_ENCODEFRAME_H_ #ifndef VP9_ENCODER_VP9_ENCODEFRAME_H_
#define VP9_ENCODER_VP9_ENCODEFRAME_H_ #define VP9_ENCODER_VP9_ENCODEFRAME_H_
#include "vpx/vpx_integer.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -38,7 +40,7 @@ void vp9_init_tile_data(struct VP9_COMP *cpi); ...@@ -38,7 +40,7 @@ void vp9_init_tile_data(struct VP9_COMP *cpi);
void vp9_encode_tile(struct VP9_COMP *cpi, struct ThreadData *td, void vp9_encode_tile(struct VP9_COMP *cpi, struct ThreadData *td,
int tile_row, int tile_col); int tile_row, int tile_col);
void vp9_set_vbp_thresholds(struct VP9_COMP *cpi, int q); void vp9_set_vbp_thresholds(struct VP9_COMP *cpi, int64_t thresholds[], int q);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
......
...@@ -2958,7 +2958,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi) { ...@@ -2958,7 +2958,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi) {
set_size_dependent_vars(cpi, &q, &bottom_index, &top_index); set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
vp9_set_quantizer(cm, q); vp9_set_quantizer(cm, q);
vp9_set_vbp_thresholds(cpi, q); vp9_set_vbp_thresholds(cpi, cpi->vbp_thresholds, q);
setup_frame(cpi); setup_frame(cpi);
......
...@@ -460,10 +460,9 @@ typedef struct VP9_COMP { ...@@ -460,10 +460,9 @@ typedef struct VP9_COMP {
int resize_pending; int resize_pending;
// VAR_BASED_PARTITION thresholds // VAR_BASED_PARTITION thresholds
int64_t vbp_threshold_64x64; // 0 - threshold_64x64; 1 - threshold_32x32;
int64_t vbp_threshold_32x32; // 2 - threshold_16x16; 3 - vbp_threshold_8x8;
int64_t vbp_threshold_16x16; int64_t vbp_thresholds[4];
int64_t vbp_threshold_8x8;
BLOCK_SIZE vbp_bsize_min; BLOCK_SIZE vbp_bsize_min;
// Multi-threading // Multi-threading
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment