xref: /aosp_15_r20/external/libaom/av1/encoder/tune_butteraugli.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2021, 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 #include <math.h>
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/tune_butteraugli.h"
15*77c1e3ccSAndroid Build Coastguard Worker 
16*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/butteraugli.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/encodeframe.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/encoder_utils.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/extend.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/var_based_part.h"
21*77c1e3ccSAndroid Build Coastguard Worker 
22*77c1e3ccSAndroid Build Coastguard Worker static const int resize_factor = 2;
23*77c1e3ccSAndroid Build Coastguard Worker 
set_mb_butteraugli_rdmult_scaling(AV1_COMP * cpi,const YV12_BUFFER_CONFIG * source,const YV12_BUFFER_CONFIG * recon,const double K)24*77c1e3ccSAndroid Build Coastguard Worker static void set_mb_butteraugli_rdmult_scaling(AV1_COMP *cpi,
25*77c1e3ccSAndroid Build Coastguard Worker                                               const YV12_BUFFER_CONFIG *source,
26*77c1e3ccSAndroid Build Coastguard Worker                                               const YV12_BUFFER_CONFIG *recon,
27*77c1e3ccSAndroid Build Coastguard Worker                                               const double K) {
28*77c1e3ccSAndroid Build Coastguard Worker   AV1_COMMON *const cm = &cpi->common;
29*77c1e3ccSAndroid Build Coastguard Worker   SequenceHeader *const seq_params = cm->seq_params;
30*77c1e3ccSAndroid Build Coastguard Worker   const CommonModeInfoParams *const mi_params = &cm->mi_params;
31*77c1e3ccSAndroid Build Coastguard Worker   const aom_color_range_t color_range =
32*77c1e3ccSAndroid Build Coastguard Worker       seq_params->color_range != 0 ? AOM_CR_FULL_RANGE : AOM_CR_STUDIO_RANGE;
33*77c1e3ccSAndroid Build Coastguard Worker   const int bit_depth = cpi->td.mb.e_mbd.bd;
34*77c1e3ccSAndroid Build Coastguard Worker   const int width = source->y_crop_width;
35*77c1e3ccSAndroid Build Coastguard Worker   const int height = source->y_crop_height;
36*77c1e3ccSAndroid Build Coastguard Worker   const int ss_x = source->subsampling_x;
37*77c1e3ccSAndroid Build Coastguard Worker   const int ss_y = source->subsampling_y;
38*77c1e3ccSAndroid Build Coastguard Worker 
39*77c1e3ccSAndroid Build Coastguard Worker   float *diffmap;
40*77c1e3ccSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(cm, diffmap, aom_malloc(width * height * sizeof(*diffmap)));
41*77c1e3ccSAndroid Build Coastguard Worker   if (!aom_calc_butteraugli(source, recon, bit_depth,
42*77c1e3ccSAndroid Build Coastguard Worker                             seq_params->matrix_coefficients, color_range,
43*77c1e3ccSAndroid Build Coastguard Worker                             diffmap)) {
44*77c1e3ccSAndroid Build Coastguard Worker     aom_internal_error(cm->error, AOM_CODEC_ERROR,
45*77c1e3ccSAndroid Build Coastguard Worker                        "Failed to calculate Butteraugli distances.");
46*77c1e3ccSAndroid Build Coastguard Worker   }
47*77c1e3ccSAndroid Build Coastguard Worker 
48*77c1e3ccSAndroid Build Coastguard Worker   const int num_mi_w = mi_size_wide[butteraugli_rdo_bsize] / resize_factor;
49*77c1e3ccSAndroid Build Coastguard Worker   const int num_mi_h = mi_size_high[butteraugli_rdo_bsize] / resize_factor;
50*77c1e3ccSAndroid Build Coastguard Worker   const int num_cols =
51*77c1e3ccSAndroid Build Coastguard Worker       (mi_params->mi_cols / resize_factor + num_mi_w - 1) / num_mi_w;
52*77c1e3ccSAndroid Build Coastguard Worker   const int num_rows =
53*77c1e3ccSAndroid Build Coastguard Worker       (mi_params->mi_rows / resize_factor + num_mi_h - 1) / num_mi_h;
54*77c1e3ccSAndroid Build Coastguard Worker   const int block_w = num_mi_w << 2;
55*77c1e3ccSAndroid Build Coastguard Worker   const int block_h = num_mi_h << 2;
56*77c1e3ccSAndroid Build Coastguard Worker   double log_sum = 0.0;
57*77c1e3ccSAndroid Build Coastguard Worker   double blk_count = 0.0;
58*77c1e3ccSAndroid Build Coastguard Worker 
59*77c1e3ccSAndroid Build Coastguard Worker   // Loop through each block.
60*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < num_rows; ++row) {
61*77c1e3ccSAndroid Build Coastguard Worker     for (int col = 0; col < num_cols; ++col) {
62*77c1e3ccSAndroid Build Coastguard Worker       const int index = row * num_cols + col;
63*77c1e3ccSAndroid Build Coastguard Worker       const int y_start = row * block_h;
64*77c1e3ccSAndroid Build Coastguard Worker       const int x_start = col * block_w;
65*77c1e3ccSAndroid Build Coastguard Worker       float dbutteraugli = 0.0f;
66*77c1e3ccSAndroid Build Coastguard Worker       float dmse = 0.0f;
67*77c1e3ccSAndroid Build Coastguard Worker       float px_count = 0.0f;
68*77c1e3ccSAndroid Build Coastguard Worker 
69*77c1e3ccSAndroid Build Coastguard Worker       // Loop through each pixel.
70*77c1e3ccSAndroid Build Coastguard Worker       for (int y = y_start; y < y_start + block_h && y < height; y++) {
71*77c1e3ccSAndroid Build Coastguard Worker         for (int x = x_start; x < x_start + block_w && x < width; x++) {
72*77c1e3ccSAndroid Build Coastguard Worker           dbutteraugli += powf(diffmap[y * width + x], 12.0f);
73*77c1e3ccSAndroid Build Coastguard Worker           float px_diff = source->y_buffer[y * source->y_stride + x] -
74*77c1e3ccSAndroid Build Coastguard Worker                           recon->y_buffer[y * recon->y_stride + x];
75*77c1e3ccSAndroid Build Coastguard Worker           dmse += px_diff * px_diff;
76*77c1e3ccSAndroid Build Coastguard Worker           px_count += 1.0f;
77*77c1e3ccSAndroid Build Coastguard Worker         }
78*77c1e3ccSAndroid Build Coastguard Worker       }
79*77c1e3ccSAndroid Build Coastguard Worker       const int y_end = AOMMIN((y_start >> ss_y) + (block_h >> ss_y),
80*77c1e3ccSAndroid Build Coastguard Worker                                (height + ss_y) >> ss_y);
81*77c1e3ccSAndroid Build Coastguard Worker       for (int y = y_start >> ss_y; y < y_end; y++) {
82*77c1e3ccSAndroid Build Coastguard Worker         const int x_end = AOMMIN((x_start >> ss_x) + (block_w >> ss_x),
83*77c1e3ccSAndroid Build Coastguard Worker                                  (width + ss_x) >> ss_x);
84*77c1e3ccSAndroid Build Coastguard Worker         for (int x = x_start >> ss_x; x < x_end; x++) {
85*77c1e3ccSAndroid Build Coastguard Worker           const int src_px_index = y * source->uv_stride + x;
86*77c1e3ccSAndroid Build Coastguard Worker           const int recon_px_index = y * recon->uv_stride + x;
87*77c1e3ccSAndroid Build Coastguard Worker           const float px_diff_u = (float)(source->u_buffer[src_px_index] -
88*77c1e3ccSAndroid Build Coastguard Worker                                           recon->u_buffer[recon_px_index]);
89*77c1e3ccSAndroid Build Coastguard Worker           const float px_diff_v = (float)(source->v_buffer[src_px_index] -
90*77c1e3ccSAndroid Build Coastguard Worker                                           recon->v_buffer[recon_px_index]);
91*77c1e3ccSAndroid Build Coastguard Worker           dmse += px_diff_u * px_diff_u + px_diff_v * px_diff_v;
92*77c1e3ccSAndroid Build Coastguard Worker           px_count += 2.0f;
93*77c1e3ccSAndroid Build Coastguard Worker         }
94*77c1e3ccSAndroid Build Coastguard Worker       }
95*77c1e3ccSAndroid Build Coastguard Worker 
96*77c1e3ccSAndroid Build Coastguard Worker       dbutteraugli = powf(dbutteraugli, 1.0f / 12.0f);
97*77c1e3ccSAndroid Build Coastguard Worker       dmse = dmse / px_count;
98*77c1e3ccSAndroid Build Coastguard Worker       const float eps = 0.01f;
99*77c1e3ccSAndroid Build Coastguard Worker       double weight;
100*77c1e3ccSAndroid Build Coastguard Worker       if (dbutteraugli < eps || dmse < eps) {
101*77c1e3ccSAndroid Build Coastguard Worker         weight = -1.0;
102*77c1e3ccSAndroid Build Coastguard Worker       } else {
103*77c1e3ccSAndroid Build Coastguard Worker         blk_count += 1.0;
104*77c1e3ccSAndroid Build Coastguard Worker         weight = dmse / dbutteraugli;
105*77c1e3ccSAndroid Build Coastguard Worker         weight = AOMMIN(weight, 5.0);
106*77c1e3ccSAndroid Build Coastguard Worker         weight += K;
107*77c1e3ccSAndroid Build Coastguard Worker         log_sum += log(weight);
108*77c1e3ccSAndroid Build Coastguard Worker       }
109*77c1e3ccSAndroid Build Coastguard Worker       cpi->butteraugli_info.rdmult_scaling_factors[index] = weight;
110*77c1e3ccSAndroid Build Coastguard Worker     }
111*77c1e3ccSAndroid Build Coastguard Worker   }
112*77c1e3ccSAndroid Build Coastguard Worker   // Geometric average of the weights.
113*77c1e3ccSAndroid Build Coastguard Worker   log_sum = exp(log_sum / blk_count);
114*77c1e3ccSAndroid Build Coastguard Worker 
115*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < num_rows; ++row) {
116*77c1e3ccSAndroid Build Coastguard Worker     for (int col = 0; col < num_cols; ++col) {
117*77c1e3ccSAndroid Build Coastguard Worker       const int index = row * num_cols + col;
118*77c1e3ccSAndroid Build Coastguard Worker       double *weight = &cpi->butteraugli_info.rdmult_scaling_factors[index];
119*77c1e3ccSAndroid Build Coastguard Worker       if (*weight <= 0.0) {
120*77c1e3ccSAndroid Build Coastguard Worker         *weight = 1.0;
121*77c1e3ccSAndroid Build Coastguard Worker       } else {
122*77c1e3ccSAndroid Build Coastguard Worker         *weight /= log_sum;
123*77c1e3ccSAndroid Build Coastguard Worker       }
124*77c1e3ccSAndroid Build Coastguard Worker       *weight = AOMMIN(*weight, 2.5);
125*77c1e3ccSAndroid Build Coastguard Worker       *weight = AOMMAX(*weight, 0.4);
126*77c1e3ccSAndroid Build Coastguard Worker     }
127*77c1e3ccSAndroid Build Coastguard Worker   }
128*77c1e3ccSAndroid Build Coastguard Worker 
129*77c1e3ccSAndroid Build Coastguard Worker   aom_free(diffmap);
130*77c1e3ccSAndroid Build Coastguard Worker }
131*77c1e3ccSAndroid Build Coastguard Worker 
av1_set_butteraugli_rdmult(const AV1_COMP * cpi,MACROBLOCK * x,BLOCK_SIZE bsize,int mi_row,int mi_col,int * rdmult)132*77c1e3ccSAndroid Build Coastguard Worker void av1_set_butteraugli_rdmult(const AV1_COMP *cpi, MACROBLOCK *x,
133*77c1e3ccSAndroid Build Coastguard Worker                                 BLOCK_SIZE bsize, int mi_row, int mi_col,
134*77c1e3ccSAndroid Build Coastguard Worker                                 int *rdmult) {
135*77c1e3ccSAndroid Build Coastguard Worker   assert(cpi->oxcf.tune_cfg.tuning == AOM_TUNE_BUTTERAUGLI);
136*77c1e3ccSAndroid Build Coastguard Worker   if (!cpi->butteraugli_info.recon_set) {
137*77c1e3ccSAndroid Build Coastguard Worker     return;
138*77c1e3ccSAndroid Build Coastguard Worker   }
139*77c1e3ccSAndroid Build Coastguard Worker   const AV1_COMMON *const cm = &cpi->common;
140*77c1e3ccSAndroid Build Coastguard Worker 
141*77c1e3ccSAndroid Build Coastguard Worker   const int num_mi_w = mi_size_wide[butteraugli_rdo_bsize];
142*77c1e3ccSAndroid Build Coastguard Worker   const int num_mi_h = mi_size_high[butteraugli_rdo_bsize];
143*77c1e3ccSAndroid Build Coastguard Worker   const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
144*77c1e3ccSAndroid Build Coastguard Worker   const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
145*77c1e3ccSAndroid Build Coastguard Worker   const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
146*77c1e3ccSAndroid Build Coastguard Worker   const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
147*77c1e3ccSAndroid Build Coastguard Worker   double num_of_mi = 0.0;
148*77c1e3ccSAndroid Build Coastguard Worker   double geom_mean_of_scale = 0.0;
149*77c1e3ccSAndroid Build Coastguard Worker 
150*77c1e3ccSAndroid Build Coastguard Worker   for (int row = mi_row / num_mi_w;
151*77c1e3ccSAndroid Build Coastguard Worker        row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
152*77c1e3ccSAndroid Build Coastguard Worker     for (int col = mi_col / num_mi_h;
153*77c1e3ccSAndroid Build Coastguard Worker          col < num_cols && col < mi_col / num_mi_h + num_bcols; ++col) {
154*77c1e3ccSAndroid Build Coastguard Worker       const int index = row * num_cols + col;
155*77c1e3ccSAndroid Build Coastguard Worker       geom_mean_of_scale +=
156*77c1e3ccSAndroid Build Coastguard Worker           log(cpi->butteraugli_info.rdmult_scaling_factors[index]);
157*77c1e3ccSAndroid Build Coastguard Worker       num_of_mi += 1.0;
158*77c1e3ccSAndroid Build Coastguard Worker     }
159*77c1e3ccSAndroid Build Coastguard Worker   }
160*77c1e3ccSAndroid Build Coastguard Worker   geom_mean_of_scale = exp(geom_mean_of_scale / num_of_mi);
161*77c1e3ccSAndroid Build Coastguard Worker 
162*77c1e3ccSAndroid Build Coastguard Worker   *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
163*77c1e3ccSAndroid Build Coastguard Worker   *rdmult = AOMMAX(*rdmult, 0);
164*77c1e3ccSAndroid Build Coastguard Worker   av1_set_error_per_bit(&x->errorperbit, *rdmult);
165*77c1e3ccSAndroid Build Coastguard Worker }
166*77c1e3ccSAndroid Build Coastguard Worker 
copy_plane(const uint8_t * src,int src_stride,uint8_t * dst,int dst_stride,int w,int h)167*77c1e3ccSAndroid Build Coastguard Worker static void copy_plane(const uint8_t *src, int src_stride, uint8_t *dst,
168*77c1e3ccSAndroid Build Coastguard Worker                        int dst_stride, int w, int h) {
169*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < h; row++) {
170*77c1e3ccSAndroid Build Coastguard Worker     memcpy(dst, src, w);
171*77c1e3ccSAndroid Build Coastguard Worker     src += src_stride;
172*77c1e3ccSAndroid Build Coastguard Worker     dst += dst_stride;
173*77c1e3ccSAndroid Build Coastguard Worker   }
174*77c1e3ccSAndroid Build Coastguard Worker }
175*77c1e3ccSAndroid Build Coastguard Worker 
copy_img(const YV12_BUFFER_CONFIG * src,YV12_BUFFER_CONFIG * dst,int width,int height)176*77c1e3ccSAndroid Build Coastguard Worker static void copy_img(const YV12_BUFFER_CONFIG *src, YV12_BUFFER_CONFIG *dst,
177*77c1e3ccSAndroid Build Coastguard Worker                      int width, int height) {
178*77c1e3ccSAndroid Build Coastguard Worker   copy_plane(src->y_buffer, src->y_stride, dst->y_buffer, dst->y_stride, width,
179*77c1e3ccSAndroid Build Coastguard Worker              height);
180*77c1e3ccSAndroid Build Coastguard Worker   const int width_uv = (width + src->subsampling_x) >> src->subsampling_x;
181*77c1e3ccSAndroid Build Coastguard Worker   const int height_uv = (height + src->subsampling_y) >> src->subsampling_y;
182*77c1e3ccSAndroid Build Coastguard Worker   copy_plane(src->u_buffer, src->uv_stride, dst->u_buffer, dst->uv_stride,
183*77c1e3ccSAndroid Build Coastguard Worker              width_uv, height_uv);
184*77c1e3ccSAndroid Build Coastguard Worker   copy_plane(src->v_buffer, src->uv_stride, dst->v_buffer, dst->uv_stride,
185*77c1e3ccSAndroid Build Coastguard Worker              width_uv, height_uv);
186*77c1e3ccSAndroid Build Coastguard Worker }
187*77c1e3ccSAndroid Build Coastguard Worker 
zero_plane(uint8_t * dst,int dst_stride,int h)188*77c1e3ccSAndroid Build Coastguard Worker static void zero_plane(uint8_t *dst, int dst_stride, int h) {
189*77c1e3ccSAndroid Build Coastguard Worker   for (int row = 0; row < h; row++) {
190*77c1e3ccSAndroid Build Coastguard Worker     memset(dst, 0, dst_stride);
191*77c1e3ccSAndroid Build Coastguard Worker     dst += dst_stride;
192*77c1e3ccSAndroid Build Coastguard Worker   }
193*77c1e3ccSAndroid Build Coastguard Worker }
194*77c1e3ccSAndroid Build Coastguard Worker 
zero_img(YV12_BUFFER_CONFIG * dst)195*77c1e3ccSAndroid Build Coastguard Worker static void zero_img(YV12_BUFFER_CONFIG *dst) {
196*77c1e3ccSAndroid Build Coastguard Worker   zero_plane(dst->y_buffer, dst->y_stride, dst->y_height);
197*77c1e3ccSAndroid Build Coastguard Worker   zero_plane(dst->u_buffer, dst->uv_stride, dst->uv_height);
198*77c1e3ccSAndroid Build Coastguard Worker   zero_plane(dst->v_buffer, dst->uv_stride, dst->uv_height);
199*77c1e3ccSAndroid Build Coastguard Worker }
200*77c1e3ccSAndroid Build Coastguard Worker 
av1_setup_butteraugli_source(AV1_COMP * cpi)201*77c1e3ccSAndroid Build Coastguard Worker void av1_setup_butteraugli_source(AV1_COMP *cpi) {
202*77c1e3ccSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *const dst = &cpi->butteraugli_info.source;
203*77c1e3ccSAndroid Build Coastguard Worker   AV1_COMMON *const cm = &cpi->common;
204*77c1e3ccSAndroid Build Coastguard Worker   const int width = cpi->source->y_crop_width;
205*77c1e3ccSAndroid Build Coastguard Worker   const int height = cpi->source->y_crop_height;
206*77c1e3ccSAndroid Build Coastguard Worker   const int bit_depth = cpi->td.mb.e_mbd.bd;
207*77c1e3ccSAndroid Build Coastguard Worker   const int ss_x = cpi->source->subsampling_x;
208*77c1e3ccSAndroid Build Coastguard Worker   const int ss_y = cpi->source->subsampling_y;
209*77c1e3ccSAndroid Build Coastguard Worker   if (dst->buffer_alloc_sz == 0) {
210*77c1e3ccSAndroid Build Coastguard Worker     aom_alloc_frame_buffer(
211*77c1e3ccSAndroid Build Coastguard Worker         dst, width, height, ss_x, ss_y, cm->seq_params->use_highbitdepth,
212*77c1e3ccSAndroid Build Coastguard Worker         cpi->oxcf.border_in_pixels, cm->features.byte_alignment, false, 0);
213*77c1e3ccSAndroid Build Coastguard Worker   }
214*77c1e3ccSAndroid Build Coastguard Worker   av1_copy_and_extend_frame(cpi->source, dst);
215*77c1e3ccSAndroid Build Coastguard Worker 
216*77c1e3ccSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *const resized_dst = &cpi->butteraugli_info.resized_source;
217*77c1e3ccSAndroid Build Coastguard Worker   if (resized_dst->buffer_alloc_sz == 0) {
218*77c1e3ccSAndroid Build Coastguard Worker     aom_alloc_frame_buffer(
219*77c1e3ccSAndroid Build Coastguard Worker         resized_dst, width / resize_factor, height / resize_factor, ss_x, ss_y,
220*77c1e3ccSAndroid Build Coastguard Worker         cm->seq_params->use_highbitdepth, cpi->oxcf.border_in_pixels,
221*77c1e3ccSAndroid Build Coastguard Worker         cm->features.byte_alignment, false, 0);
222*77c1e3ccSAndroid Build Coastguard Worker   }
223*77c1e3ccSAndroid Build Coastguard Worker   if (!av1_resize_and_extend_frame_nonnormative(
224*77c1e3ccSAndroid Build Coastguard Worker           cpi->source, resized_dst, bit_depth, av1_num_planes(cm))) {
225*77c1e3ccSAndroid Build Coastguard Worker     aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
226*77c1e3ccSAndroid Build Coastguard Worker                        "Error allocating buffers during resize");
227*77c1e3ccSAndroid Build Coastguard Worker   }
228*77c1e3ccSAndroid Build Coastguard Worker 
229*77c1e3ccSAndroid Build Coastguard Worker   zero_img(cpi->source);
230*77c1e3ccSAndroid Build Coastguard Worker   copy_img(resized_dst, cpi->source, width / resize_factor,
231*77c1e3ccSAndroid Build Coastguard Worker            height / resize_factor);
232*77c1e3ccSAndroid Build Coastguard Worker }
233*77c1e3ccSAndroid Build Coastguard Worker 
av1_setup_butteraugli_rdmult_and_restore_source(AV1_COMP * cpi,double K)234*77c1e3ccSAndroid Build Coastguard Worker void av1_setup_butteraugli_rdmult_and_restore_source(AV1_COMP *cpi, double K) {
235*77c1e3ccSAndroid Build Coastguard Worker   av1_copy_and_extend_frame(&cpi->butteraugli_info.source, cpi->source);
236*77c1e3ccSAndroid Build Coastguard Worker   AV1_COMMON *const cm = &cpi->common;
237*77c1e3ccSAndroid Build Coastguard Worker   const int width = cpi->source->y_crop_width;
238*77c1e3ccSAndroid Build Coastguard Worker   const int height = cpi->source->y_crop_height;
239*77c1e3ccSAndroid Build Coastguard Worker   const int ss_x = cpi->source->subsampling_x;
240*77c1e3ccSAndroid Build Coastguard Worker   const int ss_y = cpi->source->subsampling_y;
241*77c1e3ccSAndroid Build Coastguard Worker 
242*77c1e3ccSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG resized_recon;
243*77c1e3ccSAndroid Build Coastguard Worker   memset(&resized_recon, 0, sizeof(resized_recon));
244*77c1e3ccSAndroid Build Coastguard Worker   aom_alloc_frame_buffer(
245*77c1e3ccSAndroid Build Coastguard Worker       &resized_recon, width / resize_factor, height / resize_factor, ss_x, ss_y,
246*77c1e3ccSAndroid Build Coastguard Worker       cm->seq_params->use_highbitdepth, cpi->oxcf.border_in_pixels,
247*77c1e3ccSAndroid Build Coastguard Worker       cm->features.byte_alignment, false, 0);
248*77c1e3ccSAndroid Build Coastguard Worker   copy_img(&cpi->common.cur_frame->buf, &resized_recon, width / resize_factor,
249*77c1e3ccSAndroid Build Coastguard Worker            height / resize_factor);
250*77c1e3ccSAndroid Build Coastguard Worker 
251*77c1e3ccSAndroid Build Coastguard Worker   set_mb_butteraugli_rdmult_scaling(cpi, &cpi->butteraugli_info.resized_source,
252*77c1e3ccSAndroid Build Coastguard Worker                                     &resized_recon, K);
253*77c1e3ccSAndroid Build Coastguard Worker   cpi->butteraugli_info.recon_set = true;
254*77c1e3ccSAndroid Build Coastguard Worker   aom_free_frame_buffer(&resized_recon);
255*77c1e3ccSAndroid Build Coastguard Worker }
256*77c1e3ccSAndroid Build Coastguard Worker 
av1_setup_butteraugli_rdmult(AV1_COMP * cpi)257*77c1e3ccSAndroid Build Coastguard Worker void av1_setup_butteraugli_rdmult(AV1_COMP *cpi) {
258*77c1e3ccSAndroid Build Coastguard Worker   AV1_COMMON *const cm = &cpi->common;
259*77c1e3ccSAndroid Build Coastguard Worker   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
260*77c1e3ccSAndroid Build Coastguard Worker   const QuantizationCfg *const q_cfg = &oxcf->q_cfg;
261*77c1e3ccSAndroid Build Coastguard Worker   const int q_index = 96;
262*77c1e3ccSAndroid Build Coastguard Worker 
263*77c1e3ccSAndroid Build Coastguard Worker   // Setup necessary params for encoding, including frame source, etc.
264*77c1e3ccSAndroid Build Coastguard Worker   if (cm->current_frame.frame_type == KEY_FRAME) copy_frame_prob_info(cpi);
265*77c1e3ccSAndroid Build Coastguard Worker   av1_set_frame_size(cpi, cm->superres_upscaled_width,
266*77c1e3ccSAndroid Build Coastguard Worker                      cm->superres_upscaled_height);
267*77c1e3ccSAndroid Build Coastguard Worker 
268*77c1e3ccSAndroid Build Coastguard Worker   cpi->source = av1_realloc_and_scale_if_required(
269*77c1e3ccSAndroid Build Coastguard Worker       cm, cpi->unscaled_source, &cpi->scaled_source, cm->features.interp_filter,
270*77c1e3ccSAndroid Build Coastguard Worker       0, false, false, cpi->oxcf.border_in_pixels, cpi->alloc_pyramid);
271*77c1e3ccSAndroid Build Coastguard Worker   if (cpi->unscaled_last_source != NULL) {
272*77c1e3ccSAndroid Build Coastguard Worker     cpi->last_source = av1_realloc_and_scale_if_required(
273*77c1e3ccSAndroid Build Coastguard Worker         cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
274*77c1e3ccSAndroid Build Coastguard Worker         cm->features.interp_filter, 0, false, false, cpi->oxcf.border_in_pixels,
275*77c1e3ccSAndroid Build Coastguard Worker         cpi->alloc_pyramid);
276*77c1e3ccSAndroid Build Coastguard Worker   }
277*77c1e3ccSAndroid Build Coastguard Worker 
278*77c1e3ccSAndroid Build Coastguard Worker   av1_setup_butteraugli_source(cpi);
279*77c1e3ccSAndroid Build Coastguard Worker   av1_setup_frame(cpi);
280*77c1e3ccSAndroid Build Coastguard Worker 
281*77c1e3ccSAndroid Build Coastguard Worker   if (cm->seg.enabled) {
282*77c1e3ccSAndroid Build Coastguard Worker     if (!cm->seg.update_data && cm->prev_frame) {
283*77c1e3ccSAndroid Build Coastguard Worker       segfeatures_copy(&cm->seg, &cm->prev_frame->seg);
284*77c1e3ccSAndroid Build Coastguard Worker       cm->seg.enabled = cm->prev_frame->seg.enabled;
285*77c1e3ccSAndroid Build Coastguard Worker     } else {
286*77c1e3ccSAndroid Build Coastguard Worker       av1_calculate_segdata(&cm->seg);
287*77c1e3ccSAndroid Build Coastguard Worker     }
288*77c1e3ccSAndroid Build Coastguard Worker   } else {
289*77c1e3ccSAndroid Build Coastguard Worker     memset(&cm->seg, 0, sizeof(cm->seg));
290*77c1e3ccSAndroid Build Coastguard Worker   }
291*77c1e3ccSAndroid Build Coastguard Worker   segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
292*77c1e3ccSAndroid Build Coastguard Worker   cm->cur_frame->seg.enabled = cm->seg.enabled;
293*77c1e3ccSAndroid Build Coastguard Worker 
294*77c1e3ccSAndroid Build Coastguard Worker   const PARTITION_SEARCH_TYPE partition_search_type =
295*77c1e3ccSAndroid Build Coastguard Worker       cpi->sf.part_sf.partition_search_type;
296*77c1e3ccSAndroid Build Coastguard Worker   const BLOCK_SIZE fixed_partition_size = cpi->sf.part_sf.fixed_partition_size;
297*77c1e3ccSAndroid Build Coastguard Worker   // Enable a quicker pass by uncommenting the following lines:
298*77c1e3ccSAndroid Build Coastguard Worker   // cpi->sf.part_sf.partition_search_type = FIXED_PARTITION;
299*77c1e3ccSAndroid Build Coastguard Worker   // cpi->sf.part_sf.fixed_partition_size = BLOCK_32X32;
300*77c1e3ccSAndroid Build Coastguard Worker 
301*77c1e3ccSAndroid Build Coastguard Worker   av1_set_quantizer(cm, q_cfg->qm_minlevel, q_cfg->qm_maxlevel, q_index,
302*77c1e3ccSAndroid Build Coastguard Worker                     q_cfg->enable_chroma_deltaq, q_cfg->enable_hdr_deltaq);
303*77c1e3ccSAndroid Build Coastguard Worker   av1_set_speed_features_qindex_dependent(cpi, oxcf->speed);
304*77c1e3ccSAndroid Build Coastguard Worker   av1_init_quantizer(&cpi->enc_quant_dequant_params, &cm->quant_params,
305*77c1e3ccSAndroid Build Coastguard Worker                      cm->seq_params->bit_depth);
306*77c1e3ccSAndroid Build Coastguard Worker 
307*77c1e3ccSAndroid Build Coastguard Worker   av1_set_variance_partition_thresholds(cpi, q_index, 0);
308*77c1e3ccSAndroid Build Coastguard Worker   av1_encode_frame(cpi);
309*77c1e3ccSAndroid Build Coastguard Worker 
310*77c1e3ccSAndroid Build Coastguard Worker   av1_setup_butteraugli_rdmult_and_restore_source(cpi, 0.3);
311*77c1e3ccSAndroid Build Coastguard Worker   cpi->sf.part_sf.partition_search_type = partition_search_type;
312*77c1e3ccSAndroid Build Coastguard Worker   cpi->sf.part_sf.fixed_partition_size = fixed_partition_size;
313*77c1e3ccSAndroid Build Coastguard Worker }
314