1*77c1e3ccSAndroid Build Coastguard Worker /* 2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2020, Alliance for Open Media. All rights reserved. 3*77c1e3ccSAndroid Build Coastguard Worker * 4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and 5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can 7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the 9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10*77c1e3ccSAndroid Build Coastguard Worker */ 11*77c1e3ccSAndroid Build Coastguard Worker 12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AV1_ENCODER_INTERP_FILTER_SEARCH_H_ 13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_INTERP_FILTER_SEARCH_H_ 14*77c1e3ccSAndroid Build Coastguard Worker 15*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/block.h" 16*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/encoder.h" 17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/rdopt_utils.h" 18*77c1e3ccSAndroid Build Coastguard Worker 19*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus 20*77c1e3ccSAndroid Build Coastguard Worker extern "C" { 21*77c1e3ccSAndroid Build Coastguard Worker #endif 22*77c1e3ccSAndroid Build Coastguard Worker 23*77c1e3ccSAndroid Build Coastguard Worker /*!\cond */ 24*77c1e3ccSAndroid Build Coastguard Worker #define MAX_INTERP_FILTER_STATS 128 25*77c1e3ccSAndroid Build Coastguard Worker #define DUAL_FILTER_SET_SIZE (SWITCHABLE_FILTERS * SWITCHABLE_FILTERS) 26*77c1e3ccSAndroid Build Coastguard Worker 27*77c1e3ccSAndroid Build Coastguard Worker typedef struct { 28*77c1e3ccSAndroid Build Coastguard Worker int_interpfilters filters; 29*77c1e3ccSAndroid Build Coastguard Worker int_mv mv[2]; 30*77c1e3ccSAndroid Build Coastguard Worker int8_t ref_frames[2]; 31*77c1e3ccSAndroid Build Coastguard Worker COMPOUND_TYPE comp_type; 32*77c1e3ccSAndroid Build Coastguard Worker int compound_idx; 33*77c1e3ccSAndroid Build Coastguard Worker int64_t rd; 34*77c1e3ccSAndroid Build Coastguard Worker unsigned int pred_sse; 35*77c1e3ccSAndroid Build Coastguard Worker } INTERPOLATION_FILTER_STATS; 36*77c1e3ccSAndroid Build Coastguard Worker /*!\endcond */ 37*77c1e3ccSAndroid Build Coastguard Worker 38*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Miscellaneous arguments for inter mode search. 39*77c1e3ccSAndroid Build Coastguard Worker */ 40*77c1e3ccSAndroid Build Coastguard Worker typedef struct HandleInterModeArgs { 41*77c1e3ccSAndroid Build Coastguard Worker /*! 42*77c1e3ccSAndroid Build Coastguard Worker * Buffer for the above predictor in OBMC 43*77c1e3ccSAndroid Build Coastguard Worker */ 44*77c1e3ccSAndroid Build Coastguard Worker uint8_t *above_pred_buf[MAX_MB_PLANE]; 45*77c1e3ccSAndroid Build Coastguard Worker /*! 46*77c1e3ccSAndroid Build Coastguard Worker * Stride for the above predictor in OBMC 47*77c1e3ccSAndroid Build Coastguard Worker */ 48*77c1e3ccSAndroid Build Coastguard Worker int above_pred_stride[MAX_MB_PLANE]; 49*77c1e3ccSAndroid Build Coastguard Worker /*! 50*77c1e3ccSAndroid Build Coastguard Worker * Buffer for the left predictor in OBMC 51*77c1e3ccSAndroid Build Coastguard Worker */ 52*77c1e3ccSAndroid Build Coastguard Worker uint8_t *left_pred_buf[MAX_MB_PLANE]; 53*77c1e3ccSAndroid Build Coastguard Worker /*! 54*77c1e3ccSAndroid Build Coastguard Worker * Stride for the left predictor in OBMC 55*77c1e3ccSAndroid Build Coastguard Worker */ 56*77c1e3ccSAndroid Build Coastguard Worker int left_pred_stride[MAX_MB_PLANE]; 57*77c1e3ccSAndroid Build Coastguard Worker /*! 58*77c1e3ccSAndroid Build Coastguard Worker * Pointer to the first member in a 2D array which holds 59*77c1e3ccSAndroid Build Coastguard Worker * single reference mode motion vectors to be used as a starting 60*77c1e3ccSAndroid Build Coastguard Worker * point in the mv search for compound modes. Each array is length REF_FRAMES, 61*77c1e3ccSAndroid Build Coastguard Worker * meaning there is a slot for a single reference motion vector for 62*77c1e3ccSAndroid Build Coastguard Worker * each possible reference frame. The 2D array consists of N of these arrays, 63*77c1e3ccSAndroid Build Coastguard Worker * where N is the length of the reference mv stack computed for the single 64*77c1e3ccSAndroid Build Coastguard Worker * reference case for that particular reference frame. 65*77c1e3ccSAndroid Build Coastguard Worker */ 66*77c1e3ccSAndroid Build Coastguard Worker int_mv (*single_newmv)[REF_FRAMES]; 67*77c1e3ccSAndroid Build Coastguard Worker /*! 68*77c1e3ccSAndroid Build Coastguard Worker * Pointer to the first array of a 2D array with the same setup as 69*77c1e3ccSAndroid Build Coastguard Worker * single_newmv array above. This is a 2D array to hold the rate 70*77c1e3ccSAndroid Build Coastguard Worker * corresponding to each of the single reference mode motion vectors 71*77c1e3ccSAndroid Build Coastguard Worker * held in single_newmv. 72*77c1e3ccSAndroid Build Coastguard Worker */ 73*77c1e3ccSAndroid Build Coastguard Worker int (*single_newmv_rate)[REF_FRAMES]; 74*77c1e3ccSAndroid Build Coastguard Worker /*! 75*77c1e3ccSAndroid Build Coastguard Worker * Pointer to the first array of a 2D array with the same setup as 76*77c1e3ccSAndroid Build Coastguard Worker * single_newmv array above. This is a 2D array to hold a 0 or 1 77*77c1e3ccSAndroid Build Coastguard Worker * validity value corresponding to each of the single reference mode motion 78*77c1e3ccSAndroid Build Coastguard Worker * vectors held in single_newmv. 79*77c1e3ccSAndroid Build Coastguard Worker */ 80*77c1e3ccSAndroid Build Coastguard Worker int (*single_newmv_valid)[REF_FRAMES]; 81*77c1e3ccSAndroid Build Coastguard Worker /*! 82*77c1e3ccSAndroid Build Coastguard Worker * Pointer to the first array in a 3D array of predicted rate-distortion. 83*77c1e3ccSAndroid Build Coastguard Worker * The dimensions of this structure are: 84*77c1e3ccSAndroid Build Coastguard Worker * (number of possible inter modes) X 85*77c1e3ccSAndroid Build Coastguard Worker * (number of reference MVs) X 86*77c1e3ccSAndroid Build Coastguard Worker * (number of reference frames). 87*77c1e3ccSAndroid Build Coastguard Worker */ 88*77c1e3ccSAndroid Build Coastguard Worker int64_t (*modelled_rd)[MAX_REF_MV_SEARCH][REF_FRAMES]; 89*77c1e3ccSAndroid Build Coastguard Worker /*! 90*77c1e3ccSAndroid Build Coastguard Worker * Holds an estimated entropy cost for picking the current reference frame. 91*77c1e3ccSAndroid Build Coastguard Worker * This is used to compute an rd estimate. 92*77c1e3ccSAndroid Build Coastguard Worker */ 93*77c1e3ccSAndroid Build Coastguard Worker int ref_frame_cost; 94*77c1e3ccSAndroid Build Coastguard Worker /*! 95*77c1e3ccSAndroid Build Coastguard Worker * Holds an estimated entropy cost for picking single or compound 96*77c1e3ccSAndroid Build Coastguard Worker * reference. This is used to compute an rd estimate. 97*77c1e3ccSAndroid Build Coastguard Worker */ 98*77c1e3ccSAndroid Build Coastguard Worker int single_comp_cost; 99*77c1e3ccSAndroid Build Coastguard Worker /*! 100*77c1e3ccSAndroid Build Coastguard Worker * Pointer to the first element in a 3D array holding rd's of 101*77c1e3ccSAndroid Build Coastguard Worker * SIMPLE_TRANSLATION used to prune out the motion mode search in single ref 102*77c1e3ccSAndroid Build Coastguard Worker * modes used to determine compound ref modes. The full structure is: 103*77c1e3ccSAndroid Build Coastguard Worker * (number of inter modes) X (length of refmv list) X (number of ref frames) 104*77c1e3ccSAndroid Build Coastguard Worker */ 105*77c1e3ccSAndroid Build Coastguard Worker int64_t (*simple_rd)[MAX_REF_MV_SEARCH][REF_FRAMES]; 106*77c1e3ccSAndroid Build Coastguard Worker /*! 107*77c1e3ccSAndroid Build Coastguard Worker * An integer value 0 or 1 which indicates whether or not to skip the motion 108*77c1e3ccSAndroid Build Coastguard Worker * mode search and default to SIMPLE_TRANSLATION as a speed feature. 109*77c1e3ccSAndroid Build Coastguard Worker */ 110*77c1e3ccSAndroid Build Coastguard Worker int skip_motion_mode; 111*77c1e3ccSAndroid Build Coastguard Worker /*! 112*77c1e3ccSAndroid Build Coastguard Worker * Initialized to false. If true, skips interpolation filter search and uses 113*77c1e3ccSAndroid Build Coastguard Worker * the default EIGHTTAP_REGULAR. 114*77c1e3ccSAndroid Build Coastguard Worker */ 115*77c1e3ccSAndroid Build Coastguard Worker bool skip_ifs; 116*77c1e3ccSAndroid Build Coastguard Worker /*! 117*77c1e3ccSAndroid Build Coastguard Worker * A pointer to the first element in an array of INTERINTRA_MODE types. This 118*77c1e3ccSAndroid Build Coastguard Worker * contains the best inter_intra mode for each reference frame. 119*77c1e3ccSAndroid Build Coastguard Worker */ 120*77c1e3ccSAndroid Build Coastguard Worker INTERINTRA_MODE *inter_intra_mode; 121*77c1e3ccSAndroid Build Coastguard Worker /*! 122*77c1e3ccSAndroid Build Coastguard Worker * Array of saved interpolation filter stats collected to avoid repeating 123*77c1e3ccSAndroid Build Coastguard Worker * an interpolation filter search when the mv and ref_frame are the same 124*77c1e3ccSAndroid Build Coastguard Worker * as a previous search. 125*77c1e3ccSAndroid Build Coastguard Worker */ 126*77c1e3ccSAndroid Build Coastguard Worker INTERPOLATION_FILTER_STATS interp_filter_stats[MAX_INTERP_FILTER_STATS]; 127*77c1e3ccSAndroid Build Coastguard Worker 128*77c1e3ccSAndroid Build Coastguard Worker /*! 129*77c1e3ccSAndroid Build Coastguard Worker * Stack to store full pixel search start mv of NEWMV mode. 130*77c1e3ccSAndroid Build Coastguard Worker */ 131*77c1e3ccSAndroid Build Coastguard Worker FULLPEL_MV start_mv_stack[(MAX_REF_MV_SEARCH - 1) * 2]; 132*77c1e3ccSAndroid Build Coastguard Worker 133*77c1e3ccSAndroid Build Coastguard Worker /*! 134*77c1e3ccSAndroid Build Coastguard Worker * Stack to store ref_mv_idx of NEWMV mode. 135*77c1e3ccSAndroid Build Coastguard Worker */ 136*77c1e3ccSAndroid Build Coastguard Worker uint8_t ref_mv_idx_stack[(MAX_REF_MV_SEARCH - 1) * 2]; 137*77c1e3ccSAndroid Build Coastguard Worker 138*77c1e3ccSAndroid Build Coastguard Worker /*! 139*77c1e3ccSAndroid Build Coastguard Worker * Count of mvs in start mv stack. 140*77c1e3ccSAndroid Build Coastguard Worker */ 141*77c1e3ccSAndroid Build Coastguard Worker int start_mv_cnt; 142*77c1e3ccSAndroid Build Coastguard Worker 143*77c1e3ccSAndroid Build Coastguard Worker /*! 144*77c1e3ccSAndroid Build Coastguard Worker * Index of the last set of saved stats in the interp_filter_stats array. 145*77c1e3ccSAndroid Build Coastguard Worker */ 146*77c1e3ccSAndroid Build Coastguard Worker int interp_filter_stats_idx; 147*77c1e3ccSAndroid Build Coastguard Worker /*! 148*77c1e3ccSAndroid Build Coastguard Worker * Estimated wedge index. 149*77c1e3ccSAndroid Build Coastguard Worker */ 150*77c1e3ccSAndroid Build Coastguard Worker int wedge_index; 151*77c1e3ccSAndroid Build Coastguard Worker /*! 152*77c1e3ccSAndroid Build Coastguard Worker * Estimated wedge sign. 153*77c1e3ccSAndroid Build Coastguard Worker */ 154*77c1e3ccSAndroid Build Coastguard Worker int wedge_sign; 155*77c1e3ccSAndroid Build Coastguard Worker /*! 156*77c1e3ccSAndroid Build Coastguard Worker * Estimated diff wtd index. 157*77c1e3ccSAndroid Build Coastguard Worker */ 158*77c1e3ccSAndroid Build Coastguard Worker int diffwtd_index; 159*77c1e3ccSAndroid Build Coastguard Worker /*! 160*77c1e3ccSAndroid Build Coastguard Worker * Estimated cmp mode. 161*77c1e3ccSAndroid Build Coastguard Worker */ 162*77c1e3ccSAndroid Build Coastguard Worker int cmp_mode[MODE_CTX_REF_FRAMES]; 163*77c1e3ccSAndroid Build Coastguard Worker /*! 164*77c1e3ccSAndroid Build Coastguard Worker * The best sse during single new_mv search. Note that the sse here comes from 165*77c1e3ccSAndroid Build Coastguard Worker * single_motion_search, and not from interpolation_filter_search. This has 166*77c1e3ccSAndroid Build Coastguard Worker * two implications: 167*77c1e3ccSAndroid Build Coastguard Worker * 1. The mv used to calculate the sse here does not have to be the best sse 168*77c1e3ccSAndroid Build Coastguard Worker * found in handle_inter_mode. 169*77c1e3ccSAndroid Build Coastguard Worker * 2. Even if the mvs agree, the sse here can differ from the sse in \ref 170*77c1e3ccSAndroid Build Coastguard Worker * MACROBLOCK::pred_sse due to different interpolation filter used. 171*77c1e3ccSAndroid Build Coastguard Worker */ 172*77c1e3ccSAndroid Build Coastguard Worker unsigned int best_single_sse_in_refs[REF_FRAMES]; 173*77c1e3ccSAndroid Build Coastguard Worker /*! 174*77c1e3ccSAndroid Build Coastguard Worker * Holds the sse of best mode so far in the mode evaluation process. This is 175*77c1e3ccSAndroid Build Coastguard Worker * used in intermediate termination of NEWMV mode evaluation. 176*77c1e3ccSAndroid Build Coastguard Worker */ 177*77c1e3ccSAndroid Build Coastguard Worker unsigned int best_pred_sse; 178*77c1e3ccSAndroid Build Coastguard Worker } HandleInterModeArgs; 179*77c1e3ccSAndroid Build Coastguard Worker 180*77c1e3ccSAndroid Build Coastguard Worker /*!\cond */ 181*77c1e3ccSAndroid Build Coastguard Worker static const int_interpfilters filter_sets[DUAL_FILTER_SET_SIZE] = { 182*77c1e3ccSAndroid Build Coastguard Worker { 0x00000000 }, { 0x00010000 }, { 0x00020000 }, // y = 0 183*77c1e3ccSAndroid Build Coastguard Worker { 0x00000001 }, { 0x00010001 }, { 0x00020001 }, // y = 1 184*77c1e3ccSAndroid Build Coastguard Worker { 0x00000002 }, { 0x00010002 }, { 0x00020002 }, // y = 2 185*77c1e3ccSAndroid Build Coastguard Worker }; 186*77c1e3ccSAndroid Build Coastguard Worker 187*77c1e3ccSAndroid Build Coastguard Worker int64_t av1_interpolation_filter_search( 188*77c1e3ccSAndroid Build Coastguard Worker MACROBLOCK *const x, const AV1_COMP *const cpi, 189*77c1e3ccSAndroid Build Coastguard Worker const TileDataEnc *tile_data, BLOCK_SIZE bsize, 190*77c1e3ccSAndroid Build Coastguard Worker const BUFFER_SET *const tmp_dst, const BUFFER_SET *const orig_dst, 191*77c1e3ccSAndroid Build Coastguard Worker int64_t *const rd, int *const switchable_rate, int *skip_build_pred, 192*77c1e3ccSAndroid Build Coastguard Worker HandleInterModeArgs *args, int64_t ref_best_rd); 193*77c1e3ccSAndroid Build Coastguard Worker 194*77c1e3ccSAndroid Build Coastguard Worker /*!\endcond */ 195*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus 196*77c1e3ccSAndroid Build Coastguard Worker } // extern "C" 197*77c1e3ccSAndroid Build Coastguard Worker #endif 198*77c1e3ccSAndroid Build Coastguard Worker 199*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_AV1_ENCODER_INTERP_FILTER_SEARCH_H_ 200