Refactor: Refine interpolation_filter_search 1. Extract function interpolation_filter_rd to calculate the rdcost of a given interpolation_filter 2. Reorder the conditions in interpolation_filter_search Change-Id: If282f545a1564544796611e2a737039f897f2b2c
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index db9a8a2..08adfec 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -64,9 +64,10 @@ #endif #define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS) -static const int filter_sets[DUAL_FILTER_SET_SIZE][2] = { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 1, 0 }, { 1, 1 }, - { 1, 2 }, { 2, 0 }, { 2, 1 }, { 2, 2 }, +static const InterpFilters filter_sets[DUAL_FILTER_SET_SIZE] = { + 0x00000000, 0x00010000, 0x00020000, // y = 0 + 0x00000001, 0x00010001, 0x00020001, // y = 1 + 0x00000002, 0x00010002, 0x00020002, // y = 2 }; #define SECOND_REF_FRAME_MASK \ @@ -7412,6 +7413,46 @@ return 0; } +static INLINE void swap_dst_buf(MACROBLOCKD *xd, const BUFFER_SET *dst_bufs[2], + int num_planes) { + const BUFFER_SET *buf0 = dst_bufs[0]; + dst_bufs[0] = dst_bufs[1]; + dst_bufs[1] = buf0; + restore_dst_buf(xd, *dst_bufs[0], num_planes); +} + +// calculate the rdcost of given interpolation_filter +static INLINE int64_t interpolation_filter_rd( + MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize, + int mi_row, int mi_col, BUFFER_SET *const orig_dst, int64_t *const rd, + int *const switchable_rate, int *const skip_txfm_sb, + int64_t *const skip_sse_sb, const BUFFER_SET *dst_bufs[2], int filter_idx) { + const AV1_COMMON *cm = &cpi->common; + const int num_planes = av1_num_planes(cm); + MACROBLOCKD *const xd = &x->e_mbd; + MB_MODE_INFO *const mbmi = xd->mi[0]; + int tmp_rate, tmp_skip_sb = 0; + int64_t tmp_dist, tmp_skip_sse = INT64_MAX; + + const InterpFilters last_best = mbmi->interp_filters; + mbmi->interp_filters = filter_sets[filter_idx]; + const int tmp_rs = av1_get_switchable_rate(cm, x, xd); + av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, bsize); + model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, &tmp_dist, + &tmp_skip_sb, &tmp_skip_sse, NULL, NULL, NULL); + int64_t tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); + if (tmp_rd < *rd) { + *rd = tmp_rd; + *switchable_rate = tmp_rs; + *skip_txfm_sb = tmp_skip_sb; + *skip_sse_sb = tmp_skip_sse; + swap_dst_buf(xd, dst_bufs, num_planes); + return 1; + } + mbmi->interp_filters = last_best; + return 0; +} + static int64_t interpolation_filter_search( MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize, int mi_row, int mi_col, const BUFFER_SET *const tmp_dst, @@ -7422,16 +7463,12 @@ const int num_planes = av1_num_planes(cm); MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *const mbmi = xd->mi[0]; - int i; - int tmp_rate; + int i, tmp_rate; int64_t tmp_dist; (void)single_filter; - InterpFilter assign_filter = SWITCHABLE; - - if (cm->interp_filter != SWITCHABLE) assign_filter = cm->interp_filter; - + const InterpFilter assign_filter = cm->interp_filter; set_default_interp_filters(mbmi, assign_filter); *switchable_rate = av1_get_switchable_rate(cm, x, xd); @@ -7440,136 +7477,52 @@ skip_txfm_sb, skip_sse_sb, NULL, NULL, NULL); *rd = RDCOST(x->rdmult, *switchable_rate + tmp_rate, tmp_dist); - if (assign_filter == SWITCHABLE) { - // do interp_filter search - if (av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd)) { - const int filter_set_size = DUAL_FILTER_SET_SIZE; - int best_in_temp = 0; - InterpFilters best_filters = mbmi->interp_filters; - restore_dst_buf(xd, *tmp_dst, num_planes); - - if (cpi->sf.use_fast_interpolation_filter_search && - cm->seq_params.enable_dual_filter) { - int tmp_skip_sb = 0; - int64_t tmp_skip_sse = INT64_MAX; - int tmp_rs; - int64_t tmp_rd; - - // default to (R,R): EIGHTTAP_REGULARxEIGHTTAP_REGULAR - int best_dual_mode = 0; - // Find best of {R}x{R,Sm,Sh} - // EIGHTTAP_REGULAR mode is calculated beforehand - for (i = 1; i < SWITCHABLE_FILTERS; ++i) { - tmp_skip_sb = 0; - tmp_skip_sse = INT64_MAX; - - mbmi->interp_filters = - av1_make_interp_filters(filter_sets[i][0], filter_sets[i][1]); - - tmp_rs = av1_get_switchable_rate(cm, x, xd); - av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, - bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, - &tmp_dist, &tmp_skip_sb, &tmp_skip_sse, NULL, NULL, - NULL); - tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); - - if (tmp_rd < *rd) { - best_dual_mode = i; - - *rd = tmp_rd; - *switchable_rate = tmp_rs; - best_filters = mbmi->interp_filters; - *skip_txfm_sb = tmp_skip_sb; - *skip_sse_sb = tmp_skip_sse; - best_in_temp = !best_in_temp; - if (best_in_temp) { - restore_dst_buf(xd, *orig_dst, num_planes); - } else { - restore_dst_buf(xd, *tmp_dst, num_planes); - } - } - } - - // From best of horizontal EIGHTTAP_REGULAR modes, check vertical modes - for (i = best_dual_mode + SWITCHABLE_FILTERS; i < filter_set_size; - i += SWITCHABLE_FILTERS) { - tmp_skip_sb = 0; - tmp_skip_sse = INT64_MAX; - - mbmi->interp_filters = - av1_make_interp_filters(filter_sets[i][0], filter_sets[i][1]); - - tmp_rs = av1_get_switchable_rate(cm, x, xd); - av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, - bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, - &tmp_dist, &tmp_skip_sb, &tmp_skip_sse, NULL, NULL, - NULL); - tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); - - if (tmp_rd < *rd) { - *rd = tmp_rd; - *switchable_rate = tmp_rs; - best_filters = mbmi->interp_filters; - *skip_txfm_sb = tmp_skip_sb; - *skip_sse_sb = tmp_skip_sse; - best_in_temp = !best_in_temp; - if (best_in_temp) { - restore_dst_buf(xd, *orig_dst, num_planes); - } else { - restore_dst_buf(xd, *tmp_dst, num_planes); - } - } - } - } else { - // EIGHTTAP_REGULAR mode is calculated beforehand - for (i = 1; i < filter_set_size; ++i) { - int tmp_skip_sb = 0; - int64_t tmp_skip_sse = INT64_MAX; - int tmp_rs; - int64_t tmp_rd; - - if (cm->seq_params.enable_dual_filter == 0) - if (filter_sets[i][0] != filter_sets[i][1]) continue; - - mbmi->interp_filters = - av1_make_interp_filters(filter_sets[i][0], filter_sets[i][1]); - tmp_rs = av1_get_switchable_rate(cm, x, xd); - av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, orig_dst, - bsize); - model_rd_for_sb(cpi, bsize, x, xd, 0, num_planes - 1, &tmp_rate, - &tmp_dist, &tmp_skip_sb, &tmp_skip_sse, NULL, NULL, - NULL); - tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate, tmp_dist); - - if (tmp_rd < *rd) { - *rd = tmp_rd; - *switchable_rate = tmp_rs; - best_filters = mbmi->interp_filters; - *skip_txfm_sb = tmp_skip_sb; - *skip_sse_sb = tmp_skip_sse; - best_in_temp = !best_in_temp; - if (best_in_temp) { - restore_dst_buf(xd, *orig_dst, num_planes); - } else { - restore_dst_buf(xd, *tmp_dst, num_planes); - } - } - } + if (assign_filter != SWITCHABLE) { + return 0; + } + if (!av1_is_interp_needed(xd) || !av1_is_interp_search_needed(xd)) { + assert(mbmi->interp_filters == + av1_broadcast_interp_filter(EIGHTTAP_REGULAR)); + return 0; + } + // do interp_filter search + const int filter_set_size = DUAL_FILTER_SET_SIZE; + restore_dst_buf(xd, *tmp_dst, num_planes); + const BUFFER_SET *dst_bufs[2] = { tmp_dst, orig_dst }; + if (cpi->sf.use_fast_interpolation_filter_search && + cm->seq_params.enable_dual_filter) { + // default to (R,R): EIGHTTAP_REGULARxEIGHTTAP_REGULAR + int best_dual_mode = 0; + // Find best of {R}x{R,Sm,Sh} + // EIGHTTAP_REGULAR mode is calculated beforehand + for (i = 1; i < SWITCHABLE_FILTERS; ++i) { + if (interpolation_filter_rd(x, cpi, bsize, mi_row, mi_col, orig_dst, rd, + switchable_rate, skip_txfm_sb, skip_sse_sb, + dst_bufs, i)) { + best_dual_mode = i; } - - if (best_in_temp) { - restore_dst_buf(xd, *tmp_dst, num_planes); - } else { - restore_dst_buf(xd, *orig_dst, num_planes); + } + // From best of horizontal EIGHTTAP_REGULAR modes, check vertical modes + for (i = best_dual_mode + SWITCHABLE_FILTERS; i < filter_set_size; + i += SWITCHABLE_FILTERS) { + interpolation_filter_rd(x, cpi, bsize, mi_row, mi_col, orig_dst, rd, + switchable_rate, skip_txfm_sb, skip_sse_sb, + dst_bufs, i); + } + } else { + // EIGHTTAP_REGULAR mode is calculated beforehand + for (i = 1; i < filter_set_size; ++i) { + if (cm->seq_params.enable_dual_filter == 0) { + const int16_t filter_y = filter_sets[i] & 0xffff; + const int16_t filter_x = filter_sets[i] >> 16; + if (filter_x != filter_y) continue; } - mbmi->interp_filters = best_filters; - } else { - assert(mbmi->interp_filters == - av1_broadcast_interp_filter(EIGHTTAP_REGULAR)); + interpolation_filter_rd(x, cpi, bsize, mi_row, mi_col, orig_dst, rd, + switchable_rate, skip_txfm_sb, skip_sse_sb, + dst_bufs, i); } } + swap_dst_buf(xd, dst_bufs, num_planes); return 0; }