rtc-screen: Reduce color artifacts in screen
Adjustments to reduce color artifacts for screen:
-condition testing GF sad on content_state
-skip testing zero motion mode (when sb block has motion)
only if color_sensitivity is set to 0
-force intra check for flat blocks with color on/1
-use larger spatial threshold to set color off/0
This reduces color artifacts observed in 4K test clip.
For rtc_screen set (1080p and 720p) at speed 10:
bdrate change is overall neutral (~0.04/0.3 for avg/ovr psnr),
small IC (instruction count) reduction of ~0.65.
Negligible effect for video mode: only first item
above affects video, but this leads to small IC reduction.
Change-Id: Ied9ece45b4822d2a6fb7e0a7a8fefdfcd1bfab70
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 40220f1..e0621d8 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2119,8 +2119,11 @@
inter_mode_thresh = RDCOST(x->rdmult, intra_cost_penalty, 0);
do_early_exit_rdthresh = 0;
}
- if (x->source_variance < AOMMAX(50, (spatial_var_thresh >> 1)) &&
- x->content_state_sb.source_sad_nonrd >= kHighSad)
+ if ((x->source_variance < AOMMAX(50, (spatial_var_thresh >> 1)) &&
+ x->content_state_sb.source_sad_nonrd >= kHighSad) ||
+ (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
+ x->source_variance == 0 &&
+ (x->color_sensitivity[0] == 1 || x->color_sensitivity[1] == 1)))
force_intra_check = 1;
// For big blocks worth checking intra (since only DC will be checked),
// even if best_early_term is set.
@@ -2376,13 +2379,15 @@
NOISE_LEVEL noise_level = kLow;
int norm_sad =
y_sad >> (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+ unsigned int thresh_spatial = (cpi->common.width > 1920) ? 5000 : 1000;
// If the spatial source variance is high and the normalized y_sad
// is low, then y-channel is likely good for mode estimation, so keep
// color_sensitivity off. For low noise content for now, since there is
// some bdrate regression for noisy color clip.
if (cpi->noise_estimate.enabled)
noise_level = av1_noise_estimate_extract_level(&cpi->noise_estimate);
- if (noise_level == kLow && source_variance > 1000 && norm_sad < 50) {
+ if (noise_level == kLow && source_variance > thresh_spatial &&
+ norm_sad < 50) {
x->color_sensitivity[0] = 0;
x->color_sensitivity[1] = 0;
return;
@@ -2844,7 +2849,8 @@
if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN) {
// If source_sad is computed: skip non-zero motion
// check for stationary (super)blocks. Otherwise if superblock
- // has motion skip the modes with zero motion for flat blocks.
+ // has motion skip the modes with zero motion for flat blocks,
+ // and color is not set.
// For the latter condition: the same condition should apply
// to newmv if (0, 0), so this latter condition is repeated
// below after search_new_mv.
@@ -2853,6 +2859,8 @@
x->content_state_sb.source_sad_nonrd == kZeroSad) ||
(frame_mv[this_mode][ref_frame].as_int == 0 &&
x->content_state_sb.source_sad_nonrd != kZeroSad &&
+ ((x->color_sensitivity[0] == 0 && x->color_sensitivity[1] == 0) ||
+ cpi->rc.high_source_sad) &&
x->source_variance == 0))
continue;
}
@@ -2935,12 +2943,14 @@
if (skip_this_mv && !comp_pred) continue;
// For screen: for spatially flat blocks with non-zero motion,
- // skip newmv if the motion vector is (0, 0).
+ // skip newmv if the motion vector is (0, 0), and color is not set.
if (this_mode == NEWMV &&
cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
cpi->sf.rt_sf.source_metrics_sb_nonrd) {
if (frame_mv[this_mode][ref_frame].as_int == 0 &&
x->content_state_sb.source_sad_nonrd != kZeroSad &&
+ ((x->color_sensitivity[0] == 0 && x->color_sensitivity[1] == 0) ||
+ cpi->rc.high_source_sad) &&
x->source_variance == 0)
continue;
}
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c
index 3c99e29..74256a6 100644
--- a/av1/encoder/var_based_part.c
+++ b/av1/encoder/var_based_part.c
@@ -1063,7 +1063,8 @@
// For non-SVC GOLDEN is another temporal reference. Check if it should be
// used as reference for partitioning.
- if (!cpi->ppi->use_svc && (cpi->ref_frame_flags & AOM_GOLD_FLAG)) {
+ if (!cpi->ppi->use_svc && (cpi->ref_frame_flags & AOM_GOLD_FLAG) &&
+ x->content_state_sb.source_sad_nonrd != kZeroSad) {
yv12_g = get_ref_frame_yv12_buf(cm, GOLDEN_FRAME);
if (yv12_g && yv12_g != yv12) {
av1_setup_pre_planes(xd, 0, yv12_g, mi_row, mi_col,