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,