xref: /aosp_15_r20/external/libaom/av1/encoder/model_rd.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_MODEL_RD_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_MODEL_RD_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/encoder/encoder.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/pustats.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/rdopt_utils.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_dsp_rtcd.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 // 0: Legacy model
27*77c1e3ccSAndroid Build Coastguard Worker // 1: Curve fit model
28*77c1e3ccSAndroid Build Coastguard Worker // 2: Surface fit model
29*77c1e3ccSAndroid Build Coastguard Worker // 3: DNN regression model
30*77c1e3ccSAndroid Build Coastguard Worker // 4: Full rd model
31*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_INTERP_FILTER 1
32*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_TX_SEARCH_PRUNE 1
33*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_MASKED_COMPOUND 1
34*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_INTERINTRA 1
35*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_INTRA 1
36*77c1e3ccSAndroid Build Coastguard Worker #define MODELRD_TYPE_MOTION_MODE_RD 1
37*77c1e3ccSAndroid Build Coastguard Worker 
38*77c1e3ccSAndroid Build Coastguard Worker typedef void (*model_rd_for_sb_type)(
39*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMP *const cpi, BLOCK_SIZE bsize, MACROBLOCK *x, MACROBLOCKD *xd,
40*77c1e3ccSAndroid Build Coastguard Worker     int plane_from, int plane_to, int *out_rate_sum, int64_t *out_dist_sum,
41*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *skip_txfm_sb, int64_t *skip_sse_sb, int *plane_rate,
42*77c1e3ccSAndroid Build Coastguard Worker     int64_t *plane_sse, int64_t *plane_dist);
43*77c1e3ccSAndroid Build Coastguard Worker typedef void (*model_rd_from_sse_type)(const AV1_COMP *const cpi,
44*77c1e3ccSAndroid Build Coastguard Worker                                        const MACROBLOCK *const x,
45*77c1e3ccSAndroid Build Coastguard Worker                                        BLOCK_SIZE plane_bsize, int plane,
46*77c1e3ccSAndroid Build Coastguard Worker                                        int64_t sse, int num_samples, int *rate,
47*77c1e3ccSAndroid Build Coastguard Worker                                        int64_t *dist);
48*77c1e3ccSAndroid Build Coastguard Worker 
calculate_sse(MACROBLOCKD * const xd,const struct macroblock_plane * p,struct macroblockd_plane * pd,const int bw,const int bh)49*77c1e3ccSAndroid Build Coastguard Worker static int64_t calculate_sse(MACROBLOCKD *const xd,
50*77c1e3ccSAndroid Build Coastguard Worker                              const struct macroblock_plane *p,
51*77c1e3ccSAndroid Build Coastguard Worker                              struct macroblockd_plane *pd, const int bw,
52*77c1e3ccSAndroid Build Coastguard Worker                              const int bh) {
53*77c1e3ccSAndroid Build Coastguard Worker   int64_t sse = 0;
54*77c1e3ccSAndroid Build Coastguard Worker   const int shift = xd->bd - 8;
55*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
56*77c1e3ccSAndroid Build Coastguard Worker   if (is_cur_buf_hbd(xd)) {
57*77c1e3ccSAndroid Build Coastguard Worker     sse = aom_highbd_sse(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride,
58*77c1e3ccSAndroid Build Coastguard Worker                          bw, bh);
59*77c1e3ccSAndroid Build Coastguard Worker   } else {
60*77c1e3ccSAndroid Build Coastguard Worker     sse =
61*77c1e3ccSAndroid Build Coastguard Worker         aom_sse(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride, bw, bh);
62*77c1e3ccSAndroid Build Coastguard Worker   }
63*77c1e3ccSAndroid Build Coastguard Worker #else
64*77c1e3ccSAndroid Build Coastguard Worker   sse = aom_sse(p->src.buf, p->src.stride, pd->dst.buf, pd->dst.stride, bw, bh);
65*77c1e3ccSAndroid Build Coastguard Worker #endif
66*77c1e3ccSAndroid Build Coastguard Worker   sse = ROUND_POWER_OF_TWO(sse, shift * 2);
67*77c1e3ccSAndroid Build Coastguard Worker   return sse;
68*77c1e3ccSAndroid Build Coastguard Worker }
69*77c1e3ccSAndroid Build Coastguard Worker 
compute_sse_plane(MACROBLOCK * x,MACROBLOCKD * xd,int plane,const BLOCK_SIZE bsize)70*77c1e3ccSAndroid Build Coastguard Worker static inline int64_t compute_sse_plane(MACROBLOCK *x, MACROBLOCKD *xd,
71*77c1e3ccSAndroid Build Coastguard Worker                                         int plane, const BLOCK_SIZE bsize) {
72*77c1e3ccSAndroid Build Coastguard Worker   struct macroblockd_plane *const pd = &xd->plane[plane];
73*77c1e3ccSAndroid Build Coastguard Worker   const BLOCK_SIZE plane_bsize =
74*77c1e3ccSAndroid Build Coastguard Worker       get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
75*77c1e3ccSAndroid Build Coastguard Worker   int bw, bh;
76*77c1e3ccSAndroid Build Coastguard Worker   const struct macroblock_plane *const p = &x->plane[plane];
77*77c1e3ccSAndroid Build Coastguard Worker   get_txb_dimensions(xd, plane, plane_bsize, 0, 0, plane_bsize, NULL, NULL, &bw,
78*77c1e3ccSAndroid Build Coastguard Worker                      &bh);
79*77c1e3ccSAndroid Build Coastguard Worker 
80*77c1e3ccSAndroid Build Coastguard Worker   int64_t sse = calculate_sse(xd, p, pd, bw, bh);
81*77c1e3ccSAndroid Build Coastguard Worker 
82*77c1e3ccSAndroid Build Coastguard Worker   return sse;
83*77c1e3ccSAndroid Build Coastguard Worker }
84*77c1e3ccSAndroid Build Coastguard Worker 
model_rd_from_sse(const AV1_COMP * const cpi,const MACROBLOCK * const x,BLOCK_SIZE plane_bsize,int plane,int64_t sse,int num_samples,int * rate,int64_t * dist)85*77c1e3ccSAndroid Build Coastguard Worker static inline void model_rd_from_sse(const AV1_COMP *const cpi,
86*77c1e3ccSAndroid Build Coastguard Worker                                      const MACROBLOCK *const x,
87*77c1e3ccSAndroid Build Coastguard Worker                                      BLOCK_SIZE plane_bsize, int plane,
88*77c1e3ccSAndroid Build Coastguard Worker                                      int64_t sse, int num_samples, int *rate,
89*77c1e3ccSAndroid Build Coastguard Worker                                      int64_t *dist) {
90*77c1e3ccSAndroid Build Coastguard Worker   (void)num_samples;
91*77c1e3ccSAndroid Build Coastguard Worker   const MACROBLOCKD *const xd = &x->e_mbd;
92*77c1e3ccSAndroid Build Coastguard Worker   const struct macroblock_plane *const p = &x->plane[plane];
93*77c1e3ccSAndroid Build Coastguard Worker   const int dequant_shift = (is_cur_buf_hbd(xd)) ? xd->bd - 5 : 3;
94*77c1e3ccSAndroid Build Coastguard Worker 
95*77c1e3ccSAndroid Build Coastguard Worker   // Fast approximate the modelling function.
96*77c1e3ccSAndroid Build Coastguard Worker   if (cpi->sf.rd_sf.simple_model_rd_from_var) {
97*77c1e3ccSAndroid Build Coastguard Worker     const int64_t square_error = sse;
98*77c1e3ccSAndroid Build Coastguard Worker     int quantizer = p->dequant_QTX[1] >> dequant_shift;
99*77c1e3ccSAndroid Build Coastguard Worker     if (quantizer < 120)
100*77c1e3ccSAndroid Build Coastguard Worker       *rate = (int)AOMMIN(
101*77c1e3ccSAndroid Build Coastguard Worker           (square_error * (280 - quantizer)) >> (16 - AV1_PROB_COST_SHIFT),
102*77c1e3ccSAndroid Build Coastguard Worker           INT_MAX);
103*77c1e3ccSAndroid Build Coastguard Worker     else
104*77c1e3ccSAndroid Build Coastguard Worker       *rate = 0;
105*77c1e3ccSAndroid Build Coastguard Worker     assert(*rate >= 0);
106*77c1e3ccSAndroid Build Coastguard Worker     *dist = (square_error * quantizer) >> 8;
107*77c1e3ccSAndroid Build Coastguard Worker   } else {
108*77c1e3ccSAndroid Build Coastguard Worker     av1_model_rd_from_var_lapndz(sse, num_pels_log2_lookup[plane_bsize],
109*77c1e3ccSAndroid Build Coastguard Worker                                  p->dequant_QTX[1] >> dequant_shift, rate,
110*77c1e3ccSAndroid Build Coastguard Worker                                  dist);
111*77c1e3ccSAndroid Build Coastguard Worker   }
112*77c1e3ccSAndroid Build Coastguard Worker   *dist <<= 4;
113*77c1e3ccSAndroid Build Coastguard Worker }
114*77c1e3ccSAndroid Build Coastguard Worker 
115*77c1e3ccSAndroid Build Coastguard Worker // Fits a curve for rate and distortion using as feature:
116*77c1e3ccSAndroid Build Coastguard Worker // log2(sse_norm/qstep^2)
model_rd_with_curvfit(const AV1_COMP * const cpi,const MACROBLOCK * const x,BLOCK_SIZE plane_bsize,int plane,int64_t sse,int num_samples,int * rate,int64_t * dist)117*77c1e3ccSAndroid Build Coastguard Worker static inline void model_rd_with_curvfit(const AV1_COMP *const cpi,
118*77c1e3ccSAndroid Build Coastguard Worker                                          const MACROBLOCK *const x,
119*77c1e3ccSAndroid Build Coastguard Worker                                          BLOCK_SIZE plane_bsize, int plane,
120*77c1e3ccSAndroid Build Coastguard Worker                                          int64_t sse, int num_samples,
121*77c1e3ccSAndroid Build Coastguard Worker                                          int *rate, int64_t *dist) {
122*77c1e3ccSAndroid Build Coastguard Worker   (void)cpi;
123*77c1e3ccSAndroid Build Coastguard Worker   (void)plane_bsize;
124*77c1e3ccSAndroid Build Coastguard Worker   const MACROBLOCKD *const xd = &x->e_mbd;
125*77c1e3ccSAndroid Build Coastguard Worker   const struct macroblock_plane *const p = &x->plane[plane];
126*77c1e3ccSAndroid Build Coastguard Worker   const int dequant_shift = (is_cur_buf_hbd(xd)) ? xd->bd - 5 : 3;
127*77c1e3ccSAndroid Build Coastguard Worker   const int qstep = AOMMAX(p->dequant_QTX[1] >> dequant_shift, 1);
128*77c1e3ccSAndroid Build Coastguard Worker 
129*77c1e3ccSAndroid Build Coastguard Worker   if (sse == 0) {
130*77c1e3ccSAndroid Build Coastguard Worker     if (rate) *rate = 0;
131*77c1e3ccSAndroid Build Coastguard Worker     if (dist) *dist = 0;
132*77c1e3ccSAndroid Build Coastguard Worker     return;
133*77c1e3ccSAndroid Build Coastguard Worker   }
134*77c1e3ccSAndroid Build Coastguard Worker   const double sse_norm = (double)sse / num_samples;
135*77c1e3ccSAndroid Build Coastguard Worker   const double qstepsqr = (double)qstep * qstep;
136*77c1e3ccSAndroid Build Coastguard Worker   const double xqr = log2(sse_norm / qstepsqr);
137*77c1e3ccSAndroid Build Coastguard Worker   double rate_f, dist_by_sse_norm_f;
138*77c1e3ccSAndroid Build Coastguard Worker   av1_model_rd_curvfit(plane_bsize, sse_norm, xqr, &rate_f,
139*77c1e3ccSAndroid Build Coastguard Worker                        &dist_by_sse_norm_f);
140*77c1e3ccSAndroid Build Coastguard Worker 
141*77c1e3ccSAndroid Build Coastguard Worker   const double dist_f = dist_by_sse_norm_f * sse_norm;
142*77c1e3ccSAndroid Build Coastguard Worker   int rate_i = (int)(AOMMAX(0.0, rate_f * num_samples) + 0.5);
143*77c1e3ccSAndroid Build Coastguard Worker   int64_t dist_i = (int64_t)(AOMMAX(0.0, dist_f * num_samples) + 0.5);
144*77c1e3ccSAndroid Build Coastguard Worker 
145*77c1e3ccSAndroid Build Coastguard Worker   // Check if skip is better
146*77c1e3ccSAndroid Build Coastguard Worker   if (rate_i == 0) {
147*77c1e3ccSAndroid Build Coastguard Worker     dist_i = sse << 4;
148*77c1e3ccSAndroid Build Coastguard Worker   } else if (RDCOST(x->rdmult, rate_i, dist_i) >=
149*77c1e3ccSAndroid Build Coastguard Worker              RDCOST(x->rdmult, 0, sse << 4)) {
150*77c1e3ccSAndroid Build Coastguard Worker     rate_i = 0;
151*77c1e3ccSAndroid Build Coastguard Worker     dist_i = sse << 4;
152*77c1e3ccSAndroid Build Coastguard Worker   }
153*77c1e3ccSAndroid Build Coastguard Worker 
154*77c1e3ccSAndroid Build Coastguard Worker   if (rate) *rate = rate_i;
155*77c1e3ccSAndroid Build Coastguard Worker   if (dist) *dist = dist_i;
156*77c1e3ccSAndroid Build Coastguard Worker }
157*77c1e3ccSAndroid Build Coastguard Worker 
model_rd_for_sb(const AV1_COMP * const cpi,BLOCK_SIZE bsize,MACROBLOCK * x,MACROBLOCKD * xd,int plane_from,int plane_to,int * out_rate_sum,int64_t * out_dist_sum,uint8_t * skip_txfm_sb,int64_t * skip_sse_sb,int * plane_rate,int64_t * plane_sse,int64_t * plane_dist)158*77c1e3ccSAndroid Build Coastguard Worker static inline void model_rd_for_sb(const AV1_COMP *const cpi, BLOCK_SIZE bsize,
159*77c1e3ccSAndroid Build Coastguard Worker                                    MACROBLOCK *x, MACROBLOCKD *xd,
160*77c1e3ccSAndroid Build Coastguard Worker                                    int plane_from, int plane_to,
161*77c1e3ccSAndroid Build Coastguard Worker                                    int *out_rate_sum, int64_t *out_dist_sum,
162*77c1e3ccSAndroid Build Coastguard Worker                                    uint8_t *skip_txfm_sb, int64_t *skip_sse_sb,
163*77c1e3ccSAndroid Build Coastguard Worker                                    int *plane_rate, int64_t *plane_sse,
164*77c1e3ccSAndroid Build Coastguard Worker                                    int64_t *plane_dist) {
165*77c1e3ccSAndroid Build Coastguard Worker   // Note our transform coeffs are 8 times an orthogonal transform.
166*77c1e3ccSAndroid Build Coastguard Worker   // Hence quantizer step is also 8 times. To get effective quantizer
167*77c1e3ccSAndroid Build Coastguard Worker   // we need to divide by 8 before sending to modeling function.
168*77c1e3ccSAndroid Build Coastguard Worker   int plane;
169*77c1e3ccSAndroid Build Coastguard Worker   const int ref = xd->mi[0]->ref_frame[0];
170*77c1e3ccSAndroid Build Coastguard Worker 
171*77c1e3ccSAndroid Build Coastguard Worker   int64_t rate_sum = 0;
172*77c1e3ccSAndroid Build Coastguard Worker   int64_t dist_sum = 0;
173*77c1e3ccSAndroid Build Coastguard Worker   int64_t total_sse = 0;
174*77c1e3ccSAndroid Build Coastguard Worker 
175*77c1e3ccSAndroid Build Coastguard Worker   assert(bsize < BLOCK_SIZES_ALL);
176*77c1e3ccSAndroid Build Coastguard Worker 
177*77c1e3ccSAndroid Build Coastguard Worker   for (plane = plane_from; plane <= plane_to; ++plane) {
178*77c1e3ccSAndroid Build Coastguard Worker     if (plane && !xd->is_chroma_ref) break;
179*77c1e3ccSAndroid Build Coastguard Worker     struct macroblock_plane *const p = &x->plane[plane];
180*77c1e3ccSAndroid Build Coastguard Worker     struct macroblockd_plane *const pd = &xd->plane[plane];
181*77c1e3ccSAndroid Build Coastguard Worker     const BLOCK_SIZE plane_bsize =
182*77c1e3ccSAndroid Build Coastguard Worker         get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
183*77c1e3ccSAndroid Build Coastguard Worker     assert(plane_bsize < BLOCK_SIZES_ALL);
184*77c1e3ccSAndroid Build Coastguard Worker     const int bw = block_size_wide[plane_bsize];
185*77c1e3ccSAndroid Build Coastguard Worker     const int bh = block_size_high[plane_bsize];
186*77c1e3ccSAndroid Build Coastguard Worker     int64_t sse;
187*77c1e3ccSAndroid Build Coastguard Worker     int rate;
188*77c1e3ccSAndroid Build Coastguard Worker     int64_t dist;
189*77c1e3ccSAndroid Build Coastguard Worker 
190*77c1e3ccSAndroid Build Coastguard Worker     sse = calculate_sse(xd, p, pd, bw, bh);
191*77c1e3ccSAndroid Build Coastguard Worker 
192*77c1e3ccSAndroid Build Coastguard Worker     model_rd_from_sse(cpi, x, plane_bsize, plane, sse, bw * bh, &rate, &dist);
193*77c1e3ccSAndroid Build Coastguard Worker 
194*77c1e3ccSAndroid Build Coastguard Worker     if (plane == 0) x->pred_sse[ref] = (unsigned int)AOMMIN(sse, UINT_MAX);
195*77c1e3ccSAndroid Build Coastguard Worker 
196*77c1e3ccSAndroid Build Coastguard Worker     total_sse += sse;
197*77c1e3ccSAndroid Build Coastguard Worker     rate_sum += rate;
198*77c1e3ccSAndroid Build Coastguard Worker     dist_sum += dist;
199*77c1e3ccSAndroid Build Coastguard Worker     if (plane_rate) plane_rate[plane] = rate;
200*77c1e3ccSAndroid Build Coastguard Worker     if (plane_sse) plane_sse[plane] = sse;
201*77c1e3ccSAndroid Build Coastguard Worker     if (plane_dist) plane_dist[plane] = dist;
202*77c1e3ccSAndroid Build Coastguard Worker     assert(rate_sum >= 0);
203*77c1e3ccSAndroid Build Coastguard Worker   }
204*77c1e3ccSAndroid Build Coastguard Worker 
205*77c1e3ccSAndroid Build Coastguard Worker   if (skip_txfm_sb) *skip_txfm_sb = total_sse == 0;
206*77c1e3ccSAndroid Build Coastguard Worker   if (skip_sse_sb) *skip_sse_sb = total_sse << 4;
207*77c1e3ccSAndroid Build Coastguard Worker   rate_sum = AOMMIN(rate_sum, INT_MAX);
208*77c1e3ccSAndroid Build Coastguard Worker   *out_rate_sum = (int)rate_sum;
209*77c1e3ccSAndroid Build Coastguard Worker   *out_dist_sum = dist_sum;
210*77c1e3ccSAndroid Build Coastguard Worker }
211*77c1e3ccSAndroid Build Coastguard Worker 
model_rd_for_sb_with_curvfit(const AV1_COMP * const cpi,BLOCK_SIZE bsize,MACROBLOCK * x,MACROBLOCKD * xd,int plane_from,int plane_to,int * out_rate_sum,int64_t * out_dist_sum,uint8_t * skip_txfm_sb,int64_t * skip_sse_sb,int * plane_rate,int64_t * plane_sse,int64_t * plane_dist)212*77c1e3ccSAndroid Build Coastguard Worker static inline void model_rd_for_sb_with_curvfit(
213*77c1e3ccSAndroid Build Coastguard Worker     const AV1_COMP *const cpi, BLOCK_SIZE bsize, MACROBLOCK *x, MACROBLOCKD *xd,
214*77c1e3ccSAndroid Build Coastguard Worker     int plane_from, int plane_to, int *out_rate_sum, int64_t *out_dist_sum,
215*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *skip_txfm_sb, int64_t *skip_sse_sb, int *plane_rate,
216*77c1e3ccSAndroid Build Coastguard Worker     int64_t *plane_sse, int64_t *plane_dist) {
217*77c1e3ccSAndroid Build Coastguard Worker   // Note our transform coeffs are 8 times an orthogonal transform.
218*77c1e3ccSAndroid Build Coastguard Worker   // Hence quantizer step is also 8 times. To get effective quantizer
219*77c1e3ccSAndroid Build Coastguard Worker   // we need to divide by 8 before sending to modeling function.
220*77c1e3ccSAndroid Build Coastguard Worker   const int ref = xd->mi[0]->ref_frame[0];
221*77c1e3ccSAndroid Build Coastguard Worker 
222*77c1e3ccSAndroid Build Coastguard Worker   int64_t rate_sum = 0;
223*77c1e3ccSAndroid Build Coastguard Worker   int64_t dist_sum = 0;
224*77c1e3ccSAndroid Build Coastguard Worker   int64_t total_sse = 0;
225*77c1e3ccSAndroid Build Coastguard Worker 
226*77c1e3ccSAndroid Build Coastguard Worker   for (int plane = plane_from; plane <= plane_to; ++plane) {
227*77c1e3ccSAndroid Build Coastguard Worker     if (plane && !xd->is_chroma_ref) break;
228*77c1e3ccSAndroid Build Coastguard Worker     struct macroblockd_plane *const pd = &xd->plane[plane];
229*77c1e3ccSAndroid Build Coastguard Worker     const BLOCK_SIZE plane_bsize =
230*77c1e3ccSAndroid Build Coastguard Worker         get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
231*77c1e3ccSAndroid Build Coastguard Worker     int64_t dist, sse;
232*77c1e3ccSAndroid Build Coastguard Worker     int rate;
233*77c1e3ccSAndroid Build Coastguard Worker     int bw, bh;
234*77c1e3ccSAndroid Build Coastguard Worker     const struct macroblock_plane *const p = &x->plane[plane];
235*77c1e3ccSAndroid Build Coastguard Worker     get_txb_dimensions(xd, plane, plane_bsize, 0, 0, plane_bsize, NULL, NULL,
236*77c1e3ccSAndroid Build Coastguard Worker                        &bw, &bh);
237*77c1e3ccSAndroid Build Coastguard Worker 
238*77c1e3ccSAndroid Build Coastguard Worker     sse = calculate_sse(xd, p, pd, bw, bh);
239*77c1e3ccSAndroid Build Coastguard Worker     model_rd_with_curvfit(cpi, x, plane_bsize, plane, sse, bw * bh, &rate,
240*77c1e3ccSAndroid Build Coastguard Worker                           &dist);
241*77c1e3ccSAndroid Build Coastguard Worker 
242*77c1e3ccSAndroid Build Coastguard Worker     if (plane == 0) x->pred_sse[ref] = (unsigned int)AOMMIN(sse, UINT_MAX);
243*77c1e3ccSAndroid Build Coastguard Worker 
244*77c1e3ccSAndroid Build Coastguard Worker     total_sse += sse;
245*77c1e3ccSAndroid Build Coastguard Worker     rate_sum += rate;
246*77c1e3ccSAndroid Build Coastguard Worker     dist_sum += dist;
247*77c1e3ccSAndroid Build Coastguard Worker 
248*77c1e3ccSAndroid Build Coastguard Worker     if (plane_rate) plane_rate[plane] = rate;
249*77c1e3ccSAndroid Build Coastguard Worker     if (plane_sse) plane_sse[plane] = sse;
250*77c1e3ccSAndroid Build Coastguard Worker     if (plane_dist) plane_dist[plane] = dist;
251*77c1e3ccSAndroid Build Coastguard Worker   }
252*77c1e3ccSAndroid Build Coastguard Worker 
253*77c1e3ccSAndroid Build Coastguard Worker   if (skip_txfm_sb) *skip_txfm_sb = rate_sum == 0;
254*77c1e3ccSAndroid Build Coastguard Worker   if (skip_sse_sb) *skip_sse_sb = total_sse << 4;
255*77c1e3ccSAndroid Build Coastguard Worker   *out_rate_sum = (int)rate_sum;
256*77c1e3ccSAndroid Build Coastguard Worker   *out_dist_sum = dist_sum;
257*77c1e3ccSAndroid Build Coastguard Worker }
258*77c1e3ccSAndroid Build Coastguard Worker 
259*77c1e3ccSAndroid Build Coastguard Worker enum { MODELRD_LEGACY, MODELRD_CURVFIT, MODELRD_TYPES } UENUM1BYTE(ModelRdType);
260*77c1e3ccSAndroid Build Coastguard Worker 
261*77c1e3ccSAndroid Build Coastguard Worker static const model_rd_for_sb_type model_rd_sb_fn[MODELRD_TYPES] = {
262*77c1e3ccSAndroid Build Coastguard Worker   model_rd_for_sb, model_rd_for_sb_with_curvfit
263*77c1e3ccSAndroid Build Coastguard Worker };
264*77c1e3ccSAndroid Build Coastguard Worker 
265*77c1e3ccSAndroid Build Coastguard Worker static const model_rd_from_sse_type model_rd_sse_fn[MODELRD_TYPES] = {
266*77c1e3ccSAndroid Build Coastguard Worker   model_rd_from_sse, model_rd_with_curvfit
267*77c1e3ccSAndroid Build Coastguard Worker };
268*77c1e3ccSAndroid Build Coastguard Worker 
269*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
270*77c1e3ccSAndroid Build Coastguard Worker }  // extern "C"
271*77c1e3ccSAndroid Build Coastguard Worker #endif
272*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AV1_ENCODER_MODEL_RD_H_
273