diff options
author | Cheng Chen <chengchen@google.com> | 2021-06-17 15:36:18 -0700 |
---|---|---|
committer | Cheng Chen <chengchen@google.com> | 2021-06-25 16:31:58 -0700 |
commit | fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561 (patch) | |
tree | 536821981b47221dcc23a1b8a748b5fd301b0056 | |
parent | eebc5cd487a89c51ba148f6d6ac45779970f72d7 (diff) | |
download | libvpx-fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561.tar libvpx-fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561.tar.gz libvpx-fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561.tar.bz2 libvpx-fe1c7d2d8cce13d9cd1edfe11a6703e5521ae561.zip |
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.h | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 23 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.c | 1 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.h | 6 |
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; |