Add a speed feature optimize_b_precheck Calculate RD cost before doing optimize_b, and skip if the cost is large. On speed 1, encoding speed improves about 5%; coding loss is under 0.05%. Enabled for speed 1 and above. STATS_CHANGED Change-Id: Iaf95ad2665084f5024458602db8f7c4b7b6baff7
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index 6e2bcf9..b20a51d 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -1723,7 +1723,8 @@ void dist_block(const AV1_COMP *cpi, MACROBLOCK *x, int plane, BLOCK_SIZE plane_bsize, int block, int blk_row, int blk_col, TX_SIZE tx_size, int64_t *out_dist, int64_t *out_sse, - OUTPUT_STATUS output_status) { + OUTPUT_STATUS output_status, + int use_transform_domain_distortion) { MACROBLOCKD *const xd = &x->e_mbd; const struct macroblock_plane *const p = &x->plane[plane]; #if CONFIG_DIST_8X8 @@ -1733,17 +1734,8 @@ #endif // CONFIG_DIST_8X8 const uint16_t eob = p->eobs[block]; - int use_transform_domain_distortion = - // When eob is 0, pixel domain distortion is more efficient. - cpi->sf.use_transform_domain_distortion && eob && - // Any 64-pt transforms only preserves half the coefficients. - // Therefore transform domain distortion is not valid for these - // transform sizes. - txsize_sqr_up_map[tx_size] != TX_64X64; -#if CONFIG_DIST_8X8 - if (x->using_dist_8x8) use_transform_domain_distortion = 0; -#endif - + // When eob is 0, pixel domain distortion is more efficient and accurate. + if (!eob) use_transform_domain_distortion = 0; if (use_transform_domain_distortion) { // Transform domain distortion computation is more efficient as it does // not involve an inverse transform, but it is less accurate. @@ -1981,6 +1973,15 @@ // Need to have at least one transform type allowed. if (allowed_tx_num == 0) allowed_tx_mask[DCT_DCT] = 1; + int use_transform_domain_distortion = + cpi->sf.use_transform_domain_distortion && + // Any 64-pt transforms only preserves half the coefficients. + // Therefore transform domain distortion is not valid for these + // transform sizes. + txsize_sqr_up_map[tx_size] != TX_64X64; +#if CONFIG_DIST_8X8 + if (x->using_dist_8x8) use_transform_domain_distortion = 0; +#endif for (TX_TYPE tx_type = txk_start; tx_type <= txk_end; ++tx_type) { if (!allowed_tx_mask[tx_type]) continue; if (plane == 0) mbmi->txk_type[txk_type_idx] = tx_type; @@ -1997,12 +1998,27 @@ } else { av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size, AV1_XFORM_QUANT_FP); + if (cpi->sf.optimize_b_precheck && best_rd < INT64_MAX && + x->plane[plane].eobs[block] >= 4) { + // Calculate distortion quickly in transform domain. + dist_block(cpi, x, plane, plane_bsize, block, blk_row, blk_col, tx_size, + &this_rd_stats.dist, &this_rd_stats.sse, + OUTPUT_HAS_PREDICTED_PIXELS, 1); + rate_cost = + av1_cost_coeffs(cpi, x, plane, blk_row, blk_col, block, tx_size, + scan_order, a, l, use_fast_coef_costing); + const int64_t rd_estimate = + AOMMIN(RDCOST(x->rdmult, rate_cost, this_rd_stats.dist), + RDCOST(x->rdmult, 0, this_rd_stats.sse)); + if (rd_estimate - (rd_estimate >> 3) > AOMMIN(best_rd, ref_best_rd)) + continue; + } av1_optimize_b(cpi, x, plane, blk_row, blk_col, block, plane_bsize, tx_size, a, l, 1, &rate_cost); } dist_block(cpi, x, plane, plane_bsize, block, blk_row, blk_col, tx_size, &this_rd_stats.dist, &this_rd_stats.sse, - OUTPUT_HAS_PREDICTED_PIXELS); + OUTPUT_HAS_PREDICTED_PIXELS, use_transform_domain_distortion); this_rd_stats.rate = rate_cost;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c index c882e6d..73b8123 100644 --- a/av1/encoder/speed_features.c +++ b/av1/encoder/speed_features.c
@@ -157,6 +157,7 @@ sf->tx_type_search.skip_tx_search = 1; sf->adaptive_txb_search = 1; sf->use_intra_txb_hash = 1; + sf->optimize_b_precheck = 1; } if (speed >= 2) { @@ -452,6 +453,7 @@ sf->use_intra_txb_hash = 0; sf->use_inter_txb_hash = 1; sf->use_mb_rd_hash = 1; + sf->optimize_b_precheck = 0; for (i = 0; i < TX_SIZES; i++) { sf->intra_y_mode_mask[i] = INTRA_ALL;
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h index 6b6f385..d6edab9 100644 --- a/av1/encoder/speed_features.h +++ b/av1/encoder/speed_features.h
@@ -569,6 +569,9 @@ // Use hash table to store macroblock RD search results // to avoid repeated search on the same residue signal. int use_mb_rd_hash; + + // Calculate RD cost before doing optimize_b, and skip if the cost is large. + int optimize_b_precheck; } SPEED_FEATURES; struct AV1_COMP;