rtc: Fix uv sad calculation The y_sad used in chroma_check for setting the color_sensitivity is based on last frame so uv_sad based on last frame should be used in the comparison. However, for zero motion, uv_sad based on golden frame was being used sometimes, as the predictor could be set based on golden frame in the function setup_planes(). To overcome this issue, last frame predictor block is setup in chroma_check function. Also, in set_color_sensitivity() function, the predictor buffer used in uv_sad calculation is corrected, as 'pd->dst' is not setup before. STATS_CHANGED Change-Id: I50ac5a1492bf938da9897a6d3290c0c0242e06fa
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c index 8ac3b5c..768e888 100644 --- a/av1/encoder/nonrd_pickmode.c +++ b/av1/encoder/nonrd_pickmode.c
@@ -2428,9 +2428,11 @@ return 0; } -void set_color_sensitivity(AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, - BLOCK_SIZE bsize, int y_sad, - unsigned int source_variance) { +void set_color_sensitivity(AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, + int y_sad, unsigned int source_variance, + 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; int factor = (bsize >= BLOCK_32X32) ? 2 : 3; int shift = 3; if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN && @@ -2457,11 +2459,12 @@ for (int i = 1; i <= 2; ++i) { if (x->color_sensitivity[i - 1] == 2 || source_variance < 50) { struct macroblock_plane *const p = &x->plane[i]; - struct macroblockd_plane *const pd = &xd->plane[i]; const BLOCK_SIZE bs = - get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y); - const int uv_sad = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride, - pd->dst.buf, pd->dst.stride); + get_plane_block_size(bsize, subsampling_x, subsampling_y); + + const int uv_sad = cpi->ppi->fn_ptr[bs].sdf( + p->src.buf, p->src.stride, yv12_mb[i].buf, yv12_mb[i].stride); + const int norm_uv_sad = uv_sad >> (b_width_log2_lookup[bs] + b_height_log2_lookup[bs]); x->color_sensitivity[i - 1] = @@ -3110,7 +3113,8 @@ (abs(frame_mv[NEARESTMV][LAST_FRAME].as_mv.col) + abs(frame_mv[NEARESTMV][LAST_FRAME].as_mv.row))) y_sad = x->pred_mv1_sad[LAST_FRAME]; - set_color_sensitivity(cpi, x, xd, bsize, y_sad, x->source_variance); + set_color_sensitivity(cpi, x, bsize, y_sad, x->source_variance, + yv12_mb[LAST_FRAME]); } mi->motion_mode = SIMPLE_TRANSLATION; #if !CONFIG_REALTIME_ONLY
diff --git a/av1/encoder/var_based_part.c b/av1/encoder/var_based_part.c index 48b5220..2c88427 100644 --- a/av1/encoder/var_based_part.c +++ b/av1/encoder/var_based_part.c
@@ -906,6 +906,13 @@ cpi->rc.high_source_sad) shift = 5; + MB_MODE_INFO *mi = xd->mi[0]; + const AV1_COMMON *const cm = &cpi->common; + const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME); + const struct scale_factors *const sf = + get_ref_scale_factors_const(cm, LAST_FRAME); + struct buf_2d dst; + for (i = 1; i <= 2; ++i) { struct macroblock_plane *p = &x->plane[i]; struct macroblockd_plane *pd = &xd->plane[i]; @@ -913,10 +920,21 @@ get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y); if (bs != BLOCK_INVALID) { - if (zero_motion) - uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf( - p->src.buf, p->src.stride, pd->pre[0].buf, pd->pre[0].stride); - else + if (zero_motion) { + if (mi->ref_frame[0] == LAST_FRAME) { + uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf( + p->src.buf, p->src.stride, pd->pre[0].buf, pd->pre[0].stride); + } else { + uint8_t *src = (i == 1) ? yv12->u_buffer : yv12->v_buffer; + setup_pred_plane(&dst, xd->mi[0]->bsize, src, yv12->uv_crop_width, + yv12->uv_crop_height, yv12->uv_stride, xd->mi_row, + xd->mi_col, sf, xd->plane[i].subsampling_x, + xd->plane[i].subsampling_y); + + uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride, + dst.buf, dst.stride); + } + } else uv_sad[i - 1] = cpi->ppi->fn_ptr[bs].sdf(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride); }