xref: /aosp_15_r20/external/libaom/av1/encoder/encodeframe_utils.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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_ENCODEFRAME_UTILS_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_ENCODEFRAME_UTILS_H_
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #include "aom_ports/aom_timer.h"
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/reconinter.h"
18*77c1e3ccSAndroid Build Coastguard Worker 
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/encoder.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/rdopt.h"
21*77c1e3ccSAndroid Build Coastguard Worker 
22*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
23*77c1e3ccSAndroid Build Coastguard Worker extern "C" {
24*77c1e3ccSAndroid Build Coastguard Worker #endif
25*77c1e3ccSAndroid Build Coastguard Worker 
26*77c1e3ccSAndroid Build Coastguard Worker #define WRITE_FEATURE_TO_FILE 0
27*77c1e3ccSAndroid Build Coastguard Worker 
28*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_SMS_SPLIT_FAST 6
29*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_SMS_SPLIT 17
30*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_SMS_PRUNE_PART 25
31*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_SMS_TERM_NONE 28
32*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_FP_SMS_TERM_NONE 20
33*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SIZE_MAX_MIN_PART_PRED 13
34*77c1e3ccSAndroid Build Coastguard Worker #define MAX_NUM_CLASSES_MAX_MIN_PART_PRED 4
35*77c1e3ccSAndroid Build Coastguard Worker 
36*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SMS_NONE_FLAG 1
37*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SMS_SPLIT_FLAG (1 << 1)
38*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SMS_RECT_FLAG (1 << 2)
39*77c1e3ccSAndroid Build Coastguard Worker 
40*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SMS_PRUNE_PART_FLAG \
41*77c1e3ccSAndroid Build Coastguard Worker   (FEATURE_SMS_NONE_FLAG | FEATURE_SMS_SPLIT_FLAG | FEATURE_SMS_RECT_FLAG)
42*77c1e3ccSAndroid Build Coastguard Worker #define FEATURE_SMS_SPLIT_MODEL_FLAG \
43*77c1e3ccSAndroid Build Coastguard Worker   (FEATURE_SMS_NONE_FLAG | FEATURE_SMS_SPLIT_FLAG)
44*77c1e3ccSAndroid Build Coastguard Worker 
45*77c1e3ccSAndroid Build Coastguard Worker // Number of sub-partitions in rectangular partition types.
46*77c1e3ccSAndroid Build Coastguard Worker #define SUB_PARTITIONS_RECT 2
47*77c1e3ccSAndroid Build Coastguard Worker 
48*77c1e3ccSAndroid Build Coastguard Worker // Number of sub-partitions in split partition type.
49*77c1e3ccSAndroid Build Coastguard Worker #define SUB_PARTITIONS_SPLIT 4
50*77c1e3ccSAndroid Build Coastguard Worker 
51*77c1e3ccSAndroid Build Coastguard Worker // Number of sub-partitions in AB partition types.
52*77c1e3ccSAndroid Build Coastguard Worker #define SUB_PARTITIONS_AB 3
53*77c1e3ccSAndroid Build Coastguard Worker 
54*77c1e3ccSAndroid Build Coastguard Worker // Number of sub-partitions in 4-way partition types.
55*77c1e3ccSAndroid Build Coastguard Worker #define SUB_PARTITIONS_PART4 4
56*77c1e3ccSAndroid Build Coastguard Worker 
57*77c1e3ccSAndroid Build Coastguard Worker // 4part partition types.
58*77c1e3ccSAndroid Build Coastguard Worker enum { HORZ4 = 0, VERT4, NUM_PART4_TYPES } UENUM1BYTE(PART4_TYPES);
59*77c1e3ccSAndroid Build Coastguard Worker 
60*77c1e3ccSAndroid Build Coastguard Worker // AB partition types.
61*77c1e3ccSAndroid Build Coastguard Worker enum {
62*77c1e3ccSAndroid Build Coastguard Worker   HORZ_A = 0,
63*77c1e3ccSAndroid Build Coastguard Worker   HORZ_B,
64*77c1e3ccSAndroid Build Coastguard Worker   VERT_A,
65*77c1e3ccSAndroid Build Coastguard Worker   VERT_B,
66*77c1e3ccSAndroid Build Coastguard Worker   NUM_AB_PARTS
67*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(AB_PART_TYPE);
68*77c1e3ccSAndroid Build Coastguard Worker 
69*77c1e3ccSAndroid Build Coastguard Worker // Rectangular partition types.
70*77c1e3ccSAndroid Build Coastguard Worker enum { HORZ = 0, VERT, NUM_RECT_PARTS } UENUM1BYTE(RECT_PART_TYPE);
71*77c1e3ccSAndroid Build Coastguard Worker 
72*77c1e3ccSAndroid Build Coastguard Worker // Structure to keep win flags for HORZ and VERT partition evaluations.
73*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
74*77c1e3ccSAndroid Build Coastguard Worker   int rect_part_win[NUM_RECT_PARTS];
75*77c1e3ccSAndroid Build Coastguard Worker } RD_RECT_PART_WIN_INFO;
76*77c1e3ccSAndroid Build Coastguard Worker 
77*77c1e3ccSAndroid Build Coastguard Worker enum { PICK_MODE_RD = 0, PICK_MODE_NONRD };
78*77c1e3ccSAndroid Build Coastguard Worker 
79*77c1e3ccSAndroid Build Coastguard Worker enum {
80*77c1e3ccSAndroid Build Coastguard Worker   SB_SINGLE_PASS,  // Single pass encoding: all ctxs get updated normally
81*77c1e3ccSAndroid Build Coastguard Worker   SB_DRY_PASS,     // First pass of multi-pass: does not update the ctxs
82*77c1e3ccSAndroid Build Coastguard Worker   SB_WET_PASS      // Second pass of multi-pass: finalize and update the ctx
83*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(SB_MULTI_PASS_MODE);
84*77c1e3ccSAndroid Build Coastguard Worker 
85*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
86*77c1e3ccSAndroid Build Coastguard Worker   ENTROPY_CONTEXT a[MAX_MIB_SIZE * MAX_MB_PLANE];
87*77c1e3ccSAndroid Build Coastguard Worker   ENTROPY_CONTEXT l[MAX_MIB_SIZE * MAX_MB_PLANE];
88*77c1e3ccSAndroid Build Coastguard Worker   PARTITION_CONTEXT sa[MAX_MIB_SIZE];
89*77c1e3ccSAndroid Build Coastguard Worker   PARTITION_CONTEXT sl[MAX_MIB_SIZE];
90*77c1e3ccSAndroid Build Coastguard Worker   TXFM_CONTEXT *p_ta;
91*77c1e3ccSAndroid Build Coastguard Worker   TXFM_CONTEXT *p_tl;
92*77c1e3ccSAndroid Build Coastguard Worker   TXFM_CONTEXT ta[MAX_MIB_SIZE];
93*77c1e3ccSAndroid Build Coastguard Worker   TXFM_CONTEXT tl[MAX_MIB_SIZE];
94*77c1e3ccSAndroid Build Coastguard Worker } RD_SEARCH_MACROBLOCK_CONTEXT;
95*77c1e3ccSAndroid Build Coastguard Worker 
96*77c1e3ccSAndroid Build Coastguard Worker // This struct is used to store the statistics used by sb-level multi-pass
97*77c1e3ccSAndroid Build Coastguard Worker // encoding. Currently, this is only used to make a copy of the state before we
98*77c1e3ccSAndroid Build Coastguard Worker // perform the first pass
99*77c1e3ccSAndroid Build Coastguard Worker typedef struct SB_FIRST_PASS_STATS {
100*77c1e3ccSAndroid Build Coastguard Worker   RD_SEARCH_MACROBLOCK_CONTEXT x_ctx;
101*77c1e3ccSAndroid Build Coastguard Worker   RD_COUNTS rd_count;
102*77c1e3ccSAndroid Build Coastguard Worker 
103*77c1e3ccSAndroid Build Coastguard Worker   int split_count;
104*77c1e3ccSAndroid Build Coastguard Worker   FRAME_COUNTS fc;
105*77c1e3ccSAndroid Build Coastguard Worker   InterModeRdModel inter_mode_rd_models[BLOCK_SIZES_ALL];
106*77c1e3ccSAndroid Build Coastguard Worker   int thresh_freq_fact[BLOCK_SIZES_ALL][MAX_MODES];
107*77c1e3ccSAndroid Build Coastguard Worker   int current_qindex;
108*77c1e3ccSAndroid Build Coastguard Worker 
109*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
110*77c1e3ccSAndroid Build Coastguard Worker   unsigned int mode_chosen_counts[MAX_MODES];
111*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_INTERNAL_STATS
112*77c1e3ccSAndroid Build Coastguard Worker } SB_FIRST_PASS_STATS;
113*77c1e3ccSAndroid Build Coastguard Worker 
114*77c1e3ccSAndroid Build Coastguard Worker // This structure contains block size related
115*77c1e3ccSAndroid Build Coastguard Worker // variables for use in rd_pick_partition().
116*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
117*77c1e3ccSAndroid Build Coastguard Worker   // Half of block width to determine block edge.
118*77c1e3ccSAndroid Build Coastguard Worker   int mi_step;
119*77c1e3ccSAndroid Build Coastguard Worker 
120*77c1e3ccSAndroid Build Coastguard Worker   // Block row and column indices.
121*77c1e3ccSAndroid Build Coastguard Worker   int mi_row;
122*77c1e3ccSAndroid Build Coastguard Worker   int mi_col;
123*77c1e3ccSAndroid Build Coastguard Worker 
124*77c1e3ccSAndroid Build Coastguard Worker   // Block edge row and column indices.
125*77c1e3ccSAndroid Build Coastguard Worker   int mi_row_edge;
126*77c1e3ccSAndroid Build Coastguard Worker   int mi_col_edge;
127*77c1e3ccSAndroid Build Coastguard Worker 
128*77c1e3ccSAndroid Build Coastguard Worker   // Block width of current partition block.
129*77c1e3ccSAndroid Build Coastguard Worker   int width;
130*77c1e3ccSAndroid Build Coastguard Worker 
131*77c1e3ccSAndroid Build Coastguard Worker   // Block width of minimum partition size allowed.
132*77c1e3ccSAndroid Build Coastguard Worker   int min_partition_size_1d;
133*77c1e3ccSAndroid Build Coastguard Worker 
134*77c1e3ccSAndroid Build Coastguard Worker   // Flag to indicate if partition is 8x8 or higher size.
135*77c1e3ccSAndroid Build Coastguard Worker   int bsize_at_least_8x8;
136*77c1e3ccSAndroid Build Coastguard Worker 
137*77c1e3ccSAndroid Build Coastguard Worker   // Indicates edge blocks in frame.
138*77c1e3ccSAndroid Build Coastguard Worker   int has_rows;
139*77c1e3ccSAndroid Build Coastguard Worker   int has_cols;
140*77c1e3ccSAndroid Build Coastguard Worker 
141*77c1e3ccSAndroid Build Coastguard Worker   // Block size of current partition.
142*77c1e3ccSAndroid Build Coastguard Worker   BLOCK_SIZE bsize;
143*77c1e3ccSAndroid Build Coastguard Worker 
144*77c1e3ccSAndroid Build Coastguard Worker   // Size of current sub-partition.
145*77c1e3ccSAndroid Build Coastguard Worker   BLOCK_SIZE subsize;
146*77c1e3ccSAndroid Build Coastguard Worker 
147*77c1e3ccSAndroid Build Coastguard Worker   // Size of split partition.
148*77c1e3ccSAndroid Build Coastguard Worker   BLOCK_SIZE split_bsize2;
149*77c1e3ccSAndroid Build Coastguard Worker } PartitionBlkParams;
150*77c1e3ccSAndroid Build Coastguard Worker 
151*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_COLLECT_PARTITION_STATS
152*77c1e3ccSAndroid Build Coastguard Worker typedef struct PartitionTimingStats {
153*77c1e3ccSAndroid Build Coastguard Worker   // Tracks the number of partition decision used in the current call to \ref
154*77c1e3ccSAndroid Build Coastguard Worker   // av1_rd_pick_partition
155*77c1e3ccSAndroid Build Coastguard Worker   int partition_decisions[EXT_PARTITION_TYPES];
156*77c1e3ccSAndroid Build Coastguard Worker   // Tracks the number of partition_block searched in the current call to \ref
157*77c1e3ccSAndroid Build Coastguard Worker   // av1_rd_pick_partition
158*77c1e3ccSAndroid Build Coastguard Worker   int partition_attempts[EXT_PARTITION_TYPES];
159*77c1e3ccSAndroid Build Coastguard Worker   // Tracks the time spent on each partition search in the current call to \ref
160*77c1e3ccSAndroid Build Coastguard Worker   // av1_rd_pick_partition
161*77c1e3ccSAndroid Build Coastguard Worker   int64_t partition_times[EXT_PARTITION_TYPES];
162*77c1e3ccSAndroid Build Coastguard Worker   // Tracks the rdcost spent on each partition search in the current call to
163*77c1e3ccSAndroid Build Coastguard Worker   // \ref av1_rd_pick_partition
164*77c1e3ccSAndroid Build Coastguard Worker   int64_t partition_rdcost[EXT_PARTITION_TYPES];
165*77c1e3ccSAndroid Build Coastguard Worker   // Timer used to time the partitions.
166*77c1e3ccSAndroid Build Coastguard Worker   struct aom_usec_timer timer;
167*77c1e3ccSAndroid Build Coastguard Worker   // Whether the timer is on
168*77c1e3ccSAndroid Build Coastguard Worker   int timer_is_on;
169*77c1e3ccSAndroid Build Coastguard Worker } PartitionTimingStats;
170*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_COLLECT_PARTITION_STATS
171*77c1e3ccSAndroid Build Coastguard Worker 
172*77c1e3ccSAndroid Build Coastguard Worker // Structure holding state variables for partition search.
173*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
174*77c1e3ccSAndroid Build Coastguard Worker   // Intra partitioning related info.
175*77c1e3ccSAndroid Build Coastguard Worker   PartitionSearchInfo *intra_part_info;
176*77c1e3ccSAndroid Build Coastguard Worker 
177*77c1e3ccSAndroid Build Coastguard Worker   // Parameters related to partition block size.
178*77c1e3ccSAndroid Build Coastguard Worker   PartitionBlkParams part_blk_params;
179*77c1e3ccSAndroid Build Coastguard Worker 
180*77c1e3ccSAndroid Build Coastguard Worker   // Win flags for HORZ and VERT partition evaluations.
181*77c1e3ccSAndroid Build Coastguard Worker   RD_RECT_PART_WIN_INFO split_part_rect_win[SUB_PARTITIONS_SPLIT];
182*77c1e3ccSAndroid Build Coastguard Worker 
183*77c1e3ccSAndroid Build Coastguard Worker   // RD cost for the current block of given partition type.
184*77c1e3ccSAndroid Build Coastguard Worker   RD_STATS this_rdc;
185*77c1e3ccSAndroid Build Coastguard Worker 
186*77c1e3ccSAndroid Build Coastguard Worker   // RD cost summed across all blocks of partition type.
187*77c1e3ccSAndroid Build Coastguard Worker   RD_STATS sum_rdc;
188*77c1e3ccSAndroid Build Coastguard Worker 
189*77c1e3ccSAndroid Build Coastguard Worker   // Array holding partition type cost.
190*77c1e3ccSAndroid Build Coastguard Worker   int tmp_partition_cost[PARTITION_TYPES];
191*77c1e3ccSAndroid Build Coastguard Worker 
192*77c1e3ccSAndroid Build Coastguard Worker   // Pointer to partition cost buffer
193*77c1e3ccSAndroid Build Coastguard Worker   int *partition_cost;
194*77c1e3ccSAndroid Build Coastguard Worker 
195*77c1e3ccSAndroid Build Coastguard Worker   // RD costs for different partition types.
196*77c1e3ccSAndroid Build Coastguard Worker   int64_t none_rd;
197*77c1e3ccSAndroid Build Coastguard Worker   int64_t split_rd[SUB_PARTITIONS_SPLIT];
198*77c1e3ccSAndroid Build Coastguard Worker   // RD costs for rectangular partitions.
199*77c1e3ccSAndroid Build Coastguard Worker   // rect_part_rd[0][i] is the RD cost of ith partition index of PARTITION_HORZ.
200*77c1e3ccSAndroid Build Coastguard Worker   // rect_part_rd[1][i] is the RD cost of ith partition index of PARTITION_VERT.
201*77c1e3ccSAndroid Build Coastguard Worker   int64_t rect_part_rd[NUM_RECT_PARTS][SUB_PARTITIONS_RECT];
202*77c1e3ccSAndroid Build Coastguard Worker 
203*77c1e3ccSAndroid Build Coastguard Worker   // Flags indicating if the corresponding partition was winner or not.
204*77c1e3ccSAndroid Build Coastguard Worker   // Used to bypass similar blocks during AB partition evaluation.
205*77c1e3ccSAndroid Build Coastguard Worker   int is_split_ctx_is_ready[2];
206*77c1e3ccSAndroid Build Coastguard Worker   int is_rect_ctx_is_ready[NUM_RECT_PARTS];
207*77c1e3ccSAndroid Build Coastguard Worker 
208*77c1e3ccSAndroid Build Coastguard Worker   // If true, skips the rest of partition evaluation at the current bsize level.
209*77c1e3ccSAndroid Build Coastguard Worker   int terminate_partition_search;
210*77c1e3ccSAndroid Build Coastguard Worker 
211*77c1e3ccSAndroid Build Coastguard Worker   // If false, skips rdopt on PARTITION_NONE.
212*77c1e3ccSAndroid Build Coastguard Worker   int partition_none_allowed;
213*77c1e3ccSAndroid Build Coastguard Worker 
214*77c1e3ccSAndroid Build Coastguard Worker   // If partition_rect_allowed[HORZ] is false, skips searching PARTITION_HORZ,
215*77c1e3ccSAndroid Build Coastguard Worker   // PARTITION_HORZ_A, PARTITIO_HORZ_B, PARTITION_HORZ_4. Same holds for VERT.
216*77c1e3ccSAndroid Build Coastguard Worker   int partition_rect_allowed[NUM_RECT_PARTS];
217*77c1e3ccSAndroid Build Coastguard Worker 
218*77c1e3ccSAndroid Build Coastguard Worker   // If false, skips searching rectangular partition unless some logic related
219*77c1e3ccSAndroid Build Coastguard Worker   // to edge detection holds.
220*77c1e3ccSAndroid Build Coastguard Worker   int do_rectangular_split;
221*77c1e3ccSAndroid Build Coastguard Worker 
222*77c1e3ccSAndroid Build Coastguard Worker   // If false, skips searching PARTITION_SPLIT.
223*77c1e3ccSAndroid Build Coastguard Worker   int do_square_split;
224*77c1e3ccSAndroid Build Coastguard Worker 
225*77c1e3ccSAndroid Build Coastguard Worker   // If true, prunes the corresponding PARTITION_HORZ/PARTITION_VERT. Note that
226*77c1e3ccSAndroid Build Coastguard Worker   // this does not directly affect the extended partitions, so this can be used
227*77c1e3ccSAndroid Build Coastguard Worker   // to prune out PARTITION_HORZ/PARTITION_VERT while still allowing rdopt of
228*77c1e3ccSAndroid Build Coastguard Worker   // PARTITION_HORZ_AB4, etc.
229*77c1e3ccSAndroid Build Coastguard Worker   int prune_rect_part[NUM_RECT_PARTS];
230*77c1e3ccSAndroid Build Coastguard Worker 
231*77c1e3ccSAndroid Build Coastguard Worker   // Chroma subsampling in x and y directions.
232*77c1e3ccSAndroid Build Coastguard Worker   int ss_x;
233*77c1e3ccSAndroid Build Coastguard Worker   int ss_y;
234*77c1e3ccSAndroid Build Coastguard Worker 
235*77c1e3ccSAndroid Build Coastguard Worker   // Partition plane context index.
236*77c1e3ccSAndroid Build Coastguard Worker   int pl_ctx_idx;
237*77c1e3ccSAndroid Build Coastguard Worker 
238*77c1e3ccSAndroid Build Coastguard Worker   // This flag will be set if best partition is found from the search.
239*77c1e3ccSAndroid Build Coastguard Worker   bool found_best_partition;
240*77c1e3ccSAndroid Build Coastguard Worker 
241*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_COLLECT_PARTITION_STATS
242*77c1e3ccSAndroid Build Coastguard Worker   PartitionTimingStats part_timing_stats;
243*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_COLLECT_PARTITION_STATS
244*77c1e3ccSAndroid Build Coastguard Worker } PartitionSearchState;
245*77c1e3ccSAndroid Build Coastguard Worker 
av1_disable_square_split_partition(PartitionSearchState * part_state)246*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_disable_square_split_partition(
247*77c1e3ccSAndroid Build Coastguard Worker     PartitionSearchState *part_state) {
248*77c1e3ccSAndroid Build Coastguard Worker   part_state->do_square_split = 0;
249*77c1e3ccSAndroid Build Coastguard Worker }
250*77c1e3ccSAndroid Build Coastguard Worker 
251*77c1e3ccSAndroid Build Coastguard Worker // Disables all possible rectangular splits. This includes PARTITION_AB4 as they
252*77c1e3ccSAndroid Build Coastguard Worker // depend on the corresponding partition_rect_allowed.
av1_disable_rect_partitions(PartitionSearchState * part_state)253*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_disable_rect_partitions(
254*77c1e3ccSAndroid Build Coastguard Worker     PartitionSearchState *part_state) {
255*77c1e3ccSAndroid Build Coastguard Worker   part_state->do_rectangular_split = 0;
256*77c1e3ccSAndroid Build Coastguard Worker   part_state->partition_rect_allowed[HORZ] = 0;
257*77c1e3ccSAndroid Build Coastguard Worker   part_state->partition_rect_allowed[VERT] = 0;
258*77c1e3ccSAndroid Build Coastguard Worker }
259*77c1e3ccSAndroid Build Coastguard Worker 
260*77c1e3ccSAndroid Build Coastguard Worker // Disables all possible splits so that only PARTITION_NONE *might* be allowed.
av1_disable_all_splits(PartitionSearchState * part_state)261*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_disable_all_splits(PartitionSearchState *part_state) {
262*77c1e3ccSAndroid Build Coastguard Worker   av1_disable_square_split_partition(part_state);
263*77c1e3ccSAndroid Build Coastguard Worker   av1_disable_rect_partitions(part_state);
264*77c1e3ccSAndroid Build Coastguard Worker }
265*77c1e3ccSAndroid Build Coastguard Worker 
av1_set_square_split_only(PartitionSearchState * part_state)266*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_set_square_split_only(PartitionSearchState *part_state) {
267*77c1e3ccSAndroid Build Coastguard Worker   part_state->partition_none_allowed = 0;
268*77c1e3ccSAndroid Build Coastguard Worker   part_state->do_square_split = 1;
269*77c1e3ccSAndroid Build Coastguard Worker   av1_disable_rect_partitions(part_state);
270*77c1e3ccSAndroid Build Coastguard Worker }
271*77c1e3ccSAndroid Build Coastguard Worker 
av1_blk_has_rows_and_cols(const PartitionBlkParams * blk_params)272*77c1e3ccSAndroid Build Coastguard Worker static inline bool av1_blk_has_rows_and_cols(
273*77c1e3ccSAndroid Build Coastguard Worker     const PartitionBlkParams *blk_params) {
274*77c1e3ccSAndroid Build Coastguard Worker   return blk_params->has_rows && blk_params->has_cols;
275*77c1e3ccSAndroid Build Coastguard Worker }
276*77c1e3ccSAndroid Build Coastguard Worker 
av1_is_whole_blk_in_frame(const PartitionBlkParams * blk_params,const CommonModeInfoParams * mi_params)277*77c1e3ccSAndroid Build Coastguard Worker static inline bool av1_is_whole_blk_in_frame(
278*77c1e3ccSAndroid Build Coastguard Worker     const PartitionBlkParams *blk_params,
279*77c1e3ccSAndroid Build Coastguard Worker     const CommonModeInfoParams *mi_params) {
280*77c1e3ccSAndroid Build Coastguard Worker   const int mi_row = blk_params->mi_row, mi_col = blk_params->mi_col;
281*77c1e3ccSAndroid Build Coastguard Worker   const BLOCK_SIZE bsize = blk_params->bsize;
282*77c1e3ccSAndroid Build Coastguard Worker   return mi_row + mi_size_high[bsize] <= mi_params->mi_rows &&
283*77c1e3ccSAndroid Build Coastguard Worker          mi_col + mi_size_wide[bsize] <= mi_params->mi_cols;
284*77c1e3ccSAndroid Build Coastguard Worker }
285*77c1e3ccSAndroid Build Coastguard Worker 
update_filter_type_cdf(const MACROBLOCKD * xd,const MB_MODE_INFO * mbmi,int dual_filter)286*77c1e3ccSAndroid Build Coastguard Worker static inline void update_filter_type_cdf(const MACROBLOCKD *xd,
287*77c1e3ccSAndroid Build Coastguard Worker                                           const MB_MODE_INFO *mbmi,
288*77c1e3ccSAndroid Build Coastguard Worker                                           int dual_filter) {
289*77c1e3ccSAndroid Build Coastguard Worker   for (int dir = 0; dir < 2; ++dir) {
290*77c1e3ccSAndroid Build Coastguard Worker     if (dir && !dual_filter) break;
291*77c1e3ccSAndroid Build Coastguard Worker     const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
292*77c1e3ccSAndroid Build Coastguard Worker     InterpFilter filter = av1_extract_interp_filter(mbmi->interp_filters, dir);
293*77c1e3ccSAndroid Build Coastguard Worker     update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
294*77c1e3ccSAndroid Build Coastguard Worker                SWITCHABLE_FILTERS);
295*77c1e3ccSAndroid Build Coastguard Worker   }
296*77c1e3ccSAndroid Build Coastguard Worker }
297*77c1e3ccSAndroid Build Coastguard Worker 
set_rdmult(const AV1_COMP * const cpi,const MACROBLOCK * const x,int segment_id)298*77c1e3ccSAndroid Build Coastguard Worker static inline int set_rdmult(const AV1_COMP *const cpi,
299*77c1e3ccSAndroid Build Coastguard Worker                              const MACROBLOCK *const x, int segment_id) {
300*77c1e3ccSAndroid Build Coastguard Worker   const AV1_COMMON *const cm = &cpi->common;
301*77c1e3ccSAndroid Build Coastguard Worker   const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
302*77c1e3ccSAndroid Build Coastguard Worker   const CommonQuantParams *quant_params = &cm->quant_params;
303*77c1e3ccSAndroid Build Coastguard Worker   const aom_bit_depth_t bit_depth = cm->seq_params->bit_depth;
304*77c1e3ccSAndroid Build Coastguard Worker   const FRAME_UPDATE_TYPE update_type =
305*77c1e3ccSAndroid Build Coastguard Worker       cpi->ppi->gf_group.update_type[cpi->gf_frame_index];
306*77c1e3ccSAndroid Build Coastguard Worker   const FRAME_TYPE frame_type = cm->current_frame.frame_type;
307*77c1e3ccSAndroid Build Coastguard Worker   const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100));
308*77c1e3ccSAndroid Build Coastguard Worker   const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6);
309*77c1e3ccSAndroid Build Coastguard Worker 
310*77c1e3ccSAndroid Build Coastguard Worker   int qindex;
311*77c1e3ccSAndroid Build Coastguard Worker   if (segment_id >= 0) {
312*77c1e3ccSAndroid Build Coastguard Worker     qindex = av1_get_qindex(&cm->seg, segment_id, cm->quant_params.base_qindex);
313*77c1e3ccSAndroid Build Coastguard Worker   } else {
314*77c1e3ccSAndroid Build Coastguard Worker     qindex = quant_params->base_qindex + x->rdmult_delta_qindex +
315*77c1e3ccSAndroid Build Coastguard Worker              quant_params->y_dc_delta_q;
316*77c1e3ccSAndroid Build Coastguard Worker   }
317*77c1e3ccSAndroid Build Coastguard Worker 
318*77c1e3ccSAndroid Build Coastguard Worker   return av1_compute_rd_mult(
319*77c1e3ccSAndroid Build Coastguard Worker       qindex, bit_depth, update_type, layer_depth, boost_index, frame_type,
320*77c1e3ccSAndroid Build Coastguard Worker       cpi->oxcf.q_cfg.use_fixed_qp_offsets, is_stat_consumption_stage(cpi));
321*77c1e3ccSAndroid Build Coastguard Worker }
322*77c1e3ccSAndroid Build Coastguard Worker 
do_split_check(BLOCK_SIZE bsize)323*77c1e3ccSAndroid Build Coastguard Worker static inline int do_split_check(BLOCK_SIZE bsize) {
324*77c1e3ccSAndroid Build Coastguard Worker   return (bsize == BLOCK_16X16 || bsize == BLOCK_32X32);
325*77c1e3ccSAndroid Build Coastguard Worker }
326*77c1e3ccSAndroid Build Coastguard Worker 
327*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
read_one_frame_stats(const TWO_PASS * p,int frm)328*77c1e3ccSAndroid Build Coastguard Worker static inline const FIRSTPASS_STATS *read_one_frame_stats(const TWO_PASS *p,
329*77c1e3ccSAndroid Build Coastguard Worker                                                           int frm) {
330*77c1e3ccSAndroid Build Coastguard Worker   assert(frm >= 0);
331*77c1e3ccSAndroid Build Coastguard Worker   if (frm < 0 ||
332*77c1e3ccSAndroid Build Coastguard Worker       p->stats_buf_ctx->stats_in_start + frm > p->stats_buf_ctx->stats_in_end) {
333*77c1e3ccSAndroid Build Coastguard Worker     return NULL;
334*77c1e3ccSAndroid Build Coastguard Worker   }
335*77c1e3ccSAndroid Build Coastguard Worker 
336*77c1e3ccSAndroid Build Coastguard Worker   return &p->stats_buf_ctx->stats_in_start[frm];
337*77c1e3ccSAndroid Build Coastguard Worker }
338*77c1e3ccSAndroid Build Coastguard Worker 
339*77c1e3ccSAndroid Build Coastguard Worker int av1_get_rdmult_delta(AV1_COMP *cpi, BLOCK_SIZE bsize, int mi_row,
340*77c1e3ccSAndroid Build Coastguard Worker                          int mi_col, int orig_rdmult);
341*77c1e3ccSAndroid Build Coastguard Worker 
342*77c1e3ccSAndroid Build Coastguard Worker int av1_active_h_edge(const AV1_COMP *cpi, int mi_row, int mi_step);
343*77c1e3ccSAndroid Build Coastguard Worker 
344*77c1e3ccSAndroid Build Coastguard Worker int av1_active_v_edge(const AV1_COMP *cpi, int mi_col, int mi_step);
345*77c1e3ccSAndroid Build Coastguard Worker 
346*77c1e3ccSAndroid Build Coastguard Worker void av1_get_tpl_stats_sb(AV1_COMP *cpi, BLOCK_SIZE bsize, int mi_row,
347*77c1e3ccSAndroid Build Coastguard Worker                           int mi_col, SuperBlockEnc *sb_enc);
348*77c1e3ccSAndroid Build Coastguard Worker 
349*77c1e3ccSAndroid Build Coastguard Worker int av1_get_q_for_deltaq_objective(AV1_COMP *const cpi, ThreadData *td,
350*77c1e3ccSAndroid Build Coastguard Worker                                    int64_t *delta_dist, BLOCK_SIZE bsize,
351*77c1e3ccSAndroid Build Coastguard Worker                                    int mi_row, int mi_col);
352*77c1e3ccSAndroid Build Coastguard Worker 
353*77c1e3ccSAndroid Build Coastguard Worker int av1_get_q_for_hdr(AV1_COMP *const cpi, MACROBLOCK *const x,
354*77c1e3ccSAndroid Build Coastguard Worker                       BLOCK_SIZE bsize, int mi_row, int mi_col);
355*77c1e3ccSAndroid Build Coastguard Worker 
356*77c1e3ccSAndroid Build Coastguard Worker int av1_get_cb_rdmult(const AV1_COMP *const cpi, MACROBLOCK *const x,
357*77c1e3ccSAndroid Build Coastguard Worker                       const BLOCK_SIZE bsize, const int mi_row,
358*77c1e3ccSAndroid Build Coastguard Worker                       const int mi_col);
359*77c1e3ccSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
360*77c1e3ccSAndroid Build Coastguard Worker 
361*77c1e3ccSAndroid Build Coastguard Worker void av1_set_ssim_rdmult(const AV1_COMP *const cpi, int *errorperbit,
362*77c1e3ccSAndroid Build Coastguard Worker                          const BLOCK_SIZE bsize, const int mi_row,
363*77c1e3ccSAndroid Build Coastguard Worker                          const int mi_col, int *const rdmult);
364*77c1e3ccSAndroid Build Coastguard Worker 
365*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_SALIENCY_MAP
366*77c1e3ccSAndroid Build Coastguard Worker void av1_set_saliency_map_vmaf_rdmult(const AV1_COMP *const cpi,
367*77c1e3ccSAndroid Build Coastguard Worker                                       int *errorperbit, const BLOCK_SIZE bsize,
368*77c1e3ccSAndroid Build Coastguard Worker                                       const int mi_row, const int mi_col,
369*77c1e3ccSAndroid Build Coastguard Worker                                       int *const rdmult);
370*77c1e3ccSAndroid Build Coastguard Worker #endif
371*77c1e3ccSAndroid Build Coastguard Worker 
372*77c1e3ccSAndroid Build Coastguard Worker void av1_update_state(const AV1_COMP *const cpi, ThreadData *td,
373*77c1e3ccSAndroid Build Coastguard Worker                       const PICK_MODE_CONTEXT *const ctx, int mi_row,
374*77c1e3ccSAndroid Build Coastguard Worker                       int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run);
375*77c1e3ccSAndroid Build Coastguard Worker 
376*77c1e3ccSAndroid Build Coastguard Worker void av1_update_inter_mode_stats(FRAME_CONTEXT *fc, FRAME_COUNTS *counts,
377*77c1e3ccSAndroid Build Coastguard Worker                                  PREDICTION_MODE mode, int16_t mode_context);
378*77c1e3ccSAndroid Build Coastguard Worker 
379*77c1e3ccSAndroid Build Coastguard Worker void av1_sum_intra_stats(const AV1_COMMON *const cm, FRAME_COUNTS *counts,
380*77c1e3ccSAndroid Build Coastguard Worker                          MACROBLOCKD *xd, const MB_MODE_INFO *const mbmi,
381*77c1e3ccSAndroid Build Coastguard Worker                          const MB_MODE_INFO *above_mi,
382*77c1e3ccSAndroid Build Coastguard Worker                          const MB_MODE_INFO *left_mi, const int intraonly);
383*77c1e3ccSAndroid Build Coastguard Worker 
384*77c1e3ccSAndroid Build Coastguard Worker void av1_restore_context(MACROBLOCK *x, const RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
385*77c1e3ccSAndroid Build Coastguard Worker                          int mi_row, int mi_col, BLOCK_SIZE bsize,
386*77c1e3ccSAndroid Build Coastguard Worker                          const int num_planes);
387*77c1e3ccSAndroid Build Coastguard Worker 
388*77c1e3ccSAndroid Build Coastguard Worker void av1_save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
389*77c1e3ccSAndroid Build Coastguard Worker                       int mi_row, int mi_col, BLOCK_SIZE bsize,
390*77c1e3ccSAndroid Build Coastguard Worker                       const int num_planes);
391*77c1e3ccSAndroid Build Coastguard Worker 
392*77c1e3ccSAndroid Build Coastguard Worker void av1_set_fixed_partitioning(AV1_COMP *cpi, const TileInfo *const tile,
393*77c1e3ccSAndroid Build Coastguard Worker                                 MB_MODE_INFO **mib, int mi_row, int mi_col,
394*77c1e3ccSAndroid Build Coastguard Worker                                 BLOCK_SIZE bsize);
395*77c1e3ccSAndroid Build Coastguard Worker 
396*77c1e3ccSAndroid Build Coastguard Worker int av1_is_leaf_split_partition(AV1_COMMON *cm, int mi_row, int mi_col,
397*77c1e3ccSAndroid Build Coastguard Worker                                 BLOCK_SIZE bsize);
398*77c1e3ccSAndroid Build Coastguard Worker 
399*77c1e3ccSAndroid Build Coastguard Worker void av1_reset_simple_motion_tree_partition(SIMPLE_MOTION_DATA_TREE *sms_tree,
400*77c1e3ccSAndroid Build Coastguard Worker                                             BLOCK_SIZE bsize);
401*77c1e3ccSAndroid Build Coastguard Worker 
402*77c1e3ccSAndroid Build Coastguard Worker void av1_update_picked_ref_frames_mask(MACROBLOCK *const x, int ref_type,
403*77c1e3ccSAndroid Build Coastguard Worker                                        BLOCK_SIZE bsize, int mib_size,
404*77c1e3ccSAndroid Build Coastguard Worker                                        int mi_row, int mi_col);
405*77c1e3ccSAndroid Build Coastguard Worker 
406*77c1e3ccSAndroid Build Coastguard Worker void av1_avg_cdf_symbols(FRAME_CONTEXT *ctx_left, FRAME_CONTEXT *ctx_tr,
407*77c1e3ccSAndroid Build Coastguard Worker                          int wt_left, int wt_tr);
408*77c1e3ccSAndroid Build Coastguard Worker 
409*77c1e3ccSAndroid Build Coastguard Worker void av1_source_content_sb(AV1_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
410*77c1e3ccSAndroid Build Coastguard Worker                            int mi_row, int mi_col);
411*77c1e3ccSAndroid Build Coastguard Worker 
412*77c1e3ccSAndroid Build Coastguard Worker void av1_reset_mbmi(CommonModeInfoParams *const mi_params, BLOCK_SIZE sb_size,
413*77c1e3ccSAndroid Build Coastguard Worker                     int mi_row, int mi_col);
414*77c1e3ccSAndroid Build Coastguard Worker 
415*77c1e3ccSAndroid Build Coastguard Worker void av1_backup_sb_state(SB_FIRST_PASS_STATS *sb_fp_stats, const AV1_COMP *cpi,
416*77c1e3ccSAndroid Build Coastguard Worker                          ThreadData *td, const TileDataEnc *tile_data,
417*77c1e3ccSAndroid Build Coastguard Worker                          int mi_row, int mi_col);
418*77c1e3ccSAndroid Build Coastguard Worker 
419*77c1e3ccSAndroid Build Coastguard Worker void av1_restore_sb_state(const SB_FIRST_PASS_STATS *sb_fp_stats, AV1_COMP *cpi,
420*77c1e3ccSAndroid Build Coastguard Worker                           ThreadData *td, TileDataEnc *tile_data, int mi_row,
421*77c1e3ccSAndroid Build Coastguard Worker                           int mi_col);
422*77c1e3ccSAndroid Build Coastguard Worker 
423*77c1e3ccSAndroid Build Coastguard Worker void av1_set_cost_upd_freq(AV1_COMP *cpi, ThreadData *td,
424*77c1e3ccSAndroid Build Coastguard Worker                            const TileInfo *const tile_info, const int mi_row,
425*77c1e3ccSAndroid Build Coastguard Worker                            const int mi_col);
426*77c1e3ccSAndroid Build Coastguard Worker 
427*77c1e3ccSAndroid Build Coastguard Worker void av1_dealloc_src_diff_buf(struct macroblock *mb, int num_planes);
428*77c1e3ccSAndroid Build Coastguard Worker 
av1_dealloc_mb_data(struct macroblock * mb,int num_planes)429*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_dealloc_mb_data(struct macroblock *mb, int num_planes) {
430*77c1e3ccSAndroid Build Coastguard Worker   aom_free(mb->txfm_search_info.mb_rd_record);
431*77c1e3ccSAndroid Build Coastguard Worker   mb->txfm_search_info.mb_rd_record = NULL;
432*77c1e3ccSAndroid Build Coastguard Worker 
433*77c1e3ccSAndroid Build Coastguard Worker   aom_free(mb->inter_modes_info);
434*77c1e3ccSAndroid Build Coastguard Worker   mb->inter_modes_info = NULL;
435*77c1e3ccSAndroid Build Coastguard Worker 
436*77c1e3ccSAndroid Build Coastguard Worker   av1_dealloc_src_diff_buf(mb, num_planes);
437*77c1e3ccSAndroid Build Coastguard Worker 
438*77c1e3ccSAndroid Build Coastguard Worker   aom_free(mb->e_mbd.seg_mask);
439*77c1e3ccSAndroid Build Coastguard Worker   mb->e_mbd.seg_mask = NULL;
440*77c1e3ccSAndroid Build Coastguard Worker 
441*77c1e3ccSAndroid Build Coastguard Worker   aom_free(mb->winner_mode_stats);
442*77c1e3ccSAndroid Build Coastguard Worker   mb->winner_mode_stats = NULL;
443*77c1e3ccSAndroid Build Coastguard Worker 
444*77c1e3ccSAndroid Build Coastguard Worker   aom_free(mb->dqcoeff_buf);
445*77c1e3ccSAndroid Build Coastguard Worker   mb->dqcoeff_buf = NULL;
446*77c1e3ccSAndroid Build Coastguard Worker }
447*77c1e3ccSAndroid Build Coastguard Worker 
allocate_winner_mode_stats(const AV1_COMP * cpi,struct macroblock * mb)448*77c1e3ccSAndroid Build Coastguard Worker static inline void allocate_winner_mode_stats(const AV1_COMP *cpi,
449*77c1e3ccSAndroid Build Coastguard Worker                                               struct macroblock *mb) {
450*77c1e3ccSAndroid Build Coastguard Worker   const SPEED_FEATURES *sf = &cpi->sf;
451*77c1e3ccSAndroid Build Coastguard Worker   // The winner_mode_stats buffer is not required in these cases.
452*77c1e3ccSAndroid Build Coastguard Worker   if (is_stat_generation_stage(cpi) ||
453*77c1e3ccSAndroid Build Coastguard Worker       (sf->rt_sf.use_nonrd_pick_mode && !sf->rt_sf.hybrid_intra_pickmode) ||
454*77c1e3ccSAndroid Build Coastguard Worker       (sf->winner_mode_sf.multi_winner_mode_type == MULTI_WINNER_MODE_OFF))
455*77c1e3ccSAndroid Build Coastguard Worker     return;
456*77c1e3ccSAndroid Build Coastguard Worker 
457*77c1e3ccSAndroid Build Coastguard Worker   const AV1_COMMON *cm = &cpi->common;
458*77c1e3ccSAndroid Build Coastguard Worker   const int winner_mode_count =
459*77c1e3ccSAndroid Build Coastguard Worker       winner_mode_count_allowed[sf->winner_mode_sf.multi_winner_mode_type];
460*77c1e3ccSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(cm, mb->winner_mode_stats,
461*77c1e3ccSAndroid Build Coastguard Worker                   (WinnerModeStats *)aom_malloc(
462*77c1e3ccSAndroid Build Coastguard Worker                       winner_mode_count * sizeof(mb->winner_mode_stats[0])));
463*77c1e3ccSAndroid Build Coastguard Worker }
464*77c1e3ccSAndroid Build Coastguard Worker 
465*77c1e3ccSAndroid Build Coastguard Worker void av1_alloc_src_diff_buf(const struct AV1Common *cm, struct macroblock *mb);
466*77c1e3ccSAndroid Build Coastguard Worker 
av1_alloc_mb_data(const AV1_COMP * cpi,struct macroblock * mb)467*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_alloc_mb_data(const AV1_COMP *cpi,
468*77c1e3ccSAndroid Build Coastguard Worker                                      struct macroblock *mb) {
469*77c1e3ccSAndroid Build Coastguard Worker   const AV1_COMMON *cm = &cpi->common;
470*77c1e3ccSAndroid Build Coastguard Worker   const SPEED_FEATURES *sf = &cpi->sf;
471*77c1e3ccSAndroid Build Coastguard Worker   if (!sf->rt_sf.use_nonrd_pick_mode) {
472*77c1e3ccSAndroid Build Coastguard Worker     // Memory for mb_rd_record is allocated only when use_mb_rd_hash sf is
473*77c1e3ccSAndroid Build Coastguard Worker     // enabled.
474*77c1e3ccSAndroid Build Coastguard Worker     if (sf->rd_sf.use_mb_rd_hash)
475*77c1e3ccSAndroid Build Coastguard Worker       CHECK_MEM_ERROR(cm, mb->txfm_search_info.mb_rd_record,
476*77c1e3ccSAndroid Build Coastguard Worker                       (MB_RD_RECORD *)aom_malloc(sizeof(MB_RD_RECORD)));
477*77c1e3ccSAndroid Build Coastguard Worker     if (!frame_is_intra_only(cm))
478*77c1e3ccSAndroid Build Coastguard Worker       CHECK_MEM_ERROR(
479*77c1e3ccSAndroid Build Coastguard Worker           cm, mb->inter_modes_info,
480*77c1e3ccSAndroid Build Coastguard Worker           (InterModesInfo *)aom_malloc(sizeof(*mb->inter_modes_info)));
481*77c1e3ccSAndroid Build Coastguard Worker   }
482*77c1e3ccSAndroid Build Coastguard Worker 
483*77c1e3ccSAndroid Build Coastguard Worker   av1_alloc_src_diff_buf(cm, mb);
484*77c1e3ccSAndroid Build Coastguard Worker 
485*77c1e3ccSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(cm, mb->e_mbd.seg_mask,
486*77c1e3ccSAndroid Build Coastguard Worker                   (uint8_t *)aom_memalign(
487*77c1e3ccSAndroid Build Coastguard Worker                       16, 2 * MAX_SB_SQUARE * sizeof(mb->e_mbd.seg_mask[0])));
488*77c1e3ccSAndroid Build Coastguard Worker 
489*77c1e3ccSAndroid Build Coastguard Worker   allocate_winner_mode_stats(cpi, mb);
490*77c1e3ccSAndroid Build Coastguard Worker 
491*77c1e3ccSAndroid Build Coastguard Worker   const int max_sb_square_y = 1
492*77c1e3ccSAndroid Build Coastguard Worker                               << num_pels_log2_lookup[cm->seq_params->sb_size];
493*77c1e3ccSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
494*77c1e3ccSAndroid Build Coastguard Worker       cm, mb->dqcoeff_buf,
495*77c1e3ccSAndroid Build Coastguard Worker       (tran_low_t *)aom_memalign(32, max_sb_square_y * sizeof(tran_low_t)));
496*77c1e3ccSAndroid Build Coastguard Worker }
497*77c1e3ccSAndroid Build Coastguard Worker 
498*77c1e3ccSAndroid Build Coastguard Worker // This function will compute the number of reference frames to be disabled
499*77c1e3ccSAndroid Build Coastguard Worker // based on selective_ref_frame speed feature.
get_num_refs_to_disable(const AV1_COMP * cpi,const int * ref_frame_flags,const unsigned int * ref_display_order_hint,unsigned int cur_frame_display_index)500*77c1e3ccSAndroid Build Coastguard Worker static inline unsigned int get_num_refs_to_disable(
501*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMP *cpi, const int *ref_frame_flags,
502*77c1e3ccSAndroid Build Coastguard Worker     const unsigned int *ref_display_order_hint,
503*77c1e3ccSAndroid Build Coastguard Worker     unsigned int cur_frame_display_index) {
504*77c1e3ccSAndroid Build Coastguard Worker   unsigned int num_refs_to_disable = 0;
505*77c1e3ccSAndroid Build Coastguard Worker   if (cpi->sf.inter_sf.selective_ref_frame >= 3) {
506*77c1e3ccSAndroid Build Coastguard Worker     num_refs_to_disable++;
507*77c1e3ccSAndroid Build Coastguard Worker     if (cpi->sf.inter_sf.selective_ref_frame >= 6) {
508*77c1e3ccSAndroid Build Coastguard Worker       // Disable LAST2_FRAME  and ALTREF2_FRAME
509*77c1e3ccSAndroid Build Coastguard Worker       num_refs_to_disable += 2;
510*77c1e3ccSAndroid Build Coastguard Worker     } else if (cpi->sf.inter_sf.selective_ref_frame == 5 &&
511*77c1e3ccSAndroid Build Coastguard Worker                *ref_frame_flags & av1_ref_frame_flag_list[LAST2_FRAME]) {
512*77c1e3ccSAndroid Build Coastguard Worker       const int last2_frame_dist = av1_encoder_get_relative_dist(
513*77c1e3ccSAndroid Build Coastguard Worker           ref_display_order_hint[LAST2_FRAME - LAST_FRAME],
514*77c1e3ccSAndroid Build Coastguard Worker           cur_frame_display_index);
515*77c1e3ccSAndroid Build Coastguard Worker       // Disable LAST2_FRAME if it is a temporally distant frame
516*77c1e3ccSAndroid Build Coastguard Worker       if (abs(last2_frame_dist) > 2) {
517*77c1e3ccSAndroid Build Coastguard Worker         num_refs_to_disable++;
518*77c1e3ccSAndroid Build Coastguard Worker       }
519*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
520*77c1e3ccSAndroid Build Coastguard Worker       else if (is_stat_consumption_stage_twopass(cpi)) {
521*77c1e3ccSAndroid Build Coastguard Worker         const FIRSTPASS_STATS *const this_frame_stats =
522*77c1e3ccSAndroid Build Coastguard Worker             read_one_frame_stats(&cpi->ppi->twopass, cur_frame_display_index);
523*77c1e3ccSAndroid Build Coastguard Worker         const double coded_error_per_mb = this_frame_stats->coded_error;
524*77c1e3ccSAndroid Build Coastguard Worker         // Disable LAST2_FRAME if the coded error of the current frame based on
525*77c1e3ccSAndroid Build Coastguard Worker         // first pass stats is very low.
526*77c1e3ccSAndroid Build Coastguard Worker         if (coded_error_per_mb < 100.0) num_refs_to_disable++;
527*77c1e3ccSAndroid Build Coastguard Worker       }
528*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_REALTIME_ONLY
529*77c1e3ccSAndroid Build Coastguard Worker     }
530*77c1e3ccSAndroid Build Coastguard Worker   }
531*77c1e3ccSAndroid Build Coastguard Worker   return num_refs_to_disable;
532*77c1e3ccSAndroid Build Coastguard Worker }
533*77c1e3ccSAndroid Build Coastguard Worker 
get_max_allowed_ref_frames(const AV1_COMP * cpi,const int * ref_frame_flags,const unsigned int * ref_display_order_hint,unsigned int cur_frame_display_index)534*77c1e3ccSAndroid Build Coastguard Worker static inline int get_max_allowed_ref_frames(
535*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMP *cpi, const int *ref_frame_flags,
536*77c1e3ccSAndroid Build Coastguard Worker     const unsigned int *ref_display_order_hint,
537*77c1e3ccSAndroid Build Coastguard Worker     unsigned int cur_frame_display_index) {
538*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int max_reference_frames =
539*77c1e3ccSAndroid Build Coastguard Worker       cpi->oxcf.ref_frm_cfg.max_reference_frames;
540*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int num_refs_to_disable = get_num_refs_to_disable(
541*77c1e3ccSAndroid Build Coastguard Worker       cpi, ref_frame_flags, ref_display_order_hint, cur_frame_display_index);
542*77c1e3ccSAndroid Build Coastguard Worker   const unsigned int max_allowed_refs_for_given_speed =
543*77c1e3ccSAndroid Build Coastguard Worker       INTER_REFS_PER_FRAME - num_refs_to_disable;
544*77c1e3ccSAndroid Build Coastguard Worker   return AOMMIN(max_allowed_refs_for_given_speed, max_reference_frames);
545*77c1e3ccSAndroid Build Coastguard Worker }
546*77c1e3ccSAndroid Build Coastguard Worker 
547*77c1e3ccSAndroid Build Coastguard Worker // Enforce the number of references for each arbitrary frame based on user
548*77c1e3ccSAndroid Build Coastguard Worker // options and speed.
enforce_max_ref_frames(AV1_COMP * cpi,int * ref_frame_flags,const unsigned int * ref_display_order_hint,unsigned int cur_frame_display_index)549*77c1e3ccSAndroid Build Coastguard Worker static inline void enforce_max_ref_frames(
550*77c1e3ccSAndroid Build Coastguard Worker     AV1_COMP *cpi, int *ref_frame_flags,
551*77c1e3ccSAndroid Build Coastguard Worker     const unsigned int *ref_display_order_hint,
552*77c1e3ccSAndroid Build Coastguard Worker     unsigned int cur_frame_display_index) {
553*77c1e3ccSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref_frame;
554*77c1e3ccSAndroid Build Coastguard Worker   int total_valid_refs = 0;
555*77c1e3ccSAndroid Build Coastguard Worker 
556*77c1e3ccSAndroid Build Coastguard Worker   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
557*77c1e3ccSAndroid Build Coastguard Worker     if (*ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
558*77c1e3ccSAndroid Build Coastguard Worker       total_valid_refs++;
559*77c1e3ccSAndroid Build Coastguard Worker     }
560*77c1e3ccSAndroid Build Coastguard Worker   }
561*77c1e3ccSAndroid Build Coastguard Worker 
562*77c1e3ccSAndroid Build Coastguard Worker   const int max_allowed_refs = get_max_allowed_ref_frames(
563*77c1e3ccSAndroid Build Coastguard Worker       cpi, ref_frame_flags, ref_display_order_hint, cur_frame_display_index);
564*77c1e3ccSAndroid Build Coastguard Worker 
565*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < 4 && total_valid_refs > max_allowed_refs; ++i) {
566*77c1e3ccSAndroid Build Coastguard Worker     const MV_REFERENCE_FRAME ref_frame_to_disable = disable_order[i];
567*77c1e3ccSAndroid Build Coastguard Worker 
568*77c1e3ccSAndroid Build Coastguard Worker     if (!(*ref_frame_flags & av1_ref_frame_flag_list[ref_frame_to_disable])) {
569*77c1e3ccSAndroid Build Coastguard Worker       continue;
570*77c1e3ccSAndroid Build Coastguard Worker     }
571*77c1e3ccSAndroid Build Coastguard Worker 
572*77c1e3ccSAndroid Build Coastguard Worker     switch (ref_frame_to_disable) {
573*77c1e3ccSAndroid Build Coastguard Worker       case LAST3_FRAME: *ref_frame_flags &= ~AOM_LAST3_FLAG; break;
574*77c1e3ccSAndroid Build Coastguard Worker       case LAST2_FRAME: *ref_frame_flags &= ~AOM_LAST2_FLAG; break;
575*77c1e3ccSAndroid Build Coastguard Worker       case ALTREF2_FRAME: *ref_frame_flags &= ~AOM_ALT2_FLAG; break;
576*77c1e3ccSAndroid Build Coastguard Worker       case BWDREF_FRAME: *ref_frame_flags &= ~AOM_GOLD_FLAG; break;
577*77c1e3ccSAndroid Build Coastguard Worker       default: assert(0);
578*77c1e3ccSAndroid Build Coastguard Worker     }
579*77c1e3ccSAndroid Build Coastguard Worker     --total_valid_refs;
580*77c1e3ccSAndroid Build Coastguard Worker   }
581*77c1e3ccSAndroid Build Coastguard Worker   assert(total_valid_refs <= max_allowed_refs);
582*77c1e3ccSAndroid Build Coastguard Worker }
583*77c1e3ccSAndroid Build Coastguard Worker 
584*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
585*77c1e3ccSAndroid Build Coastguard Worker }  // extern "C"
586*77c1e3ccSAndroid Build Coastguard Worker #endif
587*77c1e3ccSAndroid Build Coastguard Worker 
588*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AV1_ENCODER_ENCODEFRAME_UTILS_H_
589