rtc: Fix to color artifacts for real-time mode
Change the thresholds for setting the color_sensitivity
at superblock and coding block level, based on the
source_sad. Avoid screen-content for now.
Also, change the setting for estimating motion for
variance partitioning from 3 to 2 locally based
on superblock sad. Level 3 uses neighbor MVs without
using coarse motion estimation, and will early exit
based on source_sad. Forcing level 2 is safer for now.
This significantly removes artifacts on strong color
test clip.
Overall small and acceptable change in stats across
the rtc test sets.
Change-Id: Iea3c184a01969925ed011c3beea6f9e8f18915c7
(cherry picked from commit d4b429f0ba9928074f7a6c126d4639391bdc244f)
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 71f931e..24a5264 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -1924,7 +1924,12 @@
struct buf_2d yv12_mb[MAX_MB_PLANE]) {
const int subsampling_x = cpi->common.seq_params->subsampling_x;
const int subsampling_y = cpi->common.seq_params->subsampling_y;
+ const int source_sad_nonrd = x->content_state_sb.source_sad_nonrd;
int shift = 3;
+ if (source_sad_nonrd >= kMedSad &&
+ cpi->oxcf.tune_cfg.content != AOM_CONTENT_SCREEN &&
+ cpi->common.width * cpi->common.height >= 640 * 360)
+ shift = 4;
if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
cpi->rc.high_source_sad) {
shift = 6;
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c
index 6dd0782..5b8f598 100644
--- a/av1/encoder/var_based_part.c
+++ b/av1/encoder/var_based_part.c
@@ -1001,7 +1001,9 @@
unsigned int y_sad_alt, bool is_key_frame,
bool zero_motion, unsigned int *uv_sad) {
MACROBLOCKD *xd = &x->e_mbd;
- int shift = 3;
+ const int source_sad_nonrd = x->content_state_sb.source_sad_nonrd;
+ int shift_upper_limit = 1;
+ int shift_lower_limit = 3;
int fac_uv = 6;
if (is_key_frame || cpi->oxcf.tool_cfg.enable_monochrome) return;
@@ -1017,8 +1019,14 @@
fac_uv = 5;
}
if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN &&
- cpi->rc.high_source_sad)
- shift = 7;
+ cpi->rc.high_source_sad) {
+ shift_lower_limit = 7;
+ } else if (source_sad_nonrd >= kMedSad &&
+ cpi->oxcf.tune_cfg.content != AOM_CONTENT_SCREEN &&
+ cpi->common.width * cpi->common.height >= 640 * 360) {
+ shift_upper_limit = 2;
+ shift_lower_limit = source_sad_nonrd > kMedSad ? 5 : 4;
+ }
MB_MODE_INFO *mi = xd->mi[0];
const AV1_COMMON *const cm = &cpi->common;
@@ -1082,9 +1090,9 @@
}
}
- if (uv_sad[plane - 1] > (y_sad >> 1))
+ if (uv_sad[plane - 1] > (y_sad >> shift_upper_limit))
x->color_sensitivity_sb[COLOR_SENS_IDX(plane)] = 1;
- else if (uv_sad[plane - 1] < (y_sad >> shift))
+ else if (uv_sad[plane - 1] < (y_sad >> shift_lower_limit))
x->color_sensitivity_sb[COLOR_SENS_IDX(plane)] = 0;
// Borderline case: to be refined at coding block level in nonrd_pickmode,
// for coding block size < sb_size.
@@ -1392,6 +1400,7 @@
}
if (use_last_ref) {
+ const int source_sad_nonrd = x->content_state_sb.source_sad_nonrd;
av1_setup_pre_planes(
xd, 0, yv12, mi_row, mi_col,
scaled_ref_last ? NULL : get_ref_scale_factors(cm, LAST_FRAME),
@@ -1402,8 +1411,13 @@
mi->mv[0].as_int = 0;
mi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
- const int est_motion =
- cpi->sf.rt_sf.estimate_motion_for_var_based_partition;
+ int est_motion = cpi->sf.rt_sf.estimate_motion_for_var_based_partition;
+ // TODO(b/290596301): Look into adjusting this condition.
+ // There is regression on color content when
+ // estimate_motion_for_var_based_partition = 3 and high motion,
+ // so for now force it to 2 based on superblock sad.
+ if (est_motion > 2 && source_sad_nonrd > kMedSad) est_motion = 2;
+
if (est_motion == 1 || est_motion == 2) {
if (xd->mb_to_right_edge >= 0 && xd->mb_to_bottom_edge >= 0) {
const MV dummy_mv = { 0, 0 };