xref: /aosp_15_r20/external/libaom/av1/encoder/rdopt_utils.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2019, 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_RDOPT_UTILS_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_RDOPT_UTILS_H_
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/block.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/cfl.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/pred_common.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/rdopt_data_defs.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
22*77c1e3ccSAndroid Build Coastguard Worker extern "C" {
23*77c1e3ccSAndroid Build Coastguard Worker #endif
24*77c1e3ccSAndroid Build Coastguard Worker 
25*77c1e3ccSAndroid Build Coastguard Worker #define MAX_REF_MV_SEARCH 3
26*77c1e3ccSAndroid Build Coastguard Worker #define MAX_TX_RD_GATE_LEVEL 5
27*77c1e3ccSAndroid Build Coastguard Worker #define INTER_INTRA_RD_THRESH_SCALE 9
28*77c1e3ccSAndroid Build Coastguard Worker #define INTER_INTRA_RD_THRESH_SHIFT 4
29*77c1e3ccSAndroid Build Coastguard Worker 
30*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
31*77c1e3ccSAndroid Build Coastguard Worker   PREDICTION_MODE mode;
32*77c1e3ccSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref_frame[2];
33*77c1e3ccSAndroid Build Coastguard Worker } MODE_DEFINITION;
34*77c1e3ccSAndroid Build Coastguard Worker 
35*77c1e3ccSAndroid Build Coastguard Worker // This array defines the mapping from the enums in THR_MODES to the actual
36*77c1e3ccSAndroid Build Coastguard Worker // prediction modes and refrence frames
37*77c1e3ccSAndroid Build Coastguard Worker static const MODE_DEFINITION av1_mode_defs[MAX_MODES] = {
38*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { LAST_FRAME, NONE_FRAME } },
39*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { LAST2_FRAME, NONE_FRAME } },
40*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { LAST3_FRAME, NONE_FRAME } },
41*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { BWDREF_FRAME, NONE_FRAME } },
42*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { ALTREF2_FRAME, NONE_FRAME } },
43*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { ALTREF_FRAME, NONE_FRAME } },
44*77c1e3ccSAndroid Build Coastguard Worker   { NEARESTMV, { GOLDEN_FRAME, NONE_FRAME } },
45*77c1e3ccSAndroid Build Coastguard Worker 
46*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { LAST_FRAME, NONE_FRAME } },
47*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { LAST2_FRAME, NONE_FRAME } },
48*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { LAST3_FRAME, NONE_FRAME } },
49*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { BWDREF_FRAME, NONE_FRAME } },
50*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { ALTREF2_FRAME, NONE_FRAME } },
51*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { ALTREF_FRAME, NONE_FRAME } },
52*77c1e3ccSAndroid Build Coastguard Worker   { NEWMV, { GOLDEN_FRAME, NONE_FRAME } },
53*77c1e3ccSAndroid Build Coastguard Worker 
54*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { LAST_FRAME, NONE_FRAME } },
55*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { LAST2_FRAME, NONE_FRAME } },
56*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { LAST3_FRAME, NONE_FRAME } },
57*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { BWDREF_FRAME, NONE_FRAME } },
58*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { ALTREF2_FRAME, NONE_FRAME } },
59*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { ALTREF_FRAME, NONE_FRAME } },
60*77c1e3ccSAndroid Build Coastguard Worker   { NEARMV, { GOLDEN_FRAME, NONE_FRAME } },
61*77c1e3ccSAndroid Build Coastguard Worker 
62*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { LAST_FRAME, NONE_FRAME } },
63*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { LAST2_FRAME, NONE_FRAME } },
64*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { LAST3_FRAME, NONE_FRAME } },
65*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { BWDREF_FRAME, NONE_FRAME } },
66*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { ALTREF2_FRAME, NONE_FRAME } },
67*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { ALTREF_FRAME, NONE_FRAME } },
68*77c1e3ccSAndroid Build Coastguard Worker   { GLOBALMV, { GOLDEN_FRAME, NONE_FRAME } },
69*77c1e3ccSAndroid Build Coastguard Worker 
70*77c1e3ccSAndroid Build Coastguard Worker   // TODO(zoeliu): May need to reconsider the order on the modes to check
71*77c1e3ccSAndroid Build Coastguard Worker 
72*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
73*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
74*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
75*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
76*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
77*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
78*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
79*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
80*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, ALTREF2_FRAME } },
81*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST2_FRAME, ALTREF2_FRAME } },
82*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST3_FRAME, ALTREF2_FRAME } },
83*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
84*77c1e3ccSAndroid Build Coastguard Worker 
85*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, LAST2_FRAME } },
86*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, LAST3_FRAME } },
87*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { LAST_FRAME, GOLDEN_FRAME } },
88*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEARESTMV, { BWDREF_FRAME, ALTREF_FRAME } },
89*77c1e3ccSAndroid Build Coastguard Worker 
90*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
91*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
92*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, BWDREF_FRAME } },
93*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
94*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, BWDREF_FRAME } },
95*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, BWDREF_FRAME } },
96*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, BWDREF_FRAME } },
97*77c1e3ccSAndroid Build Coastguard Worker 
98*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
99*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
100*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, ALTREF_FRAME } },
101*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
102*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, ALTREF_FRAME } },
103*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, ALTREF_FRAME } },
104*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, ALTREF_FRAME } },
105*77c1e3ccSAndroid Build Coastguard Worker 
106*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
107*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
108*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST2_FRAME, ALTREF_FRAME } },
109*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
110*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST2_FRAME, ALTREF_FRAME } },
111*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST2_FRAME, ALTREF_FRAME } },
112*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST2_FRAME, ALTREF_FRAME } },
113*77c1e3ccSAndroid Build Coastguard Worker 
114*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
115*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
116*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST3_FRAME, ALTREF_FRAME } },
117*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
118*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST3_FRAME, ALTREF_FRAME } },
119*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST3_FRAME, ALTREF_FRAME } },
120*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST3_FRAME, ALTREF_FRAME } },
121*77c1e3ccSAndroid Build Coastguard Worker 
122*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
123*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
124*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF_FRAME } },
125*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
126*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { GOLDEN_FRAME, ALTREF_FRAME } },
127*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF_FRAME } },
128*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { GOLDEN_FRAME, ALTREF_FRAME } },
129*77c1e3ccSAndroid Build Coastguard Worker 
130*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
131*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
132*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST2_FRAME, BWDREF_FRAME } },
133*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
134*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST2_FRAME, BWDREF_FRAME } },
135*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST2_FRAME, BWDREF_FRAME } },
136*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST2_FRAME, BWDREF_FRAME } },
137*77c1e3ccSAndroid Build Coastguard Worker 
138*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
139*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
140*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST3_FRAME, BWDREF_FRAME } },
141*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
142*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST3_FRAME, BWDREF_FRAME } },
143*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST3_FRAME, BWDREF_FRAME } },
144*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST3_FRAME, BWDREF_FRAME } },
145*77c1e3ccSAndroid Build Coastguard Worker 
146*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
147*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
148*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { GOLDEN_FRAME, BWDREF_FRAME } },
149*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
150*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { GOLDEN_FRAME, BWDREF_FRAME } },
151*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { GOLDEN_FRAME, BWDREF_FRAME } },
152*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { GOLDEN_FRAME, BWDREF_FRAME } },
153*77c1e3ccSAndroid Build Coastguard Worker 
154*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, ALTREF2_FRAME } },
155*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, ALTREF2_FRAME } },
156*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, ALTREF2_FRAME } },
157*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, ALTREF2_FRAME } },
158*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, ALTREF2_FRAME } },
159*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, ALTREF2_FRAME } },
160*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, ALTREF2_FRAME } },
161*77c1e3ccSAndroid Build Coastguard Worker 
162*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST2_FRAME, ALTREF2_FRAME } },
163*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST2_FRAME, ALTREF2_FRAME } },
164*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST2_FRAME, ALTREF2_FRAME } },
165*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST2_FRAME, ALTREF2_FRAME } },
166*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST2_FRAME, ALTREF2_FRAME } },
167*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST2_FRAME, ALTREF2_FRAME } },
168*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST2_FRAME, ALTREF2_FRAME } },
169*77c1e3ccSAndroid Build Coastguard Worker 
170*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST3_FRAME, ALTREF2_FRAME } },
171*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST3_FRAME, ALTREF2_FRAME } },
172*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST3_FRAME, ALTREF2_FRAME } },
173*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST3_FRAME, ALTREF2_FRAME } },
174*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST3_FRAME, ALTREF2_FRAME } },
175*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST3_FRAME, ALTREF2_FRAME } },
176*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST3_FRAME, ALTREF2_FRAME } },
177*77c1e3ccSAndroid Build Coastguard Worker 
178*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
179*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
180*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
181*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
182*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
183*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
184*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { GOLDEN_FRAME, ALTREF2_FRAME } },
185*77c1e3ccSAndroid Build Coastguard Worker 
186*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, LAST2_FRAME } },
187*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, LAST2_FRAME } },
188*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, LAST2_FRAME } },
189*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, LAST2_FRAME } },
190*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, LAST2_FRAME } },
191*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, LAST2_FRAME } },
192*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, LAST2_FRAME } },
193*77c1e3ccSAndroid Build Coastguard Worker 
194*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, LAST3_FRAME } },
195*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, LAST3_FRAME } },
196*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, LAST3_FRAME } },
197*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, LAST3_FRAME } },
198*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, LAST3_FRAME } },
199*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, LAST3_FRAME } },
200*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, LAST3_FRAME } },
201*77c1e3ccSAndroid Build Coastguard Worker 
202*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { LAST_FRAME, GOLDEN_FRAME } },
203*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
204*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { LAST_FRAME, GOLDEN_FRAME } },
205*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
206*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { LAST_FRAME, GOLDEN_FRAME } },
207*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { LAST_FRAME, GOLDEN_FRAME } },
208*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { LAST_FRAME, GOLDEN_FRAME } },
209*77c1e3ccSAndroid Build Coastguard Worker 
210*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEARMV, { BWDREF_FRAME, ALTREF_FRAME } },
211*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
212*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARESTMV, { BWDREF_FRAME, ALTREF_FRAME } },
213*77c1e3ccSAndroid Build Coastguard Worker   { NEAREST_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
214*77c1e3ccSAndroid Build Coastguard Worker   { NEW_NEARMV, { BWDREF_FRAME, ALTREF_FRAME } },
215*77c1e3ccSAndroid Build Coastguard Worker   { NEAR_NEWMV, { BWDREF_FRAME, ALTREF_FRAME } },
216*77c1e3ccSAndroid Build Coastguard Worker   { GLOBAL_GLOBALMV, { BWDREF_FRAME, ALTREF_FRAME } },
217*77c1e3ccSAndroid Build Coastguard Worker 
218*77c1e3ccSAndroid Build Coastguard Worker   // intra modes
219*77c1e3ccSAndroid Build Coastguard Worker   { DC_PRED, { INTRA_FRAME, NONE_FRAME } },
220*77c1e3ccSAndroid Build Coastguard Worker   { PAETH_PRED, { INTRA_FRAME, NONE_FRAME } },
221*77c1e3ccSAndroid Build Coastguard Worker   { SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
222*77c1e3ccSAndroid Build Coastguard Worker   { SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
223*77c1e3ccSAndroid Build Coastguard Worker   { SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
224*77c1e3ccSAndroid Build Coastguard Worker   { H_PRED, { INTRA_FRAME, NONE_FRAME } },
225*77c1e3ccSAndroid Build Coastguard Worker   { V_PRED, { INTRA_FRAME, NONE_FRAME } },
226*77c1e3ccSAndroid Build Coastguard Worker   { D135_PRED, { INTRA_FRAME, NONE_FRAME } },
227*77c1e3ccSAndroid Build Coastguard Worker   { D203_PRED, { INTRA_FRAME, NONE_FRAME } },
228*77c1e3ccSAndroid Build Coastguard Worker   { D157_PRED, { INTRA_FRAME, NONE_FRAME } },
229*77c1e3ccSAndroid Build Coastguard Worker   { D67_PRED, { INTRA_FRAME, NONE_FRAME } },
230*77c1e3ccSAndroid Build Coastguard Worker   { D113_PRED, { INTRA_FRAME, NONE_FRAME } },
231*77c1e3ccSAndroid Build Coastguard Worker   { D45_PRED, { INTRA_FRAME, NONE_FRAME } },
232*77c1e3ccSAndroid Build Coastguard Worker };
233*77c1e3ccSAndroid Build Coastguard Worker 
234*77c1e3ccSAndroid Build Coastguard Worker // Number of winner modes allowed for different values of the speed feature
235*77c1e3ccSAndroid Build Coastguard Worker // multi_winner_mode_type.
236*77c1e3ccSAndroid Build Coastguard Worker static const int winner_mode_count_allowed[MULTI_WINNER_MODE_LEVELS] = {
237*77c1e3ccSAndroid Build Coastguard Worker   1,  // MULTI_WINNER_MODE_OFF
238*77c1e3ccSAndroid Build Coastguard Worker   2,  // MULTI_WINNER_MODE_FAST
239*77c1e3ccSAndroid Build Coastguard Worker   3   // MULTI_WINNER_MODE_DEFAULT
240*77c1e3ccSAndroid Build Coastguard Worker };
241*77c1e3ccSAndroid Build Coastguard Worker 
restore_dst_buf(MACROBLOCKD * xd,const BUFFER_SET dst,const int num_planes)242*77c1e3ccSAndroid Build Coastguard Worker static inline void restore_dst_buf(MACROBLOCKD *xd, const BUFFER_SET dst,
243*77c1e3ccSAndroid Build Coastguard Worker                                    const int num_planes) {
244*77c1e3ccSAndroid Build Coastguard Worker   for (int i = 0; i < num_planes; i++) {
245*77c1e3ccSAndroid Build Coastguard Worker     xd->plane[i].dst.buf = dst.plane[i];
246*77c1e3ccSAndroid Build Coastguard Worker     xd->plane[i].dst.stride = dst.stride[i];
247*77c1e3ccSAndroid Build Coastguard Worker   }
248*77c1e3ccSAndroid Build Coastguard Worker }
249*77c1e3ccSAndroid Build Coastguard Worker 
swap_dst_buf(MACROBLOCKD * xd,const BUFFER_SET * dst_bufs[2],int num_planes)250*77c1e3ccSAndroid Build Coastguard Worker static inline void swap_dst_buf(MACROBLOCKD *xd, const BUFFER_SET *dst_bufs[2],
251*77c1e3ccSAndroid Build Coastguard Worker                                 int num_planes) {
252*77c1e3ccSAndroid Build Coastguard Worker   const BUFFER_SET *buf0 = dst_bufs[0];
253*77c1e3ccSAndroid Build Coastguard Worker   dst_bufs[0] = dst_bufs[1];
254*77c1e3ccSAndroid Build Coastguard Worker   dst_bufs[1] = buf0;
255*77c1e3ccSAndroid Build Coastguard Worker   restore_dst_buf(xd, *dst_bufs[0], num_planes);
256*77c1e3ccSAndroid Build Coastguard Worker }
257*77c1e3ccSAndroid Build Coastguard Worker 
258*77c1e3ccSAndroid Build Coastguard Worker /* clang-format on */
259*77c1e3ccSAndroid Build Coastguard Worker // Calculate rd threshold based on ref best rd and relevant scaling factors
get_rd_thresh_from_best_rd(int64_t ref_best_rd,int mul_factor,int div_factor)260*77c1e3ccSAndroid Build Coastguard Worker static inline int64_t get_rd_thresh_from_best_rd(int64_t ref_best_rd,
261*77c1e3ccSAndroid Build Coastguard Worker                                                  int mul_factor,
262*77c1e3ccSAndroid Build Coastguard Worker                                                  int div_factor) {
263*77c1e3ccSAndroid Build Coastguard Worker   int64_t rd_thresh = ref_best_rd;
264*77c1e3ccSAndroid Build Coastguard Worker   if (div_factor != 0) {
265*77c1e3ccSAndroid Build Coastguard Worker     rd_thresh = ref_best_rd < (div_factor * (INT64_MAX / mul_factor))
266*77c1e3ccSAndroid Build Coastguard Worker                     ? ((ref_best_rd / div_factor) * mul_factor)
267*77c1e3ccSAndroid Build Coastguard Worker                     : INT64_MAX;
268*77c1e3ccSAndroid Build Coastguard Worker   }
269*77c1e3ccSAndroid Build Coastguard Worker   return rd_thresh;
270*77c1e3ccSAndroid Build Coastguard Worker }
271*77c1e3ccSAndroid Build Coastguard Worker 
get_prediction_mode_idx(PREDICTION_MODE this_mode,MV_REFERENCE_FRAME ref_frame,MV_REFERENCE_FRAME second_ref_frame)272*77c1e3ccSAndroid Build Coastguard Worker static inline THR_MODES get_prediction_mode_idx(
273*77c1e3ccSAndroid Build Coastguard Worker     PREDICTION_MODE this_mode, MV_REFERENCE_FRAME ref_frame,
274*77c1e3ccSAndroid Build Coastguard Worker     MV_REFERENCE_FRAME second_ref_frame) {
275*77c1e3ccSAndroid Build Coastguard Worker   if (this_mode < INTRA_MODE_END) {
276*77c1e3ccSAndroid Build Coastguard Worker     assert(ref_frame == INTRA_FRAME);
277*77c1e3ccSAndroid Build Coastguard Worker     assert(second_ref_frame == NONE_FRAME);
278*77c1e3ccSAndroid Build Coastguard Worker     return intra_to_mode_idx[this_mode - INTRA_MODE_START];
279*77c1e3ccSAndroid Build Coastguard Worker   }
280*77c1e3ccSAndroid Build Coastguard Worker   if (this_mode >= SINGLE_INTER_MODE_START &&
281*77c1e3ccSAndroid Build Coastguard Worker       this_mode < SINGLE_INTER_MODE_END) {
282*77c1e3ccSAndroid Build Coastguard Worker     assert((ref_frame > INTRA_FRAME) && (ref_frame <= ALTREF_FRAME));
283*77c1e3ccSAndroid Build Coastguard Worker     return single_inter_to_mode_idx[this_mode - SINGLE_INTER_MODE_START]
284*77c1e3ccSAndroid Build Coastguard Worker                                    [ref_frame];
285*77c1e3ccSAndroid Build Coastguard Worker   }
286*77c1e3ccSAndroid Build Coastguard Worker   if (this_mode >= COMP_INTER_MODE_START && this_mode < COMP_INTER_MODE_END &&
287*77c1e3ccSAndroid Build Coastguard Worker       second_ref_frame != NONE_FRAME) {
288*77c1e3ccSAndroid Build Coastguard Worker     assert((ref_frame > INTRA_FRAME) && (ref_frame <= ALTREF_FRAME));
289*77c1e3ccSAndroid Build Coastguard Worker     assert((second_ref_frame > INTRA_FRAME) &&
290*77c1e3ccSAndroid Build Coastguard Worker            (second_ref_frame <= ALTREF_FRAME));
291*77c1e3ccSAndroid Build Coastguard Worker     return comp_inter_to_mode_idx[this_mode - COMP_INTER_MODE_START][ref_frame]
292*77c1e3ccSAndroid Build Coastguard Worker                                  [second_ref_frame];
293*77c1e3ccSAndroid Build Coastguard Worker   }
294*77c1e3ccSAndroid Build Coastguard Worker   assert(0);
295*77c1e3ccSAndroid Build Coastguard Worker   return THR_INVALID;
296*77c1e3ccSAndroid Build Coastguard Worker }
297*77c1e3ccSAndroid Build Coastguard Worker 
inter_mode_data_block_idx(BLOCK_SIZE bsize)298*77c1e3ccSAndroid Build Coastguard Worker static inline int inter_mode_data_block_idx(BLOCK_SIZE bsize) {
299*77c1e3ccSAndroid Build Coastguard Worker   if (bsize == BLOCK_4X4 || bsize == BLOCK_4X8 || bsize == BLOCK_8X4 ||
300*77c1e3ccSAndroid Build Coastguard Worker       bsize == BLOCK_4X16 || bsize == BLOCK_16X4) {
301*77c1e3ccSAndroid Build Coastguard Worker     return -1;
302*77c1e3ccSAndroid Build Coastguard Worker   }
303*77c1e3ccSAndroid Build Coastguard Worker   return 1;
304*77c1e3ccSAndroid Build Coastguard Worker }
305*77c1e3ccSAndroid Build Coastguard Worker 
306*77c1e3ccSAndroid Build Coastguard Worker // Get transform block visible dimensions cropped to the MI units.
get_txb_dimensions(const MACROBLOCKD * xd,int plane,BLOCK_SIZE plane_bsize,int blk_row,int blk_col,BLOCK_SIZE tx_bsize,int * width,int * height,int * visible_width,int * visible_height)307*77c1e3ccSAndroid Build Coastguard Worker static inline void get_txb_dimensions(const MACROBLOCKD *xd, int plane,
308*77c1e3ccSAndroid Build Coastguard Worker                                       BLOCK_SIZE plane_bsize, int blk_row,
309*77c1e3ccSAndroid Build Coastguard Worker                                       int blk_col, BLOCK_SIZE tx_bsize,
310*77c1e3ccSAndroid Build Coastguard Worker                                       int *width, int *height,
311*77c1e3ccSAndroid Build Coastguard Worker                                       int *visible_width, int *visible_height) {
312*77c1e3ccSAndroid Build Coastguard Worker   assert(tx_bsize <= plane_bsize);
313*77c1e3ccSAndroid Build Coastguard Worker   const int txb_height = block_size_high[tx_bsize];
314*77c1e3ccSAndroid Build Coastguard Worker   const int txb_width = block_size_wide[tx_bsize];
315*77c1e3ccSAndroid Build Coastguard Worker   const struct macroblockd_plane *const pd = &xd->plane[plane];
316*77c1e3ccSAndroid Build Coastguard Worker 
317*77c1e3ccSAndroid Build Coastguard Worker   // TODO([email protected]): Investigate using crop_width/height here rather
318*77c1e3ccSAndroid Build Coastguard Worker   // than the MI size
319*77c1e3ccSAndroid Build Coastguard Worker   if (xd->mb_to_bottom_edge >= 0) {
320*77c1e3ccSAndroid Build Coastguard Worker     *visible_height = txb_height;
321*77c1e3ccSAndroid Build Coastguard Worker   } else {
322*77c1e3ccSAndroid Build Coastguard Worker     const int block_height = block_size_high[plane_bsize];
323*77c1e3ccSAndroid Build Coastguard Worker     const int block_rows =
324*77c1e3ccSAndroid Build Coastguard Worker         (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
325*77c1e3ccSAndroid Build Coastguard Worker     *visible_height =
326*77c1e3ccSAndroid Build Coastguard Worker         clamp(block_rows - (blk_row << MI_SIZE_LOG2), 0, txb_height);
327*77c1e3ccSAndroid Build Coastguard Worker   }
328*77c1e3ccSAndroid Build Coastguard Worker   if (height) *height = txb_height;
329*77c1e3ccSAndroid Build Coastguard Worker 
330*77c1e3ccSAndroid Build Coastguard Worker   if (xd->mb_to_right_edge >= 0) {
331*77c1e3ccSAndroid Build Coastguard Worker     *visible_width = txb_width;
332*77c1e3ccSAndroid Build Coastguard Worker   } else {
333*77c1e3ccSAndroid Build Coastguard Worker     const int block_width = block_size_wide[plane_bsize];
334*77c1e3ccSAndroid Build Coastguard Worker     const int block_cols =
335*77c1e3ccSAndroid Build Coastguard Worker         (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) + block_width;
336*77c1e3ccSAndroid Build Coastguard Worker     *visible_width =
337*77c1e3ccSAndroid Build Coastguard Worker         clamp(block_cols - (blk_col << MI_SIZE_LOG2), 0, txb_width);
338*77c1e3ccSAndroid Build Coastguard Worker   }
339*77c1e3ccSAndroid Build Coastguard Worker   if (width) *width = txb_width;
340*77c1e3ccSAndroid Build Coastguard Worker }
341*77c1e3ccSAndroid Build Coastguard Worker 
bsize_to_num_blk(BLOCK_SIZE bsize)342*77c1e3ccSAndroid Build Coastguard Worker static inline int bsize_to_num_blk(BLOCK_SIZE bsize) {
343*77c1e3ccSAndroid Build Coastguard Worker   int num_blk = 1 << (num_pels_log2_lookup[bsize] - 2 * MI_SIZE_LOG2);
344*77c1e3ccSAndroid Build Coastguard Worker   return num_blk;
345*77c1e3ccSAndroid Build Coastguard Worker }
346*77c1e3ccSAndroid Build Coastguard Worker 
check_txfm_eval(MACROBLOCK * const x,BLOCK_SIZE bsize,int64_t best_skip_rd,int64_t skip_rd,int level,int is_luma_only)347*77c1e3ccSAndroid Build Coastguard Worker static inline int check_txfm_eval(MACROBLOCK *const x, BLOCK_SIZE bsize,
348*77c1e3ccSAndroid Build Coastguard Worker                                   int64_t best_skip_rd, int64_t skip_rd,
349*77c1e3ccSAndroid Build Coastguard Worker                                   int level, int is_luma_only) {
350*77c1e3ccSAndroid Build Coastguard Worker   int eval_txfm = 1;
351*77c1e3ccSAndroid Build Coastguard Worker   // Derive aggressiveness factor for gating the transform search
352*77c1e3ccSAndroid Build Coastguard Worker   // Lower value indicates more aggressiveness. Be more conservative (high
353*77c1e3ccSAndroid Build Coastguard Worker   // value) for (i) low quantizers (ii) regions where prediction is poor
354*77c1e3ccSAndroid Build Coastguard Worker   const int scale[MAX_TX_RD_GATE_LEVEL + 1] = { INT_MAX, 4, 3, 2, 2, 1 };
355*77c1e3ccSAndroid Build Coastguard Worker   const int qslope = 2 * (!is_luma_only);
356*77c1e3ccSAndroid Build Coastguard Worker   const int level_to_qindex_map[MAX_TX_RD_GATE_LEVEL + 1] = { 0,  0,   0,
357*77c1e3ccSAndroid Build Coastguard Worker                                                               80, 100, 140 };
358*77c1e3ccSAndroid Build Coastguard Worker   int aggr_factor = 4;
359*77c1e3ccSAndroid Build Coastguard Worker   assert(level <= MAX_TX_RD_GATE_LEVEL);
360*77c1e3ccSAndroid Build Coastguard Worker   const int pred_qindex_thresh = level_to_qindex_map[level];
361*77c1e3ccSAndroid Build Coastguard Worker   if (!is_luma_only && level <= 2) {
362*77c1e3ccSAndroid Build Coastguard Worker     aggr_factor = 4 * AOMMAX(1, ROUND_POWER_OF_TWO((MAXQ - x->qindex) * qslope,
363*77c1e3ccSAndroid Build Coastguard Worker                                                    QINDEX_BITS));
364*77c1e3ccSAndroid Build Coastguard Worker   }
365*77c1e3ccSAndroid Build Coastguard Worker   if ((best_skip_rd >
366*77c1e3ccSAndroid Build Coastguard Worker        (x->source_variance << (num_pels_log2_lookup[bsize] + RDDIV_BITS))) &&
367*77c1e3ccSAndroid Build Coastguard Worker       (x->qindex >= pred_qindex_thresh))
368*77c1e3ccSAndroid Build Coastguard Worker     aggr_factor *= scale[level];
369*77c1e3ccSAndroid Build Coastguard Worker   // For level setting 1, be more conservative for non-luma-only case even when
370*77c1e3ccSAndroid Build Coastguard Worker   // prediction is good.
371*77c1e3ccSAndroid Build Coastguard Worker   else if ((level <= 1) && !is_luma_only)
372*77c1e3ccSAndroid Build Coastguard Worker     aggr_factor = (aggr_factor >> 2) * 6;
373*77c1e3ccSAndroid Build Coastguard Worker 
374*77c1e3ccSAndroid Build Coastguard Worker   // Be more conservative for luma only cases (called from compound type rd)
375*77c1e3ccSAndroid Build Coastguard Worker   // since best_skip_rd is computed after and skip_rd is computed (with 8-bit
376*77c1e3ccSAndroid Build Coastguard Worker   // prediction signals blended for WEDGE/DIFFWTD rather than 16-bit) before
377*77c1e3ccSAndroid Build Coastguard Worker   // interpolation filter search
378*77c1e3ccSAndroid Build Coastguard Worker   const int luma_mul[MAX_TX_RD_GATE_LEVEL + 1] = {
379*77c1e3ccSAndroid Build Coastguard Worker     INT_MAX, 32, 29, 17, 17, 17
380*77c1e3ccSAndroid Build Coastguard Worker   };
381*77c1e3ccSAndroid Build Coastguard Worker   int mul_factor = is_luma_only ? luma_mul[level] : 16;
382*77c1e3ccSAndroid Build Coastguard Worker   int64_t rd_thresh =
383*77c1e3ccSAndroid Build Coastguard Worker       (best_skip_rd == INT64_MAX)
384*77c1e3ccSAndroid Build Coastguard Worker           ? best_skip_rd
385*77c1e3ccSAndroid Build Coastguard Worker           : (int64_t)(best_skip_rd * aggr_factor * mul_factor >> 6);
386*77c1e3ccSAndroid Build Coastguard Worker   if (skip_rd > rd_thresh) eval_txfm = 0;
387*77c1e3ccSAndroid Build Coastguard Worker   return eval_txfm;
388*77c1e3ccSAndroid Build Coastguard Worker }
389*77c1e3ccSAndroid Build Coastguard Worker 
select_tx_mode(const AV1_COMMON * cm,const TX_SIZE_SEARCH_METHOD tx_size_search_method)390*77c1e3ccSAndroid Build Coastguard Worker static TX_MODE select_tx_mode(
391*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMMON *cm, const TX_SIZE_SEARCH_METHOD tx_size_search_method) {
392*77c1e3ccSAndroid Build Coastguard Worker   if (cm->features.coded_lossless) return ONLY_4X4;
393*77c1e3ccSAndroid Build Coastguard Worker   if (tx_size_search_method == USE_LARGESTALL) {
394*77c1e3ccSAndroid Build Coastguard Worker     return TX_MODE_LARGEST;
395*77c1e3ccSAndroid Build Coastguard Worker   } else {
396*77c1e3ccSAndroid Build Coastguard Worker     assert(tx_size_search_method == USE_FULL_RD ||
397*77c1e3ccSAndroid Build Coastguard Worker            tx_size_search_method == USE_FAST_RD);
398*77c1e3ccSAndroid Build Coastguard Worker     return TX_MODE_SELECT;
399*77c1e3ccSAndroid Build Coastguard Worker   }
400*77c1e3ccSAndroid Build Coastguard Worker }
401*77c1e3ccSAndroid Build Coastguard Worker 
402*77c1e3ccSAndroid Build Coastguard Worker // Checks the conditions to disable winner mode processing
bypass_winner_mode_processing(const MACROBLOCK * const x,const SPEED_FEATURES * sf,int use_txfm_skip,int actual_txfm_skip,PREDICTION_MODE best_mode)403*77c1e3ccSAndroid Build Coastguard Worker static inline int bypass_winner_mode_processing(const MACROBLOCK *const x,
404*77c1e3ccSAndroid Build Coastguard Worker                                                 const SPEED_FEATURES *sf,
405*77c1e3ccSAndroid Build Coastguard Worker                                                 int use_txfm_skip,
406*77c1e3ccSAndroid Build Coastguard Worker                                                 int actual_txfm_skip,
407*77c1e3ccSAndroid Build Coastguard Worker                                                 PREDICTION_MODE best_mode) {
408*77c1e3ccSAndroid Build Coastguard Worker   const int prune_winner_mode_eval_level =
409*77c1e3ccSAndroid Build Coastguard Worker       sf->winner_mode_sf.prune_winner_mode_eval_level;
410*77c1e3ccSAndroid Build Coastguard Worker 
411*77c1e3ccSAndroid Build Coastguard Worker   // Disable winner mode processing for blocks with low source variance.
412*77c1e3ccSAndroid Build Coastguard Worker   // The aggressiveness of this pruning logic reduces as qindex increases.
413*77c1e3ccSAndroid Build Coastguard Worker   // The threshold decreases linearly from 64 as qindex varies from 0 to 255.
414*77c1e3ccSAndroid Build Coastguard Worker   if (prune_winner_mode_eval_level == 1) {
415*77c1e3ccSAndroid Build Coastguard Worker     const unsigned int src_var_thresh = 64 - 48 * x->qindex / (MAXQ + 1);
416*77c1e3ccSAndroid Build Coastguard Worker     if (x->source_variance < src_var_thresh) return 1;
417*77c1e3ccSAndroid Build Coastguard Worker   } else if (prune_winner_mode_eval_level == 2) {
418*77c1e3ccSAndroid Build Coastguard Worker     // Skip winner mode processing of blocks for which transform turns out to be
419*77c1e3ccSAndroid Build Coastguard Worker     // skip due to nature of eob alone except NEWMV mode.
420*77c1e3ccSAndroid Build Coastguard Worker     if (!have_newmv_in_inter_mode(best_mode) && actual_txfm_skip) return 1;
421*77c1e3ccSAndroid Build Coastguard Worker   } else if (prune_winner_mode_eval_level == 3) {
422*77c1e3ccSAndroid Build Coastguard Worker     // Skip winner mode processing of blocks for which transform turns out to be
423*77c1e3ccSAndroid Build Coastguard Worker     // skip except NEWMV mode and considered based on the quantizer.
424*77c1e3ccSAndroid Build Coastguard Worker     // At high quantizers: Take conservative approach by considering transform
425*77c1e3ccSAndroid Build Coastguard Worker     // skip based on eob alone.
426*77c1e3ccSAndroid Build Coastguard Worker     // At low quantizers: Consider transform skip based on eob nature or RD cost
427*77c1e3ccSAndroid Build Coastguard Worker     // evaluation.
428*77c1e3ccSAndroid Build Coastguard Worker     const int is_txfm_skip =
429*77c1e3ccSAndroid Build Coastguard Worker         x->qindex > 127 ? actual_txfm_skip : actual_txfm_skip || use_txfm_skip;
430*77c1e3ccSAndroid Build Coastguard Worker 
431*77c1e3ccSAndroid Build Coastguard Worker     if (!have_newmv_in_inter_mode(best_mode) && is_txfm_skip) return 1;
432*77c1e3ccSAndroid Build Coastguard Worker   } else if (prune_winner_mode_eval_level >= 4) {
433*77c1e3ccSAndroid Build Coastguard Worker     // Do not skip winner mode evaluation at low quantizers if normal mode's
434*77c1e3ccSAndroid Build Coastguard Worker     // transform search was too aggressive.
435*77c1e3ccSAndroid Build Coastguard Worker     if (sf->rd_sf.perform_coeff_opt >= 5 && x->qindex <= 70) return 0;
436*77c1e3ccSAndroid Build Coastguard Worker 
437*77c1e3ccSAndroid Build Coastguard Worker     if (use_txfm_skip || actual_txfm_skip) return 1;
438*77c1e3ccSAndroid Build Coastguard Worker   }
439*77c1e3ccSAndroid Build Coastguard Worker 
440*77c1e3ccSAndroid Build Coastguard Worker   return 0;
441*77c1e3ccSAndroid Build Coastguard Worker }
442*77c1e3ccSAndroid Build Coastguard Worker 
443*77c1e3ccSAndroid Build Coastguard Worker // Checks the conditions to enable winner mode processing
is_winner_mode_processing_enabled(const struct AV1_COMP * cpi,const MACROBLOCK * const x,MB_MODE_INFO * const mbmi,int actual_txfm_skip)444*77c1e3ccSAndroid Build Coastguard Worker static inline int is_winner_mode_processing_enabled(const struct AV1_COMP *cpi,
445*77c1e3ccSAndroid Build Coastguard Worker                                                     const MACROBLOCK *const x,
446*77c1e3ccSAndroid Build Coastguard Worker                                                     MB_MODE_INFO *const mbmi,
447*77c1e3ccSAndroid Build Coastguard Worker                                                     int actual_txfm_skip) {
448*77c1e3ccSAndroid Build Coastguard Worker   const SPEED_FEATURES *sf = &cpi->sf;
449*77c1e3ccSAndroid Build Coastguard Worker   const PREDICTION_MODE best_mode = mbmi->mode;
450*77c1e3ccSAndroid Build Coastguard Worker 
451*77c1e3ccSAndroid Build Coastguard Worker   if (bypass_winner_mode_processing(x, sf, mbmi->skip_txfm, actual_txfm_skip,
452*77c1e3ccSAndroid Build Coastguard Worker                                     best_mode))
453*77c1e3ccSAndroid Build Coastguard Worker     return 0;
454*77c1e3ccSAndroid Build Coastguard Worker 
455*77c1e3ccSAndroid Build Coastguard Worker   // TODO(any): Move block independent condition checks to frame level
456*77c1e3ccSAndroid Build Coastguard Worker   if (is_inter_block(mbmi)) {
457*77c1e3ccSAndroid Build Coastguard Worker     if (is_inter_mode(best_mode) &&
458*77c1e3ccSAndroid Build Coastguard Worker         (sf->tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh != INT_MAX) &&
459*77c1e3ccSAndroid Build Coastguard Worker         !cpi->oxcf.txfm_cfg.use_inter_dct_only)
460*77c1e3ccSAndroid Build Coastguard Worker       return 1;
461*77c1e3ccSAndroid Build Coastguard Worker   } else {
462*77c1e3ccSAndroid Build Coastguard Worker     if (sf->tx_sf.tx_type_search.fast_intra_tx_type_search &&
463*77c1e3ccSAndroid Build Coastguard Worker         !cpi->oxcf.txfm_cfg.use_intra_default_tx_only &&
464*77c1e3ccSAndroid Build Coastguard Worker         !cpi->oxcf.txfm_cfg.use_intra_dct_only)
465*77c1e3ccSAndroid Build Coastguard Worker       return 1;
466*77c1e3ccSAndroid Build Coastguard Worker   }
467*77c1e3ccSAndroid Build Coastguard Worker 
468*77c1e3ccSAndroid Build Coastguard Worker   // Check speed feature related to winner mode processing
469*77c1e3ccSAndroid Build Coastguard Worker   if (sf->winner_mode_sf.enable_winner_mode_for_coeff_opt &&
470*77c1e3ccSAndroid Build Coastguard Worker       cpi->optimize_seg_arr[mbmi->segment_id] != NO_TRELLIS_OPT &&
471*77c1e3ccSAndroid Build Coastguard Worker       cpi->optimize_seg_arr[mbmi->segment_id] != FINAL_PASS_TRELLIS_OPT)
472*77c1e3ccSAndroid Build Coastguard Worker     return 1;
473*77c1e3ccSAndroid Build Coastguard Worker   if (sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch) return 1;
474*77c1e3ccSAndroid Build Coastguard Worker 
475*77c1e3ccSAndroid Build Coastguard Worker   return 0;
476*77c1e3ccSAndroid Build Coastguard Worker }
477*77c1e3ccSAndroid Build Coastguard Worker 
set_tx_size_search_method(const AV1_COMMON * cm,const WinnerModeParams * winner_mode_params,TxfmSearchParams * txfm_params,int enable_winner_mode_for_tx_size_srch,int is_winner_mode)478*77c1e3ccSAndroid Build Coastguard Worker static inline void set_tx_size_search_method(
479*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMMON *cm, const WinnerModeParams *winner_mode_params,
480*77c1e3ccSAndroid Build Coastguard Worker     TxfmSearchParams *txfm_params, int enable_winner_mode_for_tx_size_srch,
481*77c1e3ccSAndroid Build Coastguard Worker     int is_winner_mode) {
482*77c1e3ccSAndroid Build Coastguard Worker   // Populate transform size search method/transform mode appropriately
483*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->tx_size_search_method =
484*77c1e3ccSAndroid Build Coastguard Worker       winner_mode_params->tx_size_search_methods[DEFAULT_EVAL];
485*77c1e3ccSAndroid Build Coastguard Worker   if (enable_winner_mode_for_tx_size_srch) {
486*77c1e3ccSAndroid Build Coastguard Worker     if (is_winner_mode)
487*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->tx_size_search_method =
488*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->tx_size_search_methods[WINNER_MODE_EVAL];
489*77c1e3ccSAndroid Build Coastguard Worker     else
490*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->tx_size_search_method =
491*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->tx_size_search_methods[MODE_EVAL];
492*77c1e3ccSAndroid Build Coastguard Worker   }
493*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->tx_mode_search_type =
494*77c1e3ccSAndroid Build Coastguard Worker       select_tx_mode(cm, txfm_params->tx_size_search_method);
495*77c1e3ccSAndroid Build Coastguard Worker }
496*77c1e3ccSAndroid Build Coastguard Worker 
set_tx_type_prune(const SPEED_FEATURES * sf,TxfmSearchParams * txfm_params,int winner_mode_tx_type_pruning,int is_winner_mode)497*77c1e3ccSAndroid Build Coastguard Worker static inline void set_tx_type_prune(const SPEED_FEATURES *sf,
498*77c1e3ccSAndroid Build Coastguard Worker                                      TxfmSearchParams *txfm_params,
499*77c1e3ccSAndroid Build Coastguard Worker                                      int winner_mode_tx_type_pruning,
500*77c1e3ccSAndroid Build Coastguard Worker                                      int is_winner_mode) {
501*77c1e3ccSAndroid Build Coastguard Worker   // Populate prune transform mode appropriately
502*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->prune_2d_txfm_mode = sf->tx_sf.tx_type_search.prune_2d_txfm_mode;
503*77c1e3ccSAndroid Build Coastguard Worker   if (!winner_mode_tx_type_pruning) return;
504*77c1e3ccSAndroid Build Coastguard Worker 
505*77c1e3ccSAndroid Build Coastguard Worker   const int prune_mode[4][2] = { { TX_TYPE_PRUNE_3, TX_TYPE_PRUNE_0 },
506*77c1e3ccSAndroid Build Coastguard Worker                                  { TX_TYPE_PRUNE_4, TX_TYPE_PRUNE_0 },
507*77c1e3ccSAndroid Build Coastguard Worker                                  { TX_TYPE_PRUNE_5, TX_TYPE_PRUNE_2 },
508*77c1e3ccSAndroid Build Coastguard Worker                                  { TX_TYPE_PRUNE_5, TX_TYPE_PRUNE_3 } };
509*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->prune_2d_txfm_mode =
510*77c1e3ccSAndroid Build Coastguard Worker       prune_mode[winner_mode_tx_type_pruning - 1][is_winner_mode];
511*77c1e3ccSAndroid Build Coastguard Worker }
512*77c1e3ccSAndroid Build Coastguard Worker 
set_tx_domain_dist_params(const WinnerModeParams * winner_mode_params,TxfmSearchParams * txfm_params,int enable_winner_mode_for_tx_domain_dist,int is_winner_mode)513*77c1e3ccSAndroid Build Coastguard Worker static inline void set_tx_domain_dist_params(
514*77c1e3ccSAndroid Build Coastguard Worker     const WinnerModeParams *winner_mode_params, TxfmSearchParams *txfm_params,
515*77c1e3ccSAndroid Build Coastguard Worker     int enable_winner_mode_for_tx_domain_dist, int is_winner_mode) {
516*77c1e3ccSAndroid Build Coastguard Worker   if (txfm_params->use_qm_dist_metric) {
517*77c1e3ccSAndroid Build Coastguard Worker     // QM-weighted PSNR is computed in transform space, so we need to forcibly
518*77c1e3ccSAndroid Build Coastguard Worker     // enable the use of tx domain distortion.
519*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->use_transform_domain_distortion = 1;
520*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->tx_domain_dist_threshold = 0;
521*77c1e3ccSAndroid Build Coastguard Worker     return;
522*77c1e3ccSAndroid Build Coastguard Worker   }
523*77c1e3ccSAndroid Build Coastguard Worker 
524*77c1e3ccSAndroid Build Coastguard Worker   if (!enable_winner_mode_for_tx_domain_dist) {
525*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->use_transform_domain_distortion =
526*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->use_transform_domain_distortion[DEFAULT_EVAL];
527*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->tx_domain_dist_threshold =
528*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->tx_domain_dist_threshold[DEFAULT_EVAL];
529*77c1e3ccSAndroid Build Coastguard Worker     return;
530*77c1e3ccSAndroid Build Coastguard Worker   }
531*77c1e3ccSAndroid Build Coastguard Worker 
532*77c1e3ccSAndroid Build Coastguard Worker   if (is_winner_mode) {
533*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->use_transform_domain_distortion =
534*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->use_transform_domain_distortion[WINNER_MODE_EVAL];
535*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->tx_domain_dist_threshold =
536*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->tx_domain_dist_threshold[WINNER_MODE_EVAL];
537*77c1e3ccSAndroid Build Coastguard Worker   } else {
538*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->use_transform_domain_distortion =
539*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->use_transform_domain_distortion[MODE_EVAL];
540*77c1e3ccSAndroid Build Coastguard Worker     txfm_params->tx_domain_dist_threshold =
541*77c1e3ccSAndroid Build Coastguard Worker         winner_mode_params->tx_domain_dist_threshold[MODE_EVAL];
542*77c1e3ccSAndroid Build Coastguard Worker   }
543*77c1e3ccSAndroid Build Coastguard Worker }
544*77c1e3ccSAndroid Build Coastguard Worker 
545*77c1e3ccSAndroid Build Coastguard Worker // This function sets mode parameters for different mode evaluation stages
set_mode_eval_params(const struct AV1_COMP * cpi,MACROBLOCK * x,MODE_EVAL_TYPE mode_eval_type)546*77c1e3ccSAndroid Build Coastguard Worker static inline void set_mode_eval_params(const struct AV1_COMP *cpi,
547*77c1e3ccSAndroid Build Coastguard Worker                                         MACROBLOCK *x,
548*77c1e3ccSAndroid Build Coastguard Worker                                         MODE_EVAL_TYPE mode_eval_type) {
549*77c1e3ccSAndroid Build Coastguard Worker   const AV1_COMMON *cm = &cpi->common;
550*77c1e3ccSAndroid Build Coastguard Worker   const SPEED_FEATURES *sf = &cpi->sf;
551*77c1e3ccSAndroid Build Coastguard Worker   const WinnerModeParams *winner_mode_params = &cpi->winner_mode_params;
552*77c1e3ccSAndroid Build Coastguard Worker   TxfmSearchParams *txfm_params = &x->txfm_search_params;
553*77c1e3ccSAndroid Build Coastguard Worker 
554*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->use_qm_dist_metric =
555*77c1e3ccSAndroid Build Coastguard Worker       cpi->oxcf.tune_cfg.dist_metric == AOM_DIST_METRIC_QM_PSNR;
556*77c1e3ccSAndroid Build Coastguard Worker 
557*77c1e3ccSAndroid Build Coastguard Worker   switch (mode_eval_type) {
558*77c1e3ccSAndroid Build Coastguard Worker     case DEFAULT_EVAL:
559*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->default_inter_tx_type_prob_thresh = INT_MAX;
560*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->use_default_intra_tx_type = 0;
561*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->skip_txfm_level =
562*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->skip_txfm_level[DEFAULT_EVAL];
563*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->predict_dc_level =
564*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->predict_dc_level[DEFAULT_EVAL];
565*77c1e3ccSAndroid Build Coastguard Worker       // Set default transform domain distortion type
566*77c1e3ccSAndroid Build Coastguard Worker       set_tx_domain_dist_params(winner_mode_params, txfm_params, 0, 0);
567*77c1e3ccSAndroid Build Coastguard Worker 
568*77c1e3ccSAndroid Build Coastguard Worker       // Get default threshold for R-D optimization of coefficients
569*77c1e3ccSAndroid Build Coastguard Worker       get_rd_opt_coeff_thresh(winner_mode_params->coeff_opt_thresholds,
570*77c1e3ccSAndroid Build Coastguard Worker                               txfm_params, 0, 0);
571*77c1e3ccSAndroid Build Coastguard Worker 
572*77c1e3ccSAndroid Build Coastguard Worker       // Set default transform size search method
573*77c1e3ccSAndroid Build Coastguard Worker       set_tx_size_search_method(cm, winner_mode_params, txfm_params, 0, 0);
574*77c1e3ccSAndroid Build Coastguard Worker       // Set default transform type prune
575*77c1e3ccSAndroid Build Coastguard Worker       set_tx_type_prune(sf, txfm_params, 0, 0);
576*77c1e3ccSAndroid Build Coastguard Worker       break;
577*77c1e3ccSAndroid Build Coastguard Worker     case MODE_EVAL:
578*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->use_default_intra_tx_type =
579*77c1e3ccSAndroid Build Coastguard Worker           (cpi->sf.tx_sf.tx_type_search.fast_intra_tx_type_search ||
580*77c1e3ccSAndroid Build Coastguard Worker            cpi->oxcf.txfm_cfg.use_intra_default_tx_only);
581*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->default_inter_tx_type_prob_thresh =
582*77c1e3ccSAndroid Build Coastguard Worker           cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh;
583*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->skip_txfm_level =
584*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->skip_txfm_level[MODE_EVAL];
585*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->predict_dc_level =
586*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->predict_dc_level[MODE_EVAL];
587*77c1e3ccSAndroid Build Coastguard Worker       // Set transform domain distortion type for mode evaluation
588*77c1e3ccSAndroid Build Coastguard Worker       set_tx_domain_dist_params(
589*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params, txfm_params,
590*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_use_tx_domain_dist, 0);
591*77c1e3ccSAndroid Build Coastguard Worker 
592*77c1e3ccSAndroid Build Coastguard Worker       // Get threshold for R-D optimization of coefficients during mode
593*77c1e3ccSAndroid Build Coastguard Worker       // evaluation
594*77c1e3ccSAndroid Build Coastguard Worker       get_rd_opt_coeff_thresh(
595*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->coeff_opt_thresholds, txfm_params,
596*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_coeff_opt, 0);
597*77c1e3ccSAndroid Build Coastguard Worker 
598*77c1e3ccSAndroid Build Coastguard Worker       // Set the transform size search method for mode evaluation
599*77c1e3ccSAndroid Build Coastguard Worker       set_tx_size_search_method(
600*77c1e3ccSAndroid Build Coastguard Worker           cm, winner_mode_params, txfm_params,
601*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch, 0);
602*77c1e3ccSAndroid Build Coastguard Worker       // Set transform type prune for mode evaluation
603*77c1e3ccSAndroid Build Coastguard Worker       set_tx_type_prune(sf, txfm_params,
604*77c1e3ccSAndroid Build Coastguard Worker                         sf->tx_sf.tx_type_search.winner_mode_tx_type_pruning,
605*77c1e3ccSAndroid Build Coastguard Worker                         0);
606*77c1e3ccSAndroid Build Coastguard Worker       break;
607*77c1e3ccSAndroid Build Coastguard Worker     case WINNER_MODE_EVAL:
608*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->default_inter_tx_type_prob_thresh = INT_MAX;
609*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->use_default_intra_tx_type = 0;
610*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->skip_txfm_level =
611*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->skip_txfm_level[WINNER_MODE_EVAL];
612*77c1e3ccSAndroid Build Coastguard Worker       txfm_params->predict_dc_level =
613*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->predict_dc_level[WINNER_MODE_EVAL];
614*77c1e3ccSAndroid Build Coastguard Worker 
615*77c1e3ccSAndroid Build Coastguard Worker       // Set transform domain distortion type for winner mode evaluation
616*77c1e3ccSAndroid Build Coastguard Worker       set_tx_domain_dist_params(
617*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params, txfm_params,
618*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_use_tx_domain_dist, 1);
619*77c1e3ccSAndroid Build Coastguard Worker 
620*77c1e3ccSAndroid Build Coastguard Worker       // Get threshold for R-D optimization of coefficients for winner mode
621*77c1e3ccSAndroid Build Coastguard Worker       // evaluation
622*77c1e3ccSAndroid Build Coastguard Worker       get_rd_opt_coeff_thresh(
623*77c1e3ccSAndroid Build Coastguard Worker           winner_mode_params->coeff_opt_thresholds, txfm_params,
624*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_coeff_opt, 1);
625*77c1e3ccSAndroid Build Coastguard Worker 
626*77c1e3ccSAndroid Build Coastguard Worker       // Set the transform size search method for winner mode evaluation
627*77c1e3ccSAndroid Build Coastguard Worker       set_tx_size_search_method(
628*77c1e3ccSAndroid Build Coastguard Worker           cm, winner_mode_params, txfm_params,
629*77c1e3ccSAndroid Build Coastguard Worker           sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch, 1);
630*77c1e3ccSAndroid Build Coastguard Worker       // Set default transform type prune mode for winner mode evaluation
631*77c1e3ccSAndroid Build Coastguard Worker       set_tx_type_prune(sf, txfm_params,
632*77c1e3ccSAndroid Build Coastguard Worker                         sf->tx_sf.tx_type_search.winner_mode_tx_type_pruning,
633*77c1e3ccSAndroid Build Coastguard Worker                         1);
634*77c1e3ccSAndroid Build Coastguard Worker       break;
635*77c1e3ccSAndroid Build Coastguard Worker     default: assert(0);
636*77c1e3ccSAndroid Build Coastguard Worker   }
637*77c1e3ccSAndroid Build Coastguard Worker 
638*77c1e3ccSAndroid Build Coastguard Worker   // Rd record collected at a specific mode evaluation stage can not be used
639*77c1e3ccSAndroid Build Coastguard Worker   // across other evaluation stages as the transform parameters are different.
640*77c1e3ccSAndroid Build Coastguard Worker   // Hence, reset mb rd record whenever mode evaluation stage type changes.
641*77c1e3ccSAndroid Build Coastguard Worker   if (txfm_params->mode_eval_type != mode_eval_type)
642*77c1e3ccSAndroid Build Coastguard Worker     reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
643*77c1e3ccSAndroid Build Coastguard Worker 
644*77c1e3ccSAndroid Build Coastguard Worker   txfm_params->mode_eval_type = mode_eval_type;
645*77c1e3ccSAndroid Build Coastguard Worker }
646*77c1e3ccSAndroid Build Coastguard Worker 
647*77c1e3ccSAndroid Build Coastguard Worker // Similar to store_cfl_required(), but for use during the RDO process,
648*77c1e3ccSAndroid Build Coastguard Worker // where we haven't yet determined whether this block uses CfL.
store_cfl_required_rdo(const AV1_COMMON * cm,const MACROBLOCK * x)649*77c1e3ccSAndroid Build Coastguard Worker static inline CFL_ALLOWED_TYPE store_cfl_required_rdo(const AV1_COMMON *cm,
650*77c1e3ccSAndroid Build Coastguard Worker                                                       const MACROBLOCK *x) {
651*77c1e3ccSAndroid Build Coastguard Worker   const MACROBLOCKD *xd = &x->e_mbd;
652*77c1e3ccSAndroid Build Coastguard Worker 
653*77c1e3ccSAndroid Build Coastguard Worker   if (cm->seq_params->monochrome || !xd->is_chroma_ref) return CFL_DISALLOWED;
654*77c1e3ccSAndroid Build Coastguard Worker 
655*77c1e3ccSAndroid Build Coastguard Worker   if (!xd->is_chroma_ref) {
656*77c1e3ccSAndroid Build Coastguard Worker     // For non-chroma-reference blocks, we should always store the luma pixels,
657*77c1e3ccSAndroid Build Coastguard Worker     // in case the corresponding chroma-reference block uses CfL.
658*77c1e3ccSAndroid Build Coastguard Worker     // Note that this can only happen for block sizes which are <8 on
659*77c1e3ccSAndroid Build Coastguard Worker     // their shortest side, as otherwise they would be chroma reference
660*77c1e3ccSAndroid Build Coastguard Worker     // blocks.
661*77c1e3ccSAndroid Build Coastguard Worker     return CFL_ALLOWED;
662*77c1e3ccSAndroid Build Coastguard Worker   }
663*77c1e3ccSAndroid Build Coastguard Worker 
664*77c1e3ccSAndroid Build Coastguard Worker   // For chroma reference blocks, we should store data in the encoder iff we're
665*77c1e3ccSAndroid Build Coastguard Worker   // allowed to try out CfL.
666*77c1e3ccSAndroid Build Coastguard Worker   return is_cfl_allowed(xd);
667*77c1e3ccSAndroid Build Coastguard Worker }
668*77c1e3ccSAndroid Build Coastguard Worker 
init_sbuv_mode(MB_MODE_INFO * const mbmi)669*77c1e3ccSAndroid Build Coastguard Worker static inline void init_sbuv_mode(MB_MODE_INFO *const mbmi) {
670*77c1e3ccSAndroid Build Coastguard Worker   mbmi->uv_mode = UV_DC_PRED;
671*77c1e3ccSAndroid Build Coastguard Worker   mbmi->palette_mode_info.palette_size[1] = 0;
672*77c1e3ccSAndroid Build Coastguard Worker }
673*77c1e3ccSAndroid Build Coastguard Worker 
674*77c1e3ccSAndroid Build Coastguard Worker // Store best mode stats for winner mode processing
store_winner_mode_stats(const AV1_COMMON * const cm,MACROBLOCK * x,const MB_MODE_INFO * mbmi,RD_STATS * rd_cost,RD_STATS * rd_cost_y,RD_STATS * rd_cost_uv,THR_MODES mode_index,uint8_t * color_map,BLOCK_SIZE bsize,int64_t this_rd,int multi_winner_mode_type,int txfm_search_done)675*77c1e3ccSAndroid Build Coastguard Worker static inline void store_winner_mode_stats(
676*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMMON *const cm, MACROBLOCK *x, const MB_MODE_INFO *mbmi,
677*77c1e3ccSAndroid Build Coastguard Worker     RD_STATS *rd_cost, RD_STATS *rd_cost_y, RD_STATS *rd_cost_uv,
678*77c1e3ccSAndroid Build Coastguard Worker     THR_MODES mode_index, uint8_t *color_map, BLOCK_SIZE bsize, int64_t this_rd,
679*77c1e3ccSAndroid Build Coastguard Worker     int multi_winner_mode_type, int txfm_search_done) {
680*77c1e3ccSAndroid Build Coastguard Worker   WinnerModeStats *winner_mode_stats = x->winner_mode_stats;
681*77c1e3ccSAndroid Build Coastguard Worker   int mode_idx = 0;
682*77c1e3ccSAndroid Build Coastguard Worker   int is_palette_mode = mbmi->palette_mode_info.palette_size[PLANE_TYPE_Y] > 0;
683*77c1e3ccSAndroid Build Coastguard Worker   // Mode stat is not required when multiwinner mode processing is disabled
684*77c1e3ccSAndroid Build Coastguard Worker   if (multi_winner_mode_type == MULTI_WINNER_MODE_OFF) return;
685*77c1e3ccSAndroid Build Coastguard Worker   // Ignore mode with maximum rd
686*77c1e3ccSAndroid Build Coastguard Worker   if (this_rd == INT64_MAX) return;
687*77c1e3ccSAndroid Build Coastguard Worker   // TODO(any): Winner mode processing is currently not applicable for palette
688*77c1e3ccSAndroid Build Coastguard Worker   // mode in Inter frames. Clean-up the following code, once support is added
689*77c1e3ccSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm) && is_palette_mode) return;
690*77c1e3ccSAndroid Build Coastguard Worker 
691*77c1e3ccSAndroid Build Coastguard Worker   int max_winner_mode_count = winner_mode_count_allowed[multi_winner_mode_type];
692*77c1e3ccSAndroid Build Coastguard Worker   assert(x->winner_mode_count >= 0 &&
693*77c1e3ccSAndroid Build Coastguard Worker          x->winner_mode_count <= max_winner_mode_count);
694*77c1e3ccSAndroid Build Coastguard Worker 
695*77c1e3ccSAndroid Build Coastguard Worker   if (x->winner_mode_count) {
696*77c1e3ccSAndroid Build Coastguard Worker     // Find the mode which has higher rd cost than this_rd
697*77c1e3ccSAndroid Build Coastguard Worker     for (mode_idx = 0; mode_idx < x->winner_mode_count; mode_idx++)
698*77c1e3ccSAndroid Build Coastguard Worker       if (winner_mode_stats[mode_idx].rd > this_rd) break;
699*77c1e3ccSAndroid Build Coastguard Worker 
700*77c1e3ccSAndroid Build Coastguard Worker     if (mode_idx == max_winner_mode_count) {
701*77c1e3ccSAndroid Build Coastguard Worker       // No mode has higher rd cost than this_rd
702*77c1e3ccSAndroid Build Coastguard Worker       return;
703*77c1e3ccSAndroid Build Coastguard Worker     } else if (mode_idx < max_winner_mode_count - 1) {
704*77c1e3ccSAndroid Build Coastguard Worker       // Create a slot for current mode and move others to the next slot
705*77c1e3ccSAndroid Build Coastguard Worker       memmove(
706*77c1e3ccSAndroid Build Coastguard Worker           &winner_mode_stats[mode_idx + 1], &winner_mode_stats[mode_idx],
707*77c1e3ccSAndroid Build Coastguard Worker           (max_winner_mode_count - mode_idx - 1) * sizeof(*winner_mode_stats));
708*77c1e3ccSAndroid Build Coastguard Worker     }
709*77c1e3ccSAndroid Build Coastguard Worker   }
710*77c1e3ccSAndroid Build Coastguard Worker   // Add a mode stat for winner mode processing
711*77c1e3ccSAndroid Build Coastguard Worker   winner_mode_stats[mode_idx].mbmi = *mbmi;
712*77c1e3ccSAndroid Build Coastguard Worker   winner_mode_stats[mode_idx].rd = this_rd;
713*77c1e3ccSAndroid Build Coastguard Worker   winner_mode_stats[mode_idx].mode_index = mode_index;
714*77c1e3ccSAndroid Build Coastguard Worker 
715*77c1e3ccSAndroid Build Coastguard Worker   // Update rd stats required for inter frame
716*77c1e3ccSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm) && rd_cost && rd_cost_y && rd_cost_uv) {
717*77c1e3ccSAndroid Build Coastguard Worker     const MACROBLOCKD *xd = &x->e_mbd;
718*77c1e3ccSAndroid Build Coastguard Worker     const int skip_ctx = av1_get_skip_txfm_context(xd);
719*77c1e3ccSAndroid Build Coastguard Worker     const int is_intra_mode = av1_mode_defs[mode_index].mode < INTRA_MODE_END;
720*77c1e3ccSAndroid Build Coastguard Worker     const int skip_txfm = mbmi->skip_txfm && !is_intra_mode;
721*77c1e3ccSAndroid Build Coastguard Worker 
722*77c1e3ccSAndroid Build Coastguard Worker     winner_mode_stats[mode_idx].rd_cost = *rd_cost;
723*77c1e3ccSAndroid Build Coastguard Worker     if (txfm_search_done) {
724*77c1e3ccSAndroid Build Coastguard Worker       winner_mode_stats[mode_idx].rate_y =
725*77c1e3ccSAndroid Build Coastguard Worker           rd_cost_y->rate +
726*77c1e3ccSAndroid Build Coastguard Worker           x->mode_costs
727*77c1e3ccSAndroid Build Coastguard Worker               .skip_txfm_cost[skip_ctx][rd_cost->skip_txfm || skip_txfm];
728*77c1e3ccSAndroid Build Coastguard Worker       winner_mode_stats[mode_idx].rate_uv = rd_cost_uv->rate;
729*77c1e3ccSAndroid Build Coastguard Worker     }
730*77c1e3ccSAndroid Build Coastguard Worker   }
731*77c1e3ccSAndroid Build Coastguard Worker 
732*77c1e3ccSAndroid Build Coastguard Worker   if (color_map) {
733*77c1e3ccSAndroid Build Coastguard Worker     // Store color_index_map for palette mode
734*77c1e3ccSAndroid Build Coastguard Worker     const MACROBLOCKD *const xd = &x->e_mbd;
735*77c1e3ccSAndroid Build Coastguard Worker     int block_width, block_height;
736*77c1e3ccSAndroid Build Coastguard Worker     av1_get_block_dimensions(bsize, AOM_PLANE_Y, xd, &block_width,
737*77c1e3ccSAndroid Build Coastguard Worker                              &block_height, NULL, NULL);
738*77c1e3ccSAndroid Build Coastguard Worker     memcpy(winner_mode_stats[mode_idx].color_index_map, color_map,
739*77c1e3ccSAndroid Build Coastguard Worker            block_width * block_height * sizeof(color_map[0]));
740*77c1e3ccSAndroid Build Coastguard Worker   }
741*77c1e3ccSAndroid Build Coastguard Worker 
742*77c1e3ccSAndroid Build Coastguard Worker   x->winner_mode_count =
743*77c1e3ccSAndroid Build Coastguard Worker       AOMMIN(x->winner_mode_count + 1, max_winner_mode_count);
744*77c1e3ccSAndroid Build Coastguard Worker }
745*77c1e3ccSAndroid Build Coastguard Worker 
746*77c1e3ccSAndroid Build Coastguard Worker unsigned int av1_get_perpixel_variance(const AV1_COMP *cpi,
747*77c1e3ccSAndroid Build Coastguard Worker                                        const MACROBLOCKD *xd,
748*77c1e3ccSAndroid Build Coastguard Worker                                        const struct buf_2d *ref,
749*77c1e3ccSAndroid Build Coastguard Worker                                        BLOCK_SIZE bsize, int plane,
750*77c1e3ccSAndroid Build Coastguard Worker                                        int use_hbd);
751*77c1e3ccSAndroid Build Coastguard Worker 
752*77c1e3ccSAndroid Build Coastguard Worker unsigned int av1_get_perpixel_variance_facade(const struct AV1_COMP *cpi,
753*77c1e3ccSAndroid Build Coastguard Worker                                               const MACROBLOCKD *xd,
754*77c1e3ccSAndroid Build Coastguard Worker                                               const struct buf_2d *ref,
755*77c1e3ccSAndroid Build Coastguard Worker                                               BLOCK_SIZE bsize, int plane);
756*77c1e3ccSAndroid Build Coastguard Worker 
is_mode_intra(PREDICTION_MODE mode)757*77c1e3ccSAndroid Build Coastguard Worker static inline int is_mode_intra(PREDICTION_MODE mode) {
758*77c1e3ccSAndroid Build Coastguard Worker   return mode < INTRA_MODE_END;
759*77c1e3ccSAndroid Build Coastguard Worker }
760*77c1e3ccSAndroid Build Coastguard Worker 
761*77c1e3ccSAndroid Build Coastguard Worker // This function will copy usable ref_mv_stack[ref_frame][4] and
762*77c1e3ccSAndroid Build Coastguard Worker // weight[ref_frame][4] information from ref_mv_stack[ref_frame][8] and
763*77c1e3ccSAndroid Build Coastguard Worker // weight[ref_frame][8].
av1_copy_usable_ref_mv_stack_and_weight(const MACROBLOCKD * xd,MB_MODE_INFO_EXT * const mbmi_ext,MV_REFERENCE_FRAME ref_frame)764*77c1e3ccSAndroid Build Coastguard Worker static inline void av1_copy_usable_ref_mv_stack_and_weight(
765*77c1e3ccSAndroid Build Coastguard Worker     const MACROBLOCKD *xd, MB_MODE_INFO_EXT *const mbmi_ext,
766*77c1e3ccSAndroid Build Coastguard Worker     MV_REFERENCE_FRAME ref_frame) {
767*77c1e3ccSAndroid Build Coastguard Worker   memcpy(mbmi_ext->weight[ref_frame], xd->weight[ref_frame],
768*77c1e3ccSAndroid Build Coastguard Worker          USABLE_REF_MV_STACK_SIZE * sizeof(xd->weight[0][0]));
769*77c1e3ccSAndroid Build Coastguard Worker   memcpy(mbmi_ext->ref_mv_stack[ref_frame], xd->ref_mv_stack[ref_frame],
770*77c1e3ccSAndroid Build Coastguard Worker          USABLE_REF_MV_STACK_SIZE * sizeof(xd->ref_mv_stack[0][0]));
771*77c1e3ccSAndroid Build Coastguard Worker }
772*77c1e3ccSAndroid Build Coastguard Worker 
773*77c1e3ccSAndroid Build Coastguard Worker // Get transform rd gate level for the given transform search case.
get_txfm_rd_gate_level(const int is_masked_compound_enabled,const int txfm_rd_gate_level[TX_SEARCH_CASES],BLOCK_SIZE bsize,TX_SEARCH_CASE tx_search_case,int eval_motion_mode)774*77c1e3ccSAndroid Build Coastguard Worker static inline int get_txfm_rd_gate_level(
775*77c1e3ccSAndroid Build Coastguard Worker     const int is_masked_compound_enabled,
776*77c1e3ccSAndroid Build Coastguard Worker     const int txfm_rd_gate_level[TX_SEARCH_CASES], BLOCK_SIZE bsize,
777*77c1e3ccSAndroid Build Coastguard Worker     TX_SEARCH_CASE tx_search_case, int eval_motion_mode) {
778*77c1e3ccSAndroid Build Coastguard Worker   assert(tx_search_case < TX_SEARCH_CASES);
779*77c1e3ccSAndroid Build Coastguard Worker   if (tx_search_case == TX_SEARCH_MOTION_MODE && !eval_motion_mode &&
780*77c1e3ccSAndroid Build Coastguard Worker       num_pels_log2_lookup[bsize] > 8)
781*77c1e3ccSAndroid Build Coastguard Worker     return txfm_rd_gate_level[TX_SEARCH_MOTION_MODE];
782*77c1e3ccSAndroid Build Coastguard Worker   // Enable aggressive gating of transform search only when masked compound type
783*77c1e3ccSAndroid Build Coastguard Worker   // is enabled.
784*77c1e3ccSAndroid Build Coastguard Worker   else if (tx_search_case == TX_SEARCH_COMP_TYPE_MODE &&
785*77c1e3ccSAndroid Build Coastguard Worker            is_masked_compound_enabled)
786*77c1e3ccSAndroid Build Coastguard Worker     return txfm_rd_gate_level[TX_SEARCH_COMP_TYPE_MODE];
787*77c1e3ccSAndroid Build Coastguard Worker 
788*77c1e3ccSAndroid Build Coastguard Worker   return txfm_rd_gate_level[TX_SEARCH_DEFAULT];
789*77c1e3ccSAndroid Build Coastguard Worker }
790*77c1e3ccSAndroid Build Coastguard Worker 
791*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
792*77c1e3ccSAndroid Build Coastguard Worker }  // extern "C"
793*77c1e3ccSAndroid Build Coastguard Worker #endif
794*77c1e3ccSAndroid Build Coastguard Worker 
795*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AV1_ENCODER_RDOPT_UTILS_H_
796