diff options
Diffstat (limited to 'third_party/aom/av1/encoder/motion_search_facade.h')
-rw-r--r-- | third_party/aom/av1/encoder/motion_search_facade.h | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/third_party/aom/av1/encoder/motion_search_facade.h b/third_party/aom/av1/encoder/motion_search_facade.h new file mode 100644 index 0000000000..d1fa915bca --- /dev/null +++ b/third_party/aom/av1/encoder/motion_search_facade.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2020, Alliance for Open Media. All rights reserved + * + * This source code is subject to the terms of the BSD 2 Clause License and + * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License + * was not distributed with this source code in the LICENSE file, you can + * obtain it at www.aomedia.org/license/software. If the Alliance for Open + * Media Patent License 1.0 was not distributed with this source code in the + * PATENTS file, you can obtain it at www.aomedia.org/license/patent. + */ + +#ifndef AOM_AV1_ENCODER_MOTION_SEARCH_H_ +#define AOM_AV1_ENCODER_MOTION_SEARCH_H_ + +#include "av1/encoder/encoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUM_JOINT_ME_REFINE_ITER 2 +#define REDUCED_JOINT_ME_REFINE_ITER 1 +// TODO(any): rename this struct to something else. There is already another +// struct called inter_modes_info, which makes this terribly confusing. +typedef struct { + int drl_cost; + int_mv full_search_mv; + int full_mv_rate; + int full_mv_bestsme; + int skip; +} inter_mode_info; + +struct HandleInterModeArgs; +void av1_single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x, + BLOCK_SIZE bsize, int ref_idx, int *rate_mv, + int search_range, inter_mode_info *mode_info, + int_mv *best_mv, + struct HandleInterModeArgs *const args); + +int av1_joint_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE bsize, int_mv *cur_mv, + const uint8_t *mask, int mask_stride, int *rate_mv, + int allow_second_mv, int joint_me_num_refine_iter); + +int av1_interinter_compound_motion_search(const AV1_COMP *const cpi, + MACROBLOCK *x, + const int_mv *const cur_mv, + const BLOCK_SIZE bsize, + const PREDICTION_MODE this_mode); + +int av1_compound_single_motion_search_interinter( + const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int_mv *cur_mv, + const uint8_t *mask, int mask_stride, int *rate_mv, int ref_idx); + +int av1_compound_single_motion_search(const AV1_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE bsize, MV *this_mv, + const uint8_t *second_pred, + const uint8_t *mask, int mask_stride, + int *rate_mv, int ref_idx); + +// Performs a motion search in SIMPLE_TRANSLATION mode using reference frame +// ref and calculates the sse and var of the residue. Note that this sets the +// offset of mbmi, so we will need to reset it after calling this function. +int_mv av1_simple_motion_search_sse_var(struct AV1_COMP *cpi, MACROBLOCK *x, + int mi_row, int mi_col, + BLOCK_SIZE bsize, int ref, + const FULLPEL_MV start_mv, + int num_planes, int use_subpixel, + unsigned int *sse, unsigned int *var); + +static AOM_INLINE const search_site_config *av1_get_search_site_config( + const AV1_COMP *cpi, MACROBLOCK *x, SEARCH_METHODS search_method) { + const int ref_stride = x->e_mbd.plane[0].pre[0].stride; + + // AV1_COMP::mv_search_params.search_site_config is a compressor level cache + // that's shared by multiple threads. In most cases where all frames have the + // same resolution, the cache contains the search site config that we need. + const MotionVectorSearchParams *mv_search_params = &cpi->mv_search_params; + if (ref_stride == mv_search_params->search_site_cfg[SS_CFG_SRC]->stride) { + return mv_search_params->search_site_cfg[SS_CFG_SRC]; + } else if (ref_stride == + mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD]->stride) { + return mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD]; + } + + // If the cache does not contain the correct stride, then we will need to rely + // on the thread level config MACROBLOCK::search_site_cfg_buf. If even the + // thread level config doesn't match, then we need to update it. + search_method = search_method_lookup[search_method]; + assert(search_method_lookup[search_method] == search_method && + "The search_method_lookup table should be idempotent."); + if (ref_stride != x->search_site_cfg_buf[search_method].stride) { + av1_refresh_search_site_config(x->search_site_cfg_buf, search_method, + ref_stride); + } + + return x->search_site_cfg_buf; +} + +static AOM_INLINE SEARCH_METHODS +av1_get_faster_search_method(SEARCH_METHODS search_method) { + // Note on search method's accuracy: + // 1. NSTEP + // 2. DIAMOND + // 3. BIGDIA \approx SQUARE + // 4. HEX. + // 5. FAST_HEX \approx FAST_DIAMOND + switch (search_method) { + case NSTEP: return DIAMOND; + case NSTEP_8PT: return DIAMOND; + case DIAMOND: return BIGDIA; + case CLAMPED_DIAMOND: return BIGDIA; + case BIGDIA: return HEX; + case SQUARE: return HEX; + case HEX: return FAST_HEX; + case FAST_HEX: return FAST_HEX; + case FAST_DIAMOND: return VFAST_DIAMOND; + case FAST_BIGDIA: return FAST_BIGDIA; + case VFAST_DIAMOND: return VFAST_DIAMOND; + default: assert(0 && "Invalid search method!"); return DIAMOND; + } +} + +static AOM_INLINE SEARCH_METHODS av1_get_default_mv_search_method( + const MACROBLOCK *x, const MV_SPEED_FEATURES *mv_sf, BLOCK_SIZE bsize) { + SEARCH_METHODS search_method = mv_sf->search_method; + const int sf_blk_search_method = mv_sf->use_bsize_dependent_search_method; + const int min_dim = AOMMIN(block_size_wide[bsize], block_size_high[bsize]); + const int qband = x->qindex >> (QINDEX_BITS - 2); + const bool use_faster_search_method = + (sf_blk_search_method == 1 && min_dim >= 32) || + (sf_blk_search_method >= 2 && min_dim >= 16 && + x->content_state_sb.source_sad_nonrd <= kMedSad && qband < 3); + + if (use_faster_search_method) { + search_method = av1_get_faster_search_method(search_method); + } + return search_method; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_AV1_ENCODER_MOTION_SEARCH_H_ |