summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Chen <chengchen@google.com>2021-06-17 15:36:18 -0700
committerCheng Chen <chengchen@google.com>2021-06-25 16:31:58 -0700
commitfe1c7d2d8cce13d9cd1edfe11a6703e5521ae561 (patch)
tree536821981b47221dcc23a1b8a748b5fd301b0056
parenteebc5cd487a89c51ba148f6d6ac45779970f72d7 (diff)
downloadlibvpx-fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561.tar.gz
Disallow skipping transform and quantization
The encoder has a feature to skip transform and quantization based on model rd analysis. It could happen that the model based analysis lets the encoder skips transform and quantization, while a bad prediction occurs, leading to bad reconstructed blocks, which are intrusive and apparently coding errors. We add a speed feature to guard the skipping feature. Due to the risk of bad perceptual quality, we disallow such skipping by default. On hdres test set, speed 2, the coding performance difference is 0.025%, speed difference is 1.2%, which can be considered non significant. BUG=webm:1729 Change-Id: I48af01ae8dcc7a76c05c695f3f3e68b866c89574
-rw-r--r--vp9/encoder/vp9_block.h3
-rw-r--r--vp9/encoder/vp9_rdopt.c23
-rw-r--r--vp9/encoder/vp9_speed_features.c1
-rw-r--r--vp9/encoder/vp9_speed_features.h6
4 files changed, 20 insertions, 13 deletions
diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h
index 37a4605ad..20294b4b9 100644
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -157,6 +157,9 @@ struct macroblock {
// skip forward transform and quantization
uint8_t skip_txfm[MAX_MB_PLANE << 2];
#define SKIP_TXFM_NONE 0
+// TODO(chengchen): consider remove SKIP_TXFM_AC_DC from vp9 completely
+// since it increases risks of bad perceptual quality.
+// https://crbug.com/webm/1729
#define SKIP_TXFM_AC_DC 1
#define SKIP_TXFM_AC_ONLY 2
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 37de4e483..a1687dcf4 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -745,8 +745,8 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
MODE_INFO *const mi = xd->mi[0];
int64_t rd1, rd2, rd;
int rate;
- int64_t dist;
- int64_t sse;
+ int64_t dist = INT64_MAX;
+ int64_t sse = INT64_MAX;
const int coeff_ctx =
combine_entropy_contexts(args->t_left[blk_row], args->t_above[blk_col]);
struct buf_2d *recon = args->this_recon;
@@ -799,6 +799,13 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
if (max_txsize_lookup[plane_bsize] == tx_size)
skip_txfm_flag = x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))];
+ // This reduces the risk of bad perceptual quality due to bad prediction.
+ // We always force the encoder to perform transform and quantization.
+ if (!args->cpi->sf.allow_skip_txfm_ac_dc &&
+ skip_txfm_flag == SKIP_TXFM_AC_DC) {
+ skip_txfm_flag = SKIP_TXFM_NONE;
+ }
+
if (skip_txfm_flag == SKIP_TXFM_NONE ||
(recon && skip_txfm_flag == SKIP_TXFM_AC_ONLY)) {
// full forward transform and quantization
@@ -827,17 +834,7 @@ static void block_rd_txfm(int plane, int block, int blk_row, int blk_col,
dist = VPXMAX(0, sse - dc_correct);
}
} else {
- // SKIP_TXFM_AC_DC
- // skip forward transform. Because this is handled here, the quantization
- // does not need to do it.
- x->plane[plane].eobs[block] = 0;
- sse = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
- dist = sse;
- if (recon) {
- uint8_t *rec_ptr = &recon->buf[4 * (blk_row * recon->stride + blk_col)];
- copy_block_visible(xd, pd, dst, dst_stride, rec_ptr, recon->stride,
- blk_row, blk_col, plane_bsize, tx_bsize);
- }
+ assert(0 && "allow_skip_txfm_ac_dc does not allow SKIP_TXFM_AC_DC.");
}
}
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 585c9604c..fc7a67c9f 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -940,6 +940,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi, int speed) {
sf->enable_tpl_model = oxcf->enable_tpl_model;
sf->prune_ref_frame_for_rect_partitions = 0;
sf->temporal_filter_search_method = MESH;
+ sf->allow_skip_txfm_ac_dc = 0;
for (i = 0; i < TX_SIZES; i++) {
sf->intra_y_mode_mask[i] = INTRA_ALL;
diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h
index ca284ded8..5ea04709e 100644
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -612,6 +612,12 @@ typedef struct SPEED_FEATURES {
// For real-time mode: force DC only under intra search when content
// does not have high souce SAD.
int rt_intra_dc_only_low_content;
+
+ // The encoder has a feature that skips forward transform and quantization
+ // based on a model rd estimation to reduce encoding time.
+ // However, this feature is dangerous since it could lead to bad perceptual
+ // quality. This flag is added to guard the feature.
+ int allow_skip_txfm_ac_dc;
} SPEED_FEATURES;
struct VP9_COMP;