rtc: Allow for scroll sb detection for non-screen For resoln > 720p non-screen mode, allow for superblock motion estimation that can capture scroll. Reduces encode size spikes for scroll video content in the issue below. Bug: 500972837 Change-Id: I65f9f5f5907e0c064b1808dd438dff25780c4ddf
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c index 85df081..9ccb2da 100644 --- a/av1/encoder/mcomp.c +++ b/av1/encoder/mcomp.c
@@ -2141,7 +2141,8 @@ unsigned int av1_int_pro_motion_estimation( const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, const MV *ref_mv, unsigned int *y_sad_zero, - int me_search_size_col, int me_search_size_row, int is_var_part) { + int me_search_size_col, int me_search_size_row, int is_var_part, + int use_larger_search) { const AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mi = xd->mi[0]; @@ -2151,8 +2152,8 @@ const int bh = block_size_high[bsize]; const int is_screen = cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN; const int full_search = is_screen; - const bool screen_scroll_superblock = - is_screen && bsize == cm->seq_params->sb_size; + const bool scroll_superblock = + use_larger_search && bsize == cm->seq_params->sb_size; // Keep border a multiple of 16. const int border = (cpi->oxcf.border_in_pixels >> 4) << 4; int search_size_width_left = me_search_size_col; @@ -2160,7 +2161,7 @@ int search_size_height_top = me_search_size_row; int search_size_height_bottom = me_search_size_row; // Allow for larger search size for column/horizontal screen motion. - if (screen_scroll_superblock && is_var_part) { + if (scroll_superblock && is_var_part) { if (((mi_col << 2) - search_size_width_left) < -border) search_size_width_left = (mi_col << 2) + border; if (((mi_col << 2) + search_size_width_right + bw) > cm->width + border) @@ -2174,7 +2175,7 @@ } } // Allow for larger search size for row/vertical screen motion. - if (screen_scroll_superblock && is_var_part) { + if (scroll_superblock && is_var_part) { if (((mi_row << 2) - search_size_height_top) < -border) search_size_height_top = (mi_row << 2) + border; if (((mi_row << 2) + search_size_height_bottom + bh) > cm->height + border) @@ -2285,6 +2286,16 @@ best_sad = cpi->ppi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride); + if (!is_screen && scroll_superblock) { + if (best_sad_col < best_sad_row && best_sad_col < (int)best_sad) { + best_int_mv->as_fullmv.row = 0; + best_sad = best_sad_col; + } else if (best_sad_row < best_sad_col && best_sad_row < (int)best_sad) { + best_int_mv->as_fullmv.col = 0; + best_sad = best_sad_row; + } + } + // Evaluate zero MV if found MV is non-zero. if (best_int_mv->as_int != 0) { tmp_sad = cpi->ppi->fn_ptr[bsize].sdf(x->plane[0].src.buf, src_stride, @@ -2300,7 +2311,7 @@ *y_sad_zero = best_sad; } - if (!screen_scroll_superblock) { + if (!scroll_superblock) { const uint8_t *const pos[4] = { ref_buf - ref_stride, ref_buf - 1,
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h index d268481..eb70c29 100644 --- a/av1/encoder/mcomp.h +++ b/av1/encoder/mcomp.h
@@ -246,7 +246,8 @@ unsigned int av1_int_pro_motion_estimation( const struct AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col, const MV *ref_mv, unsigned int *y_sad_zero, - int me_search_size_col, int me_search_size_row, int is_var_part); + int me_search_size_col, int me_search_size_row, int is_var_part, + int use_larger_search); int av1_refining_search_8p_c(const FULLPEL_MOTION_SEARCH_PARAMS *ms_params, const FULLPEL_MV start_mv, FULLPEL_MV *best_mv);
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c index 49953d0..6f6dc88 100644 --- a/av1/encoder/nonrd_pickmode.c +++ b/av1/encoder/nonrd_pickmode.c
@@ -331,7 +331,7 @@ MV ref_mv = av1_get_ref_mv(x, 0).as_mv; tmp_sad = av1_int_pro_motion_estimation( cpi, x, bsize, mi_row, mi_col, &ref_mv, &y_sad_zero, me_search_size_col, - me_search_size_row, 0); + me_search_size_row, 0, 0); if (tmp_sad > x->pred_mv_sad[LAST_FRAME]) return -1;
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c index b0c1a5b..ea2053f 100644 --- a/av1/encoder/var_based_part.c +++ b/av1/encoder/var_based_part.c
@@ -1339,16 +1339,21 @@ AV1_COMMON *const cm = &cpi->common; MACROBLOCKD *xd = &x->e_mbd; MB_MODE_INFO *mi = xd->mi[0]; - const int is_screen = cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN; + const int large_search = + cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN || + (source_sad_nonrd > kMedSad && cm->width * cm->height > 1280 * 720 && + !cpi->rc.high_motion_content_screen_rtc); + const int max_sw = + (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN) ? 512 : 256; const int increase_col_sw = source_sad_nonrd > kMedSad && !cpi->rc.high_motion_content_screen_rtc; - int me_search_size_col = is_screen - ? increase_col_sw ? 512 : 96 + int me_search_size_col = large_search + ? increase_col_sw ? max_sw : 96 : block_size_wide[cm->seq_params->sb_size] >> 1; - // For screen use larger search size row motion to capture + // Use larger search size row motion to capture // vertical scroll, which can be larger motion. - int me_search_size_row = is_screen - ? source_sad_nonrd > kMedSad ? 512 : 192 + int me_search_size_row = large_search + ? source_sad_nonrd > kMedSad ? max_sw : 192 : block_size_high[cm->seq_params->sb_size] >> 1; if (cm->width * cm->height >= 3840 * 2160) { me_search_size_row = me_search_size_row << 1; @@ -1357,11 +1362,10 @@ unsigned int y_sad_zero; *y_sad = av1_int_pro_motion_estimation( cpi, x, cm->seq_params->sb_size, mi_row, mi_col, &kZeroMv, &y_sad_zero, - me_search_size_col, me_search_size_row, 1); + me_search_size_col, me_search_size_row, 1, large_search); // The logic below selects whether the motion estimated in the - // int_pro_motion() will be used in nonrd_pickmode. Only do this - // for screen for now. - if (is_screen) { + // int_pro_motion() will be used in nonrd_pickmode. + if (large_search) { unsigned int thresh_sad = (cm->seq_params->sb_size == BLOCK_128X128) ? 50000 : 20000; if (*y_sad < (y_sad_zero >> 1) && *y_sad < thresh_sad) {