Refactor pick_sb_modes to use RD_STATS for best_rd This is a preparation to add tuning for SSIM. There are no performance difference. Change-Id: Ia8f76317038a97f1de27f4cc0cf17f4bee1d467d
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index e5c60cc..b5deea8 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -510,7 +510,7 @@ MACROBLOCK *const x, int mi_row, int mi_col, RD_STATS *rd_cost, PARTITION_TYPE partition, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, - int64_t best_rd, int pick_mode_type) { + RD_STATS best_rd, int pick_mode_type) { AV1_COMMON *const cm = &cpi->common; const int num_planes = av1_num_planes(cm); TileInfo *const tile_info = &tile_data->tile_info; @@ -526,7 +526,7 @@ start_timing(cpi, rd_pick_sb_modes_time); #endif - if (best_rd < 0) { + if (best_rd.rdcost < 0) { ctx->rd_stats.rdcost = INT64_MAX; ctx->rd_stats.skip = 0; av1_invalid_rd_stats(rd_cost); @@ -645,7 +645,7 @@ start_timing(cpi, av1_rd_pick_intra_mode_sb_time); #endif av1_rd_pick_intra_mode_sb(cpi, x, mi_row, mi_col, rd_cost, bsize, ctx, - best_rd); + best_rd.rdcost); #if CONFIG_COLLECT_COMPONENT_TIMING end_timing(cpi, av1_rd_pick_intra_mode_sb_time); #endif @@ -655,7 +655,7 @@ #endif if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) { av1_rd_pick_inter_mode_sb_seg_skip(cpi, tile_data, x, mi_row, mi_col, - rd_cost, bsize, ctx, best_rd); + rd_cost, bsize, ctx, best_rd.rdcost); } else { // TODO(kyslov): do the same for pick_intra_mode and // pick_inter_mode_sb_seg_skip @@ -663,16 +663,17 @@ #if !CONFIG_REALTIME_ONLY case PICK_MODE_RD: av1_rd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, rd_cost, - bsize, ctx, best_rd); + bsize, ctx, best_rd.rdcost); break; #endif case PICK_MODE_NONRD: av1_nonrd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, - rd_cost, bsize, ctx, best_rd); + rd_cost, bsize, ctx, best_rd.rdcost); break; case PICK_MODE_FAST_NONRD: av1_fast_nonrd_pick_inter_mode_sb(cpi, tile_data, x, mi_row, mi_col, - rd_cost, bsize, ctx, best_rd); + rd_cost, bsize, ctx, + best_rd.rdcost); break; default: assert(0 && "Unknown pick mode type."); } @@ -1726,7 +1727,7 @@ : PARTITION_NONE; const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition); RD_SEARCH_MACROBLOCK_CONTEXT x_ctx; - RD_STATS last_part_rdc, none_rdc, chosen_rdc; + RD_STATS last_part_rdc, none_rdc, chosen_rdc, invalid_rdc; BLOCK_SIZE sub_subsize = BLOCK_4X4; int splits_below = 0; BLOCK_SIZE bs_type = mib[0]->sb_type; @@ -1740,6 +1741,7 @@ av1_invalid_rd_stats(&last_part_rdc); av1_invalid_rd_stats(&none_rdc); av1_invalid_rd_stats(&chosen_rdc); + av1_invalid_rd_stats(&invalid_rdc); pc_tree->partitioning = partition; @@ -1775,7 +1777,7 @@ mi_row + hbs < cm->mi_rows && mi_col + hbs < cm->mi_cols) { pc_tree->partitioning = PARTITION_NONE; pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &none_rdc, - PARTITION_NONE, bsize, ctx_none, INT64_MAX, PICK_MODE_RD); + PARTITION_NONE, bsize, ctx_none, invalid_rdc, PICK_MODE_RD); if (none_rdc.rate < INT_MAX) { none_rdc.rate += x->partition_cost[pl][PARTITION_NONE]; @@ -1791,12 +1793,12 @@ switch (partition) { case PARTITION_NONE: pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - PARTITION_NONE, bsize, ctx_none, INT64_MAX, PICK_MODE_RD); + PARTITION_NONE, bsize, ctx_none, invalid_rdc, PICK_MODE_RD); break; case PARTITION_HORZ: pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - PARTITION_HORZ, subsize, &pc_tree->horizontal[0], INT64_MAX, - PICK_MODE_RD); + PARTITION_HORZ, subsize, &pc_tree->horizontal[0], + invalid_rdc, PICK_MODE_RD); if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 && mi_row + hbs < cm->mi_rows) { RD_STATS tmp_rdc; @@ -1807,7 +1809,7 @@ mi_col, subsize, NULL); pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col, &tmp_rdc, PARTITION_HORZ, subsize, &pc_tree->horizontal[1], - INT64_MAX, PICK_MODE_RD); + invalid_rdc, PICK_MODE_RD); if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { av1_invalid_rd_stats(&last_part_rdc); break; @@ -1819,7 +1821,7 @@ break; case PARTITION_VERT: pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc, - PARTITION_VERT, subsize, &pc_tree->vertical[0], INT64_MAX, + PARTITION_VERT, subsize, &pc_tree->vertical[0], invalid_rdc, PICK_MODE_RD); if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 && mi_col + hbs < cm->mi_cols) { @@ -1831,7 +1833,7 @@ mi_col, subsize, NULL); pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs, &tmp_rdc, PARTITION_VERT, subsize, - &pc_tree->vertical[bsize > BLOCK_8X8], INT64_MAX, + &pc_tree->vertical[bsize > BLOCK_8X8], invalid_rdc, PICK_MODE_RD); if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { av1_invalid_rd_stats(&last_part_rdc); @@ -1908,7 +1910,7 @@ pc_tree->split[i]->partitioning = PARTITION_NONE; pick_sb_modes(cpi, tile_data, x, mi_row + y_idx, mi_col + x_idx, &tmp_rdc, PARTITION_SPLIT, split_subsize, &pc_tree->split[i]->none, - INT64_MAX, PICK_MODE_RD); + invalid_rdc, PICK_MODE_RD); restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes); if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) { @@ -1988,6 +1990,7 @@ : PARTITION_NONE; const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition); RD_STATS dummy_cost; + av1_invalid_rd_stats(&dummy_cost); if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return; @@ -2002,7 +2005,7 @@ switch (partition) { case PARTITION_NONE: pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &dummy_cost, - PARTITION_NONE, bsize, &pc_tree->none, INT64_MAX, + PARTITION_NONE, bsize, &pc_tree->none, dummy_cost, sf->use_fast_nonrd_pick_mode ? PICK_MODE_FAST_NONRD : PICK_MODE_NONRD); encode_b(cpi, tile_data, td, tp, mi_row, mi_col, 0, bsize, partition, @@ -2143,7 +2146,7 @@ static int rd_try_subblock(AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data, TOKENEXTRA **tp, int is_last, int mi_row, int mi_col, BLOCK_SIZE subsize, - int64_t best_rdcost, RD_STATS *sum_rdc, + RD_STATS best_rdcost, RD_STATS *sum_rdc, PARTITION_TYPE partition, PICK_MODE_CONTEXT *prev_ctx, PICK_MODE_CONTEXT *this_ctx) { @@ -2151,8 +2154,8 @@ if (cpi->sf.adaptive_motion_search) load_pred_mv(x, prev_ctx); - const int64_t rdcost_remaining = - best_rdcost == INT64_MAX ? INT64_MAX : (best_rdcost - sum_rdc->rdcost); + RD_STATS rdcost_remaining; + av1_rd_stats_subtraction(&best_rdcost, sum_rdc, &rdcost_remaining); RD_STATS this_rdc; pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, partition, subsize, this_ctx, rdcost_remaining, PICK_MODE_RD); @@ -2165,7 +2168,7 @@ sum_rdc->rdcost += this_rdc.rdcost; } - if (sum_rdc->rdcost >= best_rdcost) return 0; + if (sum_rdc->rdcost >= best_rdcost.rdcost) return 0; if (!is_last) { update_state(cpi, tile_data, td, this_ctx, mi_row, mi_col, subsize, 1); @@ -2193,17 +2196,15 @@ sum_rdc.rate = x->partition_cost[pl][partition]; sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); if (!rd_try_subblock(cpi, td, tile_data, tp, 0, mi_row0, mi_col0, subsize0, - best_rdc->rdcost, &sum_rdc, partition, ctx, &ctxs[0])) + *best_rdc, &sum_rdc, partition, ctx, &ctxs[0])) return false; if (!rd_try_subblock(cpi, td, tile_data, tp, 0, mi_row1, mi_col1, subsize1, - best_rdc->rdcost, &sum_rdc, partition, &ctxs[0], - &ctxs[1])) + *best_rdc, &sum_rdc, partition, &ctxs[0], &ctxs[1])) return false; if (!rd_try_subblock(cpi, td, tile_data, tp, 1, mi_row2, mi_col2, subsize2, - best_rdc->rdcost, &sum_rdc, partition, &ctxs[1], - &ctxs[2])) + *best_rdc, &sum_rdc, partition, &ctxs[1], &ctxs[2])) return false; if (sum_rdc.rdcost >= best_rdc->rdcost) return false; @@ -2473,10 +2474,12 @@ ? partition_cost[PARTITION_NONE] : 0; } - const int64_t partition_rd_cost = RDCOST(x->rdmult, pt_cost, 0); - const int64_t best_remain_rdcost = - (best_rdc.rdcost == INT64_MAX) ? INT64_MAX - : (best_rdc.rdcost - partition_rd_cost); + RD_STATS partition_rdcost; + av1_init_rd_stats(&partition_rdcost); + partition_rdcost.dist = pt_cost; + partition_rdcost.rdcost = RDCOST(x->rdmult, pt_cost, 0); + RD_STATS best_remain_rdcost; + av1_rd_stats_subtraction(&best_rdc, &partition_rdcost, &best_remain_rdcost); #if CONFIG_COLLECT_PARTITION_STATS if (best_remain_rdcost >= 0) { partition_attempts[PARTITION_NONE] += 1; @@ -2688,9 +2691,8 @@ } sum_rdc.rate = partition_cost[PARTITION_HORZ]; sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); - const int64_t best_remain_rdcost = best_rdc.rdcost == INT64_MAX - ? INT64_MAX - : (best_rdc.rdcost - sum_rdc.rdcost); + RD_STATS best_remain_rdcost; + av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost); #if CONFIG_COLLECT_PARTITION_STATS if (best_remain_rdcost >= 0) { partition_attempts[PARTITION_HORZ] += 1; @@ -2730,9 +2732,12 @@ pc_tree->horizontal[1].pred_interp_filter = av1_extract_interp_filter(ctx_h->mic.interp_filters, 0); } + + av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost); + pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc, PARTITION_HORZ, subsize, &pc_tree->horizontal[1], - best_rdc.rdcost - sum_rdc.rdcost, PICK_MODE_RD); + best_remain_rdcost, PICK_MODE_RD); horz_rd[1] = this_rdc.rdcost; if (this_rdc.rate == INT_MAX) { @@ -2781,9 +2786,8 @@ } sum_rdc.rate = partition_cost[PARTITION_VERT]; sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, 0); - const int64_t best_remain_rdcost = best_rdc.rdcost == INT64_MAX - ? INT64_MAX - : (best_rdc.rdcost - sum_rdc.rdcost); + RD_STATS best_remain_rdcost; + av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost); #if CONFIG_COLLECT_PARTITION_STATS if (best_remain_rdcost >= 0) { partition_attempts[PARTITION_VERT] += 1; @@ -2822,9 +2826,11 @@ pc_tree->vertical[1].pred_interp_filter = av1_extract_interp_filter(ctx_none->mic.interp_filters, 0); } + + av1_rd_stats_subtraction(&best_rdc, &sum_rdc, &best_remain_rdcost); pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc, PARTITION_VERT, subsize, &pc_tree->vertical[1], - best_rdc.rdcost - sum_rdc.rdcost, PICK_MODE_RD); + best_remain_rdcost, PICK_MODE_RD); vert_rd[1] = this_rdc.rdcost; if (this_rdc.rate == INT_MAX) { @@ -3220,7 +3226,7 @@ ctx_this->rd_mode_is_ready = 0; if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 3), this_mi_row, - mi_col, subsize, best_rdc.rdcost, &sum_rdc, + mi_col, subsize, best_rdc, &sum_rdc, PARTITION_HORZ_4, ctx_prev, ctx_this)) break; @@ -3276,7 +3282,7 @@ ctx_this->rd_mode_is_ready = 0; if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 3), mi_row, - this_mi_col, subsize, best_rdc.rdcost, &sum_rdc, + this_mi_col, subsize, best_rdc, &sum_rdc, PARTITION_VERT_4, ctx_prev, ctx_this)) break;
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h index 64ac0b4..6819fcf 100644 --- a/av1/encoder/rd.h +++ b/av1/encoder/rd.h
@@ -394,6 +394,20 @@ } } +static INLINE void av1_rd_stats_subtraction(const RD_STATS *const left, + const RD_STATS *const right, + RD_STATS *result) { + if (left->rate == INT_MAX || right->rate == INT_MAX || + left->dist == INT64_MAX || right->dist == INT64_MAX || + left->rdcost == INT64_MAX || right->rdcost == INT64_MAX) { + av1_invalid_rd_stats(result); + } else { + result->rate = left->rate - right->rate; + result->dist = left->dist - right->dist; + result->rdcost = left->rdcost - right->rdcost; + } +} + struct TileInfo; struct TileDataEnc; struct AV1_COMP;