xref: /aosp_15_r20/external/libvpx/vp9/encoder/vp9_encoder.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <limits.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <stdint.h>
14*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
15*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
16*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
17*fb1b10abSAndroid Build Coastguard Worker 
18*fb1b10abSAndroid Build Coastguard Worker #include "./vp9_rtcd.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_scale_rtcd.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_ext_ratectrl.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/psnr.h"
25*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_filter.h"
27*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
28*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/ssim.h"
29*fb1b10abSAndroid Build Coastguard Worker #endif
30*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
31*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
32*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/system_state.h"
33*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/vpx_once.h"
34*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/vpx_timer.h"
35*fb1b10abSAndroid Build Coastguard Worker #include "vpx_util/vpx_pthread.h"
36*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
37*fb1b10abSAndroid Build Coastguard Worker #include "vpx_util/vpx_debug_util.h"
38*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
39*fb1b10abSAndroid Build Coastguard Worker 
40*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_alloccommon.h"
41*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_blockd.h"
42*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_enums.h"
43*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_filter.h"
44*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_idct.h"
45*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC
46*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_postproc.h"
47*fb1b10abSAndroid Build Coastguard Worker #endif
48*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconinter.h"
49*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconintra.h"
50*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_scale.h"
51*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_tile_common.h"
52*fb1b10abSAndroid Build Coastguard Worker 
53*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
54*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_alt_ref_aq.h"
55*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_aq_360.h"
56*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_aq_complexity.h"
57*fb1b10abSAndroid Build Coastguard Worker #endif
58*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_aq_cyclicrefresh.h"
59*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
60*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_aq_variance.h"
61*fb1b10abSAndroid Build Coastguard Worker #endif
62*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_bitstream.h"
63*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
64*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_blockiness.h"
65*fb1b10abSAndroid Build Coastguard Worker #endif
66*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_context_tree.h"
67*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodeframe.h"
68*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemb.h"
69*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemv.h"
70*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encoder.h"
71*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_ethread.h"
72*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_extend.h"
73*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_firstpass.h"
74*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_mbgraph.h"
75*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_NON_GREEDY_MV
76*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_mcomp.h"
77*fb1b10abSAndroid Build Coastguard Worker #endif
78*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_multi_thread.h"
79*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_noise_estimate.h"
80*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_picklpf.h"
81*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_ratectrl.h"
82*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_rd.h"
83*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_resize.h"
84*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_segmentation.h"
85*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_skin_detection.h"
86*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_speed_features.h"
87*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_svc_layercontext.h"
88*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_temporal_filter.h"
89*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_tpl_model.h"
90*fb1b10abSAndroid Build Coastguard Worker #include "vp9/vp9_cx_iface.h"
91*fb1b10abSAndroid Build Coastguard Worker 
92*fb1b10abSAndroid Build Coastguard Worker #define AM_SEGMENT_ID_INACTIVE 7
93*fb1b10abSAndroid Build Coastguard Worker #define AM_SEGMENT_ID_ACTIVE 0
94*fb1b10abSAndroid Build Coastguard Worker 
95*fb1b10abSAndroid Build Coastguard Worker // Whether to use high precision mv for altref computation.
96*fb1b10abSAndroid Build Coastguard Worker #define ALTREF_HIGH_PRECISION_MV 1
97*fb1b10abSAndroid Build Coastguard Worker 
98*fb1b10abSAndroid Build Coastguard Worker // Q threshold for high precision mv. Choose a very high value for now so that
99*fb1b10abSAndroid Build Coastguard Worker // HIGH_PRECISION is always chosen.
100*fb1b10abSAndroid Build Coastguard Worker #define HIGH_PRECISION_MV_QTHRESH 200
101*fb1b10abSAndroid Build Coastguard Worker 
102*fb1b10abSAndroid Build Coastguard Worker #define FRAME_SIZE_FACTOR 128  // empirical params for context model threshold
103*fb1b10abSAndroid Build Coastguard Worker #define FRAME_RATE_FACTOR 8
104*fb1b10abSAndroid Build Coastguard Worker 
105*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_DENOISED
106*fb1b10abSAndroid Build Coastguard Worker FILE *yuv_denoised_file = NULL;
107*fb1b10abSAndroid Build Coastguard Worker #endif
108*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SKINMAP
109*fb1b10abSAndroid Build Coastguard Worker static FILE *yuv_skinmap_file = NULL;
110*fb1b10abSAndroid Build Coastguard Worker #endif
111*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_REC
112*fb1b10abSAndroid Build Coastguard Worker FILE *yuv_rec_file;
113*fb1b10abSAndroid Build Coastguard Worker #endif
114*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SVC_SRC
115*fb1b10abSAndroid Build Coastguard Worker FILE *yuv_svc_src[3] = { NULL, NULL, NULL };
116*fb1b10abSAndroid Build Coastguard Worker #endif
117*fb1b10abSAndroid Build Coastguard Worker 
118*fb1b10abSAndroid Build Coastguard Worker #if 0
119*fb1b10abSAndroid Build Coastguard Worker FILE *framepsnr;
120*fb1b10abSAndroid Build Coastguard Worker FILE *kf_list;
121*fb1b10abSAndroid Build Coastguard Worker FILE *keyfile;
122*fb1b10abSAndroid Build Coastguard Worker #endif
123*fb1b10abSAndroid Build Coastguard Worker 
124*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
125*fb1b10abSAndroid Build Coastguard Worker // Test condition for spatial denoise of source.
is_spatial_denoise_enabled(VP9_COMP * cpi)126*fb1b10abSAndroid Build Coastguard Worker static int is_spatial_denoise_enabled(VP9_COMP *cpi) {
127*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
128*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
129*fb1b10abSAndroid Build Coastguard Worker 
130*fb1b10abSAndroid Build Coastguard Worker   return (oxcf->pass != 1) && !is_lossless_requested(&cpi->oxcf) &&
131*fb1b10abSAndroid Build Coastguard Worker          frame_is_intra_only(cm);
132*fb1b10abSAndroid Build Coastguard Worker }
133*fb1b10abSAndroid Build Coastguard Worker #endif
134*fb1b10abSAndroid Build Coastguard Worker 
135*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
136*fb1b10abSAndroid Build Coastguard Worker // compute adaptive threshold for skip recoding
compute_context_model_thresh(const VP9_COMP * const cpi)137*fb1b10abSAndroid Build Coastguard Worker static int compute_context_model_thresh(const VP9_COMP *const cpi) {
138*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
139*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
140*fb1b10abSAndroid Build Coastguard Worker   const int frame_size = (cm->width * cm->height) >> 10;
141*fb1b10abSAndroid Build Coastguard Worker   const int bitrate = (int)(oxcf->target_bandwidth >> 10);
142*fb1b10abSAndroid Build Coastguard Worker   const int qindex_factor = cm->base_qindex + (MAXQ >> 1);
143*fb1b10abSAndroid Build Coastguard Worker 
144*fb1b10abSAndroid Build Coastguard Worker   // This equation makes the threshold adaptive to frame size.
145*fb1b10abSAndroid Build Coastguard Worker   // Coding gain obtained by recoding comes from alternate frames of large
146*fb1b10abSAndroid Build Coastguard Worker   // content change. We skip recoding if the difference of previous and current
147*fb1b10abSAndroid Build Coastguard Worker   // frame context probability model is less than a certain threshold.
148*fb1b10abSAndroid Build Coastguard Worker   // The first component is the most critical part to guarantee adaptivity.
149*fb1b10abSAndroid Build Coastguard Worker   // Other parameters are estimated based on normal setting of hd resolution
150*fb1b10abSAndroid Build Coastguard Worker   // parameters. e.g. frame_size = 1920x1080, bitrate = 8000, qindex_factor < 50
151*fb1b10abSAndroid Build Coastguard Worker   const int thresh =
152*fb1b10abSAndroid Build Coastguard Worker       ((FRAME_SIZE_FACTOR * frame_size - FRAME_RATE_FACTOR * bitrate) *
153*fb1b10abSAndroid Build Coastguard Worker        qindex_factor) >>
154*fb1b10abSAndroid Build Coastguard Worker       9;
155*fb1b10abSAndroid Build Coastguard Worker 
156*fb1b10abSAndroid Build Coastguard Worker   return thresh;
157*fb1b10abSAndroid Build Coastguard Worker }
158*fb1b10abSAndroid Build Coastguard Worker 
159*fb1b10abSAndroid Build Coastguard Worker // compute the total cost difference between current
160*fb1b10abSAndroid Build Coastguard Worker // and previous frame context prob model.
compute_context_model_diff(const VP9_COMMON * const cm)161*fb1b10abSAndroid Build Coastguard Worker static int compute_context_model_diff(const VP9_COMMON *const cm) {
162*fb1b10abSAndroid Build Coastguard Worker   const FRAME_CONTEXT *const pre_fc =
163*fb1b10abSAndroid Build Coastguard Worker       &cm->frame_contexts[cm->frame_context_idx];
164*fb1b10abSAndroid Build Coastguard Worker   const FRAME_CONTEXT *const cur_fc = cm->fc;
165*fb1b10abSAndroid Build Coastguard Worker   const FRAME_COUNTS *counts = &cm->counts;
166*fb1b10abSAndroid Build Coastguard Worker   vpx_prob pre_last_prob, cur_last_prob;
167*fb1b10abSAndroid Build Coastguard Worker   int diff = 0;
168*fb1b10abSAndroid Build Coastguard Worker   int i, j, k, l, m, n;
169*fb1b10abSAndroid Build Coastguard Worker 
170*fb1b10abSAndroid Build Coastguard Worker   // y_mode_prob
171*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) {
172*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < INTRA_MODES - 1; ++j) {
173*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->y_mode[i][j] *
174*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->y_mode_prob[i][j] - cur_fc->y_mode_prob[i][j]);
175*fb1b10abSAndroid Build Coastguard Worker     }
176*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->y_mode_prob[i][INTRA_MODES - 2];
177*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->y_mode_prob[i][INTRA_MODES - 2];
178*fb1b10abSAndroid Build Coastguard Worker 
179*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->y_mode[i][INTRA_MODES - 1] *
180*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
181*fb1b10abSAndroid Build Coastguard Worker   }
182*fb1b10abSAndroid Build Coastguard Worker 
183*fb1b10abSAndroid Build Coastguard Worker   // uv_mode_prob
184*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < INTRA_MODES; ++i) {
185*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < INTRA_MODES - 1; ++j) {
186*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->uv_mode[i][j] *
187*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->uv_mode_prob[i][j] - cur_fc->uv_mode_prob[i][j]);
188*fb1b10abSAndroid Build Coastguard Worker     }
189*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->uv_mode_prob[i][INTRA_MODES - 2];
190*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->uv_mode_prob[i][INTRA_MODES - 2];
191*fb1b10abSAndroid Build Coastguard Worker 
192*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->uv_mode[i][INTRA_MODES - 1] *
193*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
194*fb1b10abSAndroid Build Coastguard Worker   }
195*fb1b10abSAndroid Build Coastguard Worker 
196*fb1b10abSAndroid Build Coastguard Worker   // partition_prob
197*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < PARTITION_CONTEXTS; ++i) {
198*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < PARTITION_TYPES - 1; ++j) {
199*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->partition[i][j] *
200*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->partition_prob[i][j] - cur_fc->partition_prob[i][j]);
201*fb1b10abSAndroid Build Coastguard Worker     }
202*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->partition_prob[i][PARTITION_TYPES - 2];
203*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->partition_prob[i][PARTITION_TYPES - 2];
204*fb1b10abSAndroid Build Coastguard Worker 
205*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->partition[i][PARTITION_TYPES - 1] *
206*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
207*fb1b10abSAndroid Build Coastguard Worker   }
208*fb1b10abSAndroid Build Coastguard Worker 
209*fb1b10abSAndroid Build Coastguard Worker   // coef_probs
210*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < TX_SIZES; ++i) {
211*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < PLANE_TYPES; ++j) {
212*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; k < REF_TYPES; ++k) {
213*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; l < COEF_BANDS; ++l) {
214*fb1b10abSAndroid Build Coastguard Worker           for (m = 0; m < BAND_COEFF_CONTEXTS(l); ++m) {
215*fb1b10abSAndroid Build Coastguard Worker             for (n = 0; n < UNCONSTRAINED_NODES; ++n) {
216*fb1b10abSAndroid Build Coastguard Worker               diff += (int)counts->coef[i][j][k][l][m][n] *
217*fb1b10abSAndroid Build Coastguard Worker                       (pre_fc->coef_probs[i][j][k][l][m][n] -
218*fb1b10abSAndroid Build Coastguard Worker                        cur_fc->coef_probs[i][j][k][l][m][n]);
219*fb1b10abSAndroid Build Coastguard Worker             }
220*fb1b10abSAndroid Build Coastguard Worker 
221*fb1b10abSAndroid Build Coastguard Worker             pre_last_prob =
222*fb1b10abSAndroid Build Coastguard Worker                 MAX_PROB -
223*fb1b10abSAndroid Build Coastguard Worker                 pre_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1];
224*fb1b10abSAndroid Build Coastguard Worker             cur_last_prob =
225*fb1b10abSAndroid Build Coastguard Worker                 MAX_PROB -
226*fb1b10abSAndroid Build Coastguard Worker                 cur_fc->coef_probs[i][j][k][l][m][UNCONSTRAINED_NODES - 1];
227*fb1b10abSAndroid Build Coastguard Worker 
228*fb1b10abSAndroid Build Coastguard Worker             diff += (int)counts->coef[i][j][k][l][m][UNCONSTRAINED_NODES] *
229*fb1b10abSAndroid Build Coastguard Worker                     (pre_last_prob - cur_last_prob);
230*fb1b10abSAndroid Build Coastguard Worker           }
231*fb1b10abSAndroid Build Coastguard Worker         }
232*fb1b10abSAndroid Build Coastguard Worker       }
233*fb1b10abSAndroid Build Coastguard Worker     }
234*fb1b10abSAndroid Build Coastguard Worker   }
235*fb1b10abSAndroid Build Coastguard Worker 
236*fb1b10abSAndroid Build Coastguard Worker   // switchable_interp_prob
237*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) {
238*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < SWITCHABLE_FILTERS - 1; ++j) {
239*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->switchable_interp[i][j] *
240*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->switchable_interp_prob[i][j] -
241*fb1b10abSAndroid Build Coastguard Worker                cur_fc->switchable_interp_prob[i][j]);
242*fb1b10abSAndroid Build Coastguard Worker     }
243*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob =
244*fb1b10abSAndroid Build Coastguard Worker         MAX_PROB - pre_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2];
245*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob =
246*fb1b10abSAndroid Build Coastguard Worker         MAX_PROB - cur_fc->switchable_interp_prob[i][SWITCHABLE_FILTERS - 2];
247*fb1b10abSAndroid Build Coastguard Worker 
248*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->switchable_interp[i][SWITCHABLE_FILTERS - 1] *
249*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
250*fb1b10abSAndroid Build Coastguard Worker   }
251*fb1b10abSAndroid Build Coastguard Worker 
252*fb1b10abSAndroid Build Coastguard Worker   // inter_mode_probs
253*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
254*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < INTER_MODES - 1; ++j) {
255*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->inter_mode[i][j] *
256*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->inter_mode_probs[i][j] - cur_fc->inter_mode_probs[i][j]);
257*fb1b10abSAndroid Build Coastguard Worker     }
258*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->inter_mode_probs[i][INTER_MODES - 2];
259*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->inter_mode_probs[i][INTER_MODES - 2];
260*fb1b10abSAndroid Build Coastguard Worker 
261*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->inter_mode[i][INTER_MODES - 1] *
262*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
263*fb1b10abSAndroid Build Coastguard Worker   }
264*fb1b10abSAndroid Build Coastguard Worker 
265*fb1b10abSAndroid Build Coastguard Worker   // intra_inter_prob
266*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) {
267*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->intra_inter[i][0] *
268*fb1b10abSAndroid Build Coastguard Worker             (pre_fc->intra_inter_prob[i] - cur_fc->intra_inter_prob[i]);
269*fb1b10abSAndroid Build Coastguard Worker 
270*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->intra_inter_prob[i];
271*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->intra_inter_prob[i];
272*fb1b10abSAndroid Build Coastguard Worker 
273*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->intra_inter[i][1] * (pre_last_prob - cur_last_prob);
274*fb1b10abSAndroid Build Coastguard Worker   }
275*fb1b10abSAndroid Build Coastguard Worker 
276*fb1b10abSAndroid Build Coastguard Worker   // comp_inter_prob
277*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < COMP_INTER_CONTEXTS; ++i) {
278*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->comp_inter[i][0] *
279*fb1b10abSAndroid Build Coastguard Worker             (pre_fc->comp_inter_prob[i] - cur_fc->comp_inter_prob[i]);
280*fb1b10abSAndroid Build Coastguard Worker 
281*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->comp_inter_prob[i];
282*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->comp_inter_prob[i];
283*fb1b10abSAndroid Build Coastguard Worker 
284*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->comp_inter[i][1] * (pre_last_prob - cur_last_prob);
285*fb1b10abSAndroid Build Coastguard Worker   }
286*fb1b10abSAndroid Build Coastguard Worker 
287*fb1b10abSAndroid Build Coastguard Worker   // single_ref_prob
288*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < REF_CONTEXTS; ++i) {
289*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < 2; ++j) {
290*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->single_ref[i][j][0] *
291*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->single_ref_prob[i][j] - cur_fc->single_ref_prob[i][j]);
292*fb1b10abSAndroid Build Coastguard Worker 
293*fb1b10abSAndroid Build Coastguard Worker       pre_last_prob = MAX_PROB - pre_fc->single_ref_prob[i][j];
294*fb1b10abSAndroid Build Coastguard Worker       cur_last_prob = MAX_PROB - cur_fc->single_ref_prob[i][j];
295*fb1b10abSAndroid Build Coastguard Worker 
296*fb1b10abSAndroid Build Coastguard Worker       diff +=
297*fb1b10abSAndroid Build Coastguard Worker           (int)counts->single_ref[i][j][1] * (pre_last_prob - cur_last_prob);
298*fb1b10abSAndroid Build Coastguard Worker     }
299*fb1b10abSAndroid Build Coastguard Worker   }
300*fb1b10abSAndroid Build Coastguard Worker 
301*fb1b10abSAndroid Build Coastguard Worker   // comp_ref_prob
302*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < REF_CONTEXTS; ++i) {
303*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->comp_ref[i][0] *
304*fb1b10abSAndroid Build Coastguard Worker             (pre_fc->comp_ref_prob[i] - cur_fc->comp_ref_prob[i]);
305*fb1b10abSAndroid Build Coastguard Worker 
306*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->comp_ref_prob[i];
307*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->comp_ref_prob[i];
308*fb1b10abSAndroid Build Coastguard Worker 
309*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->comp_ref[i][1] * (pre_last_prob - cur_last_prob);
310*fb1b10abSAndroid Build Coastguard Worker   }
311*fb1b10abSAndroid Build Coastguard Worker 
312*fb1b10abSAndroid Build Coastguard Worker   // tx_probs
313*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < TX_SIZE_CONTEXTS; ++i) {
314*fb1b10abSAndroid Build Coastguard Worker     // p32x32
315*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < TX_SIZES - 1; ++j) {
316*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->tx.p32x32[i][j] *
317*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->tx_probs.p32x32[i][j] - cur_fc->tx_probs.p32x32[i][j]);
318*fb1b10abSAndroid Build Coastguard Worker     }
319*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->tx_probs.p32x32[i][TX_SIZES - 2];
320*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->tx_probs.p32x32[i][TX_SIZES - 2];
321*fb1b10abSAndroid Build Coastguard Worker 
322*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->tx.p32x32[i][TX_SIZES - 1] *
323*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
324*fb1b10abSAndroid Build Coastguard Worker 
325*fb1b10abSAndroid Build Coastguard Worker     // p16x16
326*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < TX_SIZES - 2; ++j) {
327*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->tx.p16x16[i][j] *
328*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->tx_probs.p16x16[i][j] - cur_fc->tx_probs.p16x16[i][j]);
329*fb1b10abSAndroid Build Coastguard Worker     }
330*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->tx_probs.p16x16[i][TX_SIZES - 3];
331*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->tx_probs.p16x16[i][TX_SIZES - 3];
332*fb1b10abSAndroid Build Coastguard Worker 
333*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->tx.p16x16[i][TX_SIZES - 2] *
334*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
335*fb1b10abSAndroid Build Coastguard Worker 
336*fb1b10abSAndroid Build Coastguard Worker     // p8x8
337*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < TX_SIZES - 3; ++j) {
338*fb1b10abSAndroid Build Coastguard Worker       diff += (int)counts->tx.p8x8[i][j] *
339*fb1b10abSAndroid Build Coastguard Worker               (pre_fc->tx_probs.p8x8[i][j] - cur_fc->tx_probs.p8x8[i][j]);
340*fb1b10abSAndroid Build Coastguard Worker     }
341*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->tx_probs.p8x8[i][TX_SIZES - 4];
342*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->tx_probs.p8x8[i][TX_SIZES - 4];
343*fb1b10abSAndroid Build Coastguard Worker 
344*fb1b10abSAndroid Build Coastguard Worker     diff +=
345*fb1b10abSAndroid Build Coastguard Worker         (int)counts->tx.p8x8[i][TX_SIZES - 3] * (pre_last_prob - cur_last_prob);
346*fb1b10abSAndroid Build Coastguard Worker   }
347*fb1b10abSAndroid Build Coastguard Worker 
348*fb1b10abSAndroid Build Coastguard Worker   // skip_probs
349*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < SKIP_CONTEXTS; ++i) {
350*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->skip[i][0] *
351*fb1b10abSAndroid Build Coastguard Worker             (pre_fc->skip_probs[i] - cur_fc->skip_probs[i]);
352*fb1b10abSAndroid Build Coastguard Worker 
353*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_fc->skip_probs[i];
354*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_fc->skip_probs[i];
355*fb1b10abSAndroid Build Coastguard Worker 
356*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->skip[i][1] * (pre_last_prob - cur_last_prob);
357*fb1b10abSAndroid Build Coastguard Worker   }
358*fb1b10abSAndroid Build Coastguard Worker 
359*fb1b10abSAndroid Build Coastguard Worker   // mv
360*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MV_JOINTS - 1; ++i) {
361*fb1b10abSAndroid Build Coastguard Worker     diff += (int)counts->mv.joints[i] *
362*fb1b10abSAndroid Build Coastguard Worker             (pre_fc->nmvc.joints[i] - cur_fc->nmvc.joints[i]);
363*fb1b10abSAndroid Build Coastguard Worker   }
364*fb1b10abSAndroid Build Coastguard Worker   pre_last_prob = MAX_PROB - pre_fc->nmvc.joints[MV_JOINTS - 2];
365*fb1b10abSAndroid Build Coastguard Worker   cur_last_prob = MAX_PROB - cur_fc->nmvc.joints[MV_JOINTS - 2];
366*fb1b10abSAndroid Build Coastguard Worker 
367*fb1b10abSAndroid Build Coastguard Worker   diff +=
368*fb1b10abSAndroid Build Coastguard Worker       (int)counts->mv.joints[MV_JOINTS - 1] * (pre_last_prob - cur_last_prob);
369*fb1b10abSAndroid Build Coastguard Worker 
370*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < 2; ++i) {
371*fb1b10abSAndroid Build Coastguard Worker     const nmv_component_counts *nmv_count = &counts->mv.comps[i];
372*fb1b10abSAndroid Build Coastguard Worker     const nmv_component *pre_nmv_prob = &pre_fc->nmvc.comps[i];
373*fb1b10abSAndroid Build Coastguard Worker     const nmv_component *cur_nmv_prob = &cur_fc->nmvc.comps[i];
374*fb1b10abSAndroid Build Coastguard Worker 
375*fb1b10abSAndroid Build Coastguard Worker     // sign
376*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->sign[0] * (pre_nmv_prob->sign - cur_nmv_prob->sign);
377*fb1b10abSAndroid Build Coastguard Worker 
378*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->sign;
379*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->sign;
380*fb1b10abSAndroid Build Coastguard Worker 
381*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->sign[1] * (pre_last_prob - cur_last_prob);
382*fb1b10abSAndroid Build Coastguard Worker 
383*fb1b10abSAndroid Build Coastguard Worker     // classes
384*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < MV_CLASSES - 1; ++j) {
385*fb1b10abSAndroid Build Coastguard Worker       diff += (int)nmv_count->classes[j] *
386*fb1b10abSAndroid Build Coastguard Worker               (pre_nmv_prob->classes[j] - cur_nmv_prob->classes[j]);
387*fb1b10abSAndroid Build Coastguard Worker     }
388*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->classes[MV_CLASSES - 2];
389*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->classes[MV_CLASSES - 2];
390*fb1b10abSAndroid Build Coastguard Worker 
391*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->classes[MV_CLASSES - 1] *
392*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
393*fb1b10abSAndroid Build Coastguard Worker 
394*fb1b10abSAndroid Build Coastguard Worker     // class0
395*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < CLASS0_SIZE - 1; ++j) {
396*fb1b10abSAndroid Build Coastguard Worker       diff += (int)nmv_count->class0[j] *
397*fb1b10abSAndroid Build Coastguard Worker               (pre_nmv_prob->class0[j] - cur_nmv_prob->class0[j]);
398*fb1b10abSAndroid Build Coastguard Worker     }
399*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->class0[CLASS0_SIZE - 2];
400*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->class0[CLASS0_SIZE - 2];
401*fb1b10abSAndroid Build Coastguard Worker 
402*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->class0[CLASS0_SIZE - 1] *
403*fb1b10abSAndroid Build Coastguard Worker             (pre_last_prob - cur_last_prob);
404*fb1b10abSAndroid Build Coastguard Worker 
405*fb1b10abSAndroid Build Coastguard Worker     // bits
406*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < MV_OFFSET_BITS; ++j) {
407*fb1b10abSAndroid Build Coastguard Worker       diff += (int)nmv_count->bits[j][0] *
408*fb1b10abSAndroid Build Coastguard Worker               (pre_nmv_prob->bits[j] - cur_nmv_prob->bits[j]);
409*fb1b10abSAndroid Build Coastguard Worker 
410*fb1b10abSAndroid Build Coastguard Worker       pre_last_prob = MAX_PROB - pre_nmv_prob->bits[j];
411*fb1b10abSAndroid Build Coastguard Worker       cur_last_prob = MAX_PROB - cur_nmv_prob->bits[j];
412*fb1b10abSAndroid Build Coastguard Worker 
413*fb1b10abSAndroid Build Coastguard Worker       diff += (int)nmv_count->bits[j][1] * (pre_last_prob - cur_last_prob);
414*fb1b10abSAndroid Build Coastguard Worker     }
415*fb1b10abSAndroid Build Coastguard Worker 
416*fb1b10abSAndroid Build Coastguard Worker     // class0_fp
417*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < CLASS0_SIZE; ++j) {
418*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; k < MV_FP_SIZE - 1; ++k) {
419*fb1b10abSAndroid Build Coastguard Worker         diff += (int)nmv_count->class0_fp[j][k] *
420*fb1b10abSAndroid Build Coastguard Worker                 (pre_nmv_prob->class0_fp[j][k] - cur_nmv_prob->class0_fp[j][k]);
421*fb1b10abSAndroid Build Coastguard Worker       }
422*fb1b10abSAndroid Build Coastguard Worker       pre_last_prob = MAX_PROB - pre_nmv_prob->class0_fp[j][MV_FP_SIZE - 2];
423*fb1b10abSAndroid Build Coastguard Worker       cur_last_prob = MAX_PROB - cur_nmv_prob->class0_fp[j][MV_FP_SIZE - 2];
424*fb1b10abSAndroid Build Coastguard Worker 
425*fb1b10abSAndroid Build Coastguard Worker       diff += (int)nmv_count->class0_fp[j][MV_FP_SIZE - 1] *
426*fb1b10abSAndroid Build Coastguard Worker               (pre_last_prob - cur_last_prob);
427*fb1b10abSAndroid Build Coastguard Worker     }
428*fb1b10abSAndroid Build Coastguard Worker 
429*fb1b10abSAndroid Build Coastguard Worker     // fp
430*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < MV_FP_SIZE - 1; ++j) {
431*fb1b10abSAndroid Build Coastguard Worker       diff +=
432*fb1b10abSAndroid Build Coastguard Worker           (int)nmv_count->fp[j] * (pre_nmv_prob->fp[j] - cur_nmv_prob->fp[j]);
433*fb1b10abSAndroid Build Coastguard Worker     }
434*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->fp[MV_FP_SIZE - 2];
435*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->fp[MV_FP_SIZE - 2];
436*fb1b10abSAndroid Build Coastguard Worker 
437*fb1b10abSAndroid Build Coastguard Worker     diff +=
438*fb1b10abSAndroid Build Coastguard Worker         (int)nmv_count->fp[MV_FP_SIZE - 1] * (pre_last_prob - cur_last_prob);
439*fb1b10abSAndroid Build Coastguard Worker 
440*fb1b10abSAndroid Build Coastguard Worker     // class0_hp
441*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->class0_hp[0] *
442*fb1b10abSAndroid Build Coastguard Worker             (pre_nmv_prob->class0_hp - cur_nmv_prob->class0_hp);
443*fb1b10abSAndroid Build Coastguard Worker 
444*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->class0_hp;
445*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->class0_hp;
446*fb1b10abSAndroid Build Coastguard Worker 
447*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->class0_hp[1] * (pre_last_prob - cur_last_prob);
448*fb1b10abSAndroid Build Coastguard Worker 
449*fb1b10abSAndroid Build Coastguard Worker     // hp
450*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->hp[0] * (pre_nmv_prob->hp - cur_nmv_prob->hp);
451*fb1b10abSAndroid Build Coastguard Worker 
452*fb1b10abSAndroid Build Coastguard Worker     pre_last_prob = MAX_PROB - pre_nmv_prob->hp;
453*fb1b10abSAndroid Build Coastguard Worker     cur_last_prob = MAX_PROB - cur_nmv_prob->hp;
454*fb1b10abSAndroid Build Coastguard Worker 
455*fb1b10abSAndroid Build Coastguard Worker     diff += (int)nmv_count->hp[1] * (pre_last_prob - cur_last_prob);
456*fb1b10abSAndroid Build Coastguard Worker   }
457*fb1b10abSAndroid Build Coastguard Worker 
458*fb1b10abSAndroid Build Coastguard Worker   return -diff;
459*fb1b10abSAndroid Build Coastguard Worker }
460*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
461*fb1b10abSAndroid Build Coastguard Worker 
462*fb1b10abSAndroid Build Coastguard Worker // Test for whether to calculate metrics for the frame.
is_psnr_calc_enabled(const VP9_COMP * cpi)463*fb1b10abSAndroid Build Coastguard Worker static int is_psnr_calc_enabled(const VP9_COMP *cpi) {
464*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
465*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
466*fb1b10abSAndroid Build Coastguard Worker 
467*fb1b10abSAndroid Build Coastguard Worker   return cpi->b_calculate_psnr && (oxcf->pass != 1) && cm->show_frame;
468*fb1b10abSAndroid Build Coastguard Worker }
469*fb1b10abSAndroid Build Coastguard Worker 
470*fb1b10abSAndroid Build Coastguard Worker /* clang-format off */
471*fb1b10abSAndroid Build Coastguard Worker const Vp9LevelSpec vp9_level_defs[VP9_LEVELS] = {
472*fb1b10abSAndroid Build Coastguard Worker   //         sample rate    size   breadth  bitrate  cpb
473*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_1,   829440,      36864,    512,   200,    400,    2, 1,  4,  8 },
474*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_1_1, 2764800,     73728,    768,   800,    1000,   2, 1,  4,  8 },
475*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_2,   4608000,     122880,   960,   1800,   1500,   2, 1,  4,  8 },
476*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_2_1, 9216000,     245760,   1344,  3600,   2800,   2, 2,  4,  8 },
477*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_3,   20736000,    552960,   2048,  7200,   6000,   2, 4,  4,  8 },
478*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_3_1, 36864000,    983040,   2752,  12000,  10000,  2, 4,  4,  8 },
479*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_4,   83558400,    2228224,  4160,  18000,  16000,  4, 4,  4,  8 },
480*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_4_1, 160432128,   2228224,  4160,  30000,  18000,  4, 4,  5,  6 },
481*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_5,   311951360,   8912896,  8384,  60000,  36000,  6, 8,  6,  4 },
482*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_5_1, 588251136,   8912896,  8384,  120000, 46000,  8, 8,  10, 4 },
483*fb1b10abSAndroid Build Coastguard Worker   // TODO(huisu): update max_cpb_size for level 5_2 ~ 6_2 when
484*fb1b10abSAndroid Build Coastguard Worker   // they are finalized (currently tentative).
485*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_5_2, 1176502272,  8912896,  8384,  180000, 90000,  8, 8,  10, 4 },
486*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_6,   1176502272,  35651584, 16832, 180000, 90000,  8, 16, 10, 4 },
487*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_6_1, 2353004544u, 35651584, 16832, 240000, 180000, 8, 16, 10, 4 },
488*fb1b10abSAndroid Build Coastguard Worker   { LEVEL_6_2, 4706009088u, 35651584, 16832, 480000, 360000, 8, 16, 10, 4 },
489*fb1b10abSAndroid Build Coastguard Worker };
490*fb1b10abSAndroid Build Coastguard Worker /* clang-format on */
491*fb1b10abSAndroid Build Coastguard Worker 
492*fb1b10abSAndroid Build Coastguard Worker static const char *level_fail_messages[TARGET_LEVEL_FAIL_IDS] = {
493*fb1b10abSAndroid Build Coastguard Worker   "The average bit-rate is too high.",
494*fb1b10abSAndroid Build Coastguard Worker   "The picture size is too large.",
495*fb1b10abSAndroid Build Coastguard Worker   "The picture width/height is too large.",
496*fb1b10abSAndroid Build Coastguard Worker   "The luma sample rate is too large.",
497*fb1b10abSAndroid Build Coastguard Worker   "The CPB size is too large.",
498*fb1b10abSAndroid Build Coastguard Worker   "The compression ratio is too small",
499*fb1b10abSAndroid Build Coastguard Worker   "Too many column tiles are used.",
500*fb1b10abSAndroid Build Coastguard Worker   "The alt-ref distance is too small.",
501*fb1b10abSAndroid Build Coastguard Worker   "Too many reference buffers are used."
502*fb1b10abSAndroid Build Coastguard Worker };
503*fb1b10abSAndroid Build Coastguard Worker 
Scale2Ratio(VPX_SCALING_MODE mode,int * hr,int * hs)504*fb1b10abSAndroid Build Coastguard Worker static INLINE void Scale2Ratio(VPX_SCALING_MODE mode, int *hr, int *hs) {
505*fb1b10abSAndroid Build Coastguard Worker   switch (mode) {
506*fb1b10abSAndroid Build Coastguard Worker     case VP8E_NORMAL:
507*fb1b10abSAndroid Build Coastguard Worker       *hr = 1;
508*fb1b10abSAndroid Build Coastguard Worker       *hs = 1;
509*fb1b10abSAndroid Build Coastguard Worker       break;
510*fb1b10abSAndroid Build Coastguard Worker     case VP8E_FOURFIVE:
511*fb1b10abSAndroid Build Coastguard Worker       *hr = 4;
512*fb1b10abSAndroid Build Coastguard Worker       *hs = 5;
513*fb1b10abSAndroid Build Coastguard Worker       break;
514*fb1b10abSAndroid Build Coastguard Worker     case VP8E_THREEFIVE:
515*fb1b10abSAndroid Build Coastguard Worker       *hr = 3;
516*fb1b10abSAndroid Build Coastguard Worker       *hs = 5;
517*fb1b10abSAndroid Build Coastguard Worker       break;
518*fb1b10abSAndroid Build Coastguard Worker     default:
519*fb1b10abSAndroid Build Coastguard Worker       assert(mode == VP8E_ONETWO);
520*fb1b10abSAndroid Build Coastguard Worker       *hr = 1;
521*fb1b10abSAndroid Build Coastguard Worker       *hs = 2;
522*fb1b10abSAndroid Build Coastguard Worker       break;
523*fb1b10abSAndroid Build Coastguard Worker   }
524*fb1b10abSAndroid Build Coastguard Worker }
525*fb1b10abSAndroid Build Coastguard Worker 
526*fb1b10abSAndroid Build Coastguard Worker // Mark all inactive blocks as active. Other segmentation features may be set
527*fb1b10abSAndroid Build Coastguard Worker // so memset cannot be used, instead only inactive blocks should be reset.
suppress_active_map(VP9_COMP * cpi)528*fb1b10abSAndroid Build Coastguard Worker static void suppress_active_map(VP9_COMP *cpi) {
529*fb1b10abSAndroid Build Coastguard Worker   unsigned char *const seg_map = cpi->segmentation_map;
530*fb1b10abSAndroid Build Coastguard Worker 
531*fb1b10abSAndroid Build Coastguard Worker   if (cpi->active_map.enabled || cpi->active_map.update) {
532*fb1b10abSAndroid Build Coastguard Worker     const int rows = cpi->common.mi_rows;
533*fb1b10abSAndroid Build Coastguard Worker     const int cols = cpi->common.mi_cols;
534*fb1b10abSAndroid Build Coastguard Worker     int i;
535*fb1b10abSAndroid Build Coastguard Worker 
536*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < rows * cols; ++i)
537*fb1b10abSAndroid Build Coastguard Worker       if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
538*fb1b10abSAndroid Build Coastguard Worker         seg_map[i] = AM_SEGMENT_ID_ACTIVE;
539*fb1b10abSAndroid Build Coastguard Worker   }
540*fb1b10abSAndroid Build Coastguard Worker }
541*fb1b10abSAndroid Build Coastguard Worker 
apply_active_map(VP9_COMP * cpi)542*fb1b10abSAndroid Build Coastguard Worker static void apply_active_map(VP9_COMP *cpi) {
543*fb1b10abSAndroid Build Coastguard Worker   struct segmentation *const seg = &cpi->common.seg;
544*fb1b10abSAndroid Build Coastguard Worker   unsigned char *const seg_map = cpi->segmentation_map;
545*fb1b10abSAndroid Build Coastguard Worker   const unsigned char *const active_map = cpi->active_map.map;
546*fb1b10abSAndroid Build Coastguard Worker   int i;
547*fb1b10abSAndroid Build Coastguard Worker 
548*fb1b10abSAndroid Build Coastguard Worker   assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
549*fb1b10abSAndroid Build Coastguard Worker 
550*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(&cpi->common)) {
551*fb1b10abSAndroid Build Coastguard Worker     cpi->active_map.enabled = 0;
552*fb1b10abSAndroid Build Coastguard Worker     cpi->active_map.update = 1;
553*fb1b10abSAndroid Build Coastguard Worker   }
554*fb1b10abSAndroid Build Coastguard Worker 
555*fb1b10abSAndroid Build Coastguard Worker   if (cpi->active_map.update) {
556*fb1b10abSAndroid Build Coastguard Worker     if (cpi->active_map.enabled) {
557*fb1b10abSAndroid Build Coastguard Worker       for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
558*fb1b10abSAndroid Build Coastguard Worker         if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
559*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segmentation(seg);
560*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
561*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
562*fb1b10abSAndroid Build Coastguard Worker       // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
563*fb1b10abSAndroid Build Coastguard Worker       // filter level being zero regardless of the value of seg->abs_delta.
564*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
565*fb1b10abSAndroid Build Coastguard Worker                       -MAX_LOOP_FILTER);
566*fb1b10abSAndroid Build Coastguard Worker     } else {
567*fb1b10abSAndroid Build Coastguard Worker       vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
568*fb1b10abSAndroid Build Coastguard Worker       vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
569*fb1b10abSAndroid Build Coastguard Worker       if (seg->enabled) {
570*fb1b10abSAndroid Build Coastguard Worker         seg->update_data = 1;
571*fb1b10abSAndroid Build Coastguard Worker         seg->update_map = 1;
572*fb1b10abSAndroid Build Coastguard Worker       }
573*fb1b10abSAndroid Build Coastguard Worker     }
574*fb1b10abSAndroid Build Coastguard Worker     cpi->active_map.update = 0;
575*fb1b10abSAndroid Build Coastguard Worker   }
576*fb1b10abSAndroid Build Coastguard Worker }
577*fb1b10abSAndroid Build Coastguard Worker 
apply_roi_map(VP9_COMP * cpi)578*fb1b10abSAndroid Build Coastguard Worker static void apply_roi_map(VP9_COMP *cpi) {
579*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
580*fb1b10abSAndroid Build Coastguard Worker   struct segmentation *const seg = &cm->seg;
581*fb1b10abSAndroid Build Coastguard Worker   vpx_roi_map_t *roi = &cpi->roi;
582*fb1b10abSAndroid Build Coastguard Worker   const int *delta_q = roi->delta_q;
583*fb1b10abSAndroid Build Coastguard Worker   const int *delta_lf = roi->delta_lf;
584*fb1b10abSAndroid Build Coastguard Worker   const int *skip = roi->skip;
585*fb1b10abSAndroid Build Coastguard Worker   int ref_frame[8];
586*fb1b10abSAndroid Build Coastguard Worker   int internal_delta_q[MAX_SEGMENTS];
587*fb1b10abSAndroid Build Coastguard Worker   int i;
588*fb1b10abSAndroid Build Coastguard Worker 
589*fb1b10abSAndroid Build Coastguard Worker   // TODO(jianj): Investigate why ROI not working in speed < 5 or in non
590*fb1b10abSAndroid Build Coastguard Worker   // realtime mode.
591*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.mode != REALTIME || cpi->oxcf.speed < 5) return;
592*fb1b10abSAndroid Build Coastguard Worker   if (!roi->enabled) return;
593*fb1b10abSAndroid Build Coastguard Worker 
594*fb1b10abSAndroid Build Coastguard Worker   memcpy(&ref_frame, roi->ref_frame, sizeof(ref_frame));
595*fb1b10abSAndroid Build Coastguard Worker 
596*fb1b10abSAndroid Build Coastguard Worker   vp9_enable_segmentation(seg);
597*fb1b10abSAndroid Build Coastguard Worker   vp9_clearall_segfeatures(seg);
598*fb1b10abSAndroid Build Coastguard Worker   // Select delta coding method;
599*fb1b10abSAndroid Build Coastguard Worker   seg->abs_delta = SEGMENT_DELTADATA;
600*fb1b10abSAndroid Build Coastguard Worker 
601*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->segmentation_map, roi->roi_map, (cm->mi_rows * cm->mi_cols));
602*fb1b10abSAndroid Build Coastguard Worker 
603*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_SEGMENTS; ++i) {
604*fb1b10abSAndroid Build Coastguard Worker     // Translate the external delta q values to internal values.
605*fb1b10abSAndroid Build Coastguard Worker     internal_delta_q[i] = vp9_quantizer_to_qindex(abs(delta_q[i]));
606*fb1b10abSAndroid Build Coastguard Worker     if (delta_q[i] < 0) internal_delta_q[i] = -internal_delta_q[i];
607*fb1b10abSAndroid Build Coastguard Worker     vp9_disable_segfeature(seg, i, SEG_LVL_ALT_Q);
608*fb1b10abSAndroid Build Coastguard Worker     vp9_disable_segfeature(seg, i, SEG_LVL_ALT_LF);
609*fb1b10abSAndroid Build Coastguard Worker     if (internal_delta_q[i] != 0) {
610*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, i, SEG_LVL_ALT_Q);
611*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, i, SEG_LVL_ALT_Q, internal_delta_q[i]);
612*fb1b10abSAndroid Build Coastguard Worker     }
613*fb1b10abSAndroid Build Coastguard Worker     if (delta_lf[i] != 0) {
614*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, i, SEG_LVL_ALT_LF);
615*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, i, SEG_LVL_ALT_LF, delta_lf[i]);
616*fb1b10abSAndroid Build Coastguard Worker     }
617*fb1b10abSAndroid Build Coastguard Worker     if (skip[i] != 0) {
618*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, i, SEG_LVL_SKIP);
619*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, i, SEG_LVL_SKIP, 0);
620*fb1b10abSAndroid Build Coastguard Worker     }
621*fb1b10abSAndroid Build Coastguard Worker     if (ref_frame[i] >= 0) {
622*fb1b10abSAndroid Build Coastguard Worker       int valid_ref = 1;
623*fb1b10abSAndroid Build Coastguard Worker       // ALTREF is not used as reference for nonrd_pickmode with 0 lag.
624*fb1b10abSAndroid Build Coastguard Worker       if (ref_frame[i] == ALTREF_FRAME && cpi->sf.use_nonrd_pick_mode)
625*fb1b10abSAndroid Build Coastguard Worker         valid_ref = 0;
626*fb1b10abSAndroid Build Coastguard Worker       // If GOLDEN is selected, make sure it's set as reference.
627*fb1b10abSAndroid Build Coastguard Worker       if (ref_frame[i] == GOLDEN_FRAME &&
628*fb1b10abSAndroid Build Coastguard Worker           !(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame[i]))) {
629*fb1b10abSAndroid Build Coastguard Worker         valid_ref = 0;
630*fb1b10abSAndroid Build Coastguard Worker       }
631*fb1b10abSAndroid Build Coastguard Worker       // GOLDEN was updated in previous encoded frame, so GOLDEN and LAST are
632*fb1b10abSAndroid Build Coastguard Worker       // same reference.
633*fb1b10abSAndroid Build Coastguard Worker       if (ref_frame[i] == GOLDEN_FRAME && cpi->rc.frames_since_golden == 0)
634*fb1b10abSAndroid Build Coastguard Worker         ref_frame[i] = LAST_FRAME;
635*fb1b10abSAndroid Build Coastguard Worker       if (valid_ref) {
636*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segfeature(seg, i, SEG_LVL_REF_FRAME);
637*fb1b10abSAndroid Build Coastguard Worker         vp9_set_segdata(seg, i, SEG_LVL_REF_FRAME, ref_frame[i]);
638*fb1b10abSAndroid Build Coastguard Worker       }
639*fb1b10abSAndroid Build Coastguard Worker     }
640*fb1b10abSAndroid Build Coastguard Worker   }
641*fb1b10abSAndroid Build Coastguard Worker   roi->enabled = 1;
642*fb1b10abSAndroid Build Coastguard Worker }
643*fb1b10abSAndroid Build Coastguard Worker 
init_level_info(Vp9LevelInfo * level_info)644*fb1b10abSAndroid Build Coastguard Worker static void init_level_info(Vp9LevelInfo *level_info) {
645*fb1b10abSAndroid Build Coastguard Worker   Vp9LevelStats *const level_stats = &level_info->level_stats;
646*fb1b10abSAndroid Build Coastguard Worker   Vp9LevelSpec *const level_spec = &level_info->level_spec;
647*fb1b10abSAndroid Build Coastguard Worker 
648*fb1b10abSAndroid Build Coastguard Worker   memset(level_stats, 0, sizeof(*level_stats));
649*fb1b10abSAndroid Build Coastguard Worker   memset(level_spec, 0, sizeof(*level_spec));
650*fb1b10abSAndroid Build Coastguard Worker   level_spec->level = LEVEL_UNKNOWN;
651*fb1b10abSAndroid Build Coastguard Worker   level_spec->min_altref_distance = INT_MAX;
652*fb1b10abSAndroid Build Coastguard Worker }
653*fb1b10abSAndroid Build Coastguard Worker 
check_seg_range(int seg_data[8],int range)654*fb1b10abSAndroid Build Coastguard Worker static int check_seg_range(int seg_data[8], int range) {
655*fb1b10abSAndroid Build Coastguard Worker   int i;
656*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < 8; ++i) {
657*fb1b10abSAndroid Build Coastguard Worker     // Note abs() alone can't be used as the behavior of abs(INT_MIN) is
658*fb1b10abSAndroid Build Coastguard Worker     // undefined.
659*fb1b10abSAndroid Build Coastguard Worker     if (seg_data[i] > range || seg_data[i] < -range) {
660*fb1b10abSAndroid Build Coastguard Worker       return 0;
661*fb1b10abSAndroid Build Coastguard Worker     }
662*fb1b10abSAndroid Build Coastguard Worker   }
663*fb1b10abSAndroid Build Coastguard Worker   return 1;
664*fb1b10abSAndroid Build Coastguard Worker }
665*fb1b10abSAndroid Build Coastguard Worker 
vp9_get_level(const Vp9LevelSpec * const level_spec)666*fb1b10abSAndroid Build Coastguard Worker VP9_LEVEL vp9_get_level(const Vp9LevelSpec *const level_spec) {
667*fb1b10abSAndroid Build Coastguard Worker   int i;
668*fb1b10abSAndroid Build Coastguard Worker   const Vp9LevelSpec *this_level;
669*fb1b10abSAndroid Build Coastguard Worker 
670*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
671*fb1b10abSAndroid Build Coastguard Worker 
672*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < VP9_LEVELS; ++i) {
673*fb1b10abSAndroid Build Coastguard Worker     this_level = &vp9_level_defs[i];
674*fb1b10abSAndroid Build Coastguard Worker     if ((double)level_spec->max_luma_sample_rate >
675*fb1b10abSAndroid Build Coastguard Worker             (double)this_level->max_luma_sample_rate *
676*fb1b10abSAndroid Build Coastguard Worker                 (1 + SAMPLE_RATE_GRACE_P) ||
677*fb1b10abSAndroid Build Coastguard Worker         level_spec->max_luma_picture_size > this_level->max_luma_picture_size ||
678*fb1b10abSAndroid Build Coastguard Worker         level_spec->max_luma_picture_breadth >
679*fb1b10abSAndroid Build Coastguard Worker             this_level->max_luma_picture_breadth ||
680*fb1b10abSAndroid Build Coastguard Worker         level_spec->average_bitrate > this_level->average_bitrate ||
681*fb1b10abSAndroid Build Coastguard Worker         level_spec->max_cpb_size > this_level->max_cpb_size ||
682*fb1b10abSAndroid Build Coastguard Worker         level_spec->compression_ratio < this_level->compression_ratio ||
683*fb1b10abSAndroid Build Coastguard Worker         level_spec->max_col_tiles > this_level->max_col_tiles ||
684*fb1b10abSAndroid Build Coastguard Worker         level_spec->min_altref_distance < this_level->min_altref_distance ||
685*fb1b10abSAndroid Build Coastguard Worker         level_spec->max_ref_frame_buffers > this_level->max_ref_frame_buffers)
686*fb1b10abSAndroid Build Coastguard Worker       continue;
687*fb1b10abSAndroid Build Coastguard Worker     break;
688*fb1b10abSAndroid Build Coastguard Worker   }
689*fb1b10abSAndroid Build Coastguard Worker   return (i == VP9_LEVELS) ? LEVEL_UNKNOWN : vp9_level_defs[i].level;
690*fb1b10abSAndroid Build Coastguard Worker }
691*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_roi_map(VP9_COMP * cpi,unsigned char * map,unsigned int rows,unsigned int cols,int delta_q[8],int delta_lf[8],int skip[8],int ref_frame[8])692*fb1b10abSAndroid Build Coastguard Worker vpx_codec_err_t vp9_set_roi_map(VP9_COMP *cpi, unsigned char *map,
693*fb1b10abSAndroid Build Coastguard Worker                                 unsigned int rows, unsigned int cols,
694*fb1b10abSAndroid Build Coastguard Worker                                 int delta_q[8], int delta_lf[8], int skip[8],
695*fb1b10abSAndroid Build Coastguard Worker                                 int ref_frame[8]) {
696*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
697*fb1b10abSAndroid Build Coastguard Worker   vpx_roi_map_t *roi = &cpi->roi;
698*fb1b10abSAndroid Build Coastguard Worker   const int range = 63;
699*fb1b10abSAndroid Build Coastguard Worker   const int ref_frame_range = 3;  // Alt-ref
700*fb1b10abSAndroid Build Coastguard Worker   const int skip_range = 1;
701*fb1b10abSAndroid Build Coastguard Worker   const int frame_rows = cpi->common.mi_rows;
702*fb1b10abSAndroid Build Coastguard Worker   const int frame_cols = cpi->common.mi_cols;
703*fb1b10abSAndroid Build Coastguard Worker 
704*fb1b10abSAndroid Build Coastguard Worker   // Check number of rows and columns match
705*fb1b10abSAndroid Build Coastguard Worker   if (frame_rows != (int)rows || frame_cols != (int)cols) {
706*fb1b10abSAndroid Build Coastguard Worker     return VPX_CODEC_INVALID_PARAM;
707*fb1b10abSAndroid Build Coastguard Worker   }
708*fb1b10abSAndroid Build Coastguard Worker 
709*fb1b10abSAndroid Build Coastguard Worker   if (!check_seg_range(delta_q, range) || !check_seg_range(delta_lf, range) ||
710*fb1b10abSAndroid Build Coastguard Worker       !check_seg_range(ref_frame, ref_frame_range) ||
711*fb1b10abSAndroid Build Coastguard Worker       !check_seg_range(skip, skip_range))
712*fb1b10abSAndroid Build Coastguard Worker     return VPX_CODEC_INVALID_PARAM;
713*fb1b10abSAndroid Build Coastguard Worker 
714*fb1b10abSAndroid Build Coastguard Worker   // Also disable segmentation if no deltas are specified.
715*fb1b10abSAndroid Build Coastguard Worker   if (!map ||
716*fb1b10abSAndroid Build Coastguard Worker       (!(delta_q[0] | delta_q[1] | delta_q[2] | delta_q[3] | delta_q[4] |
717*fb1b10abSAndroid Build Coastguard Worker          delta_q[5] | delta_q[6] | delta_q[7] | delta_lf[0] | delta_lf[1] |
718*fb1b10abSAndroid Build Coastguard Worker          delta_lf[2] | delta_lf[3] | delta_lf[4] | delta_lf[5] | delta_lf[6] |
719*fb1b10abSAndroid Build Coastguard Worker          delta_lf[7] | skip[0] | skip[1] | skip[2] | skip[3] | skip[4] |
720*fb1b10abSAndroid Build Coastguard Worker          skip[5] | skip[6] | skip[7]) &&
721*fb1b10abSAndroid Build Coastguard Worker        (ref_frame[0] == -1 && ref_frame[1] == -1 && ref_frame[2] == -1 &&
722*fb1b10abSAndroid Build Coastguard Worker         ref_frame[3] == -1 && ref_frame[4] == -1 && ref_frame[5] == -1 &&
723*fb1b10abSAndroid Build Coastguard Worker         ref_frame[6] == -1 && ref_frame[7] == -1))) {
724*fb1b10abSAndroid Build Coastguard Worker     vp9_disable_segmentation(&cm->seg);
725*fb1b10abSAndroid Build Coastguard Worker     cpi->roi.enabled = 0;
726*fb1b10abSAndroid Build Coastguard Worker     return VPX_CODEC_OK;
727*fb1b10abSAndroid Build Coastguard Worker   }
728*fb1b10abSAndroid Build Coastguard Worker 
729*fb1b10abSAndroid Build Coastguard Worker   if (roi->roi_map) {
730*fb1b10abSAndroid Build Coastguard Worker     vpx_free(roi->roi_map);
731*fb1b10abSAndroid Build Coastguard Worker     roi->roi_map = NULL;
732*fb1b10abSAndroid Build Coastguard Worker   }
733*fb1b10abSAndroid Build Coastguard Worker   roi->roi_map = vpx_malloc(rows * cols);
734*fb1b10abSAndroid Build Coastguard Worker   if (!roi->roi_map) return VPX_CODEC_MEM_ERROR;
735*fb1b10abSAndroid Build Coastguard Worker 
736*fb1b10abSAndroid Build Coastguard Worker   // Copy to ROI structure in the compressor.
737*fb1b10abSAndroid Build Coastguard Worker   memcpy(roi->roi_map, map, rows * cols);
738*fb1b10abSAndroid Build Coastguard Worker   memcpy(&roi->delta_q, delta_q, MAX_SEGMENTS * sizeof(delta_q[0]));
739*fb1b10abSAndroid Build Coastguard Worker   memcpy(&roi->delta_lf, delta_lf, MAX_SEGMENTS * sizeof(delta_lf[0]));
740*fb1b10abSAndroid Build Coastguard Worker   memcpy(&roi->skip, skip, MAX_SEGMENTS * sizeof(skip[0]));
741*fb1b10abSAndroid Build Coastguard Worker   memcpy(&roi->ref_frame, ref_frame, MAX_SEGMENTS * sizeof(ref_frame[0]));
742*fb1b10abSAndroid Build Coastguard Worker   roi->enabled = 1;
743*fb1b10abSAndroid Build Coastguard Worker   roi->rows = rows;
744*fb1b10abSAndroid Build Coastguard Worker   roi->cols = cols;
745*fb1b10abSAndroid Build Coastguard Worker 
746*fb1b10abSAndroid Build Coastguard Worker   return VPX_CODEC_OK;
747*fb1b10abSAndroid Build Coastguard Worker }
748*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_active_map(VP9_COMP * cpi,unsigned char * new_map_16x16,int rows,int cols)749*fb1b10abSAndroid Build Coastguard Worker int vp9_set_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows,
750*fb1b10abSAndroid Build Coastguard Worker                        int cols) {
751*fb1b10abSAndroid Build Coastguard Worker   if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
752*fb1b10abSAndroid Build Coastguard Worker     unsigned char *const active_map_8x8 = cpi->active_map.map;
753*fb1b10abSAndroid Build Coastguard Worker     const int mi_rows = cpi->common.mi_rows;
754*fb1b10abSAndroid Build Coastguard Worker     const int mi_cols = cpi->common.mi_cols;
755*fb1b10abSAndroid Build Coastguard Worker     cpi->active_map.update = 1;
756*fb1b10abSAndroid Build Coastguard Worker     if (new_map_16x16) {
757*fb1b10abSAndroid Build Coastguard Worker       int r, c;
758*fb1b10abSAndroid Build Coastguard Worker       for (r = 0; r < mi_rows; ++r) {
759*fb1b10abSAndroid Build Coastguard Worker         for (c = 0; c < mi_cols; ++c) {
760*fb1b10abSAndroid Build Coastguard Worker           active_map_8x8[r * mi_cols + c] =
761*fb1b10abSAndroid Build Coastguard Worker               new_map_16x16[(r >> 1) * cols + (c >> 1)]
762*fb1b10abSAndroid Build Coastguard Worker                   ? AM_SEGMENT_ID_ACTIVE
763*fb1b10abSAndroid Build Coastguard Worker                   : AM_SEGMENT_ID_INACTIVE;
764*fb1b10abSAndroid Build Coastguard Worker         }
765*fb1b10abSAndroid Build Coastguard Worker       }
766*fb1b10abSAndroid Build Coastguard Worker       cpi->active_map.enabled = 1;
767*fb1b10abSAndroid Build Coastguard Worker     } else {
768*fb1b10abSAndroid Build Coastguard Worker       cpi->active_map.enabled = 0;
769*fb1b10abSAndroid Build Coastguard Worker     }
770*fb1b10abSAndroid Build Coastguard Worker     return 0;
771*fb1b10abSAndroid Build Coastguard Worker   } else {
772*fb1b10abSAndroid Build Coastguard Worker     return -1;
773*fb1b10abSAndroid Build Coastguard Worker   }
774*fb1b10abSAndroid Build Coastguard Worker }
775*fb1b10abSAndroid Build Coastguard Worker 
vp9_get_active_map(VP9_COMP * cpi,unsigned char * new_map_16x16,int rows,int cols)776*fb1b10abSAndroid Build Coastguard Worker int vp9_get_active_map(VP9_COMP *cpi, unsigned char *new_map_16x16, int rows,
777*fb1b10abSAndroid Build Coastguard Worker                        int cols) {
778*fb1b10abSAndroid Build Coastguard Worker   if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
779*fb1b10abSAndroid Build Coastguard Worker       new_map_16x16) {
780*fb1b10abSAndroid Build Coastguard Worker     unsigned char *const seg_map_8x8 = cpi->segmentation_map;
781*fb1b10abSAndroid Build Coastguard Worker     const int mi_rows = cpi->common.mi_rows;
782*fb1b10abSAndroid Build Coastguard Worker     const int mi_cols = cpi->common.mi_cols;
783*fb1b10abSAndroid Build Coastguard Worker     memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
784*fb1b10abSAndroid Build Coastguard Worker     if (cpi->active_map.enabled) {
785*fb1b10abSAndroid Build Coastguard Worker       int r, c;
786*fb1b10abSAndroid Build Coastguard Worker       for (r = 0; r < mi_rows; ++r) {
787*fb1b10abSAndroid Build Coastguard Worker         for (c = 0; c < mi_cols; ++c) {
788*fb1b10abSAndroid Build Coastguard Worker           // Cyclic refresh segments are considered active despite not having
789*fb1b10abSAndroid Build Coastguard Worker           // AM_SEGMENT_ID_ACTIVE
790*fb1b10abSAndroid Build Coastguard Worker           new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
791*fb1b10abSAndroid Build Coastguard Worker               seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
792*fb1b10abSAndroid Build Coastguard Worker         }
793*fb1b10abSAndroid Build Coastguard Worker       }
794*fb1b10abSAndroid Build Coastguard Worker     }
795*fb1b10abSAndroid Build Coastguard Worker     return 0;
796*fb1b10abSAndroid Build Coastguard Worker   } else {
797*fb1b10abSAndroid Build Coastguard Worker     return -1;
798*fb1b10abSAndroid Build Coastguard Worker   }
799*fb1b10abSAndroid Build Coastguard Worker }
800*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_high_precision_mv(VP9_COMP * cpi,int allow_high_precision_mv)801*fb1b10abSAndroid Build Coastguard Worker void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
802*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCK *const mb = &cpi->td.mb;
803*fb1b10abSAndroid Build Coastguard Worker   cpi->common.allow_high_precision_mv = allow_high_precision_mv;
804*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.allow_high_precision_mv) {
805*fb1b10abSAndroid Build Coastguard Worker     mb->mvcost = mb->nmvcost_hp;
806*fb1b10abSAndroid Build Coastguard Worker     mb->mvsadcost = mb->nmvsadcost_hp;
807*fb1b10abSAndroid Build Coastguard Worker   } else {
808*fb1b10abSAndroid Build Coastguard Worker     mb->mvcost = mb->nmvcost;
809*fb1b10abSAndroid Build Coastguard Worker     mb->mvsadcost = mb->nmvsadcost;
810*fb1b10abSAndroid Build Coastguard Worker   }
811*fb1b10abSAndroid Build Coastguard Worker }
812*fb1b10abSAndroid Build Coastguard Worker 
setup_frame(VP9_COMP * cpi)813*fb1b10abSAndroid Build Coastguard Worker static void setup_frame(VP9_COMP *cpi) {
814*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
815*fb1b10abSAndroid Build Coastguard Worker   // Set up entropy context depending on frame type. The decoder mandates
816*fb1b10abSAndroid Build Coastguard Worker   // the use of the default context, index 0, for keyframes and inter
817*fb1b10abSAndroid Build Coastguard Worker   // frames where the error_resilient_mode or intra_only flag is set. For
818*fb1b10abSAndroid Build Coastguard Worker   // other inter-frames the encoder currently uses only two contexts;
819*fb1b10abSAndroid Build Coastguard Worker   // context 1 for ALTREF frames and context 0 for the others.
820*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
821*fb1b10abSAndroid Build Coastguard Worker     vp9_setup_past_independence(cm);
822*fb1b10abSAndroid Build Coastguard Worker   } else {
823*fb1b10abSAndroid Build Coastguard Worker     if (!cpi->use_svc) cm->frame_context_idx = cpi->refresh_alt_ref_frame;
824*fb1b10abSAndroid Build Coastguard Worker   }
825*fb1b10abSAndroid Build Coastguard Worker 
826*fb1b10abSAndroid Build Coastguard Worker   // TODO(jingning): Overwrite the frame_context_idx index in multi-layer ARF
827*fb1b10abSAndroid Build Coastguard Worker   // case. Need some further investigation on if we could apply this to single
828*fb1b10abSAndroid Build Coastguard Worker   // layer ARF case as well.
829*fb1b10abSAndroid Build Coastguard Worker   if (cpi->multi_layer_arf && !cpi->use_svc) {
830*fb1b10abSAndroid Build Coastguard Worker     GF_GROUP *const gf_group = &cpi->twopass.gf_group;
831*fb1b10abSAndroid Build Coastguard Worker     const int gf_group_index = gf_group->index;
832*fb1b10abSAndroid Build Coastguard Worker     const int boost_frame =
833*fb1b10abSAndroid Build Coastguard Worker         !cpi->rc.is_src_frame_alt_ref &&
834*fb1b10abSAndroid Build Coastguard Worker         (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame);
835*fb1b10abSAndroid Build Coastguard Worker 
836*fb1b10abSAndroid Build Coastguard Worker     // frame_context_idx           Frame Type
837*fb1b10abSAndroid Build Coastguard Worker     //        0              Intra only frame, base layer ARF
838*fb1b10abSAndroid Build Coastguard Worker     //        1              ARFs with layer depth = 2,3
839*fb1b10abSAndroid Build Coastguard Worker     //        2              ARFs with layer depth > 3
840*fb1b10abSAndroid Build Coastguard Worker     //        3              Non-boosted frames
841*fb1b10abSAndroid Build Coastguard Worker     if (frame_is_intra_only(cm)) {
842*fb1b10abSAndroid Build Coastguard Worker       cm->frame_context_idx = 0;
843*fb1b10abSAndroid Build Coastguard Worker     } else if (boost_frame) {
844*fb1b10abSAndroid Build Coastguard Worker       if (gf_group->rf_level[gf_group_index] == GF_ARF_STD)
845*fb1b10abSAndroid Build Coastguard Worker         cm->frame_context_idx = 0;
846*fb1b10abSAndroid Build Coastguard Worker       else if (gf_group->layer_depth[gf_group_index] <= 3)
847*fb1b10abSAndroid Build Coastguard Worker         cm->frame_context_idx = 1;
848*fb1b10abSAndroid Build Coastguard Worker       else
849*fb1b10abSAndroid Build Coastguard Worker         cm->frame_context_idx = 2;
850*fb1b10abSAndroid Build Coastguard Worker     } else {
851*fb1b10abSAndroid Build Coastguard Worker       cm->frame_context_idx = 3;
852*fb1b10abSAndroid Build Coastguard Worker     }
853*fb1b10abSAndroid Build Coastguard Worker   }
854*fb1b10abSAndroid Build Coastguard Worker 
855*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
856*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_golden_frame = 1;
857*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_alt_ref_frame = 1;
858*fb1b10abSAndroid Build Coastguard Worker     vp9_zero(cpi->interp_filter_selected);
859*fb1b10abSAndroid Build Coastguard Worker   } else {
860*fb1b10abSAndroid Build Coastguard Worker     *cm->fc = cm->frame_contexts[cm->frame_context_idx];
861*fb1b10abSAndroid Build Coastguard Worker     vp9_zero(cpi->interp_filter_selected[0]);
862*fb1b10abSAndroid Build Coastguard Worker   }
863*fb1b10abSAndroid Build Coastguard Worker }
864*fb1b10abSAndroid Build Coastguard Worker 
vp9_enc_setup_mi(VP9_COMMON * cm)865*fb1b10abSAndroid Build Coastguard Worker static void vp9_enc_setup_mi(VP9_COMMON *cm) {
866*fb1b10abSAndroid Build Coastguard Worker   int i;
867*fb1b10abSAndroid Build Coastguard Worker   cm->mi = cm->mip + cm->mi_stride + 1;
868*fb1b10abSAndroid Build Coastguard Worker   memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
869*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
870*fb1b10abSAndroid Build Coastguard Worker   // Clear top border row
871*fb1b10abSAndroid Build Coastguard Worker   memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
872*fb1b10abSAndroid Build Coastguard Worker   // Clear left border column
873*fb1b10abSAndroid Build Coastguard Worker   for (i = 1; i < cm->mi_rows + 1; ++i)
874*fb1b10abSAndroid Build Coastguard Worker     memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
875*fb1b10abSAndroid Build Coastguard Worker 
876*fb1b10abSAndroid Build Coastguard Worker   cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
877*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
878*fb1b10abSAndroid Build Coastguard Worker 
879*fb1b10abSAndroid Build Coastguard Worker   memset(cm->mi_grid_base, 0,
880*fb1b10abSAndroid Build Coastguard Worker          cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
881*fb1b10abSAndroid Build Coastguard Worker }
882*fb1b10abSAndroid Build Coastguard Worker 
vp9_enc_alloc_mi(VP9_COMMON * cm,int mi_size)883*fb1b10abSAndroid Build Coastguard Worker static int vp9_enc_alloc_mi(VP9_COMMON *cm, int mi_size) {
884*fb1b10abSAndroid Build Coastguard Worker   cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip));
885*fb1b10abSAndroid Build Coastguard Worker   if (!cm->mip) return 1;
886*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mip = vpx_calloc(mi_size, sizeof(*cm->prev_mip));
887*fb1b10abSAndroid Build Coastguard Worker   if (!cm->prev_mip) return 1;
888*fb1b10abSAndroid Build Coastguard Worker   cm->mi_alloc_size = mi_size;
889*fb1b10abSAndroid Build Coastguard Worker 
890*fb1b10abSAndroid Build Coastguard Worker   cm->mi_grid_base =
891*fb1b10abSAndroid Build Coastguard Worker       (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->mi_grid_base));
892*fb1b10abSAndroid Build Coastguard Worker   if (!cm->mi_grid_base) return 1;
893*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi_grid_base =
894*fb1b10abSAndroid Build Coastguard Worker       (MODE_INFO **)vpx_calloc(mi_size, sizeof(*cm->prev_mi_grid_base));
895*fb1b10abSAndroid Build Coastguard Worker   if (!cm->prev_mi_grid_base) return 1;
896*fb1b10abSAndroid Build Coastguard Worker 
897*fb1b10abSAndroid Build Coastguard Worker   return 0;
898*fb1b10abSAndroid Build Coastguard Worker }
899*fb1b10abSAndroid Build Coastguard Worker 
vp9_enc_free_mi(VP9_COMMON * cm)900*fb1b10abSAndroid Build Coastguard Worker static void vp9_enc_free_mi(VP9_COMMON *cm) {
901*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cm->mip);
902*fb1b10abSAndroid Build Coastguard Worker   cm->mip = NULL;
903*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cm->prev_mip);
904*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mip = NULL;
905*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cm->mi_grid_base);
906*fb1b10abSAndroid Build Coastguard Worker   cm->mi_grid_base = NULL;
907*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cm->prev_mi_grid_base);
908*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi_grid_base = NULL;
909*fb1b10abSAndroid Build Coastguard Worker   cm->mi_alloc_size = 0;
910*fb1b10abSAndroid Build Coastguard Worker }
911*fb1b10abSAndroid Build Coastguard Worker 
vp9_swap_mi_and_prev_mi(VP9_COMMON * cm)912*fb1b10abSAndroid Build Coastguard Worker static void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) {
913*fb1b10abSAndroid Build Coastguard Worker   // Current mip will be the prev_mip for the next frame.
914*fb1b10abSAndroid Build Coastguard Worker   MODE_INFO **temp_base = cm->prev_mi_grid_base;
915*fb1b10abSAndroid Build Coastguard Worker   MODE_INFO *temp = cm->prev_mip;
916*fb1b10abSAndroid Build Coastguard Worker 
917*fb1b10abSAndroid Build Coastguard Worker   // Skip update prev_mi frame in show_existing_frame mode.
918*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame) return;
919*fb1b10abSAndroid Build Coastguard Worker 
920*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mip = cm->mip;
921*fb1b10abSAndroid Build Coastguard Worker   cm->mip = temp;
922*fb1b10abSAndroid Build Coastguard Worker 
923*fb1b10abSAndroid Build Coastguard Worker   // Update the upper left visible macroblock ptrs.
924*fb1b10abSAndroid Build Coastguard Worker   cm->mi = cm->mip + cm->mi_stride + 1;
925*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
926*fb1b10abSAndroid Build Coastguard Worker 
927*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi_grid_base = cm->mi_grid_base;
928*fb1b10abSAndroid Build Coastguard Worker   cm->mi_grid_base = temp_base;
929*fb1b10abSAndroid Build Coastguard Worker   cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
930*fb1b10abSAndroid Build Coastguard Worker   cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
931*fb1b10abSAndroid Build Coastguard Worker }
932*fb1b10abSAndroid Build Coastguard Worker 
initialize_enc(void)933*fb1b10abSAndroid Build Coastguard Worker static void initialize_enc(void) {
934*fb1b10abSAndroid Build Coastguard Worker   vp9_rtcd();
935*fb1b10abSAndroid Build Coastguard Worker   vpx_dsp_rtcd();
936*fb1b10abSAndroid Build Coastguard Worker   vpx_scale_rtcd();
937*fb1b10abSAndroid Build Coastguard Worker   vp9_init_intra_predictors();
938*fb1b10abSAndroid Build Coastguard Worker   vp9_init_me_luts();
939*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_init_minq_luts();
940*fb1b10abSAndroid Build Coastguard Worker   vp9_entropy_mv_init();
941*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
942*fb1b10abSAndroid Build Coastguard Worker   vp9_temporal_filter_init();
943*fb1b10abSAndroid Build Coastguard Worker #endif
944*fb1b10abSAndroid Build Coastguard Worker }
945*fb1b10abSAndroid Build Coastguard Worker 
vp9_initialize_enc(void)946*fb1b10abSAndroid Build Coastguard Worker void vp9_initialize_enc(void) { once(initialize_enc); }
947*fb1b10abSAndroid Build Coastguard Worker 
dealloc_compressor_data(VP9_COMP * cpi)948*fb1b10abSAndroid Build Coastguard Worker static void dealloc_compressor_data(VP9_COMP *cpi) {
949*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
950*fb1b10abSAndroid Build Coastguard Worker   int i;
951*fb1b10abSAndroid Build Coastguard Worker 
952*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->mbmi_ext_base);
953*fb1b10abSAndroid Build Coastguard Worker   cpi->mbmi_ext_base = NULL;
954*fb1b10abSAndroid Build Coastguard Worker 
955*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->tile_data);
956*fb1b10abSAndroid Build Coastguard Worker   cpi->tile_data = NULL;
957*fb1b10abSAndroid Build Coastguard Worker 
958*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->segmentation_map);
959*fb1b10abSAndroid Build Coastguard Worker   cpi->segmentation_map = NULL;
960*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->coding_context.last_frame_seg_map_copy);
961*fb1b10abSAndroid Build Coastguard Worker   cpi->coding_context.last_frame_seg_map_copy = NULL;
962*fb1b10abSAndroid Build Coastguard Worker 
963*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvcosts[0]);
964*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvcosts[1]);
965*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvcosts[0] = NULL;
966*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvcosts[1] = NULL;
967*fb1b10abSAndroid Build Coastguard Worker 
968*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvcosts_hp[0]);
969*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvcosts_hp[1]);
970*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvcosts_hp[0] = NULL;
971*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvcosts_hp[1] = NULL;
972*fb1b10abSAndroid Build Coastguard Worker 
973*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvsadcosts[0]);
974*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvsadcosts[1]);
975*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvsadcosts[0] = NULL;
976*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvsadcosts[1] = NULL;
977*fb1b10abSAndroid Build Coastguard Worker 
978*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvsadcosts_hp[0]);
979*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->nmvsadcosts_hp[1]);
980*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvsadcosts_hp[0] = NULL;
981*fb1b10abSAndroid Build Coastguard Worker   cpi->nmvsadcosts_hp[1] = NULL;
982*fb1b10abSAndroid Build Coastguard Worker 
983*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->skin_map);
984*fb1b10abSAndroid Build Coastguard Worker   cpi->skin_map = NULL;
985*fb1b10abSAndroid Build Coastguard Worker 
986*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_partition);
987*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_partition = NULL;
988*fb1b10abSAndroid Build Coastguard Worker 
989*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->svc.prev_partition_svc);
990*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.prev_partition_svc = NULL;
991*fb1b10abSAndroid Build Coastguard Worker 
992*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_segment_id);
993*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_segment_id = NULL;
994*fb1b10abSAndroid Build Coastguard Worker 
995*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_variance_low);
996*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_variance_low = NULL;
997*fb1b10abSAndroid Build Coastguard Worker 
998*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->copied_frame_cnt);
999*fb1b10abSAndroid Build Coastguard Worker   cpi->copied_frame_cnt = NULL;
1000*fb1b10abSAndroid Build Coastguard Worker 
1001*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->content_state_sb_fd);
1002*fb1b10abSAndroid Build Coastguard Worker   cpi->content_state_sb_fd = NULL;
1003*fb1b10abSAndroid Build Coastguard Worker 
1004*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->count_arf_frame_usage);
1005*fb1b10abSAndroid Build Coastguard Worker   cpi->count_arf_frame_usage = NULL;
1006*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->count_lastgolden_frame_usage);
1007*fb1b10abSAndroid Build Coastguard Worker   cpi->count_lastgolden_frame_usage = NULL;
1008*fb1b10abSAndroid Build Coastguard Worker 
1009*fb1b10abSAndroid Build Coastguard Worker   vp9_cyclic_refresh_free(cpi->cyclic_refresh);
1010*fb1b10abSAndroid Build Coastguard Worker   cpi->cyclic_refresh = NULL;
1011*fb1b10abSAndroid Build Coastguard Worker 
1012*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->active_map.map);
1013*fb1b10abSAndroid Build Coastguard Worker   cpi->active_map.map = NULL;
1014*fb1b10abSAndroid Build Coastguard Worker 
1015*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->roi.roi_map);
1016*fb1b10abSAndroid Build Coastguard Worker   cpi->roi.roi_map = NULL;
1017*fb1b10abSAndroid Build Coastguard Worker 
1018*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->consec_zero_mv);
1019*fb1b10abSAndroid Build Coastguard Worker   cpi->consec_zero_mv = NULL;
1020*fb1b10abSAndroid Build Coastguard Worker 
1021*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->mb_wiener_variance);
1022*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_variance = NULL;
1023*fb1b10abSAndroid Build Coastguard Worker 
1024*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->mi_ssim_rdmult_scaling_factors);
1025*fb1b10abSAndroid Build Coastguard Worker   cpi->mi_ssim_rdmult_scaling_factors = NULL;
1026*fb1b10abSAndroid Build Coastguard Worker 
1027*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
1028*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.use_simple_encode_api) {
1029*fb1b10abSAndroid Build Coastguard Worker     free_partition_info(cpi);
1030*fb1b10abSAndroid Build Coastguard Worker     free_motion_vector_info(cpi);
1031*fb1b10abSAndroid Build Coastguard Worker     free_fp_motion_vector_info(cpi);
1032*fb1b10abSAndroid Build Coastguard Worker     free_tpl_stats_info(cpi);
1033*fb1b10abSAndroid Build Coastguard Worker   }
1034*fb1b10abSAndroid Build Coastguard Worker #endif
1035*fb1b10abSAndroid Build Coastguard Worker 
1036*fb1b10abSAndroid Build Coastguard Worker   vp9_free_ref_frame_buffers(cm->buffer_pool);
1037*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC
1038*fb1b10abSAndroid Build Coastguard Worker   vp9_free_postproc_buffers(cm);
1039*fb1b10abSAndroid Build Coastguard Worker #endif
1040*fb1b10abSAndroid Build Coastguard Worker   vp9_free_context_buffers(cm);
1041*fb1b10abSAndroid Build Coastguard Worker 
1042*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->last_frame_uf);
1043*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->scaled_source);
1044*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->scaled_last_source);
1045*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->tf_buffer);
1046*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
1047*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->raw_unscaled_source);
1048*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->raw_scaled_source);
1049*fb1b10abSAndroid Build Coastguard Worker #endif
1050*fb1b10abSAndroid Build Coastguard Worker 
1051*fb1b10abSAndroid Build Coastguard Worker   vp9_lookahead_destroy(cpi->lookahead);
1052*fb1b10abSAndroid Build Coastguard Worker 
1053*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->tile_tok[0][0]);
1054*fb1b10abSAndroid Build Coastguard Worker   cpi->tile_tok[0][0] = 0;
1055*fb1b10abSAndroid Build Coastguard Worker 
1056*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->tplist[0][0]);
1057*fb1b10abSAndroid Build Coastguard Worker   cpi->tplist[0][0] = NULL;
1058*fb1b10abSAndroid Build Coastguard Worker 
1059*fb1b10abSAndroid Build Coastguard Worker   vp9_free_pc_tree(&cpi->td);
1060*fb1b10abSAndroid Build Coastguard Worker 
1061*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
1062*fb1b10abSAndroid Build Coastguard Worker     LAYER_CONTEXT *const lc = &cpi->svc.layer_context[i];
1063*fb1b10abSAndroid Build Coastguard Worker     vpx_free(lc->rc_twopass_stats_in.buf);
1064*fb1b10abSAndroid Build Coastguard Worker     lc->rc_twopass_stats_in.buf = NULL;
1065*fb1b10abSAndroid Build Coastguard Worker     lc->rc_twopass_stats_in.sz = 0;
1066*fb1b10abSAndroid Build Coastguard Worker   }
1067*fb1b10abSAndroid Build Coastguard Worker 
1068*fb1b10abSAndroid Build Coastguard Worker   if (cpi->source_diff_var != NULL) {
1069*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->source_diff_var);
1070*fb1b10abSAndroid Build Coastguard Worker     cpi->source_diff_var = NULL;
1071*fb1b10abSAndroid Build Coastguard Worker   }
1072*fb1b10abSAndroid Build Coastguard Worker 
1073*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_LAG_BUFFERS; ++i) {
1074*fb1b10abSAndroid Build Coastguard Worker     vpx_free_frame_buffer(&cpi->svc.scaled_frames[i]);
1075*fb1b10abSAndroid Build Coastguard Worker   }
1076*fb1b10abSAndroid Build Coastguard Worker   memset(&cpi->svc.scaled_frames[0], 0,
1077*fb1b10abSAndroid Build Coastguard Worker          MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0]));
1078*fb1b10abSAndroid Build Coastguard Worker 
1079*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->svc.scaled_temp);
1080*fb1b10abSAndroid Build Coastguard Worker   memset(&cpi->svc.scaled_temp, 0, sizeof(cpi->svc.scaled_temp));
1081*fb1b10abSAndroid Build Coastguard Worker 
1082*fb1b10abSAndroid Build Coastguard Worker   vpx_free_frame_buffer(&cpi->svc.empty_frame.img);
1083*fb1b10abSAndroid Build Coastguard Worker   memset(&cpi->svc.empty_frame, 0, sizeof(cpi->svc.empty_frame));
1084*fb1b10abSAndroid Build Coastguard Worker 
1085*fb1b10abSAndroid Build Coastguard Worker   vp9_free_svc_cyclic_refresh(cpi);
1086*fb1b10abSAndroid Build Coastguard Worker }
1087*fb1b10abSAndroid Build Coastguard Worker 
save_coding_context(VP9_COMP * cpi)1088*fb1b10abSAndroid Build Coastguard Worker static void save_coding_context(VP9_COMP *cpi) {
1089*fb1b10abSAndroid Build Coastguard Worker   CODING_CONTEXT *const cc = &cpi->coding_context;
1090*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1091*fb1b10abSAndroid Build Coastguard Worker 
1092*fb1b10abSAndroid Build Coastguard Worker   // Stores a snapshot of key state variables which can subsequently be
1093*fb1b10abSAndroid Build Coastguard Worker   // restored with a call to vp9_restore_coding_context. These functions are
1094*fb1b10abSAndroid Build Coastguard Worker   // intended for use in a re-code loop in vp9_compress_frame where the
1095*fb1b10abSAndroid Build Coastguard Worker   // quantizer value is adjusted between loop iterations.
1096*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
1097*fb1b10abSAndroid Build Coastguard Worker 
1098*fb1b10abSAndroid Build Coastguard Worker   memcpy(cc->nmvcosts[0], cpi->nmvcosts[0],
1099*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cpi->nmvcosts[0]));
1100*fb1b10abSAndroid Build Coastguard Worker   memcpy(cc->nmvcosts[1], cpi->nmvcosts[1],
1101*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cpi->nmvcosts[1]));
1102*fb1b10abSAndroid Build Coastguard Worker   memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0],
1103*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cpi->nmvcosts_hp[0]));
1104*fb1b10abSAndroid Build Coastguard Worker   memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
1105*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));
1106*fb1b10abSAndroid Build Coastguard Worker 
1107*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs);
1108*fb1b10abSAndroid Build Coastguard Worker 
1109*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map,
1110*fb1b10abSAndroid Build Coastguard Worker          (cm->mi_rows * cm->mi_cols));
1111*fb1b10abSAndroid Build Coastguard Worker 
1112*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
1113*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
1114*fb1b10abSAndroid Build Coastguard Worker 
1115*fb1b10abSAndroid Build Coastguard Worker   cc->fc = *cm->fc;
1116*fb1b10abSAndroid Build Coastguard Worker }
1117*fb1b10abSAndroid Build Coastguard Worker 
restore_coding_context(VP9_COMP * cpi)1118*fb1b10abSAndroid Build Coastguard Worker static void restore_coding_context(VP9_COMP *cpi) {
1119*fb1b10abSAndroid Build Coastguard Worker   CODING_CONTEXT *const cc = &cpi->coding_context;
1120*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1121*fb1b10abSAndroid Build Coastguard Worker 
1122*fb1b10abSAndroid Build Coastguard Worker   // Restore key state variables to the snapshot state stored in the
1123*fb1b10abSAndroid Build Coastguard Worker   // previous call to vp9_save_coding_context.
1124*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
1125*fb1b10abSAndroid Build Coastguard Worker 
1126*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->nmvcosts[0], cc->nmvcosts[0], MV_VALS * sizeof(*cc->nmvcosts[0]));
1127*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->nmvcosts[1], cc->nmvcosts[1], MV_VALS * sizeof(*cc->nmvcosts[1]));
1128*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0],
1129*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cc->nmvcosts_hp[0]));
1130*fb1b10abSAndroid Build Coastguard Worker   memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
1131*fb1b10abSAndroid Build Coastguard Worker          MV_VALS * sizeof(*cc->nmvcosts_hp[1]));
1132*fb1b10abSAndroid Build Coastguard Worker 
1133*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs);
1134*fb1b10abSAndroid Build Coastguard Worker 
1135*fb1b10abSAndroid Build Coastguard Worker   memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy,
1136*fb1b10abSAndroid Build Coastguard Worker          (cm->mi_rows * cm->mi_cols));
1137*fb1b10abSAndroid Build Coastguard Worker 
1138*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
1139*fb1b10abSAndroid Build Coastguard Worker   vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
1140*fb1b10abSAndroid Build Coastguard Worker 
1141*fb1b10abSAndroid Build Coastguard Worker   *cm->fc = cc->fc;
1142*fb1b10abSAndroid Build Coastguard Worker }
1143*fb1b10abSAndroid Build Coastguard Worker 
1144*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
configure_static_seg_features(VP9_COMP * cpi)1145*fb1b10abSAndroid Build Coastguard Worker static void configure_static_seg_features(VP9_COMP *cpi) {
1146*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1147*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1148*fb1b10abSAndroid Build Coastguard Worker   struct segmentation *const seg = &cm->seg;
1149*fb1b10abSAndroid Build Coastguard Worker 
1150*fb1b10abSAndroid Build Coastguard Worker   int high_q = (int)(rc->avg_q > 48.0);
1151*fb1b10abSAndroid Build Coastguard Worker   int qi_delta;
1152*fb1b10abSAndroid Build Coastguard Worker 
1153*fb1b10abSAndroid Build Coastguard Worker   // Disable and clear down for KF
1154*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
1155*fb1b10abSAndroid Build Coastguard Worker     // Clear down the global segmentation map
1156*fb1b10abSAndroid Build Coastguard Worker     memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
1157*fb1b10abSAndroid Build Coastguard Worker     seg->update_map = 0;
1158*fb1b10abSAndroid Build Coastguard Worker     seg->update_data = 0;
1159*fb1b10abSAndroid Build Coastguard Worker     cpi->static_mb_pct = 0;
1160*fb1b10abSAndroid Build Coastguard Worker 
1161*fb1b10abSAndroid Build Coastguard Worker     // Disable segmentation
1162*fb1b10abSAndroid Build Coastguard Worker     vp9_disable_segmentation(seg);
1163*fb1b10abSAndroid Build Coastguard Worker 
1164*fb1b10abSAndroid Build Coastguard Worker     // Clear down the segment features.
1165*fb1b10abSAndroid Build Coastguard Worker     vp9_clearall_segfeatures(seg);
1166*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->refresh_alt_ref_frame) {
1167*fb1b10abSAndroid Build Coastguard Worker     // If this is an alt ref frame
1168*fb1b10abSAndroid Build Coastguard Worker     // Clear down the global segmentation map
1169*fb1b10abSAndroid Build Coastguard Worker     memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
1170*fb1b10abSAndroid Build Coastguard Worker     seg->update_map = 0;
1171*fb1b10abSAndroid Build Coastguard Worker     seg->update_data = 0;
1172*fb1b10abSAndroid Build Coastguard Worker     cpi->static_mb_pct = 0;
1173*fb1b10abSAndroid Build Coastguard Worker 
1174*fb1b10abSAndroid Build Coastguard Worker     // Disable segmentation and individual segment features by default
1175*fb1b10abSAndroid Build Coastguard Worker     vp9_disable_segmentation(seg);
1176*fb1b10abSAndroid Build Coastguard Worker     vp9_clearall_segfeatures(seg);
1177*fb1b10abSAndroid Build Coastguard Worker 
1178*fb1b10abSAndroid Build Coastguard Worker     // Scan frames from current to arf frame.
1179*fb1b10abSAndroid Build Coastguard Worker     // This function re-enables segmentation if appropriate.
1180*fb1b10abSAndroid Build Coastguard Worker     vp9_update_mbgraph_stats(cpi);
1181*fb1b10abSAndroid Build Coastguard Worker 
1182*fb1b10abSAndroid Build Coastguard Worker     // If segmentation was enabled set those features needed for the
1183*fb1b10abSAndroid Build Coastguard Worker     // arf itself.
1184*fb1b10abSAndroid Build Coastguard Worker     if (seg->enabled) {
1185*fb1b10abSAndroid Build Coastguard Worker       seg->update_map = 1;
1186*fb1b10abSAndroid Build Coastguard Worker       seg->update_data = 1;
1187*fb1b10abSAndroid Build Coastguard Worker 
1188*fb1b10abSAndroid Build Coastguard Worker       qi_delta =
1189*fb1b10abSAndroid Build Coastguard Worker           vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
1190*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
1191*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
1192*fb1b10abSAndroid Build Coastguard Worker 
1193*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
1194*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
1195*fb1b10abSAndroid Build Coastguard Worker 
1196*fb1b10abSAndroid Build Coastguard Worker       // Where relevant assume segment data is delta data
1197*fb1b10abSAndroid Build Coastguard Worker       seg->abs_delta = SEGMENT_DELTADATA;
1198*fb1b10abSAndroid Build Coastguard Worker     }
1199*fb1b10abSAndroid Build Coastguard Worker   } else if (seg->enabled) {
1200*fb1b10abSAndroid Build Coastguard Worker     // All other frames if segmentation has been enabled
1201*fb1b10abSAndroid Build Coastguard Worker 
1202*fb1b10abSAndroid Build Coastguard Worker     // First normal frame in a valid gf or alt ref group
1203*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_since_golden == 0) {
1204*fb1b10abSAndroid Build Coastguard Worker       // Set up segment features for normal frames in an arf group
1205*fb1b10abSAndroid Build Coastguard Worker       if (rc->source_alt_ref_active) {
1206*fb1b10abSAndroid Build Coastguard Worker         seg->update_map = 0;
1207*fb1b10abSAndroid Build Coastguard Worker         seg->update_data = 1;
1208*fb1b10abSAndroid Build Coastguard Worker         seg->abs_delta = SEGMENT_DELTADATA;
1209*fb1b10abSAndroid Build Coastguard Worker 
1210*fb1b10abSAndroid Build Coastguard Worker         qi_delta =
1211*fb1b10abSAndroid Build Coastguard Worker             vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
1212*fb1b10abSAndroid Build Coastguard Worker         vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
1213*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
1214*fb1b10abSAndroid Build Coastguard Worker 
1215*fb1b10abSAndroid Build Coastguard Worker         vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
1216*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
1217*fb1b10abSAndroid Build Coastguard Worker 
1218*fb1b10abSAndroid Build Coastguard Worker         // Segment coding disabled for compred testing
1219*fb1b10abSAndroid Build Coastguard Worker         if (high_q || (cpi->static_mb_pct == 100)) {
1220*fb1b10abSAndroid Build Coastguard Worker           vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
1221*fb1b10abSAndroid Build Coastguard Worker           vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
1222*fb1b10abSAndroid Build Coastguard Worker           vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
1223*fb1b10abSAndroid Build Coastguard Worker         }
1224*fb1b10abSAndroid Build Coastguard Worker       } else {
1225*fb1b10abSAndroid Build Coastguard Worker         // Disable segmentation and clear down features if alt ref
1226*fb1b10abSAndroid Build Coastguard Worker         // is not active for this group
1227*fb1b10abSAndroid Build Coastguard Worker 
1228*fb1b10abSAndroid Build Coastguard Worker         vp9_disable_segmentation(seg);
1229*fb1b10abSAndroid Build Coastguard Worker 
1230*fb1b10abSAndroid Build Coastguard Worker         memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
1231*fb1b10abSAndroid Build Coastguard Worker 
1232*fb1b10abSAndroid Build Coastguard Worker         seg->update_map = 0;
1233*fb1b10abSAndroid Build Coastguard Worker         seg->update_data = 0;
1234*fb1b10abSAndroid Build Coastguard Worker 
1235*fb1b10abSAndroid Build Coastguard Worker         vp9_clearall_segfeatures(seg);
1236*fb1b10abSAndroid Build Coastguard Worker       }
1237*fb1b10abSAndroid Build Coastguard Worker     } else if (rc->is_src_frame_alt_ref) {
1238*fb1b10abSAndroid Build Coastguard Worker       // Special case where we are coding over the top of a previous
1239*fb1b10abSAndroid Build Coastguard Worker       // alt ref frame.
1240*fb1b10abSAndroid Build Coastguard Worker       // Segment coding disabled for compred testing
1241*fb1b10abSAndroid Build Coastguard Worker 
1242*fb1b10abSAndroid Build Coastguard Worker       // Enable ref frame features for segment 0 as well
1243*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
1244*fb1b10abSAndroid Build Coastguard Worker       vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
1245*fb1b10abSAndroid Build Coastguard Worker 
1246*fb1b10abSAndroid Build Coastguard Worker       // All mbs should use ALTREF_FRAME
1247*fb1b10abSAndroid Build Coastguard Worker       vp9_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
1248*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
1249*fb1b10abSAndroid Build Coastguard Worker       vp9_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
1250*fb1b10abSAndroid Build Coastguard Worker       vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
1251*fb1b10abSAndroid Build Coastguard Worker 
1252*fb1b10abSAndroid Build Coastguard Worker       // Skip all MBs if high Q (0,0 mv and skip coeffs)
1253*fb1b10abSAndroid Build Coastguard Worker       if (high_q) {
1254*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP);
1255*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
1256*fb1b10abSAndroid Build Coastguard Worker       }
1257*fb1b10abSAndroid Build Coastguard Worker       // Enable data update
1258*fb1b10abSAndroid Build Coastguard Worker       seg->update_data = 1;
1259*fb1b10abSAndroid Build Coastguard Worker     } else {
1260*fb1b10abSAndroid Build Coastguard Worker       // All other frames.
1261*fb1b10abSAndroid Build Coastguard Worker 
1262*fb1b10abSAndroid Build Coastguard Worker       // No updates.. leave things as they are.
1263*fb1b10abSAndroid Build Coastguard Worker       seg->update_map = 0;
1264*fb1b10abSAndroid Build Coastguard Worker       seg->update_data = 0;
1265*fb1b10abSAndroid Build Coastguard Worker     }
1266*fb1b10abSAndroid Build Coastguard Worker   }
1267*fb1b10abSAndroid Build Coastguard Worker }
1268*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
1269*fb1b10abSAndroid Build Coastguard Worker 
update_reference_segmentation_map(VP9_COMP * cpi)1270*fb1b10abSAndroid Build Coastguard Worker static void update_reference_segmentation_map(VP9_COMP *cpi) {
1271*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1272*fb1b10abSAndroid Build Coastguard Worker   MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
1273*fb1b10abSAndroid Build Coastguard Worker   uint8_t *cache_ptr = cm->last_frame_seg_map;
1274*fb1b10abSAndroid Build Coastguard Worker   int row, col;
1275*fb1b10abSAndroid Build Coastguard Worker 
1276*fb1b10abSAndroid Build Coastguard Worker   for (row = 0; row < cm->mi_rows; row++) {
1277*fb1b10abSAndroid Build Coastguard Worker     MODE_INFO **mi_8x8 = mi_8x8_ptr;
1278*fb1b10abSAndroid Build Coastguard Worker     uint8_t *cache = cache_ptr;
1279*fb1b10abSAndroid Build Coastguard Worker     for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
1280*fb1b10abSAndroid Build Coastguard Worker       cache[0] = mi_8x8[0]->segment_id;
1281*fb1b10abSAndroid Build Coastguard Worker     mi_8x8_ptr += cm->mi_stride;
1282*fb1b10abSAndroid Build Coastguard Worker     cache_ptr += cm->mi_cols;
1283*fb1b10abSAndroid Build Coastguard Worker   }
1284*fb1b10abSAndroid Build Coastguard Worker }
1285*fb1b10abSAndroid Build Coastguard Worker 
alloc_raw_frame_buffers(VP9_COMP * cpi)1286*fb1b10abSAndroid Build Coastguard Worker static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
1287*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1288*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
1289*fb1b10abSAndroid Build Coastguard Worker 
1290*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->lookahead)
1291*fb1b10abSAndroid Build Coastguard Worker     cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
1292*fb1b10abSAndroid Build Coastguard Worker                                         cm->subsampling_x, cm->subsampling_y,
1293*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1294*fb1b10abSAndroid Build Coastguard Worker                                         cm->use_highbitdepth,
1295*fb1b10abSAndroid Build Coastguard Worker #endif
1296*fb1b10abSAndroid Build Coastguard Worker                                         oxcf->lag_in_frames);
1297*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->lookahead)
1298*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1299*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate lag buffers");
1300*fb1b10abSAndroid Build Coastguard Worker 
1301*fb1b10abSAndroid Build Coastguard Worker   // TODO(agrange) Check if ARF is enabled and skip allocation if not.
1302*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->tf_buffer, oxcf->width, oxcf->height,
1303*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1304*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1305*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1306*fb1b10abSAndroid Build Coastguard Worker #endif
1307*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1308*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1309*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1310*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate temporal filter buffer");
1311*fb1b10abSAndroid Build Coastguard Worker }
1312*fb1b10abSAndroid Build Coastguard Worker 
alloc_util_frame_buffers(VP9_COMP * cpi)1313*fb1b10abSAndroid Build Coastguard Worker static void alloc_util_frame_buffers(VP9_COMP *cpi) {
1314*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1315*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
1316*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1317*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1318*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1319*fb1b10abSAndroid Build Coastguard Worker #endif
1320*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1321*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1322*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1323*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate last frame buffer");
1324*fb1b10abSAndroid Build Coastguard Worker 
1325*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
1326*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1327*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1328*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1329*fb1b10abSAndroid Build Coastguard Worker #endif
1330*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1331*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1332*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1333*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate scaled source buffer");
1334*fb1b10abSAndroid Build Coastguard Worker 
1335*fb1b10abSAndroid Build Coastguard Worker   // For 1 pass cbr: allocate scaled_frame that may be used as an intermediate
1336*fb1b10abSAndroid Build Coastguard Worker   // buffer for a 2 stage down-sampling: two stages of 1:2 down-sampling for a
1337*fb1b10abSAndroid Build Coastguard Worker   // target of 1/4x1/4. number_spatial_layers must be greater than 2.
1338*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi) && !cpi->svc.scaled_temp_is_alloc &&
1339*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.number_spatial_layers > 2) {
1340*fb1b10abSAndroid Build Coastguard Worker     cpi->svc.scaled_temp_is_alloc = 1;
1341*fb1b10abSAndroid Build Coastguard Worker     if (vpx_realloc_frame_buffer(
1342*fb1b10abSAndroid Build Coastguard Worker             &cpi->svc.scaled_temp, cm->width >> 1, cm->height >> 1,
1343*fb1b10abSAndroid Build Coastguard Worker             cm->subsampling_x, cm->subsampling_y,
1344*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1345*fb1b10abSAndroid Build Coastguard Worker             cm->use_highbitdepth,
1346*fb1b10abSAndroid Build Coastguard Worker #endif
1347*fb1b10abSAndroid Build Coastguard Worker             VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
1348*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
1349*fb1b10abSAndroid Build Coastguard Worker                          "Failed to allocate scaled_frame for svc ");
1350*fb1b10abSAndroid Build Coastguard Worker   }
1351*fb1b10abSAndroid Build Coastguard Worker 
1352*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
1353*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1354*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1355*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1356*fb1b10abSAndroid Build Coastguard Worker #endif
1357*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1358*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1359*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1360*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate scaled last source buffer");
1361*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
1362*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->raw_unscaled_source, cm->width, cm->height,
1363*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1364*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1365*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1366*fb1b10abSAndroid Build Coastguard Worker #endif
1367*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1368*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1369*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1370*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate unscaled raw source frame buffer");
1371*fb1b10abSAndroid Build Coastguard Worker 
1372*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(&cpi->raw_scaled_source, cm->width, cm->height,
1373*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
1374*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1375*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
1376*fb1b10abSAndroid Build Coastguard Worker #endif
1377*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
1378*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
1379*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1380*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate scaled raw source frame buffer");
1381*fb1b10abSAndroid Build Coastguard Worker #endif
1382*fb1b10abSAndroid Build Coastguard Worker }
1383*fb1b10abSAndroid Build Coastguard Worker 
alloc_context_buffers_ext(VP9_COMP * cpi)1384*fb1b10abSAndroid Build Coastguard Worker static void alloc_context_buffers_ext(VP9_COMP *cpi) {
1385*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1386*fb1b10abSAndroid Build Coastguard Worker   int mi_size = cm->mi_cols * cm->mi_rows;
1387*fb1b10abSAndroid Build Coastguard Worker 
1388*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->mbmi_ext_base,
1389*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(mi_size, sizeof(*cpi->mbmi_ext_base)));
1390*fb1b10abSAndroid Build Coastguard Worker }
1391*fb1b10abSAndroid Build Coastguard Worker 
alloc_compressor_data(VP9_COMP * cpi)1392*fb1b10abSAndroid Build Coastguard Worker static void alloc_compressor_data(VP9_COMP *cpi) {
1393*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1394*fb1b10abSAndroid Build Coastguard Worker   int sb_rows;
1395*fb1b10abSAndroid Build Coastguard Worker 
1396*fb1b10abSAndroid Build Coastguard Worker   if (vp9_alloc_context_buffers(cm, cm->width, cm->height)) {
1397*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
1398*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate context buffers");
1399*fb1b10abSAndroid Build Coastguard Worker   }
1400*fb1b10abSAndroid Build Coastguard Worker 
1401*fb1b10abSAndroid Build Coastguard Worker   alloc_context_buffers_ext(cpi);
1402*fb1b10abSAndroid Build Coastguard Worker 
1403*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->tile_tok[0][0]);
1404*fb1b10abSAndroid Build Coastguard Worker 
1405*fb1b10abSAndroid Build Coastguard Worker   {
1406*fb1b10abSAndroid Build Coastguard Worker     unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
1407*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(&cm->error, cpi->tile_tok[0][0],
1408*fb1b10abSAndroid Build Coastguard Worker                     vpx_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
1409*fb1b10abSAndroid Build Coastguard Worker   }
1410*fb1b10abSAndroid Build Coastguard Worker 
1411*fb1b10abSAndroid Build Coastguard Worker   sb_rows = mi_cols_aligned_to_sb(cm->mi_rows) >> MI_BLOCK_SIZE_LOG2;
1412*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->tplist[0][0]);
1413*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
1414*fb1b10abSAndroid Build Coastguard Worker       &cm->error, cpi->tplist[0][0],
1415*fb1b10abSAndroid Build Coastguard Worker       vpx_calloc(sb_rows * 4 * (1 << 6), sizeof(*cpi->tplist[0][0])));
1416*fb1b10abSAndroid Build Coastguard Worker 
1417*fb1b10abSAndroid Build Coastguard Worker   vp9_setup_pc_tree(&cpi->common, &cpi->td);
1418*fb1b10abSAndroid Build Coastguard Worker }
1419*fb1b10abSAndroid Build Coastguard Worker 
vp9_new_framerate(VP9_COMP * cpi,double framerate)1420*fb1b10abSAndroid Build Coastguard Worker void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
1421*fb1b10abSAndroid Build Coastguard Worker   cpi->framerate = framerate < 0.1 ? 30 : framerate;
1422*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_update_framerate(cpi);
1423*fb1b10abSAndroid Build Coastguard Worker }
1424*fb1b10abSAndroid Build Coastguard Worker 
set_tile_limits(VP9_COMP * cpi)1425*fb1b10abSAndroid Build Coastguard Worker static void set_tile_limits(VP9_COMP *cpi) {
1426*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1427*fb1b10abSAndroid Build Coastguard Worker 
1428*fb1b10abSAndroid Build Coastguard Worker   int min_log2_tile_cols, max_log2_tile_cols;
1429*fb1b10abSAndroid Build Coastguard Worker   vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
1430*fb1b10abSAndroid Build Coastguard Worker 
1431*fb1b10abSAndroid Build Coastguard Worker   cm->log2_tile_cols =
1432*fb1b10abSAndroid Build Coastguard Worker       clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
1433*fb1b10abSAndroid Build Coastguard Worker   cm->log2_tile_rows = cpi->oxcf.tile_rows;
1434*fb1b10abSAndroid Build Coastguard Worker 
1435*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.target_level == LEVEL_AUTO) {
1436*fb1b10abSAndroid Build Coastguard Worker     const int level_tile_cols =
1437*fb1b10abSAndroid Build Coastguard Worker         log_tile_cols_from_picsize_level(cpi->common.width, cpi->common.height);
1438*fb1b10abSAndroid Build Coastguard Worker     if (cm->log2_tile_cols > level_tile_cols) {
1439*fb1b10abSAndroid Build Coastguard Worker       cm->log2_tile_cols = VPXMAX(level_tile_cols, min_log2_tile_cols);
1440*fb1b10abSAndroid Build Coastguard Worker     }
1441*fb1b10abSAndroid Build Coastguard Worker   }
1442*fb1b10abSAndroid Build Coastguard Worker }
1443*fb1b10abSAndroid Build Coastguard Worker 
update_frame_size(VP9_COMP * cpi)1444*fb1b10abSAndroid Build Coastguard Worker static void update_frame_size(VP9_COMP *cpi) {
1445*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1446*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
1447*fb1b10abSAndroid Build Coastguard Worker 
1448*fb1b10abSAndroid Build Coastguard Worker   vp9_set_mb_mi(cm, cm->width, cm->height);
1449*fb1b10abSAndroid Build Coastguard Worker   vp9_init_context_buffers(cm);
1450*fb1b10abSAndroid Build Coastguard Worker   vp9_init_macroblockd(cm, xd, NULL);
1451*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.mbmi_ext_base = cpi->mbmi_ext_base;
1452*fb1b10abSAndroid Build Coastguard Worker   memset(cpi->mbmi_ext_base, 0,
1453*fb1b10abSAndroid Build Coastguard Worker          cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
1454*fb1b10abSAndroid Build Coastguard Worker 
1455*fb1b10abSAndroid Build Coastguard Worker   set_tile_limits(cpi);
1456*fb1b10abSAndroid Build Coastguard Worker }
1457*fb1b10abSAndroid Build Coastguard Worker 
init_buffer_indices(VP9_COMP * cpi)1458*fb1b10abSAndroid Build Coastguard Worker static void init_buffer_indices(VP9_COMP *cpi) {
1459*fb1b10abSAndroid Build Coastguard Worker   int ref_frame;
1460*fb1b10abSAndroid Build Coastguard Worker 
1461*fb1b10abSAndroid Build Coastguard Worker   for (ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame)
1462*fb1b10abSAndroid Build Coastguard Worker     cpi->ref_fb_idx[ref_frame] = ref_frame;
1463*fb1b10abSAndroid Build Coastguard Worker 
1464*fb1b10abSAndroid Build Coastguard Worker   cpi->lst_fb_idx = cpi->ref_fb_idx[LAST_FRAME - 1];
1465*fb1b10abSAndroid Build Coastguard Worker   cpi->gld_fb_idx = cpi->ref_fb_idx[GOLDEN_FRAME - 1];
1466*fb1b10abSAndroid Build Coastguard Worker   cpi->alt_fb_idx = cpi->ref_fb_idx[ALTREF_FRAME - 1];
1467*fb1b10abSAndroid Build Coastguard Worker }
1468*fb1b10abSAndroid Build Coastguard Worker 
init_level_constraint(LevelConstraint * lc)1469*fb1b10abSAndroid Build Coastguard Worker static void init_level_constraint(LevelConstraint *lc) {
1470*fb1b10abSAndroid Build Coastguard Worker   lc->level_index = -1;
1471*fb1b10abSAndroid Build Coastguard Worker   lc->max_cpb_size = INT_MAX;
1472*fb1b10abSAndroid Build Coastguard Worker   lc->max_frame_size = INT_MAX;
1473*fb1b10abSAndroid Build Coastguard Worker   lc->fail_flag = 0;
1474*fb1b10abSAndroid Build Coastguard Worker }
1475*fb1b10abSAndroid Build Coastguard Worker 
set_level_constraint(LevelConstraint * ls,int8_t level_index)1476*fb1b10abSAndroid Build Coastguard Worker static void set_level_constraint(LevelConstraint *ls, int8_t level_index) {
1477*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
1478*fb1b10abSAndroid Build Coastguard Worker   ls->level_index = level_index;
1479*fb1b10abSAndroid Build Coastguard Worker   if (level_index >= 0) {
1480*fb1b10abSAndroid Build Coastguard Worker     ls->max_cpb_size = vp9_level_defs[level_index].max_cpb_size * (double)1000;
1481*fb1b10abSAndroid Build Coastguard Worker   }
1482*fb1b10abSAndroid Build Coastguard Worker }
1483*fb1b10abSAndroid Build Coastguard Worker 
init_config(struct VP9_COMP * cpi,const VP9EncoderConfig * oxcf)1484*fb1b10abSAndroid Build Coastguard Worker static void init_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
1485*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1486*fb1b10abSAndroid Build Coastguard Worker 
1487*fb1b10abSAndroid Build Coastguard Worker   cpi->oxcf = *oxcf;
1488*fb1b10abSAndroid Build Coastguard Worker   cpi->framerate = oxcf->init_framerate;
1489*fb1b10abSAndroid Build Coastguard Worker   cm->profile = oxcf->profile;
1490*fb1b10abSAndroid Build Coastguard Worker   cm->bit_depth = oxcf->bit_depth;
1491*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1492*fb1b10abSAndroid Build Coastguard Worker   cm->use_highbitdepth = oxcf->use_highbitdepth;
1493*fb1b10abSAndroid Build Coastguard Worker #endif
1494*fb1b10abSAndroid Build Coastguard Worker   cm->color_space = oxcf->color_space;
1495*fb1b10abSAndroid Build Coastguard Worker   cm->color_range = oxcf->color_range;
1496*fb1b10abSAndroid Build Coastguard Worker 
1497*fb1b10abSAndroid Build Coastguard Worker   cpi->target_level = oxcf->target_level;
1498*fb1b10abSAndroid Build Coastguard Worker   cpi->keep_level_stats = oxcf->target_level != LEVEL_MAX;
1499*fb1b10abSAndroid Build Coastguard Worker   set_level_constraint(&cpi->level_constraint,
1500*fb1b10abSAndroid Build Coastguard Worker                        get_level_index(cpi->target_level));
1501*fb1b10abSAndroid Build Coastguard Worker 
1502*fb1b10abSAndroid Build Coastguard Worker   cm->width = oxcf->width;
1503*fb1b10abSAndroid Build Coastguard Worker   cm->height = oxcf->height;
1504*fb1b10abSAndroid Build Coastguard Worker   alloc_compressor_data(cpi);
1505*fb1b10abSAndroid Build Coastguard Worker 
1506*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.temporal_layering_mode = oxcf->temporal_layering_mode;
1507*fb1b10abSAndroid Build Coastguard Worker 
1508*fb1b10abSAndroid Build Coastguard Worker   // Single thread case: use counts in common.
1509*fb1b10abSAndroid Build Coastguard Worker   cpi->td.counts = &cm->counts;
1510*fb1b10abSAndroid Build Coastguard Worker 
1511*fb1b10abSAndroid Build Coastguard Worker   // Spatial scalability.
1512*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
1513*fb1b10abSAndroid Build Coastguard Worker   // Temporal scalability.
1514*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.number_temporal_layers = oxcf->ts_number_layers;
1515*fb1b10abSAndroid Build Coastguard Worker 
1516*fb1b10abSAndroid Build Coastguard Worker   if ((cpi->svc.number_temporal_layers > 1) ||
1517*fb1b10abSAndroid Build Coastguard Worker       ((cpi->svc.number_temporal_layers > 1 ||
1518*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.number_spatial_layers > 1) &&
1519*fb1b10abSAndroid Build Coastguard Worker        cpi->oxcf.pass != 1)) {
1520*fb1b10abSAndroid Build Coastguard Worker     vp9_init_layer_context(cpi);
1521*fb1b10abSAndroid Build Coastguard Worker   }
1522*fb1b10abSAndroid Build Coastguard Worker 
1523*fb1b10abSAndroid Build Coastguard Worker   // change includes all joint functionality
1524*fb1b10abSAndroid Build Coastguard Worker   vp9_change_config(cpi, oxcf);
1525*fb1b10abSAndroid Build Coastguard Worker 
1526*fb1b10abSAndroid Build Coastguard Worker   cpi->static_mb_pct = 0;
1527*fb1b10abSAndroid Build Coastguard Worker   cpi->ref_frame_flags = 0;
1528*fb1b10abSAndroid Build Coastguard Worker 
1529*fb1b10abSAndroid Build Coastguard Worker   init_buffer_indices(cpi);
1530*fb1b10abSAndroid Build Coastguard Worker 
1531*fb1b10abSAndroid Build Coastguard Worker   vp9_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height);
1532*fb1b10abSAndroid Build Coastguard Worker   cpi->fixed_qp_onepass = 0;
1533*fb1b10abSAndroid Build Coastguard Worker }
1534*fb1b10abSAndroid Build Coastguard Worker 
vp9_check_reset_rc_flag(VP9_COMP * cpi)1535*fb1b10abSAndroid Build Coastguard Worker void vp9_check_reset_rc_flag(VP9_COMP *cpi) {
1536*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *rc = &cpi->rc;
1537*fb1b10abSAndroid Build Coastguard Worker 
1538*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.current_video_frame >
1539*fb1b10abSAndroid Build Coastguard Worker       (unsigned int)cpi->svc.number_spatial_layers) {
1540*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
1541*fb1b10abSAndroid Build Coastguard Worker       vp9_svc_check_reset_layer_rc_flag(cpi);
1542*fb1b10abSAndroid Build Coastguard Worker     } else {
1543*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_bandwidth / 3 > (rc->last_avg_frame_bandwidth >> 1) ||
1544*fb1b10abSAndroid Build Coastguard Worker           rc->avg_frame_bandwidth < (rc->last_avg_frame_bandwidth >> 1)) {
1545*fb1b10abSAndroid Build Coastguard Worker         rc->rc_1_frame = 0;
1546*fb1b10abSAndroid Build Coastguard Worker         rc->rc_2_frame = 0;
1547*fb1b10abSAndroid Build Coastguard Worker         rc->bits_off_target = rc->optimal_buffer_level;
1548*fb1b10abSAndroid Build Coastguard Worker         rc->buffer_level = rc->optimal_buffer_level;
1549*fb1b10abSAndroid Build Coastguard Worker       }
1550*fb1b10abSAndroid Build Coastguard Worker     }
1551*fb1b10abSAndroid Build Coastguard Worker   }
1552*fb1b10abSAndroid Build Coastguard Worker }
1553*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_rc_buffer_sizes(VP9_COMP * cpi)1554*fb1b10abSAndroid Build Coastguard Worker void vp9_set_rc_buffer_sizes(VP9_COMP *cpi) {
1555*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *rc = &cpi->rc;
1556*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
1557*fb1b10abSAndroid Build Coastguard Worker 
1558*fb1b10abSAndroid Build Coastguard Worker   const int64_t bandwidth = oxcf->target_bandwidth;
1559*fb1b10abSAndroid Build Coastguard Worker   const int64_t starting = oxcf->starting_buffer_level_ms;
1560*fb1b10abSAndroid Build Coastguard Worker   const int64_t optimal = oxcf->optimal_buffer_level_ms;
1561*fb1b10abSAndroid Build Coastguard Worker   const int64_t maximum = oxcf->maximum_buffer_size_ms;
1562*fb1b10abSAndroid Build Coastguard Worker 
1563*fb1b10abSAndroid Build Coastguard Worker   rc->starting_buffer_level = starting * bandwidth / 1000;
1564*fb1b10abSAndroid Build Coastguard Worker   rc->optimal_buffer_level =
1565*fb1b10abSAndroid Build Coastguard Worker       (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
1566*fb1b10abSAndroid Build Coastguard Worker   rc->maximum_buffer_size =
1567*fb1b10abSAndroid Build Coastguard Worker       (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
1568*fb1b10abSAndroid Build Coastguard Worker 
1569*fb1b10abSAndroid Build Coastguard Worker   // Under a configuration change, where maximum_buffer_size may change,
1570*fb1b10abSAndroid Build Coastguard Worker   // keep buffer level clipped to the maximum allowed buffer size.
1571*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size);
1572*fb1b10abSAndroid Build Coastguard Worker   rc->buffer_level = VPXMIN(rc->buffer_level, rc->maximum_buffer_size);
1573*fb1b10abSAndroid Build Coastguard Worker }
1574*fb1b10abSAndroid Build Coastguard Worker 
1575*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
1576*fb1b10abSAndroid Build Coastguard Worker #define HIGHBD_BFP(BT, SDF, SDSF, SDAF, VF, SVF, SVAF, SDX4DF, SDSX4DF) \
1577*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdf = SDF;                                            \
1578*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdsf = SDSF;                                          \
1579*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdaf = SDAF;                                          \
1580*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].vf = VF;                                              \
1581*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].svf = SVF;                                            \
1582*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].svaf = SVAF;                                          \
1583*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdx4df = SDX4DF;                                      \
1584*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdsx4df = SDSX4DF;
1585*fb1b10abSAndroid Build Coastguard Worker 
1586*fb1b10abSAndroid Build Coastguard Worker #define MAKE_BFP_SAD_WRAPPER(fnname)                                           \
1587*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits8(const uint8_t *src_ptr,                   \
1588*fb1b10abSAndroid Build Coastguard Worker                                      int source_stride,                        \
1589*fb1b10abSAndroid Build Coastguard Worker                                      const uint8_t *ref_ptr, int ref_stride) { \
1590*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride);                \
1591*fb1b10abSAndroid Build Coastguard Worker   }                                                                            \
1592*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits10(                                         \
1593*fb1b10abSAndroid Build Coastguard Worker       const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
1594*fb1b10abSAndroid Build Coastguard Worker       int ref_stride) {                                                        \
1595*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2;           \
1596*fb1b10abSAndroid Build Coastguard Worker   }                                                                            \
1597*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits12(                                         \
1598*fb1b10abSAndroid Build Coastguard Worker       const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
1599*fb1b10abSAndroid Build Coastguard Worker       int ref_stride) {                                                        \
1600*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4;           \
1601*fb1b10abSAndroid Build Coastguard Worker   }
1602*fb1b10abSAndroid Build Coastguard Worker 
1603*fb1b10abSAndroid Build Coastguard Worker #define MAKE_BFP_SADAVG_WRAPPER(fnname)                                        \
1604*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits8(                                          \
1605*fb1b10abSAndroid Build Coastguard Worker       const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
1606*fb1b10abSAndroid Build Coastguard Worker       int ref_stride, const uint8_t *second_pred) {                            \
1607*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred);   \
1608*fb1b10abSAndroid Build Coastguard Worker   }                                                                            \
1609*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits10(                                         \
1610*fb1b10abSAndroid Build Coastguard Worker       const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
1611*fb1b10abSAndroid Build Coastguard Worker       int ref_stride, const uint8_t *second_pred) {                            \
1612*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
1613*fb1b10abSAndroid Build Coastguard Worker            2;                                                                  \
1614*fb1b10abSAndroid Build Coastguard Worker   }                                                                            \
1615*fb1b10abSAndroid Build Coastguard Worker   static unsigned int fnname##_bits12(                                         \
1616*fb1b10abSAndroid Build Coastguard Worker       const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
1617*fb1b10abSAndroid Build Coastguard Worker       int ref_stride, const uint8_t *second_pred) {                            \
1618*fb1b10abSAndroid Build Coastguard Worker     return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
1619*fb1b10abSAndroid Build Coastguard Worker            4;                                                                  \
1620*fb1b10abSAndroid Build Coastguard Worker   }
1621*fb1b10abSAndroid Build Coastguard Worker 
1622*fb1b10abSAndroid Build Coastguard Worker #define MAKE_BFP_SAD4D_WRAPPER(fnname)                                        \
1623*fb1b10abSAndroid Build Coastguard Worker   static void fnname##_bits8(const uint8_t *src_ptr, int source_stride,       \
1624*fb1b10abSAndroid Build Coastguard Worker                              const uint8_t *const ref_ptr[], int ref_stride,  \
1625*fb1b10abSAndroid Build Coastguard Worker                              unsigned int *sad_array) {                       \
1626*fb1b10abSAndroid Build Coastguard Worker     fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
1627*fb1b10abSAndroid Build Coastguard Worker   }                                                                           \
1628*fb1b10abSAndroid Build Coastguard Worker   static void fnname##_bits10(const uint8_t *src_ptr, int source_stride,      \
1629*fb1b10abSAndroid Build Coastguard Worker                               const uint8_t *const ref_ptr[], int ref_stride, \
1630*fb1b10abSAndroid Build Coastguard Worker                               unsigned int *sad_array) {                      \
1631*fb1b10abSAndroid Build Coastguard Worker     int i;                                                                    \
1632*fb1b10abSAndroid Build Coastguard Worker     fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
1633*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 4; i++) sad_array[i] >>= 2;                               \
1634*fb1b10abSAndroid Build Coastguard Worker   }                                                                           \
1635*fb1b10abSAndroid Build Coastguard Worker   static void fnname##_bits12(const uint8_t *src_ptr, int source_stride,      \
1636*fb1b10abSAndroid Build Coastguard Worker                               const uint8_t *const ref_ptr[], int ref_stride, \
1637*fb1b10abSAndroid Build Coastguard Worker                               unsigned int *sad_array) {                      \
1638*fb1b10abSAndroid Build Coastguard Worker     int i;                                                                    \
1639*fb1b10abSAndroid Build Coastguard Worker     fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
1640*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 4; i++) sad_array[i] >>= 4;                               \
1641*fb1b10abSAndroid Build Coastguard Worker   }
1642*fb1b10abSAndroid Build Coastguard Worker 
1643*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x16)
MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x16)1644*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x16)
1645*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x16_avg)
1646*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x16x4d)
1647*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x16x4d)
1648*fb1b10abSAndroid Build Coastguard Worker 
1649*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x32)
1650*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x32)
1651*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x32_avg)
1652*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x32x4d)
1653*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x32x4d)
1654*fb1b10abSAndroid Build Coastguard Worker 
1655*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad64x32)
1656*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_64x32)
1657*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad64x32_avg)
1658*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad64x32x4d)
1659*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_64x32x4d)
1660*fb1b10abSAndroid Build Coastguard Worker 
1661*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x64)
1662*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x64)
1663*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x64_avg)
1664*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x64x4d)
1665*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x64x4d)
1666*fb1b10abSAndroid Build Coastguard Worker 
1667*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad32x32)
1668*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_32x32)
1669*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad32x32_avg)
1670*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad32x32x4d)
1671*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_32x32x4d)
1672*fb1b10abSAndroid Build Coastguard Worker 
1673*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad64x64)
1674*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_64x64)
1675*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad64x64_avg)
1676*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad64x64x4d)
1677*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_64x64x4d)
1678*fb1b10abSAndroid Build Coastguard Worker 
1679*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x16)
1680*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x16)
1681*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x16_avg)
1682*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x16x4d)
1683*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x16x4d)
1684*fb1b10abSAndroid Build Coastguard Worker 
1685*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad16x8)
1686*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_16x8)
1687*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad16x8_avg)
1688*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad16x8x4d)
1689*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_16x8x4d)
1690*fb1b10abSAndroid Build Coastguard Worker 
1691*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x16)
1692*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x16)
1693*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x16_avg)
1694*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x16x4d)
1695*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x16x4d)
1696*fb1b10abSAndroid Build Coastguard Worker 
1697*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x8)
1698*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x8)
1699*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x8_avg)
1700*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x8x4d)
1701*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x8x4d)
1702*fb1b10abSAndroid Build Coastguard Worker 
1703*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad8x4)
1704*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_8x4)
1705*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad8x4_avg)
1706*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad8x4x4d)
1707*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_8x4x4d)
1708*fb1b10abSAndroid Build Coastguard Worker 
1709*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad4x8)
1710*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_4x8)
1711*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad4x8_avg)
1712*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad4x8x4d)
1713*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_4x8x4d)
1714*fb1b10abSAndroid Build Coastguard Worker 
1715*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad4x4)
1716*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD_WRAPPER(vpx_highbd_sad_skip_4x4)
1717*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SADAVG_WRAPPER(vpx_highbd_sad4x4_avg)
1718*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad4x4x4d)
1719*fb1b10abSAndroid Build Coastguard Worker MAKE_BFP_SAD4D_WRAPPER(vpx_highbd_sad_skip_4x4x4d)
1720*fb1b10abSAndroid Build Coastguard Worker 
1721*fb1b10abSAndroid Build Coastguard Worker static void highbd_set_var_fns(VP9_COMP *const cpi) {
1722*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1723*fb1b10abSAndroid Build Coastguard Worker   if (cm->use_highbitdepth) {
1724*fb1b10abSAndroid Build Coastguard Worker     switch (cm->bit_depth) {
1725*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_8:
1726*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1727*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X16, vpx_highbd_sad32x16_bits8,
1728*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x16_bits8, vpx_highbd_sad32x16_avg_bits8,
1729*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance32x16, vpx_highbd_8_sub_pixel_variance32x16,
1730*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance32x16,
1731*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x16x4d_bits8, vpx_highbd_sad_skip_32x16x4d_bits8)
1732*fb1b10abSAndroid Build Coastguard Worker 
1733*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1734*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X32, vpx_highbd_sad16x32_bits8,
1735*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x32_bits8, vpx_highbd_sad16x32_avg_bits8,
1736*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance16x32, vpx_highbd_8_sub_pixel_variance16x32,
1737*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance16x32,
1738*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x32x4d_bits8, vpx_highbd_sad_skip_16x32x4d_bits8)
1739*fb1b10abSAndroid Build Coastguard Worker 
1740*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1741*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X32, vpx_highbd_sad64x32_bits8,
1742*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x32_bits8, vpx_highbd_sad64x32_avg_bits8,
1743*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance64x32, vpx_highbd_8_sub_pixel_variance64x32,
1744*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance64x32,
1745*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x32x4d_bits8, vpx_highbd_sad_skip_64x32x4d_bits8)
1746*fb1b10abSAndroid Build Coastguard Worker 
1747*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1748*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X64, vpx_highbd_sad32x64_bits8,
1749*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x64_bits8, vpx_highbd_sad32x64_avg_bits8,
1750*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance32x64, vpx_highbd_8_sub_pixel_variance32x64,
1751*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance32x64,
1752*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x64x4d_bits8, vpx_highbd_sad_skip_32x64x4d_bits8)
1753*fb1b10abSAndroid Build Coastguard Worker 
1754*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1755*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X32, vpx_highbd_sad32x32_bits8,
1756*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x32_bits8, vpx_highbd_sad32x32_avg_bits8,
1757*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance32x32, vpx_highbd_8_sub_pixel_variance32x32,
1758*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance32x32,
1759*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x32x4d_bits8, vpx_highbd_sad_skip_32x32x4d_bits8)
1760*fb1b10abSAndroid Build Coastguard Worker 
1761*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1762*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X64, vpx_highbd_sad64x64_bits8,
1763*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x64_bits8, vpx_highbd_sad64x64_avg_bits8,
1764*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance64x64, vpx_highbd_8_sub_pixel_variance64x64,
1765*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance64x64,
1766*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x64x4d_bits8, vpx_highbd_sad_skip_64x64x4d_bits8)
1767*fb1b10abSAndroid Build Coastguard Worker 
1768*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1769*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X16, vpx_highbd_sad16x16_bits8,
1770*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x16_bits8, vpx_highbd_sad16x16_avg_bits8,
1771*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance16x16, vpx_highbd_8_sub_pixel_variance16x16,
1772*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance16x16,
1773*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x16x4d_bits8, vpx_highbd_sad_skip_16x16x4d_bits8)
1774*fb1b10abSAndroid Build Coastguard Worker 
1775*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1776*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X8, vpx_highbd_sad16x8_bits8,
1777*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x8_bits8, vpx_highbd_sad16x8_avg_bits8,
1778*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance16x8, vpx_highbd_8_sub_pixel_variance16x8,
1779*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance16x8,
1780*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x8x4d_bits8, vpx_highbd_sad_skip_16x8x4d_bits8)
1781*fb1b10abSAndroid Build Coastguard Worker 
1782*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1783*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X16, vpx_highbd_sad8x16_bits8,
1784*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_8x16_bits8, vpx_highbd_sad8x16_avg_bits8,
1785*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_variance8x16, vpx_highbd_8_sub_pixel_variance8x16,
1786*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_8_sub_pixel_avg_variance8x16,
1787*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x16x4d_bits8, vpx_highbd_sad_skip_8x16x4d_bits8)
1788*fb1b10abSAndroid Build Coastguard Worker 
1789*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(BLOCK_8X8, vpx_highbd_sad8x8_bits8,
1790*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad_skip_8x8_bits8, vpx_highbd_sad8x8_avg_bits8,
1791*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_variance8x8, vpx_highbd_8_sub_pixel_variance8x8,
1792*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_sub_pixel_avg_variance8x8,
1793*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad8x8x4d_bits8, vpx_highbd_sad_skip_8x8x4d_bits8)
1794*fb1b10abSAndroid Build Coastguard Worker 
1795*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(BLOCK_8X4, vpx_highbd_sad8x4_bits8,
1796*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad_skip_8x4_bits8, vpx_highbd_sad8x4_avg_bits8,
1797*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_variance8x4, vpx_highbd_8_sub_pixel_variance8x4,
1798*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_sub_pixel_avg_variance8x4,
1799*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad8x4x4d_bits8, vpx_highbd_sad_skip_8x4x4d_bits8)
1800*fb1b10abSAndroid Build Coastguard Worker 
1801*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(BLOCK_4X8, vpx_highbd_sad4x8_bits8,
1802*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad_skip_4x8_bits8, vpx_highbd_sad4x8_avg_bits8,
1803*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_variance4x8, vpx_highbd_8_sub_pixel_variance4x8,
1804*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_sub_pixel_avg_variance4x8,
1805*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad4x8x4d_bits8, vpx_highbd_sad_skip_4x8x4d_bits8)
1806*fb1b10abSAndroid Build Coastguard Worker 
1807*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(BLOCK_4X4, vpx_highbd_sad4x4_bits8,
1808*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad_skip_4x4_bits8, vpx_highbd_sad4x4_avg_bits8,
1809*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_variance4x4, vpx_highbd_8_sub_pixel_variance4x4,
1810*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_8_sub_pixel_avg_variance4x4,
1811*fb1b10abSAndroid Build Coastguard Worker                    vpx_highbd_sad4x4x4d_bits8, vpx_highbd_sad_skip_4x4x4d_bits8)
1812*fb1b10abSAndroid Build Coastguard Worker         break;
1813*fb1b10abSAndroid Build Coastguard Worker 
1814*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_10:
1815*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1816*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X16, vpx_highbd_sad32x16_bits10,
1817*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x16_bits10, vpx_highbd_sad32x16_avg_bits10,
1818*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance32x16, vpx_highbd_10_sub_pixel_variance32x16,
1819*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance32x16,
1820*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x16x4d_bits10, vpx_highbd_sad_skip_32x16x4d_bits10)
1821*fb1b10abSAndroid Build Coastguard Worker 
1822*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1823*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X32, vpx_highbd_sad16x32_bits10,
1824*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x32_bits10, vpx_highbd_sad16x32_avg_bits10,
1825*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance16x32, vpx_highbd_10_sub_pixel_variance16x32,
1826*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance16x32,
1827*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x32x4d_bits10, vpx_highbd_sad_skip_16x32x4d_bits10)
1828*fb1b10abSAndroid Build Coastguard Worker 
1829*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1830*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X32, vpx_highbd_sad64x32_bits10,
1831*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x32_bits10, vpx_highbd_sad64x32_avg_bits10,
1832*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance64x32, vpx_highbd_10_sub_pixel_variance64x32,
1833*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance64x32,
1834*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x32x4d_bits10, vpx_highbd_sad_skip_64x32x4d_bits10)
1835*fb1b10abSAndroid Build Coastguard Worker 
1836*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1837*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X64, vpx_highbd_sad32x64_bits10,
1838*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x64_bits10, vpx_highbd_sad32x64_avg_bits10,
1839*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance32x64, vpx_highbd_10_sub_pixel_variance32x64,
1840*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance32x64,
1841*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x64x4d_bits10, vpx_highbd_sad_skip_32x64x4d_bits10)
1842*fb1b10abSAndroid Build Coastguard Worker 
1843*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1844*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X32, vpx_highbd_sad32x32_bits10,
1845*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x32_bits10, vpx_highbd_sad32x32_avg_bits10,
1846*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance32x32, vpx_highbd_10_sub_pixel_variance32x32,
1847*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance32x32,
1848*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x32x4d_bits10, vpx_highbd_sad_skip_32x32x4d_bits10)
1849*fb1b10abSAndroid Build Coastguard Worker 
1850*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1851*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X64, vpx_highbd_sad64x64_bits10,
1852*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x64_bits10, vpx_highbd_sad64x64_avg_bits10,
1853*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance64x64, vpx_highbd_10_sub_pixel_variance64x64,
1854*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance64x64,
1855*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x64x4d_bits10, vpx_highbd_sad_skip_64x64x4d_bits10)
1856*fb1b10abSAndroid Build Coastguard Worker 
1857*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1858*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X16, vpx_highbd_sad16x16_bits10,
1859*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x16_bits10, vpx_highbd_sad16x16_avg_bits10,
1860*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance16x16, vpx_highbd_10_sub_pixel_variance16x16,
1861*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance16x16,
1862*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x16x4d_bits10, vpx_highbd_sad_skip_16x16x4d_bits10)
1863*fb1b10abSAndroid Build Coastguard Worker 
1864*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1865*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X8, vpx_highbd_sad16x8_bits10,
1866*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x8_bits10, vpx_highbd_sad16x8_avg_bits10,
1867*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance16x8, vpx_highbd_10_sub_pixel_variance16x8,
1868*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance16x8,
1869*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x8x4d_bits10, vpx_highbd_sad_skip_16x8x4d_bits10)
1870*fb1b10abSAndroid Build Coastguard Worker 
1871*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1872*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X16, vpx_highbd_sad8x16_bits10,
1873*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_8x16_bits10, vpx_highbd_sad8x16_avg_bits10,
1874*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_variance8x16, vpx_highbd_10_sub_pixel_variance8x16,
1875*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance8x16,
1876*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x16x4d_bits10, vpx_highbd_sad_skip_8x16x4d_bits10)
1877*fb1b10abSAndroid Build Coastguard Worker 
1878*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1879*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X8, vpx_highbd_sad8x8_bits10, vpx_highbd_sad_skip_8x8_bits10,
1880*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x8_avg_bits10, vpx_highbd_10_variance8x8,
1881*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_variance8x8,
1882*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance8x8,
1883*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x8x4d_bits10, vpx_highbd_sad_skip_8x8x4d_bits10)
1884*fb1b10abSAndroid Build Coastguard Worker 
1885*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1886*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X4, vpx_highbd_sad8x4_bits10, vpx_highbd_sad_skip_8x4_bits10,
1887*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x4_avg_bits10, vpx_highbd_10_variance8x4,
1888*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_variance8x4,
1889*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance8x4,
1890*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x4x4d_bits10, vpx_highbd_sad_skip_8x4x4d_bits10)
1891*fb1b10abSAndroid Build Coastguard Worker 
1892*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1893*fb1b10abSAndroid Build Coastguard Worker             BLOCK_4X8, vpx_highbd_sad4x8_bits10, vpx_highbd_sad_skip_4x8_bits10,
1894*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x8_avg_bits10, vpx_highbd_10_variance4x8,
1895*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_variance4x8,
1896*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance4x8,
1897*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x8x4d_bits10, vpx_highbd_sad_skip_4x8x4d_bits10)
1898*fb1b10abSAndroid Build Coastguard Worker 
1899*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1900*fb1b10abSAndroid Build Coastguard Worker             BLOCK_4X4, vpx_highbd_sad4x4_bits10, vpx_highbd_sad_skip_4x4_bits10,
1901*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x4_avg_bits10, vpx_highbd_10_variance4x4,
1902*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_variance4x4,
1903*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_10_sub_pixel_avg_variance4x4,
1904*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x4x4d_bits10, vpx_highbd_sad_skip_4x4x4d_bits10)
1905*fb1b10abSAndroid Build Coastguard Worker         break;
1906*fb1b10abSAndroid Build Coastguard Worker 
1907*fb1b10abSAndroid Build Coastguard Worker       default:
1908*fb1b10abSAndroid Build Coastguard Worker         assert(cm->bit_depth == VPX_BITS_12);
1909*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1910*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X16, vpx_highbd_sad32x16_bits12,
1911*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x16_bits12, vpx_highbd_sad32x16_avg_bits12,
1912*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance32x16, vpx_highbd_12_sub_pixel_variance32x16,
1913*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance32x16,
1914*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x16x4d_bits12, vpx_highbd_sad_skip_32x16x4d_bits12)
1915*fb1b10abSAndroid Build Coastguard Worker 
1916*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1917*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X32, vpx_highbd_sad16x32_bits12,
1918*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x32_bits12, vpx_highbd_sad16x32_avg_bits12,
1919*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance16x32, vpx_highbd_12_sub_pixel_variance16x32,
1920*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance16x32,
1921*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x32x4d_bits12, vpx_highbd_sad_skip_16x32x4d_bits12)
1922*fb1b10abSAndroid Build Coastguard Worker 
1923*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1924*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X32, vpx_highbd_sad64x32_bits12,
1925*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x32_bits12, vpx_highbd_sad64x32_avg_bits12,
1926*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance64x32, vpx_highbd_12_sub_pixel_variance64x32,
1927*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance64x32,
1928*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x32x4d_bits12, vpx_highbd_sad_skip_64x32x4d_bits12)
1929*fb1b10abSAndroid Build Coastguard Worker 
1930*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1931*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X64, vpx_highbd_sad32x64_bits12,
1932*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x64_bits12, vpx_highbd_sad32x64_avg_bits12,
1933*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance32x64, vpx_highbd_12_sub_pixel_variance32x64,
1934*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance32x64,
1935*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x64x4d_bits12, vpx_highbd_sad_skip_32x64x4d_bits12)
1936*fb1b10abSAndroid Build Coastguard Worker 
1937*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1938*fb1b10abSAndroid Build Coastguard Worker             BLOCK_32X32, vpx_highbd_sad32x32_bits12,
1939*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_32x32_bits12, vpx_highbd_sad32x32_avg_bits12,
1940*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance32x32, vpx_highbd_12_sub_pixel_variance32x32,
1941*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance32x32,
1942*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad32x32x4d_bits12, vpx_highbd_sad_skip_32x32x4d_bits12)
1943*fb1b10abSAndroid Build Coastguard Worker 
1944*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1945*fb1b10abSAndroid Build Coastguard Worker             BLOCK_64X64, vpx_highbd_sad64x64_bits12,
1946*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_64x64_bits12, vpx_highbd_sad64x64_avg_bits12,
1947*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance64x64, vpx_highbd_12_sub_pixel_variance64x64,
1948*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance64x64,
1949*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad64x64x4d_bits12, vpx_highbd_sad_skip_64x64x4d_bits12)
1950*fb1b10abSAndroid Build Coastguard Worker 
1951*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1952*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X16, vpx_highbd_sad16x16_bits12,
1953*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x16_bits12, vpx_highbd_sad16x16_avg_bits12,
1954*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance16x16, vpx_highbd_12_sub_pixel_variance16x16,
1955*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance16x16,
1956*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x16x4d_bits12, vpx_highbd_sad_skip_16x16x4d_bits12)
1957*fb1b10abSAndroid Build Coastguard Worker 
1958*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1959*fb1b10abSAndroid Build Coastguard Worker             BLOCK_16X8, vpx_highbd_sad16x8_bits12,
1960*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_16x8_bits12, vpx_highbd_sad16x8_avg_bits12,
1961*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance16x8, vpx_highbd_12_sub_pixel_variance16x8,
1962*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance16x8,
1963*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad16x8x4d_bits12, vpx_highbd_sad_skip_16x8x4d_bits12)
1964*fb1b10abSAndroid Build Coastguard Worker 
1965*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1966*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X16, vpx_highbd_sad8x16_bits12,
1967*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad_skip_8x16_bits12, vpx_highbd_sad8x16_avg_bits12,
1968*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_variance8x16, vpx_highbd_12_sub_pixel_variance8x16,
1969*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance8x16,
1970*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x16x4d_bits12, vpx_highbd_sad_skip_8x16x4d_bits12)
1971*fb1b10abSAndroid Build Coastguard Worker 
1972*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1973*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X8, vpx_highbd_sad8x8_bits12, vpx_highbd_sad_skip_8x8_bits12,
1974*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x8_avg_bits12, vpx_highbd_12_variance8x8,
1975*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_variance8x8,
1976*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance8x8,
1977*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x8x4d_bits12, vpx_highbd_sad_skip_8x8x4d_bits12)
1978*fb1b10abSAndroid Build Coastguard Worker 
1979*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1980*fb1b10abSAndroid Build Coastguard Worker             BLOCK_8X4, vpx_highbd_sad8x4_bits12, vpx_highbd_sad_skip_8x4_bits12,
1981*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x4_avg_bits12, vpx_highbd_12_variance8x4,
1982*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_variance8x4,
1983*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance8x4,
1984*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad8x4x4d_bits12, vpx_highbd_sad_skip_8x4x4d_bits12)
1985*fb1b10abSAndroid Build Coastguard Worker 
1986*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1987*fb1b10abSAndroid Build Coastguard Worker             BLOCK_4X8, vpx_highbd_sad4x8_bits12, vpx_highbd_sad_skip_4x8_bits12,
1988*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x8_avg_bits12, vpx_highbd_12_variance4x8,
1989*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_variance4x8,
1990*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance4x8,
1991*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x8x4d_bits12, vpx_highbd_sad_skip_4x8x4d_bits12)
1992*fb1b10abSAndroid Build Coastguard Worker 
1993*fb1b10abSAndroid Build Coastguard Worker         HIGHBD_BFP(
1994*fb1b10abSAndroid Build Coastguard Worker             BLOCK_4X4, vpx_highbd_sad4x4_bits12, vpx_highbd_sad_skip_4x4_bits12,
1995*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x4_avg_bits12, vpx_highbd_12_variance4x4,
1996*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_variance4x4,
1997*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_12_sub_pixel_avg_variance4x4,
1998*fb1b10abSAndroid Build Coastguard Worker             vpx_highbd_sad4x4x4d_bits12, vpx_highbd_sad_skip_4x4x4d_bits12)
1999*fb1b10abSAndroid Build Coastguard Worker         break;
2000*fb1b10abSAndroid Build Coastguard Worker     }
2001*fb1b10abSAndroid Build Coastguard Worker   }
2002*fb1b10abSAndroid Build Coastguard Worker }
2003*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
2004*fb1b10abSAndroid Build Coastguard Worker 
realloc_segmentation_maps(VP9_COMP * cpi)2005*fb1b10abSAndroid Build Coastguard Worker static void realloc_segmentation_maps(VP9_COMP *cpi) {
2006*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2007*fb1b10abSAndroid Build Coastguard Worker 
2008*fb1b10abSAndroid Build Coastguard Worker   // Create the encoder segmentation map and set all entries to 0
2009*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->segmentation_map);
2010*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->segmentation_map,
2011*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
2012*fb1b10abSAndroid Build Coastguard Worker 
2013*fb1b10abSAndroid Build Coastguard Worker   // Create a map used for cyclic background refresh.
2014*fb1b10abSAndroid Build Coastguard Worker   if (cpi->cyclic_refresh) vp9_cyclic_refresh_free(cpi->cyclic_refresh);
2015*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->cyclic_refresh,
2016*fb1b10abSAndroid Build Coastguard Worker                   vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
2017*fb1b10abSAndroid Build Coastguard Worker 
2018*fb1b10abSAndroid Build Coastguard Worker   // Create a map used to mark inactive areas.
2019*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->active_map.map);
2020*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->active_map.map,
2021*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
2022*fb1b10abSAndroid Build Coastguard Worker 
2023*fb1b10abSAndroid Build Coastguard Worker   // And a place holder structure is the coding context
2024*fb1b10abSAndroid Build Coastguard Worker   // for use if we want to save and restore it
2025*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->coding_context.last_frame_seg_map_copy);
2026*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->coding_context.last_frame_seg_map_copy,
2027*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
2028*fb1b10abSAndroid Build Coastguard Worker }
2029*fb1b10abSAndroid Build Coastguard Worker 
alloc_copy_partition_data(VP9_COMP * cpi)2030*fb1b10abSAndroid Build Coastguard Worker static void alloc_copy_partition_data(VP9_COMP *cpi) {
2031*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2032*fb1b10abSAndroid Build Coastguard Worker   if (cpi->prev_partition == NULL) {
2033*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(&cm->error, cpi->prev_partition,
2034*fb1b10abSAndroid Build Coastguard Worker                     (BLOCK_SIZE *)vpx_calloc(cm->mi_stride * cm->mi_rows,
2035*fb1b10abSAndroid Build Coastguard Worker                                              sizeof(*cpi->prev_partition)));
2036*fb1b10abSAndroid Build Coastguard Worker   }
2037*fb1b10abSAndroid Build Coastguard Worker   if (cpi->prev_segment_id == NULL) {
2038*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
2039*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->prev_segment_id,
2040*fb1b10abSAndroid Build Coastguard Worker         (int8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1),
2041*fb1b10abSAndroid Build Coastguard Worker                              sizeof(*cpi->prev_segment_id)));
2042*fb1b10abSAndroid Build Coastguard Worker   }
2043*fb1b10abSAndroid Build Coastguard Worker   if (cpi->prev_variance_low == NULL) {
2044*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(&cm->error, cpi->prev_variance_low,
2045*fb1b10abSAndroid Build Coastguard Worker                     (uint8_t *)vpx_calloc(
2046*fb1b10abSAndroid Build Coastguard Worker                         (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) * 25,
2047*fb1b10abSAndroid Build Coastguard Worker                         sizeof(*cpi->prev_variance_low)));
2048*fb1b10abSAndroid Build Coastguard Worker   }
2049*fb1b10abSAndroid Build Coastguard Worker   if (cpi->copied_frame_cnt == NULL) {
2050*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
2051*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->copied_frame_cnt,
2052*fb1b10abSAndroid Build Coastguard Worker         (uint8_t *)vpx_calloc((cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1),
2053*fb1b10abSAndroid Build Coastguard Worker                               sizeof(*cpi->copied_frame_cnt)));
2054*fb1b10abSAndroid Build Coastguard Worker   }
2055*fb1b10abSAndroid Build Coastguard Worker }
2056*fb1b10abSAndroid Build Coastguard Worker 
free_copy_partition_data(VP9_COMP * cpi)2057*fb1b10abSAndroid Build Coastguard Worker static void free_copy_partition_data(VP9_COMP *cpi) {
2058*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_partition);
2059*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_partition = NULL;
2060*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_segment_id);
2061*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_segment_id = NULL;
2062*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->prev_variance_low);
2063*fb1b10abSAndroid Build Coastguard Worker   cpi->prev_variance_low = NULL;
2064*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->copied_frame_cnt);
2065*fb1b10abSAndroid Build Coastguard Worker   cpi->copied_frame_cnt = NULL;
2066*fb1b10abSAndroid Build Coastguard Worker }
2067*fb1b10abSAndroid Build Coastguard Worker 
vp9_change_config(struct VP9_COMP * cpi,const VP9EncoderConfig * oxcf)2068*fb1b10abSAndroid Build Coastguard Worker void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
2069*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2070*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2071*fb1b10abSAndroid Build Coastguard Worker   int last_w = cpi->oxcf.width;
2072*fb1b10abSAndroid Build Coastguard Worker   int last_h = cpi->oxcf.height;
2073*fb1b10abSAndroid Build Coastguard Worker 
2074*fb1b10abSAndroid Build Coastguard Worker   vp9_init_quantizer(cpi);
2075*fb1b10abSAndroid Build Coastguard Worker   if (cm->profile != oxcf->profile) cm->profile = oxcf->profile;
2076*fb1b10abSAndroid Build Coastguard Worker   cm->bit_depth = oxcf->bit_depth;
2077*fb1b10abSAndroid Build Coastguard Worker   cm->color_space = oxcf->color_space;
2078*fb1b10abSAndroid Build Coastguard Worker   cm->color_range = oxcf->color_range;
2079*fb1b10abSAndroid Build Coastguard Worker 
2080*fb1b10abSAndroid Build Coastguard Worker   cpi->target_level = oxcf->target_level;
2081*fb1b10abSAndroid Build Coastguard Worker   cpi->keep_level_stats = oxcf->target_level != LEVEL_MAX;
2082*fb1b10abSAndroid Build Coastguard Worker   set_level_constraint(&cpi->level_constraint,
2083*fb1b10abSAndroid Build Coastguard Worker                        get_level_index(cpi->target_level));
2084*fb1b10abSAndroid Build Coastguard Worker 
2085*fb1b10abSAndroid Build Coastguard Worker   if (cm->profile <= PROFILE_1)
2086*fb1b10abSAndroid Build Coastguard Worker     assert(cm->bit_depth == VPX_BITS_8);
2087*fb1b10abSAndroid Build Coastguard Worker   else
2088*fb1b10abSAndroid Build Coastguard Worker     assert(cm->bit_depth > VPX_BITS_8);
2089*fb1b10abSAndroid Build Coastguard Worker 
2090*fb1b10abSAndroid Build Coastguard Worker   cpi->oxcf = *oxcf;
2091*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2092*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
2093*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
2094*fb1b10abSAndroid Build Coastguard Worker 
2095*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
2096*fb1b10abSAndroid Build Coastguard Worker     rc->baseline_gf_interval = FIXED_GF_INTERVAL;
2097*fb1b10abSAndroid Build Coastguard Worker   } else {
2098*fb1b10abSAndroid Build Coastguard Worker     rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
2099*fb1b10abSAndroid Build Coastguard Worker   }
2100*fb1b10abSAndroid Build Coastguard Worker 
2101*fb1b10abSAndroid Build Coastguard Worker   cpi->refresh_golden_frame = 0;
2102*fb1b10abSAndroid Build Coastguard Worker   cpi->refresh_last_frame = 1;
2103*fb1b10abSAndroid Build Coastguard Worker   cm->refresh_frame_context = 1;
2104*fb1b10abSAndroid Build Coastguard Worker   cm->reset_frame_context = 0;
2105*fb1b10abSAndroid Build Coastguard Worker 
2106*fb1b10abSAndroid Build Coastguard Worker   vp9_reset_segment_features(&cm->seg);
2107*fb1b10abSAndroid Build Coastguard Worker   vp9_set_high_precision_mv(cpi, 0);
2108*fb1b10abSAndroid Build Coastguard Worker 
2109*fb1b10abSAndroid Build Coastguard Worker   {
2110*fb1b10abSAndroid Build Coastguard Worker     int i;
2111*fb1b10abSAndroid Build Coastguard Worker 
2112*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < MAX_SEGMENTS; i++)
2113*fb1b10abSAndroid Build Coastguard Worker       cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
2114*fb1b10abSAndroid Build Coastguard Worker   }
2115*fb1b10abSAndroid Build Coastguard Worker   cpi->encode_breakout = cpi->oxcf.encode_breakout;
2116*fb1b10abSAndroid Build Coastguard Worker 
2117*fb1b10abSAndroid Build Coastguard Worker   vp9_set_rc_buffer_sizes(cpi);
2118*fb1b10abSAndroid Build Coastguard Worker 
2119*fb1b10abSAndroid Build Coastguard Worker   // Set up frame rate and related parameters rate control values.
2120*fb1b10abSAndroid Build Coastguard Worker   vp9_new_framerate(cpi, cpi->framerate);
2121*fb1b10abSAndroid Build Coastguard Worker 
2122*fb1b10abSAndroid Build Coastguard Worker   // Set absolute upper and lower quality limits
2123*fb1b10abSAndroid Build Coastguard Worker   rc->worst_quality = cpi->oxcf.worst_allowed_q;
2124*fb1b10abSAndroid Build Coastguard Worker   rc->best_quality = cpi->oxcf.best_allowed_q;
2125*fb1b10abSAndroid Build Coastguard Worker 
2126*fb1b10abSAndroid Build Coastguard Worker   cm->interp_filter = cpi->sf.default_interp_filter;
2127*fb1b10abSAndroid Build Coastguard Worker 
2128*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
2129*fb1b10abSAndroid Build Coastguard Worker     cm->render_width = cpi->oxcf.render_width;
2130*fb1b10abSAndroid Build Coastguard Worker     cm->render_height = cpi->oxcf.render_height;
2131*fb1b10abSAndroid Build Coastguard Worker   } else {
2132*fb1b10abSAndroid Build Coastguard Worker     cm->render_width = cpi->oxcf.width;
2133*fb1b10abSAndroid Build Coastguard Worker     cm->render_height = cpi->oxcf.height;
2134*fb1b10abSAndroid Build Coastguard Worker   }
2135*fb1b10abSAndroid Build Coastguard Worker   if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
2136*fb1b10abSAndroid Build Coastguard Worker     cm->width = cpi->oxcf.width;
2137*fb1b10abSAndroid Build Coastguard Worker     cm->height = cpi->oxcf.height;
2138*fb1b10abSAndroid Build Coastguard Worker     cpi->external_resize = 1;
2139*fb1b10abSAndroid Build Coastguard Worker   }
2140*fb1b10abSAndroid Build Coastguard Worker 
2141*fb1b10abSAndroid Build Coastguard Worker   int new_mi_size = 0;
2142*fb1b10abSAndroid Build Coastguard Worker   vp9_set_mb_mi(cm, cm->width, cm->height);
2143*fb1b10abSAndroid Build Coastguard Worker   new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
2144*fb1b10abSAndroid Build Coastguard Worker   if (cm->mi_alloc_size < new_mi_size) {
2145*fb1b10abSAndroid Build Coastguard Worker     vp9_free_context_buffers(cm);
2146*fb1b10abSAndroid Build Coastguard Worker     vp9_free_pc_tree(&cpi->td);
2147*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->mbmi_ext_base);
2148*fb1b10abSAndroid Build Coastguard Worker     alloc_compressor_data(cpi);
2149*fb1b10abSAndroid Build Coastguard Worker     realloc_segmentation_maps(cpi);
2150*fb1b10abSAndroid Build Coastguard Worker     cpi->initial_width = cpi->initial_height = 0;
2151*fb1b10abSAndroid Build Coastguard Worker     cpi->external_resize = 0;
2152*fb1b10abSAndroid Build Coastguard Worker   } else if (cm->mi_alloc_size == new_mi_size &&
2153*fb1b10abSAndroid Build Coastguard Worker              (cpi->oxcf.width > last_w || cpi->oxcf.height > last_h)) {
2154*fb1b10abSAndroid Build Coastguard Worker     if (vp9_alloc_loop_filter(cm)) {
2155*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
2156*fb1b10abSAndroid Build Coastguard Worker                          "Failed to allocate loop filter data");
2157*fb1b10abSAndroid Build Coastguard Worker     }
2158*fb1b10abSAndroid Build Coastguard Worker   }
2159*fb1b10abSAndroid Build Coastguard Worker 
2160*fb1b10abSAndroid Build Coastguard Worker   if (cm->current_video_frame == 0 || last_w != cpi->oxcf.width ||
2161*fb1b10abSAndroid Build Coastguard Worker       last_h != cpi->oxcf.height)
2162*fb1b10abSAndroid Build Coastguard Worker     update_frame_size(cpi);
2163*fb1b10abSAndroid Build Coastguard Worker 
2164*fb1b10abSAndroid Build Coastguard Worker   if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
2165*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->consec_zero_mv);
2166*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
2167*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->consec_zero_mv,
2168*fb1b10abSAndroid Build Coastguard Worker         vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
2169*fb1b10abSAndroid Build Coastguard Worker 
2170*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->skin_map);
2171*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
2172*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->skin_map,
2173*fb1b10abSAndroid Build Coastguard Worker         vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->skin_map)));
2174*fb1b10abSAndroid Build Coastguard Worker 
2175*fb1b10abSAndroid Build Coastguard Worker     free_copy_partition_data(cpi);
2176*fb1b10abSAndroid Build Coastguard Worker     alloc_copy_partition_data(cpi);
2177*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2178*fb1b10abSAndroid Build Coastguard Worker       vp9_cyclic_refresh_reset_resize(cpi);
2179*fb1b10abSAndroid Build Coastguard Worker     rc->rc_1_frame = 0;
2180*fb1b10abSAndroid Build Coastguard Worker     rc->rc_2_frame = 0;
2181*fb1b10abSAndroid Build Coastguard Worker   }
2182*fb1b10abSAndroid Build Coastguard Worker 
2183*fb1b10abSAndroid Build Coastguard Worker   if ((cpi->svc.number_temporal_layers > 1) ||
2184*fb1b10abSAndroid Build Coastguard Worker       ((cpi->svc.number_temporal_layers > 1 ||
2185*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.number_spatial_layers > 1) &&
2186*fb1b10abSAndroid Build Coastguard Worker        cpi->oxcf.pass != 1)) {
2187*fb1b10abSAndroid Build Coastguard Worker     vp9_update_layer_context_change_config(cpi,
2188*fb1b10abSAndroid Build Coastguard Worker                                            (int)cpi->oxcf.target_bandwidth);
2189*fb1b10abSAndroid Build Coastguard Worker   }
2190*fb1b10abSAndroid Build Coastguard Worker 
2191*fb1b10abSAndroid Build Coastguard Worker   vp9_check_reset_rc_flag(cpi);
2192*fb1b10abSAndroid Build Coastguard Worker 
2193*fb1b10abSAndroid Build Coastguard Worker   cpi->alt_ref_source = NULL;
2194*fb1b10abSAndroid Build Coastguard Worker   rc->is_src_frame_alt_ref = 0;
2195*fb1b10abSAndroid Build Coastguard Worker 
2196*fb1b10abSAndroid Build Coastguard Worker #if 0
2197*fb1b10abSAndroid Build Coastguard Worker   // Experimental RD Code
2198*fb1b10abSAndroid Build Coastguard Worker   cpi->frame_distortion = 0;
2199*fb1b10abSAndroid Build Coastguard Worker   cpi->last_frame_distortion = 0;
2200*fb1b10abSAndroid Build Coastguard Worker #endif
2201*fb1b10abSAndroid Build Coastguard Worker 
2202*fb1b10abSAndroid Build Coastguard Worker   set_tile_limits(cpi);
2203*fb1b10abSAndroid Build Coastguard Worker 
2204*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_flags_pending = 0;
2205*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_context_pending = 0;
2206*fb1b10abSAndroid Build Coastguard Worker 
2207*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2208*fb1b10abSAndroid Build Coastguard Worker   highbd_set_var_fns(cpi);
2209*fb1b10abSAndroid Build Coastguard Worker #endif
2210*fb1b10abSAndroid Build Coastguard Worker 
2211*fb1b10abSAndroid Build Coastguard Worker   vp9_set_row_mt(cpi);
2212*fb1b10abSAndroid Build Coastguard Worker }
2213*fb1b10abSAndroid Build Coastguard Worker 
2214*fb1b10abSAndroid Build Coastguard Worker /***********************************************************************
2215*fb1b10abSAndroid Build Coastguard Worker  * Read before modifying 'cal_nmvjointsadcost' or 'cal_nmvsadcosts'    *
2216*fb1b10abSAndroid Build Coastguard Worker  ***********************************************************************
2217*fb1b10abSAndroid Build Coastguard Worker  * The following 2 functions ('cal_nmvjointsadcost' and                *
2218*fb1b10abSAndroid Build Coastguard Worker  * 'cal_nmvsadcosts') are used to calculate cost lookup tables         *
2219*fb1b10abSAndroid Build Coastguard Worker  * used by 'vp9_diamond_search_sad'. The C implementation of the       *
2220*fb1b10abSAndroid Build Coastguard Worker  * function is generic, but the NEON intrinsics optimised version      *
2221*fb1b10abSAndroid Build Coastguard Worker  * relies on the following properties of the computed tables:          *
2222*fb1b10abSAndroid Build Coastguard Worker  * For cal_nmvjointsadcost:                                            *
2223*fb1b10abSAndroid Build Coastguard Worker  *   - mvjointsadcost[1] == mvjointsadcost[2] == mvjointsadcost[3]     *
2224*fb1b10abSAndroid Build Coastguard Worker  * For cal_nmvsadcosts:                                                *
2225*fb1b10abSAndroid Build Coastguard Worker  *   - For all i: mvsadcost[0][i] == mvsadcost[1][i]                   *
2226*fb1b10abSAndroid Build Coastguard Worker  *         (Equal costs for both components)                           *
2227*fb1b10abSAndroid Build Coastguard Worker  *   - For all i: mvsadcost[0][i] == mvsadcost[0][-i]                  *
2228*fb1b10abSAndroid Build Coastguard Worker  *         (Cost function is even)                                     *
2229*fb1b10abSAndroid Build Coastguard Worker  * If these do not hold, then the NEON optimised version of the        *
2230*fb1b10abSAndroid Build Coastguard Worker  * 'vp9_diamond_search_sad' function cannot be used as it is, in which *
2231*fb1b10abSAndroid Build Coastguard Worker  * case you can revert to using the C function instead.                *
2232*fb1b10abSAndroid Build Coastguard Worker  ***********************************************************************/
2233*fb1b10abSAndroid Build Coastguard Worker 
cal_nmvjointsadcost(int * mvjointsadcost)2234*fb1b10abSAndroid Build Coastguard Worker static void cal_nmvjointsadcost(int *mvjointsadcost) {
2235*fb1b10abSAndroid Build Coastguard Worker   /*********************************************************************
2236*fb1b10abSAndroid Build Coastguard Worker    * Warning: Read the comments above before modifying this function   *
2237*fb1b10abSAndroid Build Coastguard Worker    *********************************************************************/
2238*fb1b10abSAndroid Build Coastguard Worker   mvjointsadcost[0] = 600;
2239*fb1b10abSAndroid Build Coastguard Worker   mvjointsadcost[1] = 300;
2240*fb1b10abSAndroid Build Coastguard Worker   mvjointsadcost[2] = 300;
2241*fb1b10abSAndroid Build Coastguard Worker   mvjointsadcost[3] = 300;
2242*fb1b10abSAndroid Build Coastguard Worker }
2243*fb1b10abSAndroid Build Coastguard Worker 
cal_nmvsadcosts(int * mvsadcost[2])2244*fb1b10abSAndroid Build Coastguard Worker static void cal_nmvsadcosts(int *mvsadcost[2]) {
2245*fb1b10abSAndroid Build Coastguard Worker   /*********************************************************************
2246*fb1b10abSAndroid Build Coastguard Worker    * Warning: Read the comments above before modifying this function   *
2247*fb1b10abSAndroid Build Coastguard Worker    *********************************************************************/
2248*fb1b10abSAndroid Build Coastguard Worker   int i = 1;
2249*fb1b10abSAndroid Build Coastguard Worker 
2250*fb1b10abSAndroid Build Coastguard Worker   mvsadcost[0][0] = 0;
2251*fb1b10abSAndroid Build Coastguard Worker   mvsadcost[1][0] = 0;
2252*fb1b10abSAndroid Build Coastguard Worker 
2253*fb1b10abSAndroid Build Coastguard Worker   do {
2254*fb1b10abSAndroid Build Coastguard Worker     double z = 256 * (2 * (log2f(8 * i) + .6));
2255*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[0][i] = (int)z;
2256*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[1][i] = (int)z;
2257*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[0][-i] = (int)z;
2258*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[1][-i] = (int)z;
2259*fb1b10abSAndroid Build Coastguard Worker   } while (++i <= MV_MAX);
2260*fb1b10abSAndroid Build Coastguard Worker }
2261*fb1b10abSAndroid Build Coastguard Worker 
cal_nmvsadcosts_hp(int * mvsadcost[2])2262*fb1b10abSAndroid Build Coastguard Worker static void cal_nmvsadcosts_hp(int *mvsadcost[2]) {
2263*fb1b10abSAndroid Build Coastguard Worker   int i = 1;
2264*fb1b10abSAndroid Build Coastguard Worker 
2265*fb1b10abSAndroid Build Coastguard Worker   mvsadcost[0][0] = 0;
2266*fb1b10abSAndroid Build Coastguard Worker   mvsadcost[1][0] = 0;
2267*fb1b10abSAndroid Build Coastguard Worker 
2268*fb1b10abSAndroid Build Coastguard Worker   do {
2269*fb1b10abSAndroid Build Coastguard Worker     double z = 256 * (2 * (log2f(8 * i) + .6));
2270*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[0][i] = (int)z;
2271*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[1][i] = (int)z;
2272*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[0][-i] = (int)z;
2273*fb1b10abSAndroid Build Coastguard Worker     mvsadcost[1][-i] = (int)z;
2274*fb1b10abSAndroid Build Coastguard Worker   } while (++i <= MV_MAX);
2275*fb1b10abSAndroid Build Coastguard Worker }
2276*fb1b10abSAndroid Build Coastguard Worker 
init_ref_frame_bufs(VP9_COMMON * cm)2277*fb1b10abSAndroid Build Coastguard Worker static void init_ref_frame_bufs(VP9_COMMON *cm) {
2278*fb1b10abSAndroid Build Coastguard Worker   int i;
2279*fb1b10abSAndroid Build Coastguard Worker   BufferPool *const pool = cm->buffer_pool;
2280*fb1b10abSAndroid Build Coastguard Worker   cm->new_fb_idx = INVALID_IDX;
2281*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < REF_FRAMES; ++i) {
2282*fb1b10abSAndroid Build Coastguard Worker     cm->ref_frame_map[i] = INVALID_IDX;
2283*fb1b10abSAndroid Build Coastguard Worker   }
2284*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < FRAME_BUFFERS; ++i) {
2285*fb1b10abSAndroid Build Coastguard Worker     pool->frame_bufs[i].ref_count = 0;
2286*fb1b10abSAndroid Build Coastguard Worker   }
2287*fb1b10abSAndroid Build Coastguard Worker }
2288*fb1b10abSAndroid Build Coastguard Worker 
update_initial_width(VP9_COMP * cpi,int use_highbitdepth,int subsampling_x,int subsampling_y)2289*fb1b10abSAndroid Build Coastguard Worker static void update_initial_width(VP9_COMP *cpi, int use_highbitdepth,
2290*fb1b10abSAndroid Build Coastguard Worker                                  int subsampling_x, int subsampling_y) {
2291*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2292*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_VP9_HIGHBITDEPTH
2293*fb1b10abSAndroid Build Coastguard Worker   (void)use_highbitdepth;
2294*fb1b10abSAndroid Build Coastguard Worker   assert(use_highbitdepth == 0);
2295*fb1b10abSAndroid Build Coastguard Worker #endif
2296*fb1b10abSAndroid Build Coastguard Worker 
2297*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->initial_width ||
2298*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2299*fb1b10abSAndroid Build Coastguard Worker       cm->use_highbitdepth != use_highbitdepth ||
2300*fb1b10abSAndroid Build Coastguard Worker #endif
2301*fb1b10abSAndroid Build Coastguard Worker       cm->subsampling_x != subsampling_x ||
2302*fb1b10abSAndroid Build Coastguard Worker       cm->subsampling_y != subsampling_y) {
2303*fb1b10abSAndroid Build Coastguard Worker     cm->subsampling_x = subsampling_x;
2304*fb1b10abSAndroid Build Coastguard Worker     cm->subsampling_y = subsampling_y;
2305*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2306*fb1b10abSAndroid Build Coastguard Worker     cm->use_highbitdepth = use_highbitdepth;
2307*fb1b10abSAndroid Build Coastguard Worker #endif
2308*fb1b10abSAndroid Build Coastguard Worker     alloc_util_frame_buffers(cpi);
2309*fb1b10abSAndroid Build Coastguard Worker     cpi->initial_width = cm->width;
2310*fb1b10abSAndroid Build Coastguard Worker     cpi->initial_height = cm->height;
2311*fb1b10abSAndroid Build Coastguard Worker     cpi->initial_mbs = cm->MBs;
2312*fb1b10abSAndroid Build Coastguard Worker   }
2313*fb1b10abSAndroid Build Coastguard Worker }
2314*fb1b10abSAndroid Build Coastguard Worker 
2315*fb1b10abSAndroid Build Coastguard Worker // TODO(angiebird): Check whether we can move this function to vpx_image.c
vpx_img_chroma_subsampling(vpx_img_fmt_t fmt,unsigned int * subsampling_x,unsigned int * subsampling_y)2316*fb1b10abSAndroid Build Coastguard Worker static INLINE void vpx_img_chroma_subsampling(vpx_img_fmt_t fmt,
2317*fb1b10abSAndroid Build Coastguard Worker                                               unsigned int *subsampling_x,
2318*fb1b10abSAndroid Build Coastguard Worker                                               unsigned int *subsampling_y) {
2319*fb1b10abSAndroid Build Coastguard Worker   switch (fmt) {
2320*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I420:
2321*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_YV12:
2322*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_NV12:
2323*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I422:
2324*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42016:
2325*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42216: *subsampling_x = 1; break;
2326*fb1b10abSAndroid Build Coastguard Worker     default: *subsampling_x = 0; break;
2327*fb1b10abSAndroid Build Coastguard Worker   }
2328*fb1b10abSAndroid Build Coastguard Worker 
2329*fb1b10abSAndroid Build Coastguard Worker   switch (fmt) {
2330*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I420:
2331*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I440:
2332*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_YV12:
2333*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_NV12:
2334*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I42016:
2335*fb1b10abSAndroid Build Coastguard Worker     case VPX_IMG_FMT_I44016: *subsampling_y = 1; break;
2336*fb1b10abSAndroid Build Coastguard Worker     default: *subsampling_y = 0; break;
2337*fb1b10abSAndroid Build Coastguard Worker   }
2338*fb1b10abSAndroid Build Coastguard Worker }
2339*fb1b10abSAndroid Build Coastguard Worker 
2340*fb1b10abSAndroid Build Coastguard Worker // TODO(angiebird): Check whether we can move this function to vpx_image.c
vpx_img_use_highbitdepth(vpx_img_fmt_t fmt)2341*fb1b10abSAndroid Build Coastguard Worker static INLINE int vpx_img_use_highbitdepth(vpx_img_fmt_t fmt) {
2342*fb1b10abSAndroid Build Coastguard Worker   return fmt & VPX_IMG_FMT_HIGHBITDEPTH;
2343*fb1b10abSAndroid Build Coastguard Worker }
2344*fb1b10abSAndroid Build Coastguard Worker 
2345*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
setup_denoiser_buffer(VP9_COMP * cpi)2346*fb1b10abSAndroid Build Coastguard Worker static void setup_denoiser_buffer(VP9_COMP *cpi) {
2347*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2348*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.noise_sensitivity > 0 &&
2349*fb1b10abSAndroid Build Coastguard Worker       !cpi->denoiser.frame_buffer_initialized) {
2350*fb1b10abSAndroid Build Coastguard Worker     if (vp9_denoiser_alloc(cm, &cpi->svc, &cpi->denoiser, cpi->use_svc,
2351*fb1b10abSAndroid Build Coastguard Worker                            cpi->oxcf.noise_sensitivity, cm->width, cm->height,
2352*fb1b10abSAndroid Build Coastguard Worker                            cm->subsampling_x, cm->subsampling_y,
2353*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2354*fb1b10abSAndroid Build Coastguard Worker                            cm->use_highbitdepth,
2355*fb1b10abSAndroid Build Coastguard Worker #endif
2356*fb1b10abSAndroid Build Coastguard Worker                            VP9_ENC_BORDER_IN_PIXELS))
2357*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
2358*fb1b10abSAndroid Build Coastguard Worker                          "Failed to allocate denoiser");
2359*fb1b10abSAndroid Build Coastguard Worker   }
2360*fb1b10abSAndroid Build Coastguard Worker }
2361*fb1b10abSAndroid Build Coastguard Worker #endif
2362*fb1b10abSAndroid Build Coastguard Worker 
vp9_update_compressor_with_img_fmt(VP9_COMP * cpi,vpx_img_fmt_t img_fmt)2363*fb1b10abSAndroid Build Coastguard Worker void vp9_update_compressor_with_img_fmt(VP9_COMP *cpi, vpx_img_fmt_t img_fmt) {
2364*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
2365*fb1b10abSAndroid Build Coastguard Worker   unsigned int subsampling_x, subsampling_y;
2366*fb1b10abSAndroid Build Coastguard Worker   const int use_highbitdepth = vpx_img_use_highbitdepth(img_fmt);
2367*fb1b10abSAndroid Build Coastguard Worker   vpx_img_chroma_subsampling(img_fmt, &subsampling_x, &subsampling_y);
2368*fb1b10abSAndroid Build Coastguard Worker 
2369*fb1b10abSAndroid Build Coastguard Worker   update_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
2370*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
2371*fb1b10abSAndroid Build Coastguard Worker   setup_denoiser_buffer(cpi);
2372*fb1b10abSAndroid Build Coastguard Worker #endif
2373*fb1b10abSAndroid Build Coastguard Worker 
2374*fb1b10abSAndroid Build Coastguard Worker   assert(cpi->lookahead == NULL);
2375*fb1b10abSAndroid Build Coastguard Worker   cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height, subsampling_x,
2376*fb1b10abSAndroid Build Coastguard Worker                                       subsampling_y,
2377*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2378*fb1b10abSAndroid Build Coastguard Worker                                       use_highbitdepth,
2379*fb1b10abSAndroid Build Coastguard Worker #endif
2380*fb1b10abSAndroid Build Coastguard Worker                                       oxcf->lag_in_frames);
2381*fb1b10abSAndroid Build Coastguard Worker   alloc_raw_frame_buffers(cpi);
2382*fb1b10abSAndroid Build Coastguard Worker }
2383*fb1b10abSAndroid Build Coastguard Worker 
vp9_create_compressor(const VP9EncoderConfig * oxcf,BufferPool * const pool)2384*fb1b10abSAndroid Build Coastguard Worker VP9_COMP *vp9_create_compressor(const VP9EncoderConfig *oxcf,
2385*fb1b10abSAndroid Build Coastguard Worker                                 BufferPool *const pool) {
2386*fb1b10abSAndroid Build Coastguard Worker   unsigned int i;
2387*fb1b10abSAndroid Build Coastguard Worker   VP9_COMP *volatile const cpi = vpx_memalign(32, sizeof(*cpi));
2388*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
2389*fb1b10abSAndroid Build Coastguard Worker 
2390*fb1b10abSAndroid Build Coastguard Worker   if (!cm) return NULL;
2391*fb1b10abSAndroid Build Coastguard Worker 
2392*fb1b10abSAndroid Build Coastguard Worker   vp9_zero(*cpi);
2393*fb1b10abSAndroid Build Coastguard Worker 
2394*fb1b10abSAndroid Build Coastguard Worker   if (setjmp(cm->error.jmp)) {
2395*fb1b10abSAndroid Build Coastguard Worker     cm->error.setjmp = 0;
2396*fb1b10abSAndroid Build Coastguard Worker     vp9_remove_compressor(cpi);
2397*fb1b10abSAndroid Build Coastguard Worker     return 0;
2398*fb1b10abSAndroid Build Coastguard Worker   }
2399*fb1b10abSAndroid Build Coastguard Worker 
2400*fb1b10abSAndroid Build Coastguard Worker   cm->error.setjmp = 1;
2401*fb1b10abSAndroid Build Coastguard Worker   cm->alloc_mi = vp9_enc_alloc_mi;
2402*fb1b10abSAndroid Build Coastguard Worker   cm->free_mi = vp9_enc_free_mi;
2403*fb1b10abSAndroid Build Coastguard Worker   cm->setup_mi = vp9_enc_setup_mi;
2404*fb1b10abSAndroid Build Coastguard Worker 
2405*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cm->fc,
2406*fb1b10abSAndroid Build Coastguard Worker                   (FRAME_CONTEXT *)vpx_calloc(1, sizeof(*cm->fc)));
2407*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
2408*fb1b10abSAndroid Build Coastguard Worker       &cm->error, cm->frame_contexts,
2409*fb1b10abSAndroid Build Coastguard Worker       (FRAME_CONTEXT *)vpx_calloc(FRAME_CONTEXTS, sizeof(*cm->frame_contexts)));
2410*fb1b10abSAndroid Build Coastguard Worker 
2411*fb1b10abSAndroid Build Coastguard Worker   cpi->compute_frame_low_motion_onepass = 1;
2412*fb1b10abSAndroid Build Coastguard Worker   cpi->use_svc = 0;
2413*fb1b10abSAndroid Build Coastguard Worker   cpi->resize_state = ORIG;
2414*fb1b10abSAndroid Build Coastguard Worker   cpi->external_resize = 0;
2415*fb1b10abSAndroid Build Coastguard Worker   cpi->resize_avg_qp = 0;
2416*fb1b10abSAndroid Build Coastguard Worker   cpi->resize_buffer_underflow = 0;
2417*fb1b10abSAndroid Build Coastguard Worker   cpi->use_skin_detection = 0;
2418*fb1b10abSAndroid Build Coastguard Worker   cpi->common.buffer_pool = pool;
2419*fb1b10abSAndroid Build Coastguard Worker   init_ref_frame_bufs(cm);
2420*fb1b10abSAndroid Build Coastguard Worker 
2421*fb1b10abSAndroid Build Coastguard Worker   cpi->force_update_segmentation = 0;
2422*fb1b10abSAndroid Build Coastguard Worker 
2423*fb1b10abSAndroid Build Coastguard Worker   init_config(cpi, oxcf);
2424*fb1b10abSAndroid Build Coastguard Worker   cpi->frame_info = vp9_get_frame_info(oxcf);
2425*fb1b10abSAndroid Build Coastguard Worker 
2426*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
2427*fb1b10abSAndroid Build Coastguard Worker   vp9_init_rd_parameters(cpi);
2428*fb1b10abSAndroid Build Coastguard Worker 
2429*fb1b10abSAndroid Build Coastguard Worker   init_frame_indexes(cm);
2430*fb1b10abSAndroid Build Coastguard Worker   cpi->tile_data = NULL;
2431*fb1b10abSAndroid Build Coastguard Worker 
2432*fb1b10abSAndroid Build Coastguard Worker   realloc_segmentation_maps(cpi);
2433*fb1b10abSAndroid Build Coastguard Worker 
2434*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
2435*fb1b10abSAndroid Build Coastguard Worker       &cm->error, cpi->skin_map,
2436*fb1b10abSAndroid Build Coastguard Worker       vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->skin_map)));
2437*fb1b10abSAndroid Build Coastguard Worker 
2438*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
2439*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->alt_ref_aq, vp9_alt_ref_aq_create());
2440*fb1b10abSAndroid Build Coastguard Worker #endif
2441*fb1b10abSAndroid Build Coastguard Worker 
2442*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
2443*fb1b10abSAndroid Build Coastguard Worker       &cm->error, cpi->consec_zero_mv,
2444*fb1b10abSAndroid Build Coastguard Worker       vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
2445*fb1b10abSAndroid Build Coastguard Worker 
2446*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts[0],
2447*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts[0])));
2448*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts[1],
2449*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts[1])));
2450*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts_hp[0],
2451*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[0])));
2452*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvcosts_hp[1],
2453*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[1])));
2454*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts[0],
2455*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[0])));
2456*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts[1],
2457*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[1])));
2458*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts_hp[0],
2459*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[0])));
2460*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->nmvsadcosts_hp[1],
2461*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[1])));
2462*fb1b10abSAndroid Build Coastguard Worker 
2463*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]));
2464*fb1b10abSAndroid Build Coastguard Worker        i++) {
2465*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
2466*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->mbgraph_stats[i].mb_stats,
2467*fb1b10abSAndroid Build Coastguard Worker         vpx_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
2468*fb1b10abSAndroid Build Coastguard Worker   }
2469*fb1b10abSAndroid Build Coastguard Worker 
2470*fb1b10abSAndroid Build Coastguard Worker   cpi->refresh_alt_ref_frame = 0;
2471*fb1b10abSAndroid Build Coastguard Worker   cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
2472*fb1b10abSAndroid Build Coastguard Worker 
2473*fb1b10abSAndroid Build Coastguard Worker   init_level_info(&cpi->level_info);
2474*fb1b10abSAndroid Build Coastguard Worker   init_level_constraint(&cpi->level_constraint);
2475*fb1b10abSAndroid Build Coastguard Worker 
2476*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
2477*fb1b10abSAndroid Build Coastguard Worker   cpi->b_calculate_blockiness = 1;
2478*fb1b10abSAndroid Build Coastguard Worker   cpi->b_calculate_consistency = 1;
2479*fb1b10abSAndroid Build Coastguard Worker   cpi->total_inconsistency = 0;
2480*fb1b10abSAndroid Build Coastguard Worker   cpi->psnr.worst = 100.0;
2481*fb1b10abSAndroid Build Coastguard Worker   cpi->worst_ssim = 100.0;
2482*fb1b10abSAndroid Build Coastguard Worker 
2483*fb1b10abSAndroid Build Coastguard Worker   cpi->count = 0;
2484*fb1b10abSAndroid Build Coastguard Worker   cpi->bytes = 0;
2485*fb1b10abSAndroid Build Coastguard Worker 
2486*fb1b10abSAndroid Build Coastguard Worker   if (cpi->b_calculate_psnr) {
2487*fb1b10abSAndroid Build Coastguard Worker     cpi->total_sq_error = 0;
2488*fb1b10abSAndroid Build Coastguard Worker     cpi->total_samples = 0;
2489*fb1b10abSAndroid Build Coastguard Worker 
2490*fb1b10abSAndroid Build Coastguard Worker     cpi->totalp_sq_error = 0;
2491*fb1b10abSAndroid Build Coastguard Worker     cpi->totalp_samples = 0;
2492*fb1b10abSAndroid Build Coastguard Worker 
2493*fb1b10abSAndroid Build Coastguard Worker     cpi->tot_recode_hits = 0;
2494*fb1b10abSAndroid Build Coastguard Worker     cpi->summed_quality = 0;
2495*fb1b10abSAndroid Build Coastguard Worker     cpi->summed_weights = 0;
2496*fb1b10abSAndroid Build Coastguard Worker     cpi->summedp_quality = 0;
2497*fb1b10abSAndroid Build Coastguard Worker     cpi->summedp_weights = 0;
2498*fb1b10abSAndroid Build Coastguard Worker   }
2499*fb1b10abSAndroid Build Coastguard Worker 
2500*fb1b10abSAndroid Build Coastguard Worker   cpi->fastssim.worst = 100.0;
2501*fb1b10abSAndroid Build Coastguard Worker 
2502*fb1b10abSAndroid Build Coastguard Worker   cpi->psnrhvs.worst = 100.0;
2503*fb1b10abSAndroid Build Coastguard Worker 
2504*fb1b10abSAndroid Build Coastguard Worker   if (cpi->b_calculate_blockiness) {
2505*fb1b10abSAndroid Build Coastguard Worker     cpi->total_blockiness = 0;
2506*fb1b10abSAndroid Build Coastguard Worker     cpi->worst_blockiness = 0.0;
2507*fb1b10abSAndroid Build Coastguard Worker   }
2508*fb1b10abSAndroid Build Coastguard Worker 
2509*fb1b10abSAndroid Build Coastguard Worker   if (cpi->b_calculate_consistency) {
2510*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(&cm->error, cpi->ssim_vars,
2511*fb1b10abSAndroid Build Coastguard Worker                     vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols,
2512*fb1b10abSAndroid Build Coastguard Worker                                sizeof(*cpi->ssim_vars) * 4));
2513*fb1b10abSAndroid Build Coastguard Worker     cpi->worst_consistency = 100.0;
2514*fb1b10abSAndroid Build Coastguard Worker   } else {
2515*fb1b10abSAndroid Build Coastguard Worker     cpi->ssim_vars = NULL;
2516*fb1b10abSAndroid Build Coastguard Worker   }
2517*fb1b10abSAndroid Build Coastguard Worker 
2518*fb1b10abSAndroid Build Coastguard Worker #endif
2519*fb1b10abSAndroid Build Coastguard Worker 
2520*fb1b10abSAndroid Build Coastguard Worker   cpi->first_time_stamp_ever = INT64_MAX;
2521*fb1b10abSAndroid Build Coastguard Worker 
2522*fb1b10abSAndroid Build Coastguard Worker   /*********************************************************************
2523*fb1b10abSAndroid Build Coastguard Worker    * Warning: Read the comments around 'cal_nmvjointsadcost' and       *
2524*fb1b10abSAndroid Build Coastguard Worker    * 'cal_nmvsadcosts' before modifying how these tables are computed. *
2525*fb1b10abSAndroid Build Coastguard Worker    *********************************************************************/
2526*fb1b10abSAndroid Build Coastguard Worker   cal_nmvjointsadcost(cpi->td.mb.nmvjointsadcost);
2527*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvcost[0] = &cpi->nmvcosts[0][MV_MAX];
2528*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvcost[1] = &cpi->nmvcosts[1][MV_MAX];
2529*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvsadcost[0] = &cpi->nmvsadcosts[0][MV_MAX];
2530*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvsadcost[1] = &cpi->nmvsadcosts[1][MV_MAX];
2531*fb1b10abSAndroid Build Coastguard Worker   cal_nmvsadcosts(cpi->td.mb.nmvsadcost);
2532*fb1b10abSAndroid Build Coastguard Worker 
2533*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvcost_hp[0] = &cpi->nmvcosts_hp[0][MV_MAX];
2534*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvcost_hp[1] = &cpi->nmvcosts_hp[1][MV_MAX];
2535*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvsadcost_hp[0] = &cpi->nmvsadcosts_hp[0][MV_MAX];
2536*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.nmvsadcost_hp[1] = &cpi->nmvsadcosts_hp[1][MV_MAX];
2537*fb1b10abSAndroid Build Coastguard Worker   cal_nmvsadcosts_hp(cpi->td.mb.nmvsadcost_hp);
2538*fb1b10abSAndroid Build Coastguard Worker 
2539*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
2540*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_DENOISED
2541*fb1b10abSAndroid Build Coastguard Worker   yuv_denoised_file = fopen("denoised.yuv", "ab");
2542*fb1b10abSAndroid Build Coastguard Worker #endif
2543*fb1b10abSAndroid Build Coastguard Worker #endif
2544*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SKINMAP
2545*fb1b10abSAndroid Build Coastguard Worker   yuv_skinmap_file = fopen("skinmap.yuv", "wb");
2546*fb1b10abSAndroid Build Coastguard Worker #endif
2547*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_REC
2548*fb1b10abSAndroid Build Coastguard Worker   yuv_rec_file = fopen("rec.yuv", "wb");
2549*fb1b10abSAndroid Build Coastguard Worker #endif
2550*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SVC_SRC
2551*fb1b10abSAndroid Build Coastguard Worker   yuv_svc_src[0] = fopen("svc_src_0.yuv", "wb");
2552*fb1b10abSAndroid Build Coastguard Worker   yuv_svc_src[1] = fopen("svc_src_1.yuv", "wb");
2553*fb1b10abSAndroid Build Coastguard Worker   yuv_svc_src[2] = fopen("svc_src_2.yuv", "wb");
2554*fb1b10abSAndroid Build Coastguard Worker #endif
2555*fb1b10abSAndroid Build Coastguard Worker 
2556*fb1b10abSAndroid Build Coastguard Worker #if 0
2557*fb1b10abSAndroid Build Coastguard Worker   framepsnr = fopen("framepsnr.stt", "a");
2558*fb1b10abSAndroid Build Coastguard Worker   kf_list = fopen("kf_list.stt", "w");
2559*fb1b10abSAndroid Build Coastguard Worker #endif
2560*fb1b10abSAndroid Build Coastguard Worker 
2561*fb1b10abSAndroid Build Coastguard Worker   cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
2562*fb1b10abSAndroid Build Coastguard Worker 
2563*fb1b10abSAndroid Build Coastguard Worker   {
2564*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_err_t codec_status = vp9_extrc_init(&cpi->ext_ratectrl);
2565*fb1b10abSAndroid Build Coastguard Worker     if (codec_status != VPX_CODEC_OK) {
2566*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, codec_status, "vp9_extrc_init() failed");
2567*fb1b10abSAndroid Build Coastguard Worker     }
2568*fb1b10abSAndroid Build Coastguard Worker   }
2569*fb1b10abSAndroid Build Coastguard Worker 
2570*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
2571*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 1) {
2572*fb1b10abSAndroid Build Coastguard Worker     vp9_init_first_pass(cpi);
2573*fb1b10abSAndroid Build Coastguard Worker   } else if (oxcf->pass == 2) {
2574*fb1b10abSAndroid Build Coastguard Worker     const size_t packet_sz = sizeof(FIRSTPASS_STATS);
2575*fb1b10abSAndroid Build Coastguard Worker     const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
2576*fb1b10abSAndroid Build Coastguard Worker 
2577*fb1b10abSAndroid Build Coastguard Worker     if (cpi->svc.number_spatial_layers > 1 ||
2578*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.number_temporal_layers > 1) {
2579*fb1b10abSAndroid Build Coastguard Worker       FIRSTPASS_STATS *const stats = oxcf->two_pass_stats_in.buf;
2580*fb1b10abSAndroid Build Coastguard Worker       FIRSTPASS_STATS *stats_copy[VPX_SS_MAX_LAYERS] = { 0 };
2581*fb1b10abSAndroid Build Coastguard Worker       int n;
2582*fb1b10abSAndroid Build Coastguard Worker 
2583*fb1b10abSAndroid Build Coastguard Worker       for (n = 0; n < oxcf->ss_number_layers; ++n) {
2584*fb1b10abSAndroid Build Coastguard Worker         FIRSTPASS_STATS *const last_packet_for_layer =
2585*fb1b10abSAndroid Build Coastguard Worker             &stats[packets - oxcf->ss_number_layers + n];
2586*fb1b10abSAndroid Build Coastguard Worker         const int layer_id = (int)last_packet_for_layer->spatial_layer_id;
2587*fb1b10abSAndroid Build Coastguard Worker         const int packets_in_layer = (int)last_packet_for_layer->count + 1;
2588*fb1b10abSAndroid Build Coastguard Worker         if (layer_id >= 0 && layer_id < oxcf->ss_number_layers) {
2589*fb1b10abSAndroid Build Coastguard Worker           int num_frames;
2590*fb1b10abSAndroid Build Coastguard Worker           LAYER_CONTEXT *const lc = &cpi->svc.layer_context[layer_id];
2591*fb1b10abSAndroid Build Coastguard Worker 
2592*fb1b10abSAndroid Build Coastguard Worker           vpx_free(lc->rc_twopass_stats_in.buf);
2593*fb1b10abSAndroid Build Coastguard Worker 
2594*fb1b10abSAndroid Build Coastguard Worker           lc->rc_twopass_stats_in.sz = packets_in_layer * packet_sz;
2595*fb1b10abSAndroid Build Coastguard Worker           CHECK_MEM_ERROR(&cm->error, lc->rc_twopass_stats_in.buf,
2596*fb1b10abSAndroid Build Coastguard Worker                           vpx_malloc(lc->rc_twopass_stats_in.sz));
2597*fb1b10abSAndroid Build Coastguard Worker           lc->twopass.stats_in_start = lc->rc_twopass_stats_in.buf;
2598*fb1b10abSAndroid Build Coastguard Worker           lc->twopass.stats_in = lc->twopass.stats_in_start;
2599*fb1b10abSAndroid Build Coastguard Worker           lc->twopass.stats_in_end =
2600*fb1b10abSAndroid Build Coastguard Worker               lc->twopass.stats_in_start + packets_in_layer - 1;
2601*fb1b10abSAndroid Build Coastguard Worker           // Note the last packet is cumulative first pass stats.
2602*fb1b10abSAndroid Build Coastguard Worker           // So the number of frames is packet number minus one
2603*fb1b10abSAndroid Build Coastguard Worker           num_frames = packets_in_layer - 1;
2604*fb1b10abSAndroid Build Coastguard Worker           fps_init_first_pass_info(&lc->twopass.first_pass_info,
2605*fb1b10abSAndroid Build Coastguard Worker                                    lc->rc_twopass_stats_in.buf, num_frames);
2606*fb1b10abSAndroid Build Coastguard Worker           stats_copy[layer_id] = lc->rc_twopass_stats_in.buf;
2607*fb1b10abSAndroid Build Coastguard Worker         }
2608*fb1b10abSAndroid Build Coastguard Worker       }
2609*fb1b10abSAndroid Build Coastguard Worker 
2610*fb1b10abSAndroid Build Coastguard Worker       for (n = 0; n < packets; ++n) {
2611*fb1b10abSAndroid Build Coastguard Worker         const int layer_id = (int)stats[n].spatial_layer_id;
2612*fb1b10abSAndroid Build Coastguard Worker         if (layer_id >= 0 && layer_id < oxcf->ss_number_layers &&
2613*fb1b10abSAndroid Build Coastguard Worker             stats_copy[layer_id] != NULL) {
2614*fb1b10abSAndroid Build Coastguard Worker           *stats_copy[layer_id] = stats[n];
2615*fb1b10abSAndroid Build Coastguard Worker           ++stats_copy[layer_id];
2616*fb1b10abSAndroid Build Coastguard Worker         }
2617*fb1b10abSAndroid Build Coastguard Worker       }
2618*fb1b10abSAndroid Build Coastguard Worker 
2619*fb1b10abSAndroid Build Coastguard Worker       vp9_init_second_pass_spatial_svc(cpi);
2620*fb1b10abSAndroid Build Coastguard Worker     } else {
2621*fb1b10abSAndroid Build Coastguard Worker       int num_frames;
2622*fb1b10abSAndroid Build Coastguard Worker 
2623*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
2624*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.stats_in = cpi->twopass.stats_in_start;
2625*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
2626*fb1b10abSAndroid Build Coastguard Worker       // Note the last packet is cumulative first pass stats.
2627*fb1b10abSAndroid Build Coastguard Worker       // So the number of frames is packet number minus one
2628*fb1b10abSAndroid Build Coastguard Worker       num_frames = packets - 1;
2629*fb1b10abSAndroid Build Coastguard Worker       fps_init_first_pass_info(&cpi->twopass.first_pass_info,
2630*fb1b10abSAndroid Build Coastguard Worker                                oxcf->two_pass_stats_in.buf, num_frames);
2631*fb1b10abSAndroid Build Coastguard Worker 
2632*fb1b10abSAndroid Build Coastguard Worker       vp9_init_second_pass(cpi);
2633*fb1b10abSAndroid Build Coastguard Worker     }
2634*fb1b10abSAndroid Build Coastguard Worker   }
2635*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
2636*fb1b10abSAndroid Build Coastguard Worker 
2637*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_var_cols = 0;
2638*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_var_rows = 0;
2639*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_variance = NULL;
2640*fb1b10abSAndroid Build Coastguard Worker 
2641*fb1b10abSAndroid Build Coastguard Worker   vp9_set_speed_features_framesize_independent(cpi, oxcf->speed);
2642*fb1b10abSAndroid Build Coastguard Worker   vp9_set_speed_features_framesize_dependent(cpi, oxcf->speed);
2643*fb1b10abSAndroid Build Coastguard Worker 
2644*fb1b10abSAndroid Build Coastguard Worker   {
2645*fb1b10abSAndroid Build Coastguard Worker     const int bsize = BLOCK_16X16;
2646*fb1b10abSAndroid Build Coastguard Worker     const int w = num_8x8_blocks_wide_lookup[bsize];
2647*fb1b10abSAndroid Build Coastguard Worker     const int h = num_8x8_blocks_high_lookup[bsize];
2648*fb1b10abSAndroid Build Coastguard Worker     const int num_cols = (cm->mi_cols + w - 1) / w;
2649*fb1b10abSAndroid Build Coastguard Worker     const int num_rows = (cm->mi_rows + h - 1) / h;
2650*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(&cm->error, cpi->mi_ssim_rdmult_scaling_factors,
2651*fb1b10abSAndroid Build Coastguard Worker                     vpx_calloc(num_rows * num_cols,
2652*fb1b10abSAndroid Build Coastguard Worker                                sizeof(*cpi->mi_ssim_rdmult_scaling_factors)));
2653*fb1b10abSAndroid Build Coastguard Worker   }
2654*fb1b10abSAndroid Build Coastguard Worker 
2655*fb1b10abSAndroid Build Coastguard Worker   cpi->kmeans_data_arr_alloc = 0;
2656*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_NON_GREEDY_MV
2657*fb1b10abSAndroid Build Coastguard Worker   cpi->tpl_ready = 0;
2658*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_NON_GREEDY_MV
2659*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_ARF_GOP_SIZE; ++i) {
2660*fb1b10abSAndroid Build Coastguard Worker     cpi->tpl_stats[i].tpl_stats_ptr = NULL;
2661*fb1b10abSAndroid Build Coastguard Worker   }
2662*fb1b10abSAndroid Build Coastguard Worker 
2663*fb1b10abSAndroid Build Coastguard Worker   // Allocate memory to store variances for a frame.
2664*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(&cm->error, cpi->source_diff_var,
2665*fb1b10abSAndroid Build Coastguard Worker                   vpx_calloc(cm->MBs, sizeof(cpi->source_diff_var)));
2666*fb1b10abSAndroid Build Coastguard Worker   cpi->source_var_thresh = 0;
2667*fb1b10abSAndroid Build Coastguard Worker   cpi->frames_till_next_var_check = 0;
2668*fb1b10abSAndroid Build Coastguard Worker #define BFP(BT, SDF, SDSF, SDAF, VF, SVF, SVAF, SDX4DF, SDSX4DF) \
2669*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdf = SDF;                                     \
2670*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdsf = SDSF;                                   \
2671*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdaf = SDAF;                                   \
2672*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].vf = VF;                                       \
2673*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].svf = SVF;                                     \
2674*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].svaf = SVAF;                                   \
2675*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdx4df = SDX4DF;                               \
2676*fb1b10abSAndroid Build Coastguard Worker   cpi->fn_ptr[BT].sdsx4df = SDSX4DF;
2677*fb1b10abSAndroid Build Coastguard Worker 
2678*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_32X16, vpx_sad32x16, vpx_sad_skip_32x16, vpx_sad32x16_avg,
2679*fb1b10abSAndroid Build Coastguard Worker       vpx_variance32x16, vpx_sub_pixel_variance32x16,
2680*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance32x16, vpx_sad32x16x4d, vpx_sad_skip_32x16x4d)
2681*fb1b10abSAndroid Build Coastguard Worker 
2682*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_16X32, vpx_sad16x32, vpx_sad_skip_16x32, vpx_sad16x32_avg,
2683*fb1b10abSAndroid Build Coastguard Worker       vpx_variance16x32, vpx_sub_pixel_variance16x32,
2684*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance16x32, vpx_sad16x32x4d, vpx_sad_skip_16x32x4d)
2685*fb1b10abSAndroid Build Coastguard Worker 
2686*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_64X32, vpx_sad64x32, vpx_sad_skip_64x32, vpx_sad64x32_avg,
2687*fb1b10abSAndroid Build Coastguard Worker       vpx_variance64x32, vpx_sub_pixel_variance64x32,
2688*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance64x32, vpx_sad64x32x4d, vpx_sad_skip_64x32x4d)
2689*fb1b10abSAndroid Build Coastguard Worker 
2690*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_32X64, vpx_sad32x64, vpx_sad_skip_32x64, vpx_sad32x64_avg,
2691*fb1b10abSAndroid Build Coastguard Worker       vpx_variance32x64, vpx_sub_pixel_variance32x64,
2692*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance32x64, vpx_sad32x64x4d, vpx_sad_skip_32x64x4d)
2693*fb1b10abSAndroid Build Coastguard Worker 
2694*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_32X32, vpx_sad32x32, vpx_sad_skip_32x32, vpx_sad32x32_avg,
2695*fb1b10abSAndroid Build Coastguard Worker       vpx_variance32x32, vpx_sub_pixel_variance32x32,
2696*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance32x32, vpx_sad32x32x4d, vpx_sad_skip_32x32x4d)
2697*fb1b10abSAndroid Build Coastguard Worker 
2698*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_64X64, vpx_sad64x64, vpx_sad_skip_64x64, vpx_sad64x64_avg,
2699*fb1b10abSAndroid Build Coastguard Worker       vpx_variance64x64, vpx_sub_pixel_variance64x64,
2700*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance64x64, vpx_sad64x64x4d, vpx_sad_skip_64x64x4d)
2701*fb1b10abSAndroid Build Coastguard Worker 
2702*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_16X16, vpx_sad16x16, vpx_sad_skip_16x16, vpx_sad16x16_avg,
2703*fb1b10abSAndroid Build Coastguard Worker       vpx_variance16x16, vpx_sub_pixel_variance16x16,
2704*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance16x16, vpx_sad16x16x4d, vpx_sad_skip_16x16x4d)
2705*fb1b10abSAndroid Build Coastguard Worker 
2706*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_16X8, vpx_sad16x8, vpx_sad_skip_16x8, vpx_sad16x8_avg,
2707*fb1b10abSAndroid Build Coastguard Worker       vpx_variance16x8, vpx_sub_pixel_variance16x8,
2708*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance16x8, vpx_sad16x8x4d, vpx_sad_skip_16x8x4d)
2709*fb1b10abSAndroid Build Coastguard Worker 
2710*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_8X16, vpx_sad8x16, vpx_sad_skip_8x16, vpx_sad8x16_avg,
2711*fb1b10abSAndroid Build Coastguard Worker       vpx_variance8x16, vpx_sub_pixel_variance8x16,
2712*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_avg_variance8x16, vpx_sad8x16x4d, vpx_sad_skip_8x16x4d)
2713*fb1b10abSAndroid Build Coastguard Worker 
2714*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_8X8, vpx_sad8x8, vpx_sad_skip_8x8, vpx_sad8x8_avg, vpx_variance8x8,
2715*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_variance8x8, vpx_sub_pixel_avg_variance8x8, vpx_sad8x8x4d,
2716*fb1b10abSAndroid Build Coastguard Worker       vpx_sad_skip_8x8x4d)
2717*fb1b10abSAndroid Build Coastguard Worker 
2718*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_8X4, vpx_sad8x4, vpx_sad_skip_8x4, vpx_sad8x4_avg, vpx_variance8x4,
2719*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_variance8x4, vpx_sub_pixel_avg_variance8x4, vpx_sad8x4x4d,
2720*fb1b10abSAndroid Build Coastguard Worker       vpx_sad_skip_8x4x4d)
2721*fb1b10abSAndroid Build Coastguard Worker 
2722*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_4X8, vpx_sad4x8, vpx_sad_skip_4x8, vpx_sad4x8_avg, vpx_variance4x8,
2723*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_variance4x8, vpx_sub_pixel_avg_variance4x8, vpx_sad4x8x4d,
2724*fb1b10abSAndroid Build Coastguard Worker       vpx_sad_skip_4x8x4d)
2725*fb1b10abSAndroid Build Coastguard Worker 
2726*fb1b10abSAndroid Build Coastguard Worker   BFP(BLOCK_4X4, vpx_sad4x4, vpx_sad_skip_4x4, vpx_sad4x4_avg, vpx_variance4x4,
2727*fb1b10abSAndroid Build Coastguard Worker       vpx_sub_pixel_variance4x4, vpx_sub_pixel_avg_variance4x4, vpx_sad4x4x4d,
2728*fb1b10abSAndroid Build Coastguard Worker       vpx_sad_skip_4x4x4d)
2729*fb1b10abSAndroid Build Coastguard Worker 
2730*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2731*fb1b10abSAndroid Build Coastguard Worker   highbd_set_var_fns(cpi);
2732*fb1b10abSAndroid Build Coastguard Worker #endif
2733*fb1b10abSAndroid Build Coastguard Worker 
2734*fb1b10abSAndroid Build Coastguard Worker   /* vp9_init_quantizer() is first called here. Add check in
2735*fb1b10abSAndroid Build Coastguard Worker    * vp9_frame_init_quantizer() so that vp9_init_quantizer is only
2736*fb1b10abSAndroid Build Coastguard Worker    * called later when needed. This will avoid unnecessary calls of
2737*fb1b10abSAndroid Build Coastguard Worker    * vp9_init_quantizer() for every frame.
2738*fb1b10abSAndroid Build Coastguard Worker    */
2739*fb1b10abSAndroid Build Coastguard Worker   vp9_init_quantizer(cpi);
2740*fb1b10abSAndroid Build Coastguard Worker 
2741*fb1b10abSAndroid Build Coastguard Worker   vp9_loop_filter_init(cm);
2742*fb1b10abSAndroid Build Coastguard Worker 
2743*fb1b10abSAndroid Build Coastguard Worker   // Set up the unit scaling factor used during motion search.
2744*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2745*fb1b10abSAndroid Build Coastguard Worker   vp9_setup_scale_factors_for_frame(&cpi->me_sf, cm->width, cm->height,
2746*fb1b10abSAndroid Build Coastguard Worker                                     cm->width, cm->height,
2747*fb1b10abSAndroid Build Coastguard Worker                                     cm->use_highbitdepth);
2748*fb1b10abSAndroid Build Coastguard Worker #else
2749*fb1b10abSAndroid Build Coastguard Worker   vp9_setup_scale_factors_for_frame(&cpi->me_sf, cm->width, cm->height,
2750*fb1b10abSAndroid Build Coastguard Worker                                     cm->width, cm->height);
2751*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
2752*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.me_sf = &cpi->me_sf;
2753*fb1b10abSAndroid Build Coastguard Worker 
2754*fb1b10abSAndroid Build Coastguard Worker   cm->error.setjmp = 0;
2755*fb1b10abSAndroid Build Coastguard Worker 
2756*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
2757*fb1b10abSAndroid Build Coastguard Worker   encode_command_init(&cpi->encode_command);
2758*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->use_simple_encode_api) {
2759*fb1b10abSAndroid Build Coastguard Worker     partition_info_init(cpi);
2760*fb1b10abSAndroid Build Coastguard Worker     motion_vector_info_init(cpi);
2761*fb1b10abSAndroid Build Coastguard Worker     fp_motion_vector_info_init(cpi);
2762*fb1b10abSAndroid Build Coastguard Worker     tpl_stats_info_init(cpi);
2763*fb1b10abSAndroid Build Coastguard Worker   }
2764*fb1b10abSAndroid Build Coastguard Worker #endif
2765*fb1b10abSAndroid Build Coastguard Worker 
2766*fb1b10abSAndroid Build Coastguard Worker   return cpi;
2767*fb1b10abSAndroid Build Coastguard Worker }
2768*fb1b10abSAndroid Build Coastguard Worker 
2769*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
2770*fb1b10abSAndroid Build Coastguard Worker #define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
2771*fb1b10abSAndroid Build Coastguard Worker 
2772*fb1b10abSAndroid Build Coastguard Worker #define SNPRINT2(H, T, V) \
2773*fb1b10abSAndroid Build Coastguard Worker   snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
2774*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_INTERNAL_STATS
2775*fb1b10abSAndroid Build Coastguard Worker 
vp9_remove_compressor(VP9_COMP * cpi)2776*fb1b10abSAndroid Build Coastguard Worker void vp9_remove_compressor(VP9_COMP *cpi) {
2777*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm;
2778*fb1b10abSAndroid Build Coastguard Worker   unsigned int i;
2779*fb1b10abSAndroid Build Coastguard Worker 
2780*fb1b10abSAndroid Build Coastguard Worker   if (!cpi) return;
2781*fb1b10abSAndroid Build Coastguard Worker 
2782*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
2783*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->ssim_vars);
2784*fb1b10abSAndroid Build Coastguard Worker #endif
2785*fb1b10abSAndroid Build Coastguard Worker 
2786*fb1b10abSAndroid Build Coastguard Worker   cm = &cpi->common;
2787*fb1b10abSAndroid Build Coastguard Worker   if (cm->current_video_frame > 0) {
2788*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
2789*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
2790*fb1b10abSAndroid Build Coastguard Worker 
2791*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.pass != 1) {
2792*fb1b10abSAndroid Build Coastguard Worker       char headings[512] = { 0 };
2793*fb1b10abSAndroid Build Coastguard Worker       char results[512] = { 0 };
2794*fb1b10abSAndroid Build Coastguard Worker       FILE *f = fopen("opsnr.stt", "a");
2795*fb1b10abSAndroid Build Coastguard Worker       double time_encoded =
2796*fb1b10abSAndroid Build Coastguard Worker           (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
2797*fb1b10abSAndroid Build Coastguard Worker           10000000.000;
2798*fb1b10abSAndroid Build Coastguard Worker       double total_encode_time =
2799*fb1b10abSAndroid Build Coastguard Worker           (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
2800*fb1b10abSAndroid Build Coastguard Worker       const double dr =
2801*fb1b10abSAndroid Build Coastguard Worker           (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
2802*fb1b10abSAndroid Build Coastguard Worker       const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
2803*fb1b10abSAndroid Build Coastguard Worker       const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
2804*fb1b10abSAndroid Build Coastguard Worker       const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
2805*fb1b10abSAndroid Build Coastguard Worker 
2806*fb1b10abSAndroid Build Coastguard Worker       if (cpi->b_calculate_psnr) {
2807*fb1b10abSAndroid Build Coastguard Worker         const double total_psnr = vpx_sse_to_psnr(
2808*fb1b10abSAndroid Build Coastguard Worker             (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
2809*fb1b10abSAndroid Build Coastguard Worker         const double totalp_psnr = vpx_sse_to_psnr(
2810*fb1b10abSAndroid Build Coastguard Worker             (double)cpi->totalp_samples, peak, (double)cpi->totalp_sq_error);
2811*fb1b10abSAndroid Build Coastguard Worker         const double total_ssim =
2812*fb1b10abSAndroid Build Coastguard Worker             100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
2813*fb1b10abSAndroid Build Coastguard Worker         const double totalp_ssim =
2814*fb1b10abSAndroid Build Coastguard Worker             100 * pow(cpi->summedp_quality / cpi->summedp_weights, 8.0);
2815*fb1b10abSAndroid Build Coastguard Worker 
2816*fb1b10abSAndroid Build Coastguard Worker         snprintf(headings, sizeof(headings),
2817*fb1b10abSAndroid Build Coastguard Worker                  "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
2818*fb1b10abSAndroid Build Coastguard Worker                  "VPXSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
2819*fb1b10abSAndroid Build Coastguard Worker                  "WstPsnr\tWstSsim\tWstFast\tWstHVS\t"
2820*fb1b10abSAndroid Build Coastguard Worker                  "AVPsnrY\tAPsnrCb\tAPsnrCr");
2821*fb1b10abSAndroid Build Coastguard Worker         snprintf(results, sizeof(results),
2822*fb1b10abSAndroid Build Coastguard Worker                  "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2823*fb1b10abSAndroid Build Coastguard Worker                  "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2824*fb1b10abSAndroid Build Coastguard Worker                  "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2825*fb1b10abSAndroid Build Coastguard Worker                  "%7.3f\t%7.3f\t%7.3f",
2826*fb1b10abSAndroid Build Coastguard Worker                  dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr,
2827*fb1b10abSAndroid Build Coastguard Worker                  cpi->psnrp.stat[ALL] / cpi->count, totalp_psnr, total_ssim,
2828*fb1b10abSAndroid Build Coastguard Worker                  totalp_ssim, cpi->fastssim.stat[ALL] / cpi->count,
2829*fb1b10abSAndroid Build Coastguard Worker                  cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst,
2830*fb1b10abSAndroid Build Coastguard Worker                  cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst,
2831*fb1b10abSAndroid Build Coastguard Worker                  cpi->psnr.stat[Y] / cpi->count, cpi->psnr.stat[U] / cpi->count,
2832*fb1b10abSAndroid Build Coastguard Worker                  cpi->psnr.stat[V] / cpi->count);
2833*fb1b10abSAndroid Build Coastguard Worker 
2834*fb1b10abSAndroid Build Coastguard Worker         if (cpi->b_calculate_blockiness) {
2835*fb1b10abSAndroid Build Coastguard Worker           SNPRINT(headings, "\t  Block\tWstBlck");
2836*fb1b10abSAndroid Build Coastguard Worker           SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
2837*fb1b10abSAndroid Build Coastguard Worker           SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
2838*fb1b10abSAndroid Build Coastguard Worker         }
2839*fb1b10abSAndroid Build Coastguard Worker 
2840*fb1b10abSAndroid Build Coastguard Worker         if (cpi->b_calculate_consistency) {
2841*fb1b10abSAndroid Build Coastguard Worker           double consistency =
2842*fb1b10abSAndroid Build Coastguard Worker               vpx_sse_to_psnr((double)cpi->totalp_samples, peak,
2843*fb1b10abSAndroid Build Coastguard Worker                               (double)cpi->total_inconsistency);
2844*fb1b10abSAndroid Build Coastguard Worker 
2845*fb1b10abSAndroid Build Coastguard Worker           SNPRINT(headings, "\tConsist\tWstCons");
2846*fb1b10abSAndroid Build Coastguard Worker           SNPRINT2(results, "\t%7.3f", consistency);
2847*fb1b10abSAndroid Build Coastguard Worker           SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
2848*fb1b10abSAndroid Build Coastguard Worker         }
2849*fb1b10abSAndroid Build Coastguard Worker 
2850*fb1b10abSAndroid Build Coastguard Worker         SNPRINT(headings, "\t    Time\tRcErr\tAbsErr");
2851*fb1b10abSAndroid Build Coastguard Worker         SNPRINT2(results, "\t%8.0f", total_encode_time);
2852*fb1b10abSAndroid Build Coastguard Worker         SNPRINT2(results, "\t%7.2f", rate_err);
2853*fb1b10abSAndroid Build Coastguard Worker         SNPRINT2(results, "\t%7.2f", fabs(rate_err));
2854*fb1b10abSAndroid Build Coastguard Worker 
2855*fb1b10abSAndroid Build Coastguard Worker         fprintf(f, "%s\tAPsnr611\n", headings);
2856*fb1b10abSAndroid Build Coastguard Worker         fprintf(
2857*fb1b10abSAndroid Build Coastguard Worker             f, "%s\t%7.3f\n", results,
2858*fb1b10abSAndroid Build Coastguard Worker             (6 * cpi->psnr.stat[Y] + cpi->psnr.stat[U] + cpi->psnr.stat[V]) /
2859*fb1b10abSAndroid Build Coastguard Worker                 (cpi->count * 8));
2860*fb1b10abSAndroid Build Coastguard Worker       }
2861*fb1b10abSAndroid Build Coastguard Worker 
2862*fb1b10abSAndroid Build Coastguard Worker       fclose(f);
2863*fb1b10abSAndroid Build Coastguard Worker     }
2864*fb1b10abSAndroid Build Coastguard Worker #endif
2865*fb1b10abSAndroid Build Coastguard Worker 
2866*fb1b10abSAndroid Build Coastguard Worker #if 0
2867*fb1b10abSAndroid Build Coastguard Worker     {
2868*fb1b10abSAndroid Build Coastguard Worker       printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
2869*fb1b10abSAndroid Build Coastguard Worker       printf("\n_frames receive_data encod_mb_row compress_frame  Total\n");
2870*fb1b10abSAndroid Build Coastguard Worker       printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame,
2871*fb1b10abSAndroid Build Coastguard Worker              cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000,
2872*fb1b10abSAndroid Build Coastguard Worker              cpi->time_compress_data / 1000,
2873*fb1b10abSAndroid Build Coastguard Worker              (cpi->time_receive_data + cpi->time_compress_data) / 1000);
2874*fb1b10abSAndroid Build Coastguard Worker     }
2875*fb1b10abSAndroid Build Coastguard Worker #endif
2876*fb1b10abSAndroid Build Coastguard Worker   }
2877*fb1b10abSAndroid Build Coastguard Worker 
2878*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
2879*fb1b10abSAndroid Build Coastguard Worker   vp9_denoiser_free(&(cpi->denoiser));
2880*fb1b10abSAndroid Build Coastguard Worker #endif
2881*fb1b10abSAndroid Build Coastguard Worker 
2882*fb1b10abSAndroid Build Coastguard Worker   if (cpi->kmeans_data_arr_alloc) {
2883*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
2884*fb1b10abSAndroid Build Coastguard Worker     pthread_mutex_destroy(&cpi->kmeans_mutex);
2885*fb1b10abSAndroid Build Coastguard Worker #endif
2886*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->kmeans_data_arr);
2887*fb1b10abSAndroid Build Coastguard Worker   }
2888*fb1b10abSAndroid Build Coastguard Worker 
2889*fb1b10abSAndroid Build Coastguard Worker   vp9_free_tpl_buffer(cpi);
2890*fb1b10abSAndroid Build Coastguard Worker 
2891*fb1b10abSAndroid Build Coastguard Worker   vp9_loop_filter_dealloc(&cpi->lf_row_sync);
2892*fb1b10abSAndroid Build Coastguard Worker   vp9_bitstream_encode_tiles_buffer_dealloc(cpi);
2893*fb1b10abSAndroid Build Coastguard Worker   vp9_row_mt_mem_dealloc(cpi);
2894*fb1b10abSAndroid Build Coastguard Worker   vp9_encode_free_mt_data(cpi);
2895*fb1b10abSAndroid Build Coastguard Worker 
2896*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
2897*fb1b10abSAndroid Build Coastguard Worker   vp9_alt_ref_aq_destroy(cpi->alt_ref_aq);
2898*fb1b10abSAndroid Build Coastguard Worker #endif
2899*fb1b10abSAndroid Build Coastguard Worker 
2900*fb1b10abSAndroid Build Coastguard Worker   dealloc_compressor_data(cpi);
2901*fb1b10abSAndroid Build Coastguard Worker 
2902*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
2903*fb1b10abSAndroid Build Coastguard Worker        ++i) {
2904*fb1b10abSAndroid Build Coastguard Worker     vpx_free(cpi->mbgraph_stats[i].mb_stats);
2905*fb1b10abSAndroid Build Coastguard Worker   }
2906*fb1b10abSAndroid Build Coastguard Worker 
2907*fb1b10abSAndroid Build Coastguard Worker   vp9_extrc_delete(&cpi->ext_ratectrl);
2908*fb1b10abSAndroid Build Coastguard Worker 
2909*fb1b10abSAndroid Build Coastguard Worker   // Help detect use after free of the error detail string.
2910*fb1b10abSAndroid Build Coastguard Worker   memset(cm->error.detail, 'A', sizeof(cm->error.detail) - 1);
2911*fb1b10abSAndroid Build Coastguard Worker   cm->error.detail[sizeof(cm->error.detail) - 1] = '\0';
2912*fb1b10abSAndroid Build Coastguard Worker 
2913*fb1b10abSAndroid Build Coastguard Worker   vp9_remove_common(cm);
2914*fb1b10abSAndroid Build Coastguard Worker   vp9_free_ref_frame_buffers(cm->buffer_pool);
2915*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC
2916*fb1b10abSAndroid Build Coastguard Worker   vp9_free_postproc_buffers(cm);
2917*fb1b10abSAndroid Build Coastguard Worker #endif
2918*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi);
2919*fb1b10abSAndroid Build Coastguard Worker 
2920*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
2921*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_DENOISED
2922*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_denoised_file);
2923*fb1b10abSAndroid Build Coastguard Worker #endif
2924*fb1b10abSAndroid Build Coastguard Worker #endif
2925*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SKINMAP
2926*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_skinmap_file);
2927*fb1b10abSAndroid Build Coastguard Worker #endif
2928*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_REC
2929*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_rec_file);
2930*fb1b10abSAndroid Build Coastguard Worker #endif
2931*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SVC_SRC
2932*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_svc_src[0]);
2933*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_svc_src[1]);
2934*fb1b10abSAndroid Build Coastguard Worker   fclose(yuv_svc_src[2]);
2935*fb1b10abSAndroid Build Coastguard Worker #endif
2936*fb1b10abSAndroid Build Coastguard Worker 
2937*fb1b10abSAndroid Build Coastguard Worker #if 0
2938*fb1b10abSAndroid Build Coastguard Worker 
2939*fb1b10abSAndroid Build Coastguard Worker   if (keyfile)
2940*fb1b10abSAndroid Build Coastguard Worker     fclose(keyfile);
2941*fb1b10abSAndroid Build Coastguard Worker 
2942*fb1b10abSAndroid Build Coastguard Worker   if (framepsnr)
2943*fb1b10abSAndroid Build Coastguard Worker     fclose(framepsnr);
2944*fb1b10abSAndroid Build Coastguard Worker 
2945*fb1b10abSAndroid Build Coastguard Worker   if (kf_list)
2946*fb1b10abSAndroid Build Coastguard Worker     fclose(kf_list);
2947*fb1b10abSAndroid Build Coastguard Worker 
2948*fb1b10abSAndroid Build Coastguard Worker #endif
2949*fb1b10abSAndroid Build Coastguard Worker }
2950*fb1b10abSAndroid Build Coastguard Worker 
vp9_get_psnr(const VP9_COMP * cpi,PSNR_STATS * psnr)2951*fb1b10abSAndroid Build Coastguard Worker int vp9_get_psnr(const VP9_COMP *cpi, PSNR_STATS *psnr) {
2952*fb1b10abSAndroid Build Coastguard Worker   if (is_psnr_calc_enabled(cpi)) {
2953*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
2954*fb1b10abSAndroid Build Coastguard Worker     vpx_calc_highbd_psnr(cpi->raw_source_frame, cpi->common.frame_to_show, psnr,
2955*fb1b10abSAndroid Build Coastguard Worker                          cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth);
2956*fb1b10abSAndroid Build Coastguard Worker #else
2957*fb1b10abSAndroid Build Coastguard Worker     vpx_calc_psnr(cpi->raw_source_frame, cpi->common.frame_to_show, psnr);
2958*fb1b10abSAndroid Build Coastguard Worker #endif
2959*fb1b10abSAndroid Build Coastguard Worker     return 1;
2960*fb1b10abSAndroid Build Coastguard Worker   } else {
2961*fb1b10abSAndroid Build Coastguard Worker     vp9_zero(*psnr);
2962*fb1b10abSAndroid Build Coastguard Worker     return 0;
2963*fb1b10abSAndroid Build Coastguard Worker   }
2964*fb1b10abSAndroid Build Coastguard Worker }
2965*fb1b10abSAndroid Build Coastguard Worker 
vp9_use_as_reference(VP9_COMP * cpi,int ref_frame_flags)2966*fb1b10abSAndroid Build Coastguard Worker int vp9_use_as_reference(VP9_COMP *cpi, int ref_frame_flags) {
2967*fb1b10abSAndroid Build Coastguard Worker   if (ref_frame_flags > 7) return -1;
2968*fb1b10abSAndroid Build Coastguard Worker 
2969*fb1b10abSAndroid Build Coastguard Worker   cpi->ref_frame_flags = ref_frame_flags;
2970*fb1b10abSAndroid Build Coastguard Worker   return 0;
2971*fb1b10abSAndroid Build Coastguard Worker }
2972*fb1b10abSAndroid Build Coastguard Worker 
vp9_update_reference(VP9_COMP * cpi,int ref_frame_flags)2973*fb1b10abSAndroid Build Coastguard Worker void vp9_update_reference(VP9_COMP *cpi, int ref_frame_flags) {
2974*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_golden_frame = (ref_frame_flags & VP9_GOLD_FLAG) != 0;
2975*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & VP9_ALT_FLAG) != 0;
2976*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_last_frame = (ref_frame_flags & VP9_LAST_FLAG) != 0;
2977*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_flags_pending = 1;
2978*fb1b10abSAndroid Build Coastguard Worker }
2979*fb1b10abSAndroid Build Coastguard Worker 
get_vp9_ref_frame_buffer(VP9_COMP * cpi,VP9_REFFRAME ref_frame_flag)2980*fb1b10abSAndroid Build Coastguard Worker static YV12_BUFFER_CONFIG *get_vp9_ref_frame_buffer(
2981*fb1b10abSAndroid Build Coastguard Worker     VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag) {
2982*fb1b10abSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref_frame = NO_REF_FRAME;
2983*fb1b10abSAndroid Build Coastguard Worker   if (ref_frame_flag == VP9_LAST_FLAG)
2984*fb1b10abSAndroid Build Coastguard Worker     ref_frame = LAST_FRAME;
2985*fb1b10abSAndroid Build Coastguard Worker   else if (ref_frame_flag == VP9_GOLD_FLAG)
2986*fb1b10abSAndroid Build Coastguard Worker     ref_frame = GOLDEN_FRAME;
2987*fb1b10abSAndroid Build Coastguard Worker   else if (ref_frame_flag == VP9_ALT_FLAG)
2988*fb1b10abSAndroid Build Coastguard Worker     ref_frame = ALTREF_FRAME;
2989*fb1b10abSAndroid Build Coastguard Worker 
2990*fb1b10abSAndroid Build Coastguard Worker   return ref_frame == NO_REF_FRAME ? NULL
2991*fb1b10abSAndroid Build Coastguard Worker                                    : get_ref_frame_buffer(cpi, ref_frame);
2992*fb1b10abSAndroid Build Coastguard Worker }
2993*fb1b10abSAndroid Build Coastguard Worker 
vp9_copy_reference_enc(VP9_COMP * cpi,VP9_REFFRAME ref_frame_flag,YV12_BUFFER_CONFIG * sd)2994*fb1b10abSAndroid Build Coastguard Worker int vp9_copy_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag,
2995*fb1b10abSAndroid Build Coastguard Worker                            YV12_BUFFER_CONFIG *sd) {
2996*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag);
2997*fb1b10abSAndroid Build Coastguard Worker   if (cfg) {
2998*fb1b10abSAndroid Build Coastguard Worker     vpx_yv12_copy_frame(cfg, sd);
2999*fb1b10abSAndroid Build Coastguard Worker     return 0;
3000*fb1b10abSAndroid Build Coastguard Worker   } else {
3001*fb1b10abSAndroid Build Coastguard Worker     return -1;
3002*fb1b10abSAndroid Build Coastguard Worker   }
3003*fb1b10abSAndroid Build Coastguard Worker }
3004*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_reference_enc(VP9_COMP * cpi,VP9_REFFRAME ref_frame_flag,YV12_BUFFER_CONFIG * sd)3005*fb1b10abSAndroid Build Coastguard Worker int vp9_set_reference_enc(VP9_COMP *cpi, VP9_REFFRAME ref_frame_flag,
3006*fb1b10abSAndroid Build Coastguard Worker                           YV12_BUFFER_CONFIG *sd) {
3007*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag);
3008*fb1b10abSAndroid Build Coastguard Worker   if (cfg) {
3009*fb1b10abSAndroid Build Coastguard Worker     vpx_yv12_copy_frame(sd, cfg);
3010*fb1b10abSAndroid Build Coastguard Worker     return 0;
3011*fb1b10abSAndroid Build Coastguard Worker   } else {
3012*fb1b10abSAndroid Build Coastguard Worker     return -1;
3013*fb1b10abSAndroid Build Coastguard Worker   }
3014*fb1b10abSAndroid Build Coastguard Worker }
3015*fb1b10abSAndroid Build Coastguard Worker 
vp9_update_entropy(VP9_COMP * cpi,int update)3016*fb1b10abSAndroid Build Coastguard Worker int vp9_update_entropy(VP9_COMP *cpi, int update) {
3017*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_context = update;
3018*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_context_pending = 1;
3019*fb1b10abSAndroid Build Coastguard Worker   return 0;
3020*fb1b10abSAndroid Build Coastguard Worker }
3021*fb1b10abSAndroid Build Coastguard Worker 
3022*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_REC
vp9_write_yuv_rec_frame(VP9_COMMON * cm)3023*fb1b10abSAndroid Build Coastguard Worker void vp9_write_yuv_rec_frame(VP9_COMMON *cm) {
3024*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *s = cm->frame_to_show;
3025*fb1b10abSAndroid Build Coastguard Worker   uint8_t *src = s->y_buffer;
3026*fb1b10abSAndroid Build Coastguard Worker   int h = cm->height;
3027*fb1b10abSAndroid Build Coastguard Worker 
3028*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3029*fb1b10abSAndroid Build Coastguard Worker   if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
3030*fb1b10abSAndroid Build Coastguard Worker     uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
3031*fb1b10abSAndroid Build Coastguard Worker 
3032*fb1b10abSAndroid Build Coastguard Worker     do {
3033*fb1b10abSAndroid Build Coastguard Worker       fwrite(src16, s->y_width, 2, yuv_rec_file);
3034*fb1b10abSAndroid Build Coastguard Worker       src16 += s->y_stride;
3035*fb1b10abSAndroid Build Coastguard Worker     } while (--h);
3036*fb1b10abSAndroid Build Coastguard Worker 
3037*fb1b10abSAndroid Build Coastguard Worker     src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
3038*fb1b10abSAndroid Build Coastguard Worker     h = s->uv_height;
3039*fb1b10abSAndroid Build Coastguard Worker 
3040*fb1b10abSAndroid Build Coastguard Worker     do {
3041*fb1b10abSAndroid Build Coastguard Worker       fwrite(src16, s->uv_width, 2, yuv_rec_file);
3042*fb1b10abSAndroid Build Coastguard Worker       src16 += s->uv_stride;
3043*fb1b10abSAndroid Build Coastguard Worker     } while (--h);
3044*fb1b10abSAndroid Build Coastguard Worker 
3045*fb1b10abSAndroid Build Coastguard Worker     src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
3046*fb1b10abSAndroid Build Coastguard Worker     h = s->uv_height;
3047*fb1b10abSAndroid Build Coastguard Worker 
3048*fb1b10abSAndroid Build Coastguard Worker     do {
3049*fb1b10abSAndroid Build Coastguard Worker       fwrite(src16, s->uv_width, 2, yuv_rec_file);
3050*fb1b10abSAndroid Build Coastguard Worker       src16 += s->uv_stride;
3051*fb1b10abSAndroid Build Coastguard Worker     } while (--h);
3052*fb1b10abSAndroid Build Coastguard Worker 
3053*fb1b10abSAndroid Build Coastguard Worker     fflush(yuv_rec_file);
3054*fb1b10abSAndroid Build Coastguard Worker     return;
3055*fb1b10abSAndroid Build Coastguard Worker   }
3056*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3057*fb1b10abSAndroid Build Coastguard Worker 
3058*fb1b10abSAndroid Build Coastguard Worker   do {
3059*fb1b10abSAndroid Build Coastguard Worker     fwrite(src, s->y_width, 1, yuv_rec_file);
3060*fb1b10abSAndroid Build Coastguard Worker     src += s->y_stride;
3061*fb1b10abSAndroid Build Coastguard Worker   } while (--h);
3062*fb1b10abSAndroid Build Coastguard Worker 
3063*fb1b10abSAndroid Build Coastguard Worker   src = s->u_buffer;
3064*fb1b10abSAndroid Build Coastguard Worker   h = s->uv_height;
3065*fb1b10abSAndroid Build Coastguard Worker 
3066*fb1b10abSAndroid Build Coastguard Worker   do {
3067*fb1b10abSAndroid Build Coastguard Worker     fwrite(src, s->uv_width, 1, yuv_rec_file);
3068*fb1b10abSAndroid Build Coastguard Worker     src += s->uv_stride;
3069*fb1b10abSAndroid Build Coastguard Worker   } while (--h);
3070*fb1b10abSAndroid Build Coastguard Worker 
3071*fb1b10abSAndroid Build Coastguard Worker   src = s->v_buffer;
3072*fb1b10abSAndroid Build Coastguard Worker   h = s->uv_height;
3073*fb1b10abSAndroid Build Coastguard Worker 
3074*fb1b10abSAndroid Build Coastguard Worker   do {
3075*fb1b10abSAndroid Build Coastguard Worker     fwrite(src, s->uv_width, 1, yuv_rec_file);
3076*fb1b10abSAndroid Build Coastguard Worker     src += s->uv_stride;
3077*fb1b10abSAndroid Build Coastguard Worker   } while (--h);
3078*fb1b10abSAndroid Build Coastguard Worker 
3079*fb1b10abSAndroid Build Coastguard Worker   fflush(yuv_rec_file);
3080*fb1b10abSAndroid Build Coastguard Worker }
3081*fb1b10abSAndroid Build Coastguard Worker #endif
3082*fb1b10abSAndroid Build Coastguard Worker 
3083*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG * src,YV12_BUFFER_CONFIG * dst,int bd)3084*fb1b10abSAndroid Build Coastguard Worker void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
3085*fb1b10abSAndroid Build Coastguard Worker                                              YV12_BUFFER_CONFIG *dst, int bd) {
3086*fb1b10abSAndroid Build Coastguard Worker #else
3087*fb1b10abSAndroid Build Coastguard Worker void vp9_scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
3088*fb1b10abSAndroid Build Coastguard Worker                                              YV12_BUFFER_CONFIG *dst) {
3089*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3090*fb1b10abSAndroid Build Coastguard Worker   // TODO(dkovalev): replace YV12_BUFFER_CONFIG with vpx_image_t
3091*fb1b10abSAndroid Build Coastguard Worker   int i;
3092*fb1b10abSAndroid Build Coastguard Worker   const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
3093*fb1b10abSAndroid Build Coastguard Worker                                    src->v_buffer };
3094*fb1b10abSAndroid Build Coastguard Worker   const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
3095*fb1b10abSAndroid Build Coastguard Worker   const int src_widths[3] = { src->y_crop_width, src->uv_crop_width,
3096*fb1b10abSAndroid Build Coastguard Worker                               src->uv_crop_width };
3097*fb1b10abSAndroid Build Coastguard Worker   const int src_heights[3] = { src->y_crop_height, src->uv_crop_height,
3098*fb1b10abSAndroid Build Coastguard Worker                                src->uv_crop_height };
3099*fb1b10abSAndroid Build Coastguard Worker   uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
3100*fb1b10abSAndroid Build Coastguard Worker   const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
3101*fb1b10abSAndroid Build Coastguard Worker   const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width,
3102*fb1b10abSAndroid Build Coastguard Worker                               dst->uv_crop_width };
3103*fb1b10abSAndroid Build Coastguard Worker   const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height,
3104*fb1b10abSAndroid Build Coastguard Worker                                dst->uv_crop_height };
3105*fb1b10abSAndroid Build Coastguard Worker 
3106*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_MB_PLANE; ++i) {
3107*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3108*fb1b10abSAndroid Build Coastguard Worker     if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
3109*fb1b10abSAndroid Build Coastguard Worker       vp9_highbd_resize_plane(srcs[i], src_heights[i], src_widths[i],
3110*fb1b10abSAndroid Build Coastguard Worker                               src_strides[i], dsts[i], dst_heights[i],
3111*fb1b10abSAndroid Build Coastguard Worker                               dst_widths[i], dst_strides[i], bd);
3112*fb1b10abSAndroid Build Coastguard Worker     } else {
3113*fb1b10abSAndroid Build Coastguard Worker       vp9_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
3114*fb1b10abSAndroid Build Coastguard Worker                        dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
3115*fb1b10abSAndroid Build Coastguard Worker     }
3116*fb1b10abSAndroid Build Coastguard Worker #else
3117*fb1b10abSAndroid Build Coastguard Worker     vp9_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
3118*fb1b10abSAndroid Build Coastguard Worker                      dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
3119*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3120*fb1b10abSAndroid Build Coastguard Worker   }
3121*fb1b10abSAndroid Build Coastguard Worker   vpx_extend_frame_borders(dst);
3122*fb1b10abSAndroid Build Coastguard Worker }
3123*fb1b10abSAndroid Build Coastguard Worker 
3124*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3125*fb1b10abSAndroid Build Coastguard Worker static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
3126*fb1b10abSAndroid Build Coastguard Worker                                    YV12_BUFFER_CONFIG *dst, int bd,
3127*fb1b10abSAndroid Build Coastguard Worker                                    INTERP_FILTER filter_type,
3128*fb1b10abSAndroid Build Coastguard Worker                                    int phase_scaler) {
3129*fb1b10abSAndroid Build Coastguard Worker   const int src_w = src->y_crop_width;
3130*fb1b10abSAndroid Build Coastguard Worker   const int src_h = src->y_crop_height;
3131*fb1b10abSAndroid Build Coastguard Worker   const int dst_w = dst->y_crop_width;
3132*fb1b10abSAndroid Build Coastguard Worker   const int dst_h = dst->y_crop_height;
3133*fb1b10abSAndroid Build Coastguard Worker 
3134*fb1b10abSAndroid Build Coastguard Worker   // The issue b/311394513 reveals a corner case bug.
3135*fb1b10abSAndroid Build Coastguard Worker   // For bd = 8, vpx_scaled_2d() requires both x_step_q4 and y_step_q4 are less
3136*fb1b10abSAndroid Build Coastguard Worker   // than or equal to 64. For bd >= 10, vpx_highbd_convolve8() requires both
3137*fb1b10abSAndroid Build Coastguard Worker   // x_step_q4 and y_step_q4 are less than or equal to 32. If this condition
3138*fb1b10abSAndroid Build Coastguard Worker   // isn't met, it needs to call vp9_scale_and_extend_frame_nonnormative() that
3139*fb1b10abSAndroid Build Coastguard Worker   // supports arbitrary scaling.
3140*fb1b10abSAndroid Build Coastguard Worker   const int x_step_q4 = 16 * src_w / dst_w;
3141*fb1b10abSAndroid Build Coastguard Worker   const int y_step_q4 = 16 * src_h / dst_h;
3142*fb1b10abSAndroid Build Coastguard Worker   const int is_arbitrary_scaling =
3143*fb1b10abSAndroid Build Coastguard Worker       (bd == 8 && (x_step_q4 > 64 || y_step_q4 > 64)) ||
3144*fb1b10abSAndroid Build Coastguard Worker       (bd >= 10 && (x_step_q4 > 32 || y_step_q4 > 32));
3145*fb1b10abSAndroid Build Coastguard Worker   if (is_arbitrary_scaling) {
3146*fb1b10abSAndroid Build Coastguard Worker     vp9_scale_and_extend_frame_nonnormative(src, dst, bd);
3147*fb1b10abSAndroid Build Coastguard Worker     return;
3148*fb1b10abSAndroid Build Coastguard Worker   }
3149*fb1b10abSAndroid Build Coastguard Worker 
3150*fb1b10abSAndroid Build Coastguard Worker   const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
3151*fb1b10abSAndroid Build Coastguard Worker                                    src->v_buffer };
3152*fb1b10abSAndroid Build Coastguard Worker   const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
3153*fb1b10abSAndroid Build Coastguard Worker   uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
3154*fb1b10abSAndroid Build Coastguard Worker   const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
3155*fb1b10abSAndroid Build Coastguard Worker   const InterpKernel *const kernel = vp9_filter_kernels[filter_type];
3156*fb1b10abSAndroid Build Coastguard Worker   int x, y, i;
3157*fb1b10abSAndroid Build Coastguard Worker 
3158*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_MB_PLANE; ++i) {
3159*fb1b10abSAndroid Build Coastguard Worker     const int factor = (i == 0 || i == 3 ? 1 : 2);
3160*fb1b10abSAndroid Build Coastguard Worker     const int src_stride = src_strides[i];
3161*fb1b10abSAndroid Build Coastguard Worker     const int dst_stride = dst_strides[i];
3162*fb1b10abSAndroid Build Coastguard Worker     for (y = 0; y < dst_h; y += 16) {
3163*fb1b10abSAndroid Build Coastguard Worker       const int y_q4 = y * (16 / factor) * src_h / dst_h + phase_scaler;
3164*fb1b10abSAndroid Build Coastguard Worker       for (x = 0; x < dst_w; x += 16) {
3165*fb1b10abSAndroid Build Coastguard Worker         const int x_q4 = x * (16 / factor) * src_w / dst_w + phase_scaler;
3166*fb1b10abSAndroid Build Coastguard Worker         const uint8_t *src_ptr = srcs[i] +
3167*fb1b10abSAndroid Build Coastguard Worker                                  (y / factor) * src_h / dst_h * src_stride +
3168*fb1b10abSAndroid Build Coastguard Worker                                  (x / factor) * src_w / dst_w;
3169*fb1b10abSAndroid Build Coastguard Worker         uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor);
3170*fb1b10abSAndroid Build Coastguard Worker 
3171*fb1b10abSAndroid Build Coastguard Worker         if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
3172*fb1b10abSAndroid Build Coastguard Worker           vpx_highbd_convolve8(CONVERT_TO_SHORTPTR(src_ptr), src_stride,
3173*fb1b10abSAndroid Build Coastguard Worker                                CONVERT_TO_SHORTPTR(dst_ptr), dst_stride, kernel,
3174*fb1b10abSAndroid Build Coastguard Worker                                x_q4 & 0xf, 16 * src_w / dst_w, y_q4 & 0xf,
3175*fb1b10abSAndroid Build Coastguard Worker                                16 * src_h / dst_h, 16 / factor, 16 / factor,
3176*fb1b10abSAndroid Build Coastguard Worker                                bd);
3177*fb1b10abSAndroid Build Coastguard Worker         } else {
3178*fb1b10abSAndroid Build Coastguard Worker           vpx_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride, kernel,
3179*fb1b10abSAndroid Build Coastguard Worker                         x_q4 & 0xf, 16 * src_w / dst_w, y_q4 & 0xf,
3180*fb1b10abSAndroid Build Coastguard Worker                         16 * src_h / dst_h, 16 / factor, 16 / factor);
3181*fb1b10abSAndroid Build Coastguard Worker         }
3182*fb1b10abSAndroid Build Coastguard Worker       }
3183*fb1b10abSAndroid Build Coastguard Worker     }
3184*fb1b10abSAndroid Build Coastguard Worker   }
3185*fb1b10abSAndroid Build Coastguard Worker 
3186*fb1b10abSAndroid Build Coastguard Worker   vpx_extend_frame_borders(dst);
3187*fb1b10abSAndroid Build Coastguard Worker }
3188*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3189*fb1b10abSAndroid Build Coastguard Worker 
3190*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
3191*fb1b10abSAndroid Build Coastguard Worker static int scale_down(VP9_COMP *cpi, int q) {
3192*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
3193*fb1b10abSAndroid Build Coastguard Worker   GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3194*fb1b10abSAndroid Build Coastguard Worker   int scale = 0;
3195*fb1b10abSAndroid Build Coastguard Worker   assert(frame_is_kf_gf_arf(cpi));
3196*fb1b10abSAndroid Build Coastguard Worker 
3197*fb1b10abSAndroid Build Coastguard Worker   if (rc->frame_size_selector == UNSCALED &&
3198*fb1b10abSAndroid Build Coastguard Worker       q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) {
3199*fb1b10abSAndroid Build Coastguard Worker     const int max_size_thresh =
3200*fb1b10abSAndroid Build Coastguard Worker         (int)(rate_thresh_mult[SCALE_STEP1] *
3201*fb1b10abSAndroid Build Coastguard Worker               VPXMAX(rc->this_frame_target, rc->avg_frame_bandwidth));
3202*fb1b10abSAndroid Build Coastguard Worker     scale = rc->projected_frame_size > max_size_thresh ? 1 : 0;
3203*fb1b10abSAndroid Build Coastguard Worker   }
3204*fb1b10abSAndroid Build Coastguard Worker   return scale;
3205*fb1b10abSAndroid Build Coastguard Worker }
3206*fb1b10abSAndroid Build Coastguard Worker 
3207*fb1b10abSAndroid Build Coastguard Worker static int big_rate_miss_high_threshold(VP9_COMP *cpi) {
3208*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
3209*fb1b10abSAndroid Build Coastguard Worker   int big_miss_high;
3210*fb1b10abSAndroid Build Coastguard Worker 
3211*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_kf_gf_arf(cpi))
3212*fb1b10abSAndroid Build Coastguard Worker     big_miss_high = rc->this_frame_target * 3 / 2;
3213*fb1b10abSAndroid Build Coastguard Worker   else
3214*fb1b10abSAndroid Build Coastguard Worker     big_miss_high = rc->this_frame_target * 2;
3215*fb1b10abSAndroid Build Coastguard Worker 
3216*fb1b10abSAndroid Build Coastguard Worker   return big_miss_high;
3217*fb1b10abSAndroid Build Coastguard Worker }
3218*fb1b10abSAndroid Build Coastguard Worker 
3219*fb1b10abSAndroid Build Coastguard Worker static int big_rate_miss(VP9_COMP *cpi) {
3220*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
3221*fb1b10abSAndroid Build Coastguard Worker   int big_miss_high;
3222*fb1b10abSAndroid Build Coastguard Worker   int big_miss_low;
3223*fb1b10abSAndroid Build Coastguard Worker 
3224*fb1b10abSAndroid Build Coastguard Worker   // Ignore for overlay frames
3225*fb1b10abSAndroid Build Coastguard Worker   if (rc->is_src_frame_alt_ref) {
3226*fb1b10abSAndroid Build Coastguard Worker     return 0;
3227*fb1b10abSAndroid Build Coastguard Worker   } else {
3228*fb1b10abSAndroid Build Coastguard Worker     big_miss_low = (rc->this_frame_target / 2);
3229*fb1b10abSAndroid Build Coastguard Worker     big_miss_high = big_rate_miss_high_threshold(cpi);
3230*fb1b10abSAndroid Build Coastguard Worker 
3231*fb1b10abSAndroid Build Coastguard Worker     return (rc->projected_frame_size > big_miss_high) ||
3232*fb1b10abSAndroid Build Coastguard Worker            (rc->projected_frame_size < big_miss_low);
3233*fb1b10abSAndroid Build Coastguard Worker   }
3234*fb1b10abSAndroid Build Coastguard Worker }
3235*fb1b10abSAndroid Build Coastguard Worker 
3236*fb1b10abSAndroid Build Coastguard Worker // test in two pass for the first
3237*fb1b10abSAndroid Build Coastguard Worker static int two_pass_first_group_inter(VP9_COMP *cpi) {
3238*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 2) {
3239*fb1b10abSAndroid Build Coastguard Worker     TWO_PASS *const twopass = &cpi->twopass;
3240*fb1b10abSAndroid Build Coastguard Worker     GF_GROUP *const gf_group = &twopass->gf_group;
3241*fb1b10abSAndroid Build Coastguard Worker     const int gfg_index = gf_group->index;
3242*fb1b10abSAndroid Build Coastguard Worker 
3243*fb1b10abSAndroid Build Coastguard Worker     if (gfg_index == 0) return gf_group->update_type[gfg_index] == LF_UPDATE;
3244*fb1b10abSAndroid Build Coastguard Worker     return gf_group->update_type[gfg_index - 1] != LF_UPDATE &&
3245*fb1b10abSAndroid Build Coastguard Worker            gf_group->update_type[gfg_index] == LF_UPDATE;
3246*fb1b10abSAndroid Build Coastguard Worker   } else {
3247*fb1b10abSAndroid Build Coastguard Worker     return 0;
3248*fb1b10abSAndroid Build Coastguard Worker   }
3249*fb1b10abSAndroid Build Coastguard Worker }
3250*fb1b10abSAndroid Build Coastguard Worker 
3251*fb1b10abSAndroid Build Coastguard Worker // Function to test for conditions that indicate we should loop
3252*fb1b10abSAndroid Build Coastguard Worker // back and recode a frame.
3253*fb1b10abSAndroid Build Coastguard Worker static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q,
3254*fb1b10abSAndroid Build Coastguard Worker                             int maxq, int minq) {
3255*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
3256*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
3257*fb1b10abSAndroid Build Coastguard Worker   const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
3258*fb1b10abSAndroid Build Coastguard Worker   int force_recode = 0;
3259*fb1b10abSAndroid Build Coastguard Worker 
3260*fb1b10abSAndroid Build Coastguard Worker   if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
3261*fb1b10abSAndroid Build Coastguard Worker       big_rate_miss(cpi) || (cpi->sf.recode_loop == ALLOW_RECODE) ||
3262*fb1b10abSAndroid Build Coastguard Worker       (two_pass_first_group_inter(cpi) &&
3263*fb1b10abSAndroid Build Coastguard Worker        (cpi->sf.recode_loop == ALLOW_RECODE_FIRST)) ||
3264*fb1b10abSAndroid Build Coastguard Worker       (frame_is_kfgfarf && (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF))) {
3265*fb1b10abSAndroid Build Coastguard Worker     if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
3266*fb1b10abSAndroid Build Coastguard Worker         scale_down(cpi, q)) {
3267*fb1b10abSAndroid Build Coastguard Worker       // Code this group at a lower resolution.
3268*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_pending = 1;
3269*fb1b10abSAndroid Build Coastguard Worker       return 1;
3270*fb1b10abSAndroid Build Coastguard Worker     }
3271*fb1b10abSAndroid Build Coastguard Worker 
3272*fb1b10abSAndroid Build Coastguard Worker     // Force recode for extreme overshoot.
3273*fb1b10abSAndroid Build Coastguard Worker     if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
3274*fb1b10abSAndroid Build Coastguard Worker         (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF &&
3275*fb1b10abSAndroid Build Coastguard Worker          rc->projected_frame_size >= big_rate_miss_high_threshold(cpi))) {
3276*fb1b10abSAndroid Build Coastguard Worker       return 1;
3277*fb1b10abSAndroid Build Coastguard Worker     }
3278*fb1b10abSAndroid Build Coastguard Worker 
3279*fb1b10abSAndroid Build Coastguard Worker     // TODO(agrange) high_limit could be greater than the scale-down threshold.
3280*fb1b10abSAndroid Build Coastguard Worker     if ((rc->projected_frame_size > high_limit && q < maxq) ||
3281*fb1b10abSAndroid Build Coastguard Worker         (rc->projected_frame_size < low_limit && q > minq)) {
3282*fb1b10abSAndroid Build Coastguard Worker       force_recode = 1;
3283*fb1b10abSAndroid Build Coastguard Worker     } else if (cpi->oxcf.rc_mode == VPX_CQ) {
3284*fb1b10abSAndroid Build Coastguard Worker       // Deal with frame undershoot and whether or not we are
3285*fb1b10abSAndroid Build Coastguard Worker       // below the automatically set cq level.
3286*fb1b10abSAndroid Build Coastguard Worker       if (q > oxcf->cq_level &&
3287*fb1b10abSAndroid Build Coastguard Worker           rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
3288*fb1b10abSAndroid Build Coastguard Worker         force_recode = 1;
3289*fb1b10abSAndroid Build Coastguard Worker       }
3290*fb1b10abSAndroid Build Coastguard Worker     }
3291*fb1b10abSAndroid Build Coastguard Worker   }
3292*fb1b10abSAndroid Build Coastguard Worker   return force_recode;
3293*fb1b10abSAndroid Build Coastguard Worker }
3294*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
3295*fb1b10abSAndroid Build Coastguard Worker 
3296*fb1b10abSAndroid Build Coastguard Worker static void update_ref_frames(VP9_COMP *cpi) {
3297*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3298*fb1b10abSAndroid Build Coastguard Worker   BufferPool *const pool = cm->buffer_pool;
3299*fb1b10abSAndroid Build Coastguard Worker   GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3300*fb1b10abSAndroid Build Coastguard Worker 
3301*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_ratectrl.ready &&
3302*fb1b10abSAndroid Build Coastguard Worker       (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 &&
3303*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_ratectrl.funcs.get_gop_decision != NULL) {
3304*fb1b10abSAndroid Build Coastguard Worker     const int this_gf_index = gf_group->index;
3305*fb1b10abSAndroid Build Coastguard Worker     const int update_ref_idx = gf_group->update_ref_idx[this_gf_index];
3306*fb1b10abSAndroid Build Coastguard Worker     if (gf_group->update_type[this_gf_index] == KF_UPDATE) {
3307*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[0], cm->new_fb_idx);
3308*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[1], cm->new_fb_idx);
3309*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[2], cm->new_fb_idx);
3310*fb1b10abSAndroid Build Coastguard Worker     } else if (update_ref_idx != INVALID_IDX) {
3311*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs,
3312*fb1b10abSAndroid Build Coastguard Worker                  &cm->ref_frame_map[gf_group->update_ref_idx[this_gf_index]],
3313*fb1b10abSAndroid Build Coastguard Worker                  cm->new_fb_idx);
3314*fb1b10abSAndroid Build Coastguard Worker     }
3315*fb1b10abSAndroid Build Coastguard Worker 
3316*fb1b10abSAndroid Build Coastguard Worker     const int next_gf_index = gf_group->index + 1;
3317*fb1b10abSAndroid Build Coastguard Worker 
3318*fb1b10abSAndroid Build Coastguard Worker     // Overlay frame should ideally look at the colocated ref frame from rc lib.
3319*fb1b10abSAndroid Build Coastguard Worker     // Here temporarily just don't update the indices.
3320*fb1b10abSAndroid Build Coastguard Worker     if (next_gf_index < gf_group->gf_group_size) {
3321*fb1b10abSAndroid Build Coastguard Worker       cpi->lst_fb_idx = gf_group->ext_rc_ref[next_gf_index].last_index;
3322*fb1b10abSAndroid Build Coastguard Worker       cpi->gld_fb_idx = gf_group->ext_rc_ref[next_gf_index].golden_index;
3323*fb1b10abSAndroid Build Coastguard Worker       cpi->alt_fb_idx = gf_group->ext_rc_ref[next_gf_index].altref_index;
3324*fb1b10abSAndroid Build Coastguard Worker     }
3325*fb1b10abSAndroid Build Coastguard Worker 
3326*fb1b10abSAndroid Build Coastguard Worker     return;
3327*fb1b10abSAndroid Build Coastguard Worker   }
3328*fb1b10abSAndroid Build Coastguard Worker 
3329*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.show_arf_as_gld) {
3330*fb1b10abSAndroid Build Coastguard Worker     int tmp = cpi->alt_fb_idx;
3331*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx = cpi->gld_fb_idx;
3332*fb1b10abSAndroid Build Coastguard Worker     cpi->gld_fb_idx = tmp;
3333*fb1b10abSAndroid Build Coastguard Worker   } else if (cm->show_existing_frame) {
3334*fb1b10abSAndroid Build Coastguard Worker     // Pop ARF.
3335*fb1b10abSAndroid Build Coastguard Worker     cpi->lst_fb_idx = cpi->alt_fb_idx;
3336*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx =
3337*fb1b10abSAndroid Build Coastguard Worker         stack_pop(gf_group->arf_index_stack, gf_group->stack_size);
3338*fb1b10abSAndroid Build Coastguard Worker     --gf_group->stack_size;
3339*fb1b10abSAndroid Build Coastguard Worker   }
3340*fb1b10abSAndroid Build Coastguard Worker 
3341*fb1b10abSAndroid Build Coastguard Worker   // At this point the new frame has been encoded.
3342*fb1b10abSAndroid Build Coastguard Worker   // If any buffer copy / swapping is signaled it should be done here.
3343*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
3344*fb1b10abSAndroid Build Coastguard Worker     ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3345*fb1b10abSAndroid Build Coastguard Worker                cm->new_fb_idx);
3346*fb1b10abSAndroid Build Coastguard Worker     ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3347*fb1b10abSAndroid Build Coastguard Worker                cm->new_fb_idx);
3348*fb1b10abSAndroid Build Coastguard Worker   } else if (vp9_preserve_existing_gf(cpi)) {
3349*fb1b10abSAndroid Build Coastguard Worker     // We have decided to preserve the previously existing golden frame as our
3350*fb1b10abSAndroid Build Coastguard Worker     // new ARF frame. However, in the short term in function
3351*fb1b10abSAndroid Build Coastguard Worker     // vp9_get_refresh_mask() we left it in the GF slot and, if
3352*fb1b10abSAndroid Build Coastguard Worker     // we're updating the GF with the current decoded frame, we save it to the
3353*fb1b10abSAndroid Build Coastguard Worker     // ARF slot instead.
3354*fb1b10abSAndroid Build Coastguard Worker     // We now have to update the ARF with the current frame and swap gld_fb_idx
3355*fb1b10abSAndroid Build Coastguard Worker     // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
3356*fb1b10abSAndroid Build Coastguard Worker     // slot and, if we're updating the GF, the current frame becomes the new GF.
3357*fb1b10abSAndroid Build Coastguard Worker     int tmp;
3358*fb1b10abSAndroid Build Coastguard Worker 
3359*fb1b10abSAndroid Build Coastguard Worker     ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3360*fb1b10abSAndroid Build Coastguard Worker                cm->new_fb_idx);
3361*fb1b10abSAndroid Build Coastguard Worker 
3362*fb1b10abSAndroid Build Coastguard Worker     tmp = cpi->alt_fb_idx;
3363*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx = cpi->gld_fb_idx;
3364*fb1b10abSAndroid Build Coastguard Worker     cpi->gld_fb_idx = tmp;
3365*fb1b10abSAndroid Build Coastguard Worker   } else { /* For non key/golden frames */
3366*fb1b10abSAndroid Build Coastguard Worker     if (cpi->refresh_alt_ref_frame) {
3367*fb1b10abSAndroid Build Coastguard Worker       int arf_idx = gf_group->top_arf_idx;
3368*fb1b10abSAndroid Build Coastguard Worker 
3369*fb1b10abSAndroid Build Coastguard Worker       // Push new ARF into stack.
3370*fb1b10abSAndroid Build Coastguard Worker       stack_push(gf_group->arf_index_stack, cpi->alt_fb_idx,
3371*fb1b10abSAndroid Build Coastguard Worker                  gf_group->stack_size);
3372*fb1b10abSAndroid Build Coastguard Worker       ++gf_group->stack_size;
3373*fb1b10abSAndroid Build Coastguard Worker 
3374*fb1b10abSAndroid Build Coastguard Worker       assert(arf_idx < REF_FRAMES);
3375*fb1b10abSAndroid Build Coastguard Worker 
3376*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
3377*fb1b10abSAndroid Build Coastguard Worker       memcpy(cpi->interp_filter_selected[ALTREF_FRAME],
3378*fb1b10abSAndroid Build Coastguard Worker              cpi->interp_filter_selected[0],
3379*fb1b10abSAndroid Build Coastguard Worker              sizeof(cpi->interp_filter_selected[0]));
3380*fb1b10abSAndroid Build Coastguard Worker 
3381*fb1b10abSAndroid Build Coastguard Worker       cpi->alt_fb_idx = arf_idx;
3382*fb1b10abSAndroid Build Coastguard Worker     }
3383*fb1b10abSAndroid Build Coastguard Worker 
3384*fb1b10abSAndroid Build Coastguard Worker     if (cpi->refresh_golden_frame) {
3385*fb1b10abSAndroid Build Coastguard Worker       ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3386*fb1b10abSAndroid Build Coastguard Worker                  cm->new_fb_idx);
3387*fb1b10abSAndroid Build Coastguard Worker       if (!cpi->rc.is_src_frame_alt_ref)
3388*fb1b10abSAndroid Build Coastguard Worker         memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3389*fb1b10abSAndroid Build Coastguard Worker                cpi->interp_filter_selected[0],
3390*fb1b10abSAndroid Build Coastguard Worker                sizeof(cpi->interp_filter_selected[0]));
3391*fb1b10abSAndroid Build Coastguard Worker       else
3392*fb1b10abSAndroid Build Coastguard Worker         memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3393*fb1b10abSAndroid Build Coastguard Worker                cpi->interp_filter_selected[ALTREF_FRAME],
3394*fb1b10abSAndroid Build Coastguard Worker                sizeof(cpi->interp_filter_selected[ALTREF_FRAME]));
3395*fb1b10abSAndroid Build Coastguard Worker     }
3396*fb1b10abSAndroid Build Coastguard Worker   }
3397*fb1b10abSAndroid Build Coastguard Worker 
3398*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_last_frame) {
3399*fb1b10abSAndroid Build Coastguard Worker     ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
3400*fb1b10abSAndroid Build Coastguard Worker                cm->new_fb_idx);
3401*fb1b10abSAndroid Build Coastguard Worker     if (!cpi->rc.is_src_frame_alt_ref)
3402*fb1b10abSAndroid Build Coastguard Worker       memcpy(cpi->interp_filter_selected[LAST_FRAME],
3403*fb1b10abSAndroid Build Coastguard Worker              cpi->interp_filter_selected[0],
3404*fb1b10abSAndroid Build Coastguard Worker              sizeof(cpi->interp_filter_selected[0]));
3405*fb1b10abSAndroid Build Coastguard Worker   }
3406*fb1b10abSAndroid Build Coastguard Worker 
3407*fb1b10abSAndroid Build Coastguard Worker   if (gf_group->update_type[gf_group->index] == MID_OVERLAY_UPDATE) {
3408*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx =
3409*fb1b10abSAndroid Build Coastguard Worker         stack_pop(gf_group->arf_index_stack, gf_group->stack_size);
3410*fb1b10abSAndroid Build Coastguard Worker     --gf_group->stack_size;
3411*fb1b10abSAndroid Build Coastguard Worker   }
3412*fb1b10abSAndroid Build Coastguard Worker }
3413*fb1b10abSAndroid Build Coastguard Worker 
3414*fb1b10abSAndroid Build Coastguard Worker void vp9_update_reference_frames(VP9_COMP *cpi) {
3415*fb1b10abSAndroid Build Coastguard Worker   update_ref_frames(cpi);
3416*fb1b10abSAndroid Build Coastguard Worker 
3417*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
3418*fb1b10abSAndroid Build Coastguard Worker   vp9_denoiser_update_ref_frame(cpi);
3419*fb1b10abSAndroid Build Coastguard Worker #endif
3420*fb1b10abSAndroid Build Coastguard Worker 
3421*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) vp9_svc_update_ref_frame(cpi);
3422*fb1b10abSAndroid Build Coastguard Worker }
3423*fb1b10abSAndroid Build Coastguard Worker 
3424*fb1b10abSAndroid Build Coastguard Worker static void loopfilter_frame(VP9_COMP *cpi, VP9_COMMON *cm) {
3425*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
3426*fb1b10abSAndroid Build Coastguard Worker   struct loopfilter *lf = &cm->lf;
3427*fb1b10abSAndroid Build Coastguard Worker   int is_reference_frame =
3428*fb1b10abSAndroid Build Coastguard Worker       (cm->frame_type == KEY_FRAME || cpi->refresh_last_frame ||
3429*fb1b10abSAndroid Build Coastguard Worker        cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame);
3430*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc &&
3431*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS)
3432*fb1b10abSAndroid Build Coastguard Worker     is_reference_frame = !cpi->svc.non_reference_frame;
3433*fb1b10abSAndroid Build Coastguard Worker 
3434*fb1b10abSAndroid Build Coastguard Worker   // Skip loop filter in show_existing_frame mode.
3435*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame) {
3436*fb1b10abSAndroid Build Coastguard Worker     lf->filter_level = 0;
3437*fb1b10abSAndroid Build Coastguard Worker     return;
3438*fb1b10abSAndroid Build Coastguard Worker   }
3439*fb1b10abSAndroid Build Coastguard Worker 
3440*fb1b10abSAndroid Build Coastguard Worker   if (cpi->loopfilter_ctrl == NO_LOOPFILTER ||
3441*fb1b10abSAndroid Build Coastguard Worker       (!is_reference_frame && cpi->loopfilter_ctrl == LOOPFILTER_REFERENCE)) {
3442*fb1b10abSAndroid Build Coastguard Worker     lf->filter_level = 0;
3443*fb1b10abSAndroid Build Coastguard Worker     vpx_extend_frame_inner_borders(cm->frame_to_show);
3444*fb1b10abSAndroid Build Coastguard Worker     return;
3445*fb1b10abSAndroid Build Coastguard Worker   }
3446*fb1b10abSAndroid Build Coastguard Worker 
3447*fb1b10abSAndroid Build Coastguard Worker   if (xd->lossless) {
3448*fb1b10abSAndroid Build Coastguard Worker     lf->filter_level = 0;
3449*fb1b10abSAndroid Build Coastguard Worker     lf->last_filt_level = 0;
3450*fb1b10abSAndroid Build Coastguard Worker   } else {
3451*fb1b10abSAndroid Build Coastguard Worker     struct vpx_usec_timer timer;
3452*fb1b10abSAndroid Build Coastguard Worker 
3453*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
3454*fb1b10abSAndroid Build Coastguard Worker 
3455*fb1b10abSAndroid Build Coastguard Worker     vpx_usec_timer_start(&timer);
3456*fb1b10abSAndroid Build Coastguard Worker 
3457*fb1b10abSAndroid Build Coastguard Worker     if (!cpi->rc.is_src_frame_alt_ref) {
3458*fb1b10abSAndroid Build Coastguard Worker       if ((cpi->common.frame_type == KEY_FRAME) &&
3459*fb1b10abSAndroid Build Coastguard Worker           (!cpi->rc.this_key_frame_forced)) {
3460*fb1b10abSAndroid Build Coastguard Worker         lf->last_filt_level = 0;
3461*fb1b10abSAndroid Build Coastguard Worker       }
3462*fb1b10abSAndroid Build Coastguard Worker       vp9_pick_filter_level(cpi->Source, cpi, cpi->sf.lpf_pick);
3463*fb1b10abSAndroid Build Coastguard Worker       lf->last_filt_level = lf->filter_level;
3464*fb1b10abSAndroid Build Coastguard Worker     } else {
3465*fb1b10abSAndroid Build Coastguard Worker       lf->filter_level = 0;
3466*fb1b10abSAndroid Build Coastguard Worker     }
3467*fb1b10abSAndroid Build Coastguard Worker 
3468*fb1b10abSAndroid Build Coastguard Worker     vpx_usec_timer_mark(&timer);
3469*fb1b10abSAndroid Build Coastguard Worker     cpi->time_pick_lpf += vpx_usec_timer_elapsed(&timer);
3470*fb1b10abSAndroid Build Coastguard Worker   }
3471*fb1b10abSAndroid Build Coastguard Worker 
3472*fb1b10abSAndroid Build Coastguard Worker   if (lf->filter_level > 0 && is_reference_frame) {
3473*fb1b10abSAndroid Build Coastguard Worker     vp9_build_mask_frame(cm, lf->filter_level, 0);
3474*fb1b10abSAndroid Build Coastguard Worker 
3475*fb1b10abSAndroid Build Coastguard Worker     if (cpi->num_workers > 1)
3476*fb1b10abSAndroid Build Coastguard Worker       vp9_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane,
3477*fb1b10abSAndroid Build Coastguard Worker                                lf->filter_level, 0, 0, cpi->workers,
3478*fb1b10abSAndroid Build Coastguard Worker                                cpi->num_workers, &cpi->lf_row_sync);
3479*fb1b10abSAndroid Build Coastguard Worker     else
3480*fb1b10abSAndroid Build Coastguard Worker       vp9_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
3481*fb1b10abSAndroid Build Coastguard Worker   }
3482*fb1b10abSAndroid Build Coastguard Worker 
3483*fb1b10abSAndroid Build Coastguard Worker   vpx_extend_frame_inner_borders(cm->frame_to_show);
3484*fb1b10abSAndroid Build Coastguard Worker }
3485*fb1b10abSAndroid Build Coastguard Worker 
3486*fb1b10abSAndroid Build Coastguard Worker void vp9_scale_references(VP9_COMP *cpi) {
3487*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
3488*fb1b10abSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref_frame;
3489*fb1b10abSAndroid Build Coastguard Worker   const VP9_REFFRAME ref_mask[3] = { VP9_LAST_FLAG, VP9_GOLD_FLAG,
3490*fb1b10abSAndroid Build Coastguard Worker                                      VP9_ALT_FLAG };
3491*fb1b10abSAndroid Build Coastguard Worker 
3492*fb1b10abSAndroid Build Coastguard Worker   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3493*fb1b10abSAndroid Build Coastguard Worker     // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
3494*fb1b10abSAndroid Build Coastguard Worker     if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
3495*fb1b10abSAndroid Build Coastguard Worker       BufferPool *const pool = cm->buffer_pool;
3496*fb1b10abSAndroid Build Coastguard Worker       const YV12_BUFFER_CONFIG *const ref =
3497*fb1b10abSAndroid Build Coastguard Worker           get_ref_frame_buffer(cpi, ref_frame);
3498*fb1b10abSAndroid Build Coastguard Worker 
3499*fb1b10abSAndroid Build Coastguard Worker       if (ref == NULL) {
3500*fb1b10abSAndroid Build Coastguard Worker         cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3501*fb1b10abSAndroid Build Coastguard Worker         continue;
3502*fb1b10abSAndroid Build Coastguard Worker       }
3503*fb1b10abSAndroid Build Coastguard Worker 
3504*fb1b10abSAndroid Build Coastguard Worker       if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3505*fb1b10abSAndroid Build Coastguard Worker         RefCntBuffer *new_fb_ptr = NULL;
3506*fb1b10abSAndroid Build Coastguard Worker         int force_scaling = 0;
3507*fb1b10abSAndroid Build Coastguard Worker         int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3508*fb1b10abSAndroid Build Coastguard Worker         if (new_fb == INVALID_IDX) {
3509*fb1b10abSAndroid Build Coastguard Worker           new_fb = get_free_fb(cm);
3510*fb1b10abSAndroid Build Coastguard Worker           force_scaling = 1;
3511*fb1b10abSAndroid Build Coastguard Worker         }
3512*fb1b10abSAndroid Build Coastguard Worker         if (new_fb == INVALID_IDX) return;
3513*fb1b10abSAndroid Build Coastguard Worker         new_fb_ptr = &pool->frame_bufs[new_fb];
3514*fb1b10abSAndroid Build Coastguard Worker         if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3515*fb1b10abSAndroid Build Coastguard Worker             new_fb_ptr->buf.y_crop_height != cm->height) {
3516*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3517*fb1b10abSAndroid Build Coastguard Worker           if (vpx_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
3518*fb1b10abSAndroid Build Coastguard Worker                                        cm->subsampling_x, cm->subsampling_y,
3519*fb1b10abSAndroid Build Coastguard Worker                                        cm->use_highbitdepth,
3520*fb1b10abSAndroid Build Coastguard Worker                                        VP9_ENC_BORDER_IN_PIXELS,
3521*fb1b10abSAndroid Build Coastguard Worker                                        cm->byte_alignment, NULL, NULL, NULL))
3522*fb1b10abSAndroid Build Coastguard Worker             vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
3523*fb1b10abSAndroid Build Coastguard Worker                                "Failed to allocate frame buffer");
3524*fb1b10abSAndroid Build Coastguard Worker           scale_and_extend_frame(ref, &new_fb_ptr->buf, (int)cm->bit_depth,
3525*fb1b10abSAndroid Build Coastguard Worker                                  EIGHTTAP, 0);
3526*fb1b10abSAndroid Build Coastguard Worker #else
3527*fb1b10abSAndroid Build Coastguard Worker           if (vpx_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
3528*fb1b10abSAndroid Build Coastguard Worker                                        cm->subsampling_x, cm->subsampling_y,
3529*fb1b10abSAndroid Build Coastguard Worker                                        VP9_ENC_BORDER_IN_PIXELS,
3530*fb1b10abSAndroid Build Coastguard Worker                                        cm->byte_alignment, NULL, NULL, NULL))
3531*fb1b10abSAndroid Build Coastguard Worker             vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
3532*fb1b10abSAndroid Build Coastguard Worker                                "Failed to allocate frame buffer");
3533*fb1b10abSAndroid Build Coastguard Worker           vp9_scale_and_extend_frame(ref, &new_fb_ptr->buf, EIGHTTAP, 0);
3534*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3535*fb1b10abSAndroid Build Coastguard Worker           cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3536*fb1b10abSAndroid Build Coastguard Worker           alloc_frame_mvs(cm, new_fb);
3537*fb1b10abSAndroid Build Coastguard Worker         }
3538*fb1b10abSAndroid Build Coastguard Worker       } else {
3539*fb1b10abSAndroid Build Coastguard Worker         int buf_idx;
3540*fb1b10abSAndroid Build Coastguard Worker         RefCntBuffer *buf = NULL;
3541*fb1b10abSAndroid Build Coastguard Worker         if (cpi->oxcf.pass == 0 && !cpi->use_svc) {
3542*fb1b10abSAndroid Build Coastguard Worker           // Check for release of scaled reference.
3543*fb1b10abSAndroid Build Coastguard Worker           buf_idx = cpi->scaled_ref_idx[ref_frame - 1];
3544*fb1b10abSAndroid Build Coastguard Worker           if (buf_idx != INVALID_IDX) {
3545*fb1b10abSAndroid Build Coastguard Worker             buf = &pool->frame_bufs[buf_idx];
3546*fb1b10abSAndroid Build Coastguard Worker             --buf->ref_count;
3547*fb1b10abSAndroid Build Coastguard Worker             cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3548*fb1b10abSAndroid Build Coastguard Worker           }
3549*fb1b10abSAndroid Build Coastguard Worker         }
3550*fb1b10abSAndroid Build Coastguard Worker         buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3551*fb1b10abSAndroid Build Coastguard Worker         buf = &pool->frame_bufs[buf_idx];
3552*fb1b10abSAndroid Build Coastguard Worker         buf->buf.y_crop_width = ref->y_crop_width;
3553*fb1b10abSAndroid Build Coastguard Worker         buf->buf.y_crop_height = ref->y_crop_height;
3554*fb1b10abSAndroid Build Coastguard Worker         cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
3555*fb1b10abSAndroid Build Coastguard Worker         ++buf->ref_count;
3556*fb1b10abSAndroid Build Coastguard Worker       }
3557*fb1b10abSAndroid Build Coastguard Worker     } else {
3558*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.pass != 0 || cpi->use_svc)
3559*fb1b10abSAndroid Build Coastguard Worker         cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3560*fb1b10abSAndroid Build Coastguard Worker     }
3561*fb1b10abSAndroid Build Coastguard Worker   }
3562*fb1b10abSAndroid Build Coastguard Worker }
3563*fb1b10abSAndroid Build Coastguard Worker 
3564*fb1b10abSAndroid Build Coastguard Worker static void release_scaled_references(VP9_COMP *cpi) {
3565*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
3566*fb1b10abSAndroid Build Coastguard Worker   int i;
3567*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 0 && !cpi->use_svc) {
3568*fb1b10abSAndroid Build Coastguard Worker     // Only release scaled references under certain conditions:
3569*fb1b10abSAndroid Build Coastguard Worker     // if reference will be updated, or if scaled reference has same resolution.
3570*fb1b10abSAndroid Build Coastguard Worker     int refresh[3];
3571*fb1b10abSAndroid Build Coastguard Worker     refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
3572*fb1b10abSAndroid Build Coastguard Worker     refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
3573*fb1b10abSAndroid Build Coastguard Worker     refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3574*fb1b10abSAndroid Build Coastguard Worker     for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3575*fb1b10abSAndroid Build Coastguard Worker       const int idx = cpi->scaled_ref_idx[i - 1];
3576*fb1b10abSAndroid Build Coastguard Worker       if (idx != INVALID_IDX) {
3577*fb1b10abSAndroid Build Coastguard Worker         RefCntBuffer *const buf = &cm->buffer_pool->frame_bufs[idx];
3578*fb1b10abSAndroid Build Coastguard Worker         const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
3579*fb1b10abSAndroid Build Coastguard Worker         if (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width &&
3580*fb1b10abSAndroid Build Coastguard Worker                                buf->buf.y_crop_height == ref->y_crop_height)) {
3581*fb1b10abSAndroid Build Coastguard Worker           --buf->ref_count;
3582*fb1b10abSAndroid Build Coastguard Worker           cpi->scaled_ref_idx[i - 1] = INVALID_IDX;
3583*fb1b10abSAndroid Build Coastguard Worker         }
3584*fb1b10abSAndroid Build Coastguard Worker       }
3585*fb1b10abSAndroid Build Coastguard Worker     }
3586*fb1b10abSAndroid Build Coastguard Worker   } else {
3587*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < REFS_PER_FRAME; ++i) {
3588*fb1b10abSAndroid Build Coastguard Worker       const int idx = cpi->scaled_ref_idx[i];
3589*fb1b10abSAndroid Build Coastguard Worker       if (idx != INVALID_IDX) {
3590*fb1b10abSAndroid Build Coastguard Worker         RefCntBuffer *const buf = &cm->buffer_pool->frame_bufs[idx];
3591*fb1b10abSAndroid Build Coastguard Worker         --buf->ref_count;
3592*fb1b10abSAndroid Build Coastguard Worker         cpi->scaled_ref_idx[i] = INVALID_IDX;
3593*fb1b10abSAndroid Build Coastguard Worker       }
3594*fb1b10abSAndroid Build Coastguard Worker     }
3595*fb1b10abSAndroid Build Coastguard Worker   }
3596*fb1b10abSAndroid Build Coastguard Worker }
3597*fb1b10abSAndroid Build Coastguard Worker 
3598*fb1b10abSAndroid Build Coastguard Worker static void full_to_model_count(unsigned int *model_count,
3599*fb1b10abSAndroid Build Coastguard Worker                                 unsigned int *full_count) {
3600*fb1b10abSAndroid Build Coastguard Worker   int n;
3601*fb1b10abSAndroid Build Coastguard Worker   model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
3602*fb1b10abSAndroid Build Coastguard Worker   model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
3603*fb1b10abSAndroid Build Coastguard Worker   model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
3604*fb1b10abSAndroid Build Coastguard Worker   for (n = THREE_TOKEN; n < EOB_TOKEN; ++n)
3605*fb1b10abSAndroid Build Coastguard Worker     model_count[TWO_TOKEN] += full_count[n];
3606*fb1b10abSAndroid Build Coastguard Worker   model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
3607*fb1b10abSAndroid Build Coastguard Worker }
3608*fb1b10abSAndroid Build Coastguard Worker 
3609*fb1b10abSAndroid Build Coastguard Worker static void full_to_model_counts(vp9_coeff_count_model *model_count,
3610*fb1b10abSAndroid Build Coastguard Worker                                  vp9_coeff_count *full_count) {
3611*fb1b10abSAndroid Build Coastguard Worker   int i, j, k, l;
3612*fb1b10abSAndroid Build Coastguard Worker 
3613*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < PLANE_TYPES; ++i)
3614*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < REF_TYPES; ++j)
3615*fb1b10abSAndroid Build Coastguard Worker       for (k = 0; k < COEF_BANDS; ++k)
3616*fb1b10abSAndroid Build Coastguard Worker         for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
3617*fb1b10abSAndroid Build Coastguard Worker           full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]);
3618*fb1b10abSAndroid Build Coastguard Worker }
3619*fb1b10abSAndroid Build Coastguard Worker 
3620*fb1b10abSAndroid Build Coastguard Worker #if 0 && CONFIG_INTERNAL_STATS
3621*fb1b10abSAndroid Build Coastguard Worker static void output_frame_level_debug_stats(VP9_COMP *cpi) {
3622*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3623*fb1b10abSAndroid Build Coastguard Worker   FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w");
3624*fb1b10abSAndroid Build Coastguard Worker   int64_t recon_err;
3625*fb1b10abSAndroid Build Coastguard Worker 
3626*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
3627*fb1b10abSAndroid Build Coastguard Worker 
3628*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3629*fb1b10abSAndroid Build Coastguard Worker   if (cm->use_highbitdepth) {
3630*fb1b10abSAndroid Build Coastguard Worker     recon_err = vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
3631*fb1b10abSAndroid Build Coastguard Worker   } else {
3632*fb1b10abSAndroid Build Coastguard Worker     recon_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
3633*fb1b10abSAndroid Build Coastguard Worker   }
3634*fb1b10abSAndroid Build Coastguard Worker #else
3635*fb1b10abSAndroid Build Coastguard Worker   recon_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
3636*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3637*fb1b10abSAndroid Build Coastguard Worker 
3638*fb1b10abSAndroid Build Coastguard Worker 
3639*fb1b10abSAndroid Build Coastguard Worker   if (cpi->twopass.total_left_stats.coded_error != 0.0) {
3640*fb1b10abSAndroid Build Coastguard Worker     double dc_quant_devisor;
3641*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3642*fb1b10abSAndroid Build Coastguard Worker     switch (cm->bit_depth) {
3643*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_8:
3644*fb1b10abSAndroid Build Coastguard Worker         dc_quant_devisor = 4.0;
3645*fb1b10abSAndroid Build Coastguard Worker         break;
3646*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_10:
3647*fb1b10abSAndroid Build Coastguard Worker         dc_quant_devisor = 16.0;
3648*fb1b10abSAndroid Build Coastguard Worker         break;
3649*fb1b10abSAndroid Build Coastguard Worker       default:
3650*fb1b10abSAndroid Build Coastguard Worker         assert(cm->bit_depth == VPX_BITS_12);
3651*fb1b10abSAndroid Build Coastguard Worker         dc_quant_devisor = 64.0;
3652*fb1b10abSAndroid Build Coastguard Worker         break;
3653*fb1b10abSAndroid Build Coastguard Worker     }
3654*fb1b10abSAndroid Build Coastguard Worker #else
3655*fb1b10abSAndroid Build Coastguard Worker     dc_quant_devisor = 4.0;
3656*fb1b10abSAndroid Build Coastguard Worker #endif
3657*fb1b10abSAndroid Build Coastguard Worker 
3658*fb1b10abSAndroid Build Coastguard Worker     if (!cm->current_video_frame) {
3659*fb1b10abSAndroid Build Coastguard Worker       fprintf(f, "frame, width, height, last ts, last end ts, "
3660*fb1b10abSAndroid Build Coastguard Worker           "source_alt_ref_pending, source_alt_ref_active, "
3661*fb1b10abSAndroid Build Coastguard Worker           "this_frame_target, projected_frame_size, "
3662*fb1b10abSAndroid Build Coastguard Worker           "projected_frame_size / MBs, "
3663*fb1b10abSAndroid Build Coastguard Worker           "projected_frame_size - this_frame_target, "
3664*fb1b10abSAndroid Build Coastguard Worker           "vbr_bits_off_target, vbr_bits_off_target_fast, "
3665*fb1b10abSAndroid Build Coastguard Worker           "twopass.extend_minq, twopass.extend_minq_fast, "
3666*fb1b10abSAndroid Build Coastguard Worker           "total_target_vs_actual, "
3667*fb1b10abSAndroid Build Coastguard Worker           "starting_buffer_level - bits_off_target, "
3668*fb1b10abSAndroid Build Coastguard Worker           "total_actual_bits, base_qindex, q for base_qindex, "
3669*fb1b10abSAndroid Build Coastguard Worker           "dc quant, q for active_worst_quality, avg_q, q for oxcf.cq_level, "
3670*fb1b10abSAndroid Build Coastguard Worker           "refresh_last_frame, refresh_golden_frame, refresh_alt_ref_frame, "
3671*fb1b10abSAndroid Build Coastguard Worker           "frame_type, gfu_boost, "
3672*fb1b10abSAndroid Build Coastguard Worker           "twopass.bits_left, "
3673*fb1b10abSAndroid Build Coastguard Worker           "twopass.total_left_stats.coded_error, "
3674*fb1b10abSAndroid Build Coastguard Worker           "twopass.bits_left / (1 + twopass.total_left_stats.coded_error), "
3675*fb1b10abSAndroid Build Coastguard Worker           "tot_recode_hits, recon_err, kf_boost, "
3676*fb1b10abSAndroid Build Coastguard Worker           "twopass.kf_zeromotion_pct, twopass.fr_content_type, "
3677*fb1b10abSAndroid Build Coastguard Worker           "filter_level, seg.aq_av_offset\n");
3678*fb1b10abSAndroid Build Coastguard Worker     }
3679*fb1b10abSAndroid Build Coastguard Worker 
3680*fb1b10abSAndroid Build Coastguard Worker     fprintf(f, "%10u, %d, %d, %10"PRId64", %10"PRId64", %d, %d, %10d, %10d, "
3681*fb1b10abSAndroid Build Coastguard Worker         "%10d, %10d, %10"PRId64", %10"PRId64", %5d, %5d, %10"PRId64", "
3682*fb1b10abSAndroid Build Coastguard Worker         "%10"PRId64", %10"PRId64", %10d, %7.2lf, %7.2lf, %7.2lf, %7.2lf, "
3683*fb1b10abSAndroid Build Coastguard Worker         "%7.2lf, %6d, %6d, %5d, %5d, %5d, %10"PRId64", %10.3lf, %10lf, %8u, "
3684*fb1b10abSAndroid Build Coastguard Worker         "%10"PRId64", %10d, %10d, %10d, %10d, %10d\n",
3685*fb1b10abSAndroid Build Coastguard Worker         cpi->common.current_video_frame,
3686*fb1b10abSAndroid Build Coastguard Worker         cm->width, cm->height,
3687*fb1b10abSAndroid Build Coastguard Worker         cpi->last_time_stamp_seen,
3688*fb1b10abSAndroid Build Coastguard Worker         cpi->last_end_time_stamp_seen,
3689*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.source_alt_ref_pending,
3690*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.source_alt_ref_active,
3691*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.this_frame_target,
3692*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.projected_frame_size,
3693*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.projected_frame_size / cpi->common.MBs,
3694*fb1b10abSAndroid Build Coastguard Worker         (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
3695*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.vbr_bits_off_target,
3696*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.vbr_bits_off_target_fast,
3697*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.extend_minq,
3698*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.extend_minq_fast,
3699*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.total_target_vs_actual,
3700*fb1b10abSAndroid Build Coastguard Worker         (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target),
3701*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.total_actual_bits, cm->base_qindex,
3702*fb1b10abSAndroid Build Coastguard Worker         vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth),
3703*fb1b10abSAndroid Build Coastguard Worker         (double)vp9_dc_quant(cm->base_qindex, 0, cm->bit_depth) /
3704*fb1b10abSAndroid Build Coastguard Worker             dc_quant_devisor,
3705*fb1b10abSAndroid Build Coastguard Worker         vp9_convert_qindex_to_q(cpi->twopass.active_worst_quality,
3706*fb1b10abSAndroid Build Coastguard Worker                                 cm->bit_depth),
3707*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.avg_q,
3708*fb1b10abSAndroid Build Coastguard Worker         vp9_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth),
3709*fb1b10abSAndroid Build Coastguard Worker         cpi->refresh_last_frame, cpi->refresh_golden_frame,
3710*fb1b10abSAndroid Build Coastguard Worker         cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
3711*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.bits_left,
3712*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.total_left_stats.coded_error,
3713*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.bits_left /
3714*fb1b10abSAndroid Build Coastguard Worker             (1 + cpi->twopass.total_left_stats.coded_error),
3715*fb1b10abSAndroid Build Coastguard Worker         cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
3716*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.kf_zeromotion_pct,
3717*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.fr_content_type,
3718*fb1b10abSAndroid Build Coastguard Worker         cm->lf.filter_level,
3719*fb1b10abSAndroid Build Coastguard Worker         cm->seg.aq_av_offset);
3720*fb1b10abSAndroid Build Coastguard Worker   }
3721*fb1b10abSAndroid Build Coastguard Worker   fclose(f);
3722*fb1b10abSAndroid Build Coastguard Worker 
3723*fb1b10abSAndroid Build Coastguard Worker   if (0) {
3724*fb1b10abSAndroid Build Coastguard Worker     FILE *const fmodes = fopen("Modes.stt", "a");
3725*fb1b10abSAndroid Build Coastguard Worker     int i;
3726*fb1b10abSAndroid Build Coastguard Worker 
3727*fb1b10abSAndroid Build Coastguard Worker     fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame,
3728*fb1b10abSAndroid Build Coastguard Worker             cm->frame_type, cpi->refresh_golden_frame,
3729*fb1b10abSAndroid Build Coastguard Worker             cpi->refresh_alt_ref_frame);
3730*fb1b10abSAndroid Build Coastguard Worker 
3731*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < MAX_MODES; ++i)
3732*fb1b10abSAndroid Build Coastguard Worker       fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
3733*fb1b10abSAndroid Build Coastguard Worker 
3734*fb1b10abSAndroid Build Coastguard Worker     fprintf(fmodes, "\n");
3735*fb1b10abSAndroid Build Coastguard Worker 
3736*fb1b10abSAndroid Build Coastguard Worker     fclose(fmodes);
3737*fb1b10abSAndroid Build Coastguard Worker   }
3738*fb1b10abSAndroid Build Coastguard Worker }
3739*fb1b10abSAndroid Build Coastguard Worker #endif
3740*fb1b10abSAndroid Build Coastguard Worker 
3741*fb1b10abSAndroid Build Coastguard Worker static void set_mv_search_params(VP9_COMP *cpi) {
3742*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
3743*fb1b10abSAndroid Build Coastguard Worker   const unsigned int max_mv_def = VPXMIN(cm->width, cm->height);
3744*fb1b10abSAndroid Build Coastguard Worker 
3745*fb1b10abSAndroid Build Coastguard Worker   // Default based on max resolution.
3746*fb1b10abSAndroid Build Coastguard Worker   cpi->mv_step_param = vp9_init_search_range(max_mv_def);
3747*fb1b10abSAndroid Build Coastguard Worker 
3748*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.mv.auto_mv_step_size) {
3749*fb1b10abSAndroid Build Coastguard Worker     if (frame_is_intra_only(cm)) {
3750*fb1b10abSAndroid Build Coastguard Worker       // Initialize max_mv_magnitude for use in the first INTER frame
3751*fb1b10abSAndroid Build Coastguard Worker       // after a key/intra-only frame.
3752*fb1b10abSAndroid Build Coastguard Worker       cpi->max_mv_magnitude = max_mv_def;
3753*fb1b10abSAndroid Build Coastguard Worker     } else {
3754*fb1b10abSAndroid Build Coastguard Worker       if (cm->show_frame) {
3755*fb1b10abSAndroid Build Coastguard Worker         // Allow mv_steps to correspond to twice the max mv magnitude found
3756*fb1b10abSAndroid Build Coastguard Worker         // in the previous frame, capped by the default max_mv_magnitude based
3757*fb1b10abSAndroid Build Coastguard Worker         // on resolution.
3758*fb1b10abSAndroid Build Coastguard Worker         cpi->mv_step_param = vp9_init_search_range(
3759*fb1b10abSAndroid Build Coastguard Worker             VPXMIN(max_mv_def, 2 * cpi->max_mv_magnitude));
3760*fb1b10abSAndroid Build Coastguard Worker       }
3761*fb1b10abSAndroid Build Coastguard Worker       cpi->max_mv_magnitude = 0;
3762*fb1b10abSAndroid Build Coastguard Worker     }
3763*fb1b10abSAndroid Build Coastguard Worker   }
3764*fb1b10abSAndroid Build Coastguard Worker }
3765*fb1b10abSAndroid Build Coastguard Worker 
3766*fb1b10abSAndroid Build Coastguard Worker static void set_size_independent_vars(VP9_COMP *cpi) {
3767*fb1b10abSAndroid Build Coastguard Worker   vp9_set_speed_features_framesize_independent(cpi, cpi->oxcf.speed);
3768*fb1b10abSAndroid Build Coastguard Worker   vp9_set_rd_speed_thresholds(cpi);
3769*fb1b10abSAndroid Build Coastguard Worker   vp9_set_rd_speed_thresholds_sub8x8(cpi);
3770*fb1b10abSAndroid Build Coastguard Worker   cpi->common.interp_filter = cpi->sf.default_interp_filter;
3771*fb1b10abSAndroid Build Coastguard Worker }
3772*fb1b10abSAndroid Build Coastguard Worker 
3773*fb1b10abSAndroid Build Coastguard Worker static void set_size_dependent_vars(VP9_COMP *cpi, int *q, int *bottom_index,
3774*fb1b10abSAndroid Build Coastguard Worker                                     int *top_index) {
3775*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3776*fb1b10abSAndroid Build Coastguard Worker 
3777*fb1b10abSAndroid Build Coastguard Worker   // Setup variables that depend on the dimensions of the frame.
3778*fb1b10abSAndroid Build Coastguard Worker   vp9_set_speed_features_framesize_dependent(cpi, cpi->oxcf.speed);
3779*fb1b10abSAndroid Build Coastguard Worker 
3780*fb1b10abSAndroid Build Coastguard Worker   // Decide q and q bounds.
3781*fb1b10abSAndroid Build Coastguard Worker   *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
3782*fb1b10abSAndroid Build Coastguard Worker 
3783*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.rc_mode == VPX_CBR && cpi->rc.force_max_q) {
3784*fb1b10abSAndroid Build Coastguard Worker     *q = cpi->rc.worst_quality;
3785*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.force_max_q = 0;
3786*fb1b10abSAndroid Build Coastguard Worker   }
3787*fb1b10abSAndroid Build Coastguard Worker 
3788*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) {
3789*fb1b10abSAndroid Build Coastguard Worker     cpi->svc.base_qindex[cpi->svc.spatial_layer_id] = *q;
3790*fb1b10abSAndroid Build Coastguard Worker   }
3791*fb1b10abSAndroid Build Coastguard Worker 
3792*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm)) {
3793*fb1b10abSAndroid Build Coastguard Worker     vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
3794*fb1b10abSAndroid Build Coastguard Worker   }
3795*fb1b10abSAndroid Build Coastguard Worker 
3796*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
3797*fb1b10abSAndroid Build Coastguard Worker   // Configure experimental use of segmentation for enhanced coding of
3798*fb1b10abSAndroid Build Coastguard Worker   // static regions if indicated.
3799*fb1b10abSAndroid Build Coastguard Worker   // Only allowed in the second pass of a two pass encode, as it requires
3800*fb1b10abSAndroid Build Coastguard Worker   // lagged coding, and if the relevant speed feature flag is set.
3801*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 2 && cpi->sf.static_segmentation)
3802*fb1b10abSAndroid Build Coastguard Worker     configure_static_seg_features(cpi);
3803*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
3804*fb1b10abSAndroid Build Coastguard Worker 
3805*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC && !(CONFIG_VP9_TEMPORAL_DENOISING)
3806*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.noise_sensitivity > 0) {
3807*fb1b10abSAndroid Build Coastguard Worker     int l = 0;
3808*fb1b10abSAndroid Build Coastguard Worker     switch (cpi->oxcf.noise_sensitivity) {
3809*fb1b10abSAndroid Build Coastguard Worker       case 1: l = 20; break;
3810*fb1b10abSAndroid Build Coastguard Worker       case 2: l = 40; break;
3811*fb1b10abSAndroid Build Coastguard Worker       case 3: l = 60; break;
3812*fb1b10abSAndroid Build Coastguard Worker       case 4:
3813*fb1b10abSAndroid Build Coastguard Worker       case 5: l = 100; break;
3814*fb1b10abSAndroid Build Coastguard Worker       case 6: l = 150; break;
3815*fb1b10abSAndroid Build Coastguard Worker     }
3816*fb1b10abSAndroid Build Coastguard Worker     if (!cpi->common.postproc_state.limits) {
3817*fb1b10abSAndroid Build Coastguard Worker       CHECK_MEM_ERROR(&cm->error, cpi->common.postproc_state.limits,
3818*fb1b10abSAndroid Build Coastguard Worker                       vpx_calloc(cpi->un_scaled_source->y_width,
3819*fb1b10abSAndroid Build Coastguard Worker                                  sizeof(*cpi->common.postproc_state.limits)));
3820*fb1b10abSAndroid Build Coastguard Worker     }
3821*fb1b10abSAndroid Build Coastguard Worker     vp9_denoise(&cpi->common, cpi->Source, cpi->Source, l,
3822*fb1b10abSAndroid Build Coastguard Worker                 cpi->common.postproc_state.limits);
3823*fb1b10abSAndroid Build Coastguard Worker   }
3824*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_POSTPROC
3825*fb1b10abSAndroid Build Coastguard Worker }
3826*fb1b10abSAndroid Build Coastguard Worker 
3827*fb1b10abSAndroid Build Coastguard Worker static void init_motion_estimation(VP9_COMP *cpi) {
3828*fb1b10abSAndroid Build Coastguard Worker   int y_stride = cpi->scaled_source.y_stride;
3829*fb1b10abSAndroid Build Coastguard Worker 
3830*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.mv.search_method == NSTEP) {
3831*fb1b10abSAndroid Build Coastguard Worker     vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
3832*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->sf.mv.search_method == DIAMOND) {
3833*fb1b10abSAndroid Build Coastguard Worker     vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
3834*fb1b10abSAndroid Build Coastguard Worker   }
3835*fb1b10abSAndroid Build Coastguard Worker }
3836*fb1b10abSAndroid Build Coastguard Worker 
3837*fb1b10abSAndroid Build Coastguard Worker static void set_frame_size(VP9_COMP *cpi) {
3838*fb1b10abSAndroid Build Coastguard Worker   int ref_frame;
3839*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3840*fb1b10abSAndroid Build Coastguard Worker   VP9EncoderConfig *const oxcf = &cpi->oxcf;
3841*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
3842*fb1b10abSAndroid Build Coastguard Worker 
3843*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
3844*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 2 && oxcf->rc_mode == VPX_VBR &&
3845*fb1b10abSAndroid Build Coastguard Worker       ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) ||
3846*fb1b10abSAndroid Build Coastguard Worker        (oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending))) {
3847*fb1b10abSAndroid Build Coastguard Worker     calculate_coded_size(cpi, &oxcf->scaled_frame_width,
3848*fb1b10abSAndroid Build Coastguard Worker                          &oxcf->scaled_frame_height);
3849*fb1b10abSAndroid Build Coastguard Worker 
3850*fb1b10abSAndroid Build Coastguard Worker     // There has been a change in frame size.
3851*fb1b10abSAndroid Build Coastguard Worker     vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
3852*fb1b10abSAndroid Build Coastguard Worker                          oxcf->scaled_frame_height);
3853*fb1b10abSAndroid Build Coastguard Worker   }
3854*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
3855*fb1b10abSAndroid Build Coastguard Worker 
3856*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR &&
3857*fb1b10abSAndroid Build Coastguard Worker       oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending != 0) {
3858*fb1b10abSAndroid Build Coastguard Worker     // For SVC scaled width/height will have been set (svc->resize_set=1)
3859*fb1b10abSAndroid Build Coastguard Worker     // in get_svc_params based on the layer width/height.
3860*fb1b10abSAndroid Build Coastguard Worker     if (!cpi->use_svc || !cpi->svc.resize_set) {
3861*fb1b10abSAndroid Build Coastguard Worker       oxcf->scaled_frame_width =
3862*fb1b10abSAndroid Build Coastguard Worker           (oxcf->width * cpi->resize_scale_num) / cpi->resize_scale_den;
3863*fb1b10abSAndroid Build Coastguard Worker       oxcf->scaled_frame_height =
3864*fb1b10abSAndroid Build Coastguard Worker           (oxcf->height * cpi->resize_scale_num) / cpi->resize_scale_den;
3865*fb1b10abSAndroid Build Coastguard Worker       // There has been a change in frame size.
3866*fb1b10abSAndroid Build Coastguard Worker       vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
3867*fb1b10abSAndroid Build Coastguard Worker                            oxcf->scaled_frame_height);
3868*fb1b10abSAndroid Build Coastguard Worker     }
3869*fb1b10abSAndroid Build Coastguard Worker 
3870*fb1b10abSAndroid Build Coastguard Worker     // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3871*fb1b10abSAndroid Build Coastguard Worker     set_mv_search_params(cpi);
3872*fb1b10abSAndroid Build Coastguard Worker 
3873*fb1b10abSAndroid Build Coastguard Worker     vp9_noise_estimate_init(&cpi->noise_estimate, cm->width, cm->height);
3874*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
3875*fb1b10abSAndroid Build Coastguard Worker     // Reset the denoiser on the resized frame.
3876*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.noise_sensitivity > 0) {
3877*fb1b10abSAndroid Build Coastguard Worker       vp9_denoiser_free(&(cpi->denoiser));
3878*fb1b10abSAndroid Build Coastguard Worker       setup_denoiser_buffer(cpi);
3879*fb1b10abSAndroid Build Coastguard Worker       // Dynamic resize is only triggered for non-SVC, so we can force
3880*fb1b10abSAndroid Build Coastguard Worker       // golden frame update here as temporary fix to denoiser.
3881*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 1;
3882*fb1b10abSAndroid Build Coastguard Worker     }
3883*fb1b10abSAndroid Build Coastguard Worker #endif
3884*fb1b10abSAndroid Build Coastguard Worker   }
3885*fb1b10abSAndroid Build Coastguard Worker 
3886*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 2) && !cpi->use_svc) {
3887*fb1b10abSAndroid Build Coastguard Worker     vp9_set_target_rate(cpi);
3888*fb1b10abSAndroid Build Coastguard Worker   }
3889*fb1b10abSAndroid Build Coastguard Worker 
3890*fb1b10abSAndroid Build Coastguard Worker   alloc_frame_mvs(cm, cm->new_fb_idx);
3891*fb1b10abSAndroid Build Coastguard Worker 
3892*fb1b10abSAndroid Build Coastguard Worker   // Reset the frame pointers to the current frame size.
3893*fb1b10abSAndroid Build Coastguard Worker   if (vpx_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
3894*fb1b10abSAndroid Build Coastguard Worker                                cm->subsampling_x, cm->subsampling_y,
3895*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3896*fb1b10abSAndroid Build Coastguard Worker                                cm->use_highbitdepth,
3897*fb1b10abSAndroid Build Coastguard Worker #endif
3898*fb1b10abSAndroid Build Coastguard Worker                                VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
3899*fb1b10abSAndroid Build Coastguard Worker                                NULL, NULL, NULL))
3900*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
3901*fb1b10abSAndroid Build Coastguard Worker                        "Failed to allocate frame buffer");
3902*fb1b10abSAndroid Build Coastguard Worker 
3903*fb1b10abSAndroid Build Coastguard Worker   alloc_util_frame_buffers(cpi);
3904*fb1b10abSAndroid Build Coastguard Worker   init_motion_estimation(cpi);
3905*fb1b10abSAndroid Build Coastguard Worker 
3906*fb1b10abSAndroid Build Coastguard Worker   int has_valid_ref_frame = 0;
3907*fb1b10abSAndroid Build Coastguard Worker   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3908*fb1b10abSAndroid Build Coastguard Worker     RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
3909*fb1b10abSAndroid Build Coastguard Worker     const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3910*fb1b10abSAndroid Build Coastguard Worker 
3911*fb1b10abSAndroid Build Coastguard Worker     ref_buf->idx = buf_idx;
3912*fb1b10abSAndroid Build Coastguard Worker 
3913*fb1b10abSAndroid Build Coastguard Worker     if (buf_idx != INVALID_IDX) {
3914*fb1b10abSAndroid Build Coastguard Worker       YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf;
3915*fb1b10abSAndroid Build Coastguard Worker       ref_buf->buf = buf;
3916*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3917*fb1b10abSAndroid Build Coastguard Worker       vp9_setup_scale_factors_for_frame(
3918*fb1b10abSAndroid Build Coastguard Worker           &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width,
3919*fb1b10abSAndroid Build Coastguard Worker           cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0);
3920*fb1b10abSAndroid Build Coastguard Worker #else
3921*fb1b10abSAndroid Build Coastguard Worker       vp9_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width,
3922*fb1b10abSAndroid Build Coastguard Worker                                         buf->y_crop_height, cm->width,
3923*fb1b10abSAndroid Build Coastguard Worker                                         cm->height);
3924*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3925*fb1b10abSAndroid Build Coastguard Worker       has_valid_ref_frame |= vp9_is_valid_scale(&ref_buf->sf);
3926*fb1b10abSAndroid Build Coastguard Worker       if (vp9_is_scaled(&ref_buf->sf)) vpx_extend_frame_borders(buf);
3927*fb1b10abSAndroid Build Coastguard Worker     } else {
3928*fb1b10abSAndroid Build Coastguard Worker       ref_buf->buf = NULL;
3929*fb1b10abSAndroid Build Coastguard Worker     }
3930*fb1b10abSAndroid Build Coastguard Worker   }
3931*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm) && !has_valid_ref_frame) {
3932*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(
3933*fb1b10abSAndroid Build Coastguard Worker         &cm->error, VPX_CODEC_ERROR,
3934*fb1b10abSAndroid Build Coastguard Worker         "Can't find at least one reference frame with valid size");
3935*fb1b10abSAndroid Build Coastguard Worker   }
3936*fb1b10abSAndroid Build Coastguard Worker 
3937*fb1b10abSAndroid Build Coastguard Worker   set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
3938*fb1b10abSAndroid Build Coastguard Worker }
3939*fb1b10abSAndroid Build Coastguard Worker 
3940*fb1b10abSAndroid Build Coastguard Worker static void save_encode_params(VP9_COMP *cpi) {
3941*fb1b10abSAndroid Build Coastguard Worker   int tile_idx;
3942*fb1b10abSAndroid Build Coastguard Worker   int i, j;
3943*fb1b10abSAndroid Build Coastguard Worker   TileDataEnc *tile_data;
3944*fb1b10abSAndroid Build Coastguard Worker   RD_OPT *rd_opt = &cpi->rd;
3945*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_REF_FRAMES; i++) {
3946*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < REFERENCE_MODES; j++)
3947*fb1b10abSAndroid Build Coastguard Worker       rd_opt->prediction_type_threshes_prev[i][j] =
3948*fb1b10abSAndroid Build Coastguard Worker           rd_opt->prediction_type_threshes[i][j];
3949*fb1b10abSAndroid Build Coastguard Worker 
3950*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; j++)
3951*fb1b10abSAndroid Build Coastguard Worker       rd_opt->filter_threshes_prev[i][j] = rd_opt->filter_threshes[i][j];
3952*fb1b10abSAndroid Build Coastguard Worker   }
3953*fb1b10abSAndroid Build Coastguard Worker 
3954*fb1b10abSAndroid Build Coastguard Worker   for (tile_idx = 0; tile_idx < cpi->allocated_tiles; tile_idx++) {
3955*fb1b10abSAndroid Build Coastguard Worker     assert(cpi->tile_data);
3956*fb1b10abSAndroid Build Coastguard Worker     tile_data = &cpi->tile_data[tile_idx];
3957*fb1b10abSAndroid Build Coastguard Worker     vp9_copy(tile_data->thresh_freq_fact_prev, tile_data->thresh_freq_fact);
3958*fb1b10abSAndroid Build Coastguard Worker   }
3959*fb1b10abSAndroid Build Coastguard Worker }
3960*fb1b10abSAndroid Build Coastguard Worker 
3961*fb1b10abSAndroid Build Coastguard Worker static INLINE void set_raw_source_frame(VP9_COMP *cpi) {
3962*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
3963*fb1b10abSAndroid Build Coastguard Worker   if (is_spatial_denoise_enabled(cpi)) {
3964*fb1b10abSAndroid Build Coastguard Worker     cpi->raw_source_frame = vp9_scale_if_required(
3965*fb1b10abSAndroid Build Coastguard Worker         cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source,
3966*fb1b10abSAndroid Build Coastguard Worker         (oxcf->pass == 0), EIGHTTAP, 0);
3967*fb1b10abSAndroid Build Coastguard Worker   } else {
3968*fb1b10abSAndroid Build Coastguard Worker     cpi->raw_source_frame = cpi->Source;
3969*fb1b10abSAndroid Build Coastguard Worker   }
3970*fb1b10abSAndroid Build Coastguard Worker #else
3971*fb1b10abSAndroid Build Coastguard Worker   cpi->raw_source_frame = cpi->Source;
3972*fb1b10abSAndroid Build Coastguard Worker #endif
3973*fb1b10abSAndroid Build Coastguard Worker }
3974*fb1b10abSAndroid Build Coastguard Worker 
3975*fb1b10abSAndroid Build Coastguard Worker static YV12_BUFFER_CONFIG *svc_twostage_scale(
3976*fb1b10abSAndroid Build Coastguard Worker     VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled,
3977*fb1b10abSAndroid Build Coastguard Worker     YV12_BUFFER_CONFIG *scaled_temp, INTERP_FILTER filter_type,
3978*fb1b10abSAndroid Build Coastguard Worker     int phase_scaler, INTERP_FILTER filter_type2, int phase_scaler2) {
3979*fb1b10abSAndroid Build Coastguard Worker   if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
3980*fb1b10abSAndroid Build Coastguard Worker       cm->mi_rows * MI_SIZE != unscaled->y_height) {
3981*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3982*fb1b10abSAndroid Build Coastguard Worker     if (cm->bit_depth == VPX_BITS_8) {
3983*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_and_extend_frame(unscaled, scaled_temp, filter_type2,
3984*fb1b10abSAndroid Build Coastguard Worker                                  phase_scaler2);
3985*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_and_extend_frame(scaled_temp, scaled, filter_type,
3986*fb1b10abSAndroid Build Coastguard Worker                                  phase_scaler);
3987*fb1b10abSAndroid Build Coastguard Worker     } else {
3988*fb1b10abSAndroid Build Coastguard Worker       scale_and_extend_frame(unscaled, scaled_temp, (int)cm->bit_depth,
3989*fb1b10abSAndroid Build Coastguard Worker                              filter_type2, phase_scaler2);
3990*fb1b10abSAndroid Build Coastguard Worker       scale_and_extend_frame(scaled_temp, scaled, (int)cm->bit_depth,
3991*fb1b10abSAndroid Build Coastguard Worker                              filter_type, phase_scaler);
3992*fb1b10abSAndroid Build Coastguard Worker     }
3993*fb1b10abSAndroid Build Coastguard Worker #else
3994*fb1b10abSAndroid Build Coastguard Worker     vp9_scale_and_extend_frame(unscaled, scaled_temp, filter_type2,
3995*fb1b10abSAndroid Build Coastguard Worker                                phase_scaler2);
3996*fb1b10abSAndroid Build Coastguard Worker     vp9_scale_and_extend_frame(scaled_temp, scaled, filter_type, phase_scaler);
3997*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
3998*fb1b10abSAndroid Build Coastguard Worker     return scaled;
3999*fb1b10abSAndroid Build Coastguard Worker   } else {
4000*fb1b10abSAndroid Build Coastguard Worker     return unscaled;
4001*fb1b10abSAndroid Build Coastguard Worker   }
4002*fb1b10abSAndroid Build Coastguard Worker }
4003*fb1b10abSAndroid Build Coastguard Worker 
4004*fb1b10abSAndroid Build Coastguard Worker static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
4005*fb1b10abSAndroid Build Coastguard Worker                                       uint8_t *dest, size_t dest_size) {
4006*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
4007*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
4008*fb1b10abSAndroid Build Coastguard Worker   int q = 0, bottom_index = 0, top_index = 0;
4009*fb1b10abSAndroid Build Coastguard Worker   int no_drop_scene_change = 0;
4010*fb1b10abSAndroid Build Coastguard Worker   const INTERP_FILTER filter_scaler =
4011*fb1b10abSAndroid Build Coastguard Worker       (is_one_pass_svc(cpi))
4012*fb1b10abSAndroid Build Coastguard Worker           ? svc->downsample_filter_type[svc->spatial_layer_id]
4013*fb1b10abSAndroid Build Coastguard Worker           : EIGHTTAP;
4014*fb1b10abSAndroid Build Coastguard Worker   const int phase_scaler =
4015*fb1b10abSAndroid Build Coastguard Worker       (is_one_pass_svc(cpi))
4016*fb1b10abSAndroid Build Coastguard Worker           ? svc->downsample_filter_phase[svc->spatial_layer_id]
4017*fb1b10abSAndroid Build Coastguard Worker           : 0;
4018*fb1b10abSAndroid Build Coastguard Worker 
4019*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame) {
4020*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.this_frame_target = 0;
4021*fb1b10abSAndroid Build Coastguard Worker     if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi);
4022*fb1b10abSAndroid Build Coastguard Worker     return 1;
4023*fb1b10abSAndroid Build Coastguard Worker   }
4024*fb1b10abSAndroid Build Coastguard Worker 
4025*fb1b10abSAndroid Build Coastguard Worker   svc->time_stamp_prev[svc->spatial_layer_id] = svc->time_stamp_superframe;
4026*fb1b10abSAndroid Build Coastguard Worker 
4027*fb1b10abSAndroid Build Coastguard Worker   // Flag to check if its valid to compute the source sad (used for
4028*fb1b10abSAndroid Build Coastguard Worker   // scene detection and for superblock content state in CBR mode).
4029*fb1b10abSAndroid Build Coastguard Worker   // The flag may get reset below based on SVC or resizing state.
4030*fb1b10abSAndroid Build Coastguard Worker   cpi->compute_source_sad_onepass = cpi->oxcf.mode == REALTIME;
4031*fb1b10abSAndroid Build Coastguard Worker 
4032*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
4033*fb1b10abSAndroid Build Coastguard Worker 
4034*fb1b10abSAndroid Build Coastguard Worker   set_frame_size(cpi);
4035*fb1b10abSAndroid Build Coastguard Worker 
4036*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi) &&
4037*fb1b10abSAndroid Build Coastguard Worker       cpi->un_scaled_source->y_width == cm->width << 2 &&
4038*fb1b10abSAndroid Build Coastguard Worker       cpi->un_scaled_source->y_height == cm->height << 2 &&
4039*fb1b10abSAndroid Build Coastguard Worker       svc->scaled_temp.y_width == cm->width << 1 &&
4040*fb1b10abSAndroid Build Coastguard Worker       svc->scaled_temp.y_height == cm->height << 1) {
4041*fb1b10abSAndroid Build Coastguard Worker     // For svc, if it is a 1/4x1/4 downscaling, do a two-stage scaling to take
4042*fb1b10abSAndroid Build Coastguard Worker     // advantage of the 1:2 optimized scaler. In the process, the 1/2x1/2
4043*fb1b10abSAndroid Build Coastguard Worker     // result will be saved in scaled_temp and might be used later.
4044*fb1b10abSAndroid Build Coastguard Worker     const INTERP_FILTER filter_scaler2 = svc->downsample_filter_type[1];
4045*fb1b10abSAndroid Build Coastguard Worker     const int phase_scaler2 = svc->downsample_filter_phase[1];
4046*fb1b10abSAndroid Build Coastguard Worker     cpi->Source = svc_twostage_scale(
4047*fb1b10abSAndroid Build Coastguard Worker         cm, cpi->un_scaled_source, &cpi->scaled_source, &svc->scaled_temp,
4048*fb1b10abSAndroid Build Coastguard Worker         filter_scaler, phase_scaler, filter_scaler2, phase_scaler2);
4049*fb1b10abSAndroid Build Coastguard Worker     svc->scaled_one_half = 1;
4050*fb1b10abSAndroid Build Coastguard Worker   } else if (is_one_pass_svc(cpi) &&
4051*fb1b10abSAndroid Build Coastguard Worker              cpi->un_scaled_source->y_width == cm->width << 1 &&
4052*fb1b10abSAndroid Build Coastguard Worker              cpi->un_scaled_source->y_height == cm->height << 1 &&
4053*fb1b10abSAndroid Build Coastguard Worker              svc->scaled_one_half) {
4054*fb1b10abSAndroid Build Coastguard Worker     // If the spatial layer is 1/2x1/2 and the scaling is already done in the
4055*fb1b10abSAndroid Build Coastguard Worker     // two-stage scaling, use the result directly.
4056*fb1b10abSAndroid Build Coastguard Worker     cpi->Source = &svc->scaled_temp;
4057*fb1b10abSAndroid Build Coastguard Worker     svc->scaled_one_half = 0;
4058*fb1b10abSAndroid Build Coastguard Worker   } else {
4059*fb1b10abSAndroid Build Coastguard Worker     cpi->Source = vp9_scale_if_required(
4060*fb1b10abSAndroid Build Coastguard Worker         cm, cpi->un_scaled_source, &cpi->scaled_source, (cpi->oxcf.pass == 0),
4061*fb1b10abSAndroid Build Coastguard Worker         filter_scaler, phase_scaler);
4062*fb1b10abSAndroid Build Coastguard Worker   }
4063*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SVC_SRC
4064*fb1b10abSAndroid Build Coastguard Worker   // Write out at most 3 spatial layers.
4065*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi) && svc->spatial_layer_id < 3) {
4066*fb1b10abSAndroid Build Coastguard Worker     vpx_write_yuv_frame(yuv_svc_src[svc->spatial_layer_id], cpi->Source);
4067*fb1b10abSAndroid Build Coastguard Worker   }
4068*fb1b10abSAndroid Build Coastguard Worker #endif
4069*fb1b10abSAndroid Build Coastguard Worker   // Unfiltered raw source used in metrics calculation if the source
4070*fb1b10abSAndroid Build Coastguard Worker   // has been filtered.
4071*fb1b10abSAndroid Build Coastguard Worker   if (is_psnr_calc_enabled(cpi)) {
4072*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
4073*fb1b10abSAndroid Build Coastguard Worker     if (is_spatial_denoise_enabled(cpi)) {
4074*fb1b10abSAndroid Build Coastguard Worker       cpi->raw_source_frame = vp9_scale_if_required(
4075*fb1b10abSAndroid Build Coastguard Worker           cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source,
4076*fb1b10abSAndroid Build Coastguard Worker           (cpi->oxcf.pass == 0), EIGHTTAP, phase_scaler);
4077*fb1b10abSAndroid Build Coastguard Worker     } else {
4078*fb1b10abSAndroid Build Coastguard Worker       cpi->raw_source_frame = cpi->Source;
4079*fb1b10abSAndroid Build Coastguard Worker     }
4080*fb1b10abSAndroid Build Coastguard Worker #else
4081*fb1b10abSAndroid Build Coastguard Worker     cpi->raw_source_frame = cpi->Source;
4082*fb1b10abSAndroid Build Coastguard Worker #endif
4083*fb1b10abSAndroid Build Coastguard Worker   }
4084*fb1b10abSAndroid Build Coastguard Worker 
4085*fb1b10abSAndroid Build Coastguard Worker   if ((cpi->use_svc &&
4086*fb1b10abSAndroid Build Coastguard Worker        (svc->spatial_layer_id < svc->number_spatial_layers - 1 ||
4087*fb1b10abSAndroid Build Coastguard Worker         svc->temporal_layer_id < svc->number_temporal_layers - 1 ||
4088*fb1b10abSAndroid Build Coastguard Worker         svc->current_superframe < 1)) ||
4089*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_pending || cpi->resize_state || cpi->external_resize ||
4090*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_state != ORIG) {
4091*fb1b10abSAndroid Build Coastguard Worker     cpi->compute_source_sad_onepass = 0;
4092*fb1b10abSAndroid Build Coastguard Worker     if (cpi->content_state_sb_fd != NULL)
4093*fb1b10abSAndroid Build Coastguard Worker       memset(cpi->content_state_sb_fd, 0,
4094*fb1b10abSAndroid Build Coastguard Worker              (cm->mi_stride >> 3) * ((cm->mi_rows >> 3) + 1) *
4095*fb1b10abSAndroid Build Coastguard Worker                  sizeof(*cpi->content_state_sb_fd));
4096*fb1b10abSAndroid Build Coastguard Worker   }
4097*fb1b10abSAndroid Build Coastguard Worker 
4098*fb1b10abSAndroid Build Coastguard Worker   // Avoid scaling last_source unless its needed.
4099*fb1b10abSAndroid Build Coastguard Worker   // Last source is needed if avg_source_sad() is used, or if
4100*fb1b10abSAndroid Build Coastguard Worker   // partition_search_type == SOURCE_VAR_BASED_PARTITION, or if noise
4101*fb1b10abSAndroid Build Coastguard Worker   // estimation is enabled.
4102*fb1b10abSAndroid Build Coastguard Worker   if (cpi->unscaled_last_source != NULL &&
4103*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
4104*fb1b10abSAndroid Build Coastguard Worker        (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_VBR &&
4105*fb1b10abSAndroid Build Coastguard Worker         cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5) ||
4106*fb1b10abSAndroid Build Coastguard Worker        cpi->sf.partition_search_type == SOURCE_VAR_BASED_PARTITION ||
4107*fb1b10abSAndroid Build Coastguard Worker        (cpi->noise_estimate.enabled && !cpi->oxcf.noise_sensitivity) ||
4108*fb1b10abSAndroid Build Coastguard Worker        cpi->compute_source_sad_onepass))
4109*fb1b10abSAndroid Build Coastguard Worker     cpi->Last_Source = vp9_scale_if_required(
4110*fb1b10abSAndroid Build Coastguard Worker         cm, cpi->unscaled_last_source, &cpi->scaled_last_source,
4111*fb1b10abSAndroid Build Coastguard Worker         (cpi->oxcf.pass == 0), EIGHTTAP, 0);
4112*fb1b10abSAndroid Build Coastguard Worker 
4113*fb1b10abSAndroid Build Coastguard Worker   if (cpi->Last_Source == NULL ||
4114*fb1b10abSAndroid Build Coastguard Worker       cpi->Last_Source->y_width != cpi->Source->y_width ||
4115*fb1b10abSAndroid Build Coastguard Worker       cpi->Last_Source->y_height != cpi->Source->y_height)
4116*fb1b10abSAndroid Build Coastguard Worker     cpi->compute_source_sad_onepass = 0;
4117*fb1b10abSAndroid Build Coastguard Worker 
4118*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) || cpi->resize_pending != 0) {
4119*fb1b10abSAndroid Build Coastguard Worker     memset(cpi->consec_zero_mv, 0,
4120*fb1b10abSAndroid Build Coastguard Worker            cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv));
4121*fb1b10abSAndroid Build Coastguard Worker   }
4122*fb1b10abSAndroid Build Coastguard Worker 
4123*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
4124*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.noise_sensitivity > 0 && cpi->use_svc)
4125*fb1b10abSAndroid Build Coastguard Worker     vp9_denoiser_reset_on_first_frame(cpi);
4126*fb1b10abSAndroid Build Coastguard Worker #endif
4127*fb1b10abSAndroid Build Coastguard Worker 
4128*fb1b10abSAndroid Build Coastguard Worker   // Scene detection is always used for VBR mode or screen-content case.
4129*fb1b10abSAndroid Build Coastguard Worker   // For other cases (e.g., CBR mode) use it for 5 <= speed.
4130*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.high_source_sad = 0;
4131*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.hybrid_intra_scene_change = 0;
4132*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.re_encode_maxq_scene_change = 0;
4133*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame && cpi->oxcf.mode == REALTIME &&
4134*fb1b10abSAndroid Build Coastguard Worker       !cpi->disable_scene_detection_rtc_ratectrl &&
4135*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.rc_mode == VPX_VBR ||
4136*fb1b10abSAndroid Build Coastguard Worker        cpi->oxcf.content == VP9E_CONTENT_SCREEN || cpi->oxcf.speed >= 5))
4137*fb1b10abSAndroid Build Coastguard Worker     vp9_scene_detection_onepass(cpi);
4138*fb1b10abSAndroid Build Coastguard Worker 
4139*fb1b10abSAndroid Build Coastguard Worker   if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) {
4140*fb1b10abSAndroid Build Coastguard Worker     svc->high_source_sad_superframe = cpi->rc.high_source_sad;
4141*fb1b10abSAndroid Build Coastguard Worker     svc->high_num_blocks_with_motion = cpi->rc.high_num_blocks_with_motion;
4142*fb1b10abSAndroid Build Coastguard Worker     // On scene change reset temporal layer pattern to TL0.
4143*fb1b10abSAndroid Build Coastguard Worker     // Note that if the base/lower spatial layers are skipped: instead of
4144*fb1b10abSAndroid Build Coastguard Worker     // inserting base layer here, we force max-q for the next superframe
4145*fb1b10abSAndroid Build Coastguard Worker     // with lower spatial layers: this is done in vp9_encodedframe_overshoot()
4146*fb1b10abSAndroid Build Coastguard Worker     // when max-q is decided for the current layer.
4147*fb1b10abSAndroid Build Coastguard Worker     // Only do this reset for bypass/flexible mode.
4148*fb1b10abSAndroid Build Coastguard Worker     if (svc->high_source_sad_superframe && svc->temporal_layer_id > 0 &&
4149*fb1b10abSAndroid Build Coastguard Worker         svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
4150*fb1b10abSAndroid Build Coastguard Worker       // rc->high_source_sad will get reset so copy it to restore it.
4151*fb1b10abSAndroid Build Coastguard Worker       int tmp_high_source_sad = cpi->rc.high_source_sad;
4152*fb1b10abSAndroid Build Coastguard Worker       vp9_svc_reset_temporal_layers(cpi, cm->frame_type == KEY_FRAME);
4153*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.high_source_sad = tmp_high_source_sad;
4154*fb1b10abSAndroid Build Coastguard Worker     }
4155*fb1b10abSAndroid Build Coastguard Worker   }
4156*fb1b10abSAndroid Build Coastguard Worker 
4157*fb1b10abSAndroid Build Coastguard Worker   vp9_update_noise_estimate(cpi);
4158*fb1b10abSAndroid Build Coastguard Worker 
4159*fb1b10abSAndroid Build Coastguard Worker   // For 1 pass CBR, check if we are dropping this frame.
4160*fb1b10abSAndroid Build Coastguard Worker   // Never drop on key frame, if base layer is key for svc,
4161*fb1b10abSAndroid Build Coastguard Worker   // on scene change, or if superframe has layer sync.
4162*fb1b10abSAndroid Build Coastguard Worker   if ((cpi->rc.high_source_sad || svc->high_source_sad_superframe) &&
4163*fb1b10abSAndroid Build Coastguard Worker       !(cpi->rc.use_post_encode_drop && svc->last_layer_dropped[0]))
4164*fb1b10abSAndroid Build Coastguard Worker     no_drop_scene_change = 1;
4165*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
4166*fb1b10abSAndroid Build Coastguard Worker       !frame_is_intra_only(cm) && !no_drop_scene_change &&
4167*fb1b10abSAndroid Build Coastguard Worker       !svc->superframe_has_layer_sync &&
4168*fb1b10abSAndroid Build Coastguard Worker       (!cpi->use_svc ||
4169*fb1b10abSAndroid Build Coastguard Worker        !svc->layer_context[svc->temporal_layer_id].is_key_frame)) {
4170*fb1b10abSAndroid Build Coastguard Worker     if (vp9_rc_drop_frame(cpi)) return 0;
4171*fb1b10abSAndroid Build Coastguard Worker   }
4172*fb1b10abSAndroid Build Coastguard Worker 
4173*fb1b10abSAndroid Build Coastguard Worker   // For 1 pass SVC, only ZEROMV is allowed for spatial reference frame
4174*fb1b10abSAndroid Build Coastguard Worker   // when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can
4175*fb1b10abSAndroid Build Coastguard Worker   // avoid this frame-level upsampling (for non intra_only frames).
4176*fb1b10abSAndroid Build Coastguard Worker   // For SVC single_layer mode, dynamic resize is allowed and we need to
4177*fb1b10abSAndroid Build Coastguard Worker   // scale references for this case.
4178*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) == 0 &&
4179*fb1b10abSAndroid Build Coastguard Worker       ((svc->single_layer_svc && cpi->oxcf.resize_mode == RESIZE_DYNAMIC) ||
4180*fb1b10abSAndroid Build Coastguard Worker        !(is_one_pass_svc(cpi) && svc->force_zero_mode_spatial_ref))) {
4181*fb1b10abSAndroid Build Coastguard Worker     vp9_scale_references(cpi);
4182*fb1b10abSAndroid Build Coastguard Worker   }
4183*fb1b10abSAndroid Build Coastguard Worker 
4184*fb1b10abSAndroid Build Coastguard Worker   set_size_independent_vars(cpi);
4185*fb1b10abSAndroid Build Coastguard Worker   set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
4186*fb1b10abSAndroid Build Coastguard Worker 
4187*fb1b10abSAndroid Build Coastguard Worker   // search method and step parameter might be changed in speed settings.
4188*fb1b10abSAndroid Build Coastguard Worker   init_motion_estimation(cpi);
4189*fb1b10abSAndroid Build Coastguard Worker 
4190*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.copy_partition_flag) alloc_copy_partition_data(cpi);
4191*fb1b10abSAndroid Build Coastguard Worker 
4192*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.svc_use_lowres_part &&
4193*fb1b10abSAndroid Build Coastguard Worker       svc->spatial_layer_id == svc->number_spatial_layers - 2) {
4194*fb1b10abSAndroid Build Coastguard Worker     if (svc->prev_partition_svc == NULL) {
4195*fb1b10abSAndroid Build Coastguard Worker       CHECK_MEM_ERROR(
4196*fb1b10abSAndroid Build Coastguard Worker           &cm->error, svc->prev_partition_svc,
4197*fb1b10abSAndroid Build Coastguard Worker           (BLOCK_SIZE *)vpx_calloc(cm->mi_stride * cm->mi_rows,
4198*fb1b10abSAndroid Build Coastguard Worker                                    sizeof(*svc->prev_partition_svc)));
4199*fb1b10abSAndroid Build Coastguard Worker     }
4200*fb1b10abSAndroid Build Coastguard Worker   }
4201*fb1b10abSAndroid Build Coastguard Worker 
4202*fb1b10abSAndroid Build Coastguard Worker   // TODO(jianj): Look into issue of skin detection with high bitdepth.
4203*fb1b10abSAndroid Build Coastguard Worker   if (cm->bit_depth == 8 && cpi->oxcf.speed >= 5 && cpi->oxcf.pass == 0 &&
4204*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.rc_mode == VPX_CBR &&
4205*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.content != VP9E_CONTENT_SCREEN &&
4206*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
4207*fb1b10abSAndroid Build Coastguard Worker     cpi->use_skin_detection = 1;
4208*fb1b10abSAndroid Build Coastguard Worker   }
4209*fb1b10abSAndroid Build Coastguard Worker 
4210*fb1b10abSAndroid Build Coastguard Worker   // Enable post encode frame dropping for CBR on non key frame, when
4211*fb1b10abSAndroid Build Coastguard Worker   // ext_use_post_encode_drop is specified by user.
4212*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.use_post_encode_drop = cpi->rc.ext_use_post_encode_drop &&
4213*fb1b10abSAndroid Build Coastguard Worker                                  cpi->oxcf.rc_mode == VPX_CBR &&
4214*fb1b10abSAndroid Build Coastguard Worker                                  cm->frame_type != KEY_FRAME;
4215*fb1b10abSAndroid Build Coastguard Worker 
4216*fb1b10abSAndroid Build Coastguard Worker   vp9_set_quantizer(cpi, q);
4217*fb1b10abSAndroid Build Coastguard Worker   vp9_set_variance_partition_thresholds(cpi, q, 0);
4218*fb1b10abSAndroid Build Coastguard Worker 
4219*fb1b10abSAndroid Build Coastguard Worker   setup_frame(cpi);
4220*fb1b10abSAndroid Build Coastguard Worker 
4221*fb1b10abSAndroid Build Coastguard Worker   suppress_active_map(cpi);
4222*fb1b10abSAndroid Build Coastguard Worker 
4223*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) {
4224*fb1b10abSAndroid Build Coastguard Worker     // On non-zero spatial layer, check for disabling inter-layer
4225*fb1b10abSAndroid Build Coastguard Worker     // prediction.
4226*fb1b10abSAndroid Build Coastguard Worker     if (svc->spatial_layer_id > 0) vp9_svc_constrain_inter_layer_pred(cpi);
4227*fb1b10abSAndroid Build Coastguard Worker     vp9_svc_assert_constraints_pattern(cpi);
4228*fb1b10abSAndroid Build Coastguard Worker   }
4229*fb1b10abSAndroid Build Coastguard Worker 
4230*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.last_post_encode_dropped_scene_change) {
4231*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.high_source_sad = 1;
4232*fb1b10abSAndroid Build Coastguard Worker     svc->high_source_sad_superframe = 1;
4233*fb1b10abSAndroid Build Coastguard Worker     // For now disable use_source_sad since Last_Source will not be the previous
4234*fb1b10abSAndroid Build Coastguard Worker     // encoded but the dropped one.
4235*fb1b10abSAndroid Build Coastguard Worker     cpi->sf.use_source_sad = 0;
4236*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.last_post_encode_dropped_scene_change = 0;
4237*fb1b10abSAndroid Build Coastguard Worker   }
4238*fb1b10abSAndroid Build Coastguard Worker   // Check if this high_source_sad (scene/slide change) frame should be
4239*fb1b10abSAndroid Build Coastguard Worker   // encoded at high/max QP, and if so, set the q and adjust some rate
4240*fb1b10abSAndroid Build Coastguard Worker   // control parameters.
4241*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ &&
4242*fb1b10abSAndroid Build Coastguard Worker       (cpi->rc.high_source_sad ||
4243*fb1b10abSAndroid Build Coastguard Worker        (cpi->use_svc && svc->high_source_sad_superframe))) {
4244*fb1b10abSAndroid Build Coastguard Worker     if (vp9_encodedframe_overshoot(cpi, -1, &q)) {
4245*fb1b10abSAndroid Build Coastguard Worker       vp9_set_quantizer(cpi, q);
4246*fb1b10abSAndroid Build Coastguard Worker       vp9_set_variance_partition_thresholds(cpi, q, 0);
4247*fb1b10abSAndroid Build Coastguard Worker     }
4248*fb1b10abSAndroid Build Coastguard Worker   }
4249*fb1b10abSAndroid Build Coastguard Worker 
4250*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
4251*fb1b10abSAndroid Build Coastguard Worker   // Variance adaptive and in frame q adjustment experiments are mutually
4252*fb1b10abSAndroid Build Coastguard Worker   // exclusive.
4253*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
4254*fb1b10abSAndroid Build Coastguard Worker     vp9_vaq_frame_setup(cpi);
4255*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->oxcf.aq_mode == EQUATOR360_AQ) {
4256*fb1b10abSAndroid Build Coastguard Worker     vp9_360aq_frame_setup(cpi);
4257*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
4258*fb1b10abSAndroid Build Coastguard Worker     vp9_setup_in_frame_q_adj(cpi);
4259*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ) {
4260*fb1b10abSAndroid Build Coastguard Worker     // it may be pretty bad for rate-control,
4261*fb1b10abSAndroid Build Coastguard Worker     // and I should handle it somehow
4262*fb1b10abSAndroid Build Coastguard Worker     vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
4263*fb1b10abSAndroid Build Coastguard Worker   } else {
4264*fb1b10abSAndroid Build Coastguard Worker #endif
4265*fb1b10abSAndroid Build Coastguard Worker     // If ROI is enabled and skip feature is used for segmentation, apply cyclic
4266*fb1b10abSAndroid Build Coastguard Worker     // refresh but not apply ROI for skip for the first 20 frames (defined by
4267*fb1b10abSAndroid Build Coastguard Worker     // FRAMES_NO_SKIPPING_AFTER_KEY) after key frame to improve quality.
4268*fb1b10abSAndroid Build Coastguard Worker     if (cpi->roi.enabled && !frame_is_intra_only(cm)) {
4269*fb1b10abSAndroid Build Coastguard Worker       if (cpi->roi.skip[BACKGROUND_SEG_SKIP_ID]) {
4270*fb1b10abSAndroid Build Coastguard Worker         if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
4271*fb1b10abSAndroid Build Coastguard Worker           vp9_cyclic_refresh_setup(cpi);
4272*fb1b10abSAndroid Build Coastguard Worker         if (cpi->rc.frames_since_key > FRAMES_NO_SKIPPING_AFTER_KEY)
4273*fb1b10abSAndroid Build Coastguard Worker           apply_roi_map(cpi);
4274*fb1b10abSAndroid Build Coastguard Worker       } else {
4275*fb1b10abSAndroid Build Coastguard Worker         apply_roi_map(cpi);
4276*fb1b10abSAndroid Build Coastguard Worker       }
4277*fb1b10abSAndroid Build Coastguard Worker     } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
4278*fb1b10abSAndroid Build Coastguard Worker       vp9_cyclic_refresh_setup(cpi);
4279*fb1b10abSAndroid Build Coastguard Worker     }
4280*fb1b10abSAndroid Build Coastguard Worker 
4281*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
4282*fb1b10abSAndroid Build Coastguard Worker   }
4283*fb1b10abSAndroid Build Coastguard Worker #endif
4284*fb1b10abSAndroid Build Coastguard Worker 
4285*fb1b10abSAndroid Build Coastguard Worker   apply_active_map(cpi);
4286*fb1b10abSAndroid Build Coastguard Worker 
4287*fb1b10abSAndroid Build Coastguard Worker   vp9_encode_frame(cpi);
4288*fb1b10abSAndroid Build Coastguard Worker 
4289*fb1b10abSAndroid Build Coastguard Worker   // Check if we should re-encode this frame at high Q because of high
4290*fb1b10abSAndroid Build Coastguard Worker   // overshoot based on the encoded frame size. Only for frames where
4291*fb1b10abSAndroid Build Coastguard Worker   // high temporal-source SAD is detected.
4292*fb1b10abSAndroid Build Coastguard Worker   // For SVC: all spatial layers are checked for re-encoding.
4293*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.overshoot_detection_cbr_rt == RE_ENCODE_MAXQ &&
4294*fb1b10abSAndroid Build Coastguard Worker       (cpi->rc.high_source_sad ||
4295*fb1b10abSAndroid Build Coastguard Worker        (cpi->use_svc && svc->high_source_sad_superframe))) {
4296*fb1b10abSAndroid Build Coastguard Worker     int frame_size = 0;
4297*fb1b10abSAndroid Build Coastguard Worker     // Get an estimate of the encoded frame size.
4298*fb1b10abSAndroid Build Coastguard Worker     save_coding_context(cpi);
4299*fb1b10abSAndroid Build Coastguard Worker     vp9_pack_bitstream(cpi, dest, dest_size, size);
4300*fb1b10abSAndroid Build Coastguard Worker     restore_coding_context(cpi);
4301*fb1b10abSAndroid Build Coastguard Worker     frame_size = (int)(*size) << 3;
4302*fb1b10abSAndroid Build Coastguard Worker     // Check if encoded frame will overshoot too much, and if so, set the q and
4303*fb1b10abSAndroid Build Coastguard Worker     // adjust some rate control parameters, and return to re-encode the frame.
4304*fb1b10abSAndroid Build Coastguard Worker     if (vp9_encodedframe_overshoot(cpi, frame_size, &q)) {
4305*fb1b10abSAndroid Build Coastguard Worker       vpx_clear_system_state();
4306*fb1b10abSAndroid Build Coastguard Worker       vp9_set_quantizer(cpi, q);
4307*fb1b10abSAndroid Build Coastguard Worker       vp9_set_variance_partition_thresholds(cpi, q, 0);
4308*fb1b10abSAndroid Build Coastguard Worker       suppress_active_map(cpi);
4309*fb1b10abSAndroid Build Coastguard Worker       // Turn-off cyclic refresh for re-encoded frame.
4310*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
4311*fb1b10abSAndroid Build Coastguard Worker         CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
4312*fb1b10abSAndroid Build Coastguard Worker         unsigned char *const seg_map = cpi->segmentation_map;
4313*fb1b10abSAndroid Build Coastguard Worker         memset(seg_map, 0, cm->mi_rows * cm->mi_cols);
4314*fb1b10abSAndroid Build Coastguard Worker         memset(cr->last_coded_q_map, MAXQ,
4315*fb1b10abSAndroid Build Coastguard Worker                cm->mi_rows * cm->mi_cols * sizeof(*cr->last_coded_q_map));
4316*fb1b10abSAndroid Build Coastguard Worker         cr->sb_index = 0;
4317*fb1b10abSAndroid Build Coastguard Worker         vp9_disable_segmentation(&cm->seg);
4318*fb1b10abSAndroid Build Coastguard Worker       }
4319*fb1b10abSAndroid Build Coastguard Worker       apply_active_map(cpi);
4320*fb1b10abSAndroid Build Coastguard Worker       vp9_encode_frame(cpi);
4321*fb1b10abSAndroid Build Coastguard Worker     }
4322*fb1b10abSAndroid Build Coastguard Worker   }
4323*fb1b10abSAndroid Build Coastguard Worker 
4324*fb1b10abSAndroid Build Coastguard Worker   // Update some stats from cyclic refresh, and check for golden frame update.
4325*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->seg.enabled &&
4326*fb1b10abSAndroid Build Coastguard Worker       !frame_is_intra_only(cm) && cpi->cyclic_refresh->content_mode)
4327*fb1b10abSAndroid Build Coastguard Worker     vp9_cyclic_refresh_postencode(cpi);
4328*fb1b10abSAndroid Build Coastguard Worker 
4329*fb1b10abSAndroid Build Coastguard Worker   // Update the skip mb flag probabilities based on the distribution
4330*fb1b10abSAndroid Build Coastguard Worker   // seen in the last encoder iteration.
4331*fb1b10abSAndroid Build Coastguard Worker   // update_base_skip_probs(cpi);
4332*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
4333*fb1b10abSAndroid Build Coastguard Worker   return 1;
4334*fb1b10abSAndroid Build Coastguard Worker }
4335*fb1b10abSAndroid Build Coastguard Worker 
4336*fb1b10abSAndroid Build Coastguard Worker static int get_ref_frame_flags(const VP9_COMP *cpi) {
4337*fb1b10abSAndroid Build Coastguard Worker   const int *const map = cpi->common.ref_frame_map;
4338*fb1b10abSAndroid Build Coastguard Worker   const int gold_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
4339*fb1b10abSAndroid Build Coastguard Worker   const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
4340*fb1b10abSAndroid Build Coastguard Worker   const int gold_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4341*fb1b10abSAndroid Build Coastguard Worker   int flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
4342*fb1b10abSAndroid Build Coastguard Worker 
4343*fb1b10abSAndroid Build Coastguard Worker   if (gold_is_last) flags &= ~VP9_GOLD_FLAG;
4344*fb1b10abSAndroid Build Coastguard Worker 
4345*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.frames_till_gf_update_due == INT_MAX &&
4346*fb1b10abSAndroid Build Coastguard Worker       (cpi->svc.number_temporal_layers == 1 &&
4347*fb1b10abSAndroid Build Coastguard Worker        cpi->svc.number_spatial_layers == 1))
4348*fb1b10abSAndroid Build Coastguard Worker     flags &= ~VP9_GOLD_FLAG;
4349*fb1b10abSAndroid Build Coastguard Worker 
4350*fb1b10abSAndroid Build Coastguard Worker   if (alt_is_last) flags &= ~VP9_ALT_FLAG;
4351*fb1b10abSAndroid Build Coastguard Worker 
4352*fb1b10abSAndroid Build Coastguard Worker   if (gold_is_alt) flags &= ~VP9_ALT_FLAG;
4353*fb1b10abSAndroid Build Coastguard Worker 
4354*fb1b10abSAndroid Build Coastguard Worker   return flags;
4355*fb1b10abSAndroid Build Coastguard Worker }
4356*fb1b10abSAndroid Build Coastguard Worker 
4357*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
4358*fb1b10abSAndroid Build Coastguard Worker #define MAX_QSTEP_ADJ 4
4359*fb1b10abSAndroid Build Coastguard Worker static int get_qstep_adj(int rate_excess, int rate_limit) {
4360*fb1b10abSAndroid Build Coastguard Worker   int qstep =
4361*fb1b10abSAndroid Build Coastguard Worker       rate_limit ? ((rate_excess + rate_limit / 2) / rate_limit) : INT_MAX;
4362*fb1b10abSAndroid Build Coastguard Worker   return VPXMIN(qstep, MAX_QSTEP_ADJ);
4363*fb1b10abSAndroid Build Coastguard Worker }
4364*fb1b10abSAndroid Build Coastguard Worker 
4365*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
4366*fb1b10abSAndroid Build Coastguard Worker static void init_rq_history(RATE_QINDEX_HISTORY *rq_history) {
4367*fb1b10abSAndroid Build Coastguard Worker   rq_history->recode_count = 0;
4368*fb1b10abSAndroid Build Coastguard Worker   rq_history->q_index_high = 255;
4369*fb1b10abSAndroid Build Coastguard Worker   rq_history->q_index_low = 0;
4370*fb1b10abSAndroid Build Coastguard Worker }
4371*fb1b10abSAndroid Build Coastguard Worker 
4372*fb1b10abSAndroid Build Coastguard Worker static void update_rq_history(RATE_QINDEX_HISTORY *rq_history, int target_bits,
4373*fb1b10abSAndroid Build Coastguard Worker                               int actual_bits, int q_index) {
4374*fb1b10abSAndroid Build Coastguard Worker   rq_history->q_index_history[rq_history->recode_count] = q_index;
4375*fb1b10abSAndroid Build Coastguard Worker   rq_history->rate_history[rq_history->recode_count] = actual_bits;
4376*fb1b10abSAndroid Build Coastguard Worker   if (actual_bits <= target_bits) {
4377*fb1b10abSAndroid Build Coastguard Worker     rq_history->q_index_high = q_index;
4378*fb1b10abSAndroid Build Coastguard Worker   }
4379*fb1b10abSAndroid Build Coastguard Worker   if (actual_bits >= target_bits) {
4380*fb1b10abSAndroid Build Coastguard Worker     rq_history->q_index_low = q_index;
4381*fb1b10abSAndroid Build Coastguard Worker   }
4382*fb1b10abSAndroid Build Coastguard Worker   rq_history->recode_count += 1;
4383*fb1b10abSAndroid Build Coastguard Worker }
4384*fb1b10abSAndroid Build Coastguard Worker 
4385*fb1b10abSAndroid Build Coastguard Worker static int guess_q_index_from_model(const RATE_QSTEP_MODEL *rq_model,
4386*fb1b10abSAndroid Build Coastguard Worker                                     int target_bits) {
4387*fb1b10abSAndroid Build Coastguard Worker   // The model predicts bits as follows.
4388*fb1b10abSAndroid Build Coastguard Worker   // target_bits = bias - ratio * log2(q_step)
4389*fb1b10abSAndroid Build Coastguard Worker   // Given the target_bits, we compute the q_step as follows.
4390*fb1b10abSAndroid Build Coastguard Worker   double q_step;
4391*fb1b10abSAndroid Build Coastguard Worker   assert(rq_model->ratio > 0);
4392*fb1b10abSAndroid Build Coastguard Worker   q_step = pow(2.0, (rq_model->bias - target_bits) / rq_model->ratio);
4393*fb1b10abSAndroid Build Coastguard Worker   // TODO(angiebird): Make this function support highbitdepth.
4394*fb1b10abSAndroid Build Coastguard Worker   return vp9_convert_q_to_qindex(q_step, VPX_BITS_8);
4395*fb1b10abSAndroid Build Coastguard Worker }
4396*fb1b10abSAndroid Build Coastguard Worker 
4397*fb1b10abSAndroid Build Coastguard Worker static int guess_q_index_linear(int prev_q_index, int target_bits,
4398*fb1b10abSAndroid Build Coastguard Worker                                 int actual_bits, int gap) {
4399*fb1b10abSAndroid Build Coastguard Worker   int q_index = prev_q_index;
4400*fb1b10abSAndroid Build Coastguard Worker   if (actual_bits < target_bits) {
4401*fb1b10abSAndroid Build Coastguard Worker     q_index -= gap;
4402*fb1b10abSAndroid Build Coastguard Worker     q_index = VPXMAX(q_index, 0);
4403*fb1b10abSAndroid Build Coastguard Worker   } else {
4404*fb1b10abSAndroid Build Coastguard Worker     q_index += gap;
4405*fb1b10abSAndroid Build Coastguard Worker     q_index = VPXMIN(q_index, 255);
4406*fb1b10abSAndroid Build Coastguard Worker   }
4407*fb1b10abSAndroid Build Coastguard Worker   return q_index;
4408*fb1b10abSAndroid Build Coastguard Worker }
4409*fb1b10abSAndroid Build Coastguard Worker 
4410*fb1b10abSAndroid Build Coastguard Worker static double get_bits_percent_diff(int target_bits, int actual_bits) {
4411*fb1b10abSAndroid Build Coastguard Worker   double diff;
4412*fb1b10abSAndroid Build Coastguard Worker   target_bits = VPXMAX(target_bits, 1);
4413*fb1b10abSAndroid Build Coastguard Worker   diff = abs(target_bits - actual_bits) * 1. / target_bits;
4414*fb1b10abSAndroid Build Coastguard Worker   return diff * 100;
4415*fb1b10abSAndroid Build Coastguard Worker }
4416*fb1b10abSAndroid Build Coastguard Worker 
4417*fb1b10abSAndroid Build Coastguard Worker static int rq_model_predict_q_index(const RATE_QSTEP_MODEL *rq_model,
4418*fb1b10abSAndroid Build Coastguard Worker                                     const RATE_QINDEX_HISTORY *rq_history,
4419*fb1b10abSAndroid Build Coastguard Worker                                     int target_bits) {
4420*fb1b10abSAndroid Build Coastguard Worker   int q_index = 128;
4421*fb1b10abSAndroid Build Coastguard Worker   if (rq_history->recode_count > 0) {
4422*fb1b10abSAndroid Build Coastguard Worker     const int actual_bits =
4423*fb1b10abSAndroid Build Coastguard Worker         rq_history->rate_history[rq_history->recode_count - 1];
4424*fb1b10abSAndroid Build Coastguard Worker     const int prev_q_index =
4425*fb1b10abSAndroid Build Coastguard Worker         rq_history->q_index_history[rq_history->recode_count - 1];
4426*fb1b10abSAndroid Build Coastguard Worker     const double percent_diff = get_bits_percent_diff(target_bits, actual_bits);
4427*fb1b10abSAndroid Build Coastguard Worker     if (percent_diff > 50) {
4428*fb1b10abSAndroid Build Coastguard Worker       // Binary search.
4429*fb1b10abSAndroid Build Coastguard Worker       // When the actual_bits and target_bits are far apart, binary search
4430*fb1b10abSAndroid Build Coastguard Worker       // q_index is faster.
4431*fb1b10abSAndroid Build Coastguard Worker       q_index = (rq_history->q_index_low + rq_history->q_index_high) / 2;
4432*fb1b10abSAndroid Build Coastguard Worker     } else {
4433*fb1b10abSAndroid Build Coastguard Worker       if (rq_model->ready) {
4434*fb1b10abSAndroid Build Coastguard Worker         q_index = guess_q_index_from_model(rq_model, target_bits);
4435*fb1b10abSAndroid Build Coastguard Worker       } else {
4436*fb1b10abSAndroid Build Coastguard Worker         // TODO(angiebird): Find a better way to set the gap.
4437*fb1b10abSAndroid Build Coastguard Worker         q_index =
4438*fb1b10abSAndroid Build Coastguard Worker             guess_q_index_linear(prev_q_index, target_bits, actual_bits, 20);
4439*fb1b10abSAndroid Build Coastguard Worker       }
4440*fb1b10abSAndroid Build Coastguard Worker     }
4441*fb1b10abSAndroid Build Coastguard Worker   } else {
4442*fb1b10abSAndroid Build Coastguard Worker     if (rq_model->ready) {
4443*fb1b10abSAndroid Build Coastguard Worker       q_index = guess_q_index_from_model(rq_model, target_bits);
4444*fb1b10abSAndroid Build Coastguard Worker     }
4445*fb1b10abSAndroid Build Coastguard Worker   }
4446*fb1b10abSAndroid Build Coastguard Worker 
4447*fb1b10abSAndroid Build Coastguard Worker   assert(rq_history->q_index_low <= rq_history->q_index_high);
4448*fb1b10abSAndroid Build Coastguard Worker   if (q_index <= rq_history->q_index_low) {
4449*fb1b10abSAndroid Build Coastguard Worker     q_index = rq_history->q_index_low + 1;
4450*fb1b10abSAndroid Build Coastguard Worker   }
4451*fb1b10abSAndroid Build Coastguard Worker   if (q_index >= rq_history->q_index_high) {
4452*fb1b10abSAndroid Build Coastguard Worker     q_index = rq_history->q_index_high - 1;
4453*fb1b10abSAndroid Build Coastguard Worker   }
4454*fb1b10abSAndroid Build Coastguard Worker   return q_index;
4455*fb1b10abSAndroid Build Coastguard Worker }
4456*fb1b10abSAndroid Build Coastguard Worker 
4457*fb1b10abSAndroid Build Coastguard Worker static void rq_model_update(const RATE_QINDEX_HISTORY *rq_history,
4458*fb1b10abSAndroid Build Coastguard Worker                             int target_bits, RATE_QSTEP_MODEL *rq_model) {
4459*fb1b10abSAndroid Build Coastguard Worker   const int recode_count = rq_history->recode_count;
4460*fb1b10abSAndroid Build Coastguard Worker   const double delta = 0.00001;
4461*fb1b10abSAndroid Build Coastguard Worker   if (recode_count >= 2) {
4462*fb1b10abSAndroid Build Coastguard Worker     const int q_index1 = rq_history->q_index_history[recode_count - 2];
4463*fb1b10abSAndroid Build Coastguard Worker     const int q_index2 = rq_history->q_index_history[recode_count - 1];
4464*fb1b10abSAndroid Build Coastguard Worker     const int r1 = rq_history->rate_history[recode_count - 2];
4465*fb1b10abSAndroid Build Coastguard Worker     const int r2 = rq_history->rate_history[recode_count - 1];
4466*fb1b10abSAndroid Build Coastguard Worker     int valid = 0;
4467*fb1b10abSAndroid Build Coastguard Worker     // lower q_index should yield higher bit rate
4468*fb1b10abSAndroid Build Coastguard Worker     if (q_index1 < q_index2) {
4469*fb1b10abSAndroid Build Coastguard Worker       valid = r1 > r2;
4470*fb1b10abSAndroid Build Coastguard Worker     } else if (q_index1 > q_index2) {
4471*fb1b10abSAndroid Build Coastguard Worker       valid = r1 < r2;
4472*fb1b10abSAndroid Build Coastguard Worker     }
4473*fb1b10abSAndroid Build Coastguard Worker     // Only update the model when the q_index and rate behave normally.
4474*fb1b10abSAndroid Build Coastguard Worker     if (valid) {
4475*fb1b10abSAndroid Build Coastguard Worker       // Fit the ratio and bias of rq_model based on last two recode histories.
4476*fb1b10abSAndroid Build Coastguard Worker       const double s1 = vp9_convert_qindex_to_q(q_index1, VPX_BITS_8);
4477*fb1b10abSAndroid Build Coastguard Worker       const double s2 = vp9_convert_qindex_to_q(q_index2, VPX_BITS_8);
4478*fb1b10abSAndroid Build Coastguard Worker       if (fabs(log2(s1) - log2(s2)) > delta) {
4479*fb1b10abSAndroid Build Coastguard Worker         rq_model->ratio = (r2 - r1) / (log2(s1) - log2(s2));
4480*fb1b10abSAndroid Build Coastguard Worker         rq_model->bias = r1 + (rq_model->ratio) * log2(s1);
4481*fb1b10abSAndroid Build Coastguard Worker         if (rq_model->ratio > delta && rq_model->bias > delta) {
4482*fb1b10abSAndroid Build Coastguard Worker           rq_model->ready = 1;
4483*fb1b10abSAndroid Build Coastguard Worker         }
4484*fb1b10abSAndroid Build Coastguard Worker       }
4485*fb1b10abSAndroid Build Coastguard Worker     }
4486*fb1b10abSAndroid Build Coastguard Worker   } else if (recode_count == 1) {
4487*fb1b10abSAndroid Build Coastguard Worker     if (rq_model->ready) {
4488*fb1b10abSAndroid Build Coastguard Worker       // Update the ratio only when the initial model exists and we only have
4489*fb1b10abSAndroid Build Coastguard Worker       // one recode history.
4490*fb1b10abSAndroid Build Coastguard Worker       const int prev_q = rq_history->q_index_history[recode_count - 1];
4491*fb1b10abSAndroid Build Coastguard Worker       const double prev_q_step = vp9_convert_qindex_to_q(prev_q, VPX_BITS_8);
4492*fb1b10abSAndroid Build Coastguard Worker       if (fabs(log2(prev_q_step)) > delta) {
4493*fb1b10abSAndroid Build Coastguard Worker         const int actual_bits = rq_history->rate_history[recode_count - 1];
4494*fb1b10abSAndroid Build Coastguard Worker         rq_model->ratio =
4495*fb1b10abSAndroid Build Coastguard Worker             rq_model->ratio + (target_bits - actual_bits) / log2(prev_q_step);
4496*fb1b10abSAndroid Build Coastguard Worker       }
4497*fb1b10abSAndroid Build Coastguard Worker     }
4498*fb1b10abSAndroid Build Coastguard Worker   }
4499*fb1b10abSAndroid Build Coastguard Worker }
4500*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
4501*fb1b10abSAndroid Build Coastguard Worker 
4502*fb1b10abSAndroid Build Coastguard Worker static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, uint8_t *dest,
4503*fb1b10abSAndroid Build Coastguard Worker                                     size_t dest_size
4504*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
4505*fb1b10abSAndroid Build Coastguard Worker                                     ,
4506*fb1b10abSAndroid Build Coastguard Worker                                     RATE_QINDEX_HISTORY *rq_history
4507*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
4508*fb1b10abSAndroid Build Coastguard Worker ) {
4509*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
4510*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
4511*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
4512*fb1b10abSAndroid Build Coastguard Worker   int bottom_index, top_index;
4513*fb1b10abSAndroid Build Coastguard Worker   int loop_count = 0;
4514*fb1b10abSAndroid Build Coastguard Worker   int loop_at_this_size = 0;
4515*fb1b10abSAndroid Build Coastguard Worker   int loop = 0;
4516*fb1b10abSAndroid Build Coastguard Worker   int overshoot_seen = 0;
4517*fb1b10abSAndroid Build Coastguard Worker   int undershoot_seen = 0;
4518*fb1b10abSAndroid Build Coastguard Worker   int frame_over_shoot_limit;
4519*fb1b10abSAndroid Build Coastguard Worker   int frame_under_shoot_limit;
4520*fb1b10abSAndroid Build Coastguard Worker   int q = 0, q_low = 0, q_high = 0;
4521*fb1b10abSAndroid Build Coastguard Worker   int enable_acl;
4522*fb1b10abSAndroid Build Coastguard Worker #ifdef AGGRESSIVE_VBR
4523*fb1b10abSAndroid Build Coastguard Worker   int qrange_adj = 1;
4524*fb1b10abSAndroid Build Coastguard Worker #endif
4525*fb1b10abSAndroid Build Coastguard Worker 
4526*fb1b10abSAndroid Build Coastguard Worker   const int orig_rc_max_frame_bandwidth = rc->max_frame_bandwidth;
4527*fb1b10abSAndroid Build Coastguard Worker 
4528*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
4529*fb1b10abSAndroid Build Coastguard Worker   RATE_QSTEP_MODEL *rq_model;
4530*fb1b10abSAndroid Build Coastguard Worker   {
4531*fb1b10abSAndroid Build Coastguard Worker     const FRAME_UPDATE_TYPE update_type =
4532*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index];
4533*fb1b10abSAndroid Build Coastguard Worker     const ENCODE_FRAME_TYPE frame_type = get_encode_frame_type(update_type);
4534*fb1b10abSAndroid Build Coastguard Worker     rq_model = &cpi->rq_model[frame_type];
4535*fb1b10abSAndroid Build Coastguard Worker   }
4536*fb1b10abSAndroid Build Coastguard Worker   init_rq_history(rq_history);
4537*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
4538*fb1b10abSAndroid Build Coastguard Worker 
4539*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame) {
4540*fb1b10abSAndroid Build Coastguard Worker     rc->this_frame_target = 0;
4541*fb1b10abSAndroid Build Coastguard Worker     if (is_psnr_calc_enabled(cpi)) set_raw_source_frame(cpi);
4542*fb1b10abSAndroid Build Coastguard Worker     return;
4543*fb1b10abSAndroid Build Coastguard Worker   }
4544*fb1b10abSAndroid Build Coastguard Worker 
4545*fb1b10abSAndroid Build Coastguard Worker   set_size_independent_vars(cpi);
4546*fb1b10abSAndroid Build Coastguard Worker 
4547*fb1b10abSAndroid Build Coastguard Worker   enable_acl = cpi->sf.allow_acl ? (cm->frame_type == KEY_FRAME) ||
4548*fb1b10abSAndroid Build Coastguard Worker                                        (cpi->twopass.gf_group.index == 1)
4549*fb1b10abSAndroid Build Coastguard Worker                                  : 0;
4550*fb1b10abSAndroid Build Coastguard Worker 
4551*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
4552*fb1b10abSAndroid Build Coastguard Worker   printf("\n Encoding a frame: \n");
4553*fb1b10abSAndroid Build Coastguard Worker #endif
4554*fb1b10abSAndroid Build Coastguard Worker   do {
4555*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
4556*fb1b10abSAndroid Build Coastguard Worker 
4557*fb1b10abSAndroid Build Coastguard Worker     set_frame_size(cpi);
4558*fb1b10abSAndroid Build Coastguard Worker 
4559*fb1b10abSAndroid Build Coastguard Worker     if (loop_count == 0 || cpi->resize_pending != 0) {
4560*fb1b10abSAndroid Build Coastguard Worker       set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
4561*fb1b10abSAndroid Build Coastguard Worker 
4562*fb1b10abSAndroid Build Coastguard Worker #ifdef AGGRESSIVE_VBR
4563*fb1b10abSAndroid Build Coastguard Worker       if (two_pass_first_group_inter(cpi)) {
4564*fb1b10abSAndroid Build Coastguard Worker         // Adjustment limits for min and max q
4565*fb1b10abSAndroid Build Coastguard Worker         qrange_adj = VPXMAX(1, (top_index - bottom_index) / 2);
4566*fb1b10abSAndroid Build Coastguard Worker 
4567*fb1b10abSAndroid Build Coastguard Worker         bottom_index =
4568*fb1b10abSAndroid Build Coastguard Worker             VPXMAX(bottom_index - qrange_adj / 2, oxcf->best_allowed_q);
4569*fb1b10abSAndroid Build Coastguard Worker         top_index = VPXMIN(oxcf->worst_allowed_q, top_index + qrange_adj / 2);
4570*fb1b10abSAndroid Build Coastguard Worker       }
4571*fb1b10abSAndroid Build Coastguard Worker #endif
4572*fb1b10abSAndroid Build Coastguard Worker       // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
4573*fb1b10abSAndroid Build Coastguard Worker       set_mv_search_params(cpi);
4574*fb1b10abSAndroid Build Coastguard Worker 
4575*fb1b10abSAndroid Build Coastguard Worker       // Reset the loop state for new frame size.
4576*fb1b10abSAndroid Build Coastguard Worker       overshoot_seen = 0;
4577*fb1b10abSAndroid Build Coastguard Worker       undershoot_seen = 0;
4578*fb1b10abSAndroid Build Coastguard Worker 
4579*fb1b10abSAndroid Build Coastguard Worker       // Reconfiguration for change in frame size has concluded.
4580*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_pending = 0;
4581*fb1b10abSAndroid Build Coastguard Worker 
4582*fb1b10abSAndroid Build Coastguard Worker       q_low = bottom_index;
4583*fb1b10abSAndroid Build Coastguard Worker       q_high = top_index;
4584*fb1b10abSAndroid Build Coastguard Worker 
4585*fb1b10abSAndroid Build Coastguard Worker       loop_at_this_size = 0;
4586*fb1b10abSAndroid Build Coastguard Worker     }
4587*fb1b10abSAndroid Build Coastguard Worker 
4588*fb1b10abSAndroid Build Coastguard Worker     // Decide frame size bounds first time through.
4589*fb1b10abSAndroid Build Coastguard Worker     if (loop_count == 0) {
4590*fb1b10abSAndroid Build Coastguard Worker       vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
4591*fb1b10abSAndroid Build Coastguard Worker                                        &frame_under_shoot_limit,
4592*fb1b10abSAndroid Build Coastguard Worker                                        &frame_over_shoot_limit);
4593*fb1b10abSAndroid Build Coastguard Worker     }
4594*fb1b10abSAndroid Build Coastguard Worker 
4595*fb1b10abSAndroid Build Coastguard Worker     cpi->Source =
4596*fb1b10abSAndroid Build Coastguard Worker         vp9_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source,
4597*fb1b10abSAndroid Build Coastguard Worker                               (oxcf->pass == 0), EIGHTTAP, 0);
4598*fb1b10abSAndroid Build Coastguard Worker 
4599*fb1b10abSAndroid Build Coastguard Worker     // Unfiltered raw source used in metrics calculation if the source
4600*fb1b10abSAndroid Build Coastguard Worker     // has been filtered.
4601*fb1b10abSAndroid Build Coastguard Worker     if (is_psnr_calc_enabled(cpi)) {
4602*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
4603*fb1b10abSAndroid Build Coastguard Worker       if (is_spatial_denoise_enabled(cpi)) {
4604*fb1b10abSAndroid Build Coastguard Worker         cpi->raw_source_frame = vp9_scale_if_required(
4605*fb1b10abSAndroid Build Coastguard Worker             cm, &cpi->raw_unscaled_source, &cpi->raw_scaled_source,
4606*fb1b10abSAndroid Build Coastguard Worker             (oxcf->pass == 0), EIGHTTAP, 0);
4607*fb1b10abSAndroid Build Coastguard Worker       } else {
4608*fb1b10abSAndroid Build Coastguard Worker         cpi->raw_source_frame = cpi->Source;
4609*fb1b10abSAndroid Build Coastguard Worker       }
4610*fb1b10abSAndroid Build Coastguard Worker #else
4611*fb1b10abSAndroid Build Coastguard Worker       cpi->raw_source_frame = cpi->Source;
4612*fb1b10abSAndroid Build Coastguard Worker #endif
4613*fb1b10abSAndroid Build Coastguard Worker     }
4614*fb1b10abSAndroid Build Coastguard Worker 
4615*fb1b10abSAndroid Build Coastguard Worker     if (cpi->unscaled_last_source != NULL)
4616*fb1b10abSAndroid Build Coastguard Worker       cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
4617*fb1b10abSAndroid Build Coastguard Worker                                                &cpi->scaled_last_source,
4618*fb1b10abSAndroid Build Coastguard Worker                                                (oxcf->pass == 0), EIGHTTAP, 0);
4619*fb1b10abSAndroid Build Coastguard Worker 
4620*fb1b10abSAndroid Build Coastguard Worker     if (frame_is_intra_only(cm) == 0) {
4621*fb1b10abSAndroid Build Coastguard Worker       if (loop_count > 0) {
4622*fb1b10abSAndroid Build Coastguard Worker         release_scaled_references(cpi);
4623*fb1b10abSAndroid Build Coastguard Worker       }
4624*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_references(cpi);
4625*fb1b10abSAndroid Build Coastguard Worker     }
4626*fb1b10abSAndroid Build Coastguard Worker 
4627*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
4628*fb1b10abSAndroid Build Coastguard Worker     // TODO(angiebird): This is a hack for making sure the encoder use the
4629*fb1b10abSAndroid Build Coastguard Worker     // external_quantize_index exactly. Avoid this kind of hack later.
4630*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.use_simple_encode_api) {
4631*fb1b10abSAndroid Build Coastguard Worker       if (cpi->encode_command.use_external_target_frame_bits) {
4632*fb1b10abSAndroid Build Coastguard Worker         q = rq_model_predict_q_index(rq_model, rq_history,
4633*fb1b10abSAndroid Build Coastguard Worker                                      rc->this_frame_target);
4634*fb1b10abSAndroid Build Coastguard Worker       }
4635*fb1b10abSAndroid Build Coastguard Worker       if (cpi->encode_command.use_external_quantize_index) {
4636*fb1b10abSAndroid Build Coastguard Worker         q = cpi->encode_command.external_quantize_index;
4637*fb1b10abSAndroid Build Coastguard Worker       }
4638*fb1b10abSAndroid Build Coastguard Worker     }
4639*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
4640*fb1b10abSAndroid Build Coastguard Worker     const GF_GROUP *gf_group = &cpi->twopass.gf_group;
4641*fb1b10abSAndroid Build Coastguard Worker     if (cpi->ext_ratectrl.ready &&
4642*fb1b10abSAndroid Build Coastguard Worker         (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_QP) != 0 &&
4643*fb1b10abSAndroid Build Coastguard Worker         cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL) {
4644*fb1b10abSAndroid Build Coastguard Worker       vpx_codec_err_t codec_status;
4645*fb1b10abSAndroid Build Coastguard Worker       vpx_rc_encodeframe_decision_t encode_frame_decision;
4646*fb1b10abSAndroid Build Coastguard Worker       codec_status = vp9_extrc_get_encodeframe_decision(
4647*fb1b10abSAndroid Build Coastguard Worker           &cpi->ext_ratectrl, gf_group->index, &encode_frame_decision);
4648*fb1b10abSAndroid Build Coastguard Worker       if (codec_status != VPX_CODEC_OK) {
4649*fb1b10abSAndroid Build Coastguard Worker         vpx_internal_error(&cm->error, codec_status,
4650*fb1b10abSAndroid Build Coastguard Worker                            "vp9_extrc_get_encodeframe_decision() failed");
4651*fb1b10abSAndroid Build Coastguard Worker       }
4652*fb1b10abSAndroid Build Coastguard Worker       // If the external model recommends a reserved value, we use
4653*fb1b10abSAndroid Build Coastguard Worker       // libvpx's default q.
4654*fb1b10abSAndroid Build Coastguard Worker       if (encode_frame_decision.q_index != VPX_DEFAULT_Q) {
4655*fb1b10abSAndroid Build Coastguard Worker         q = encode_frame_decision.q_index;
4656*fb1b10abSAndroid Build Coastguard Worker       }
4657*fb1b10abSAndroid Build Coastguard Worker     }
4658*fb1b10abSAndroid Build Coastguard Worker 
4659*fb1b10abSAndroid Build Coastguard Worker     if (cpi->ext_ratectrl.ready && cpi->ext_ratectrl.log_file) {
4660*fb1b10abSAndroid Build Coastguard Worker       fprintf(cpi->ext_ratectrl.log_file,
4661*fb1b10abSAndroid Build Coastguard Worker               "ENCODE_FRAME_INFO gop_index %d update_type %d q %d\n",
4662*fb1b10abSAndroid Build Coastguard Worker               gf_group->index, gf_group->update_type[gf_group->index], q);
4663*fb1b10abSAndroid Build Coastguard Worker     }
4664*fb1b10abSAndroid Build Coastguard Worker 
4665*fb1b10abSAndroid Build Coastguard Worker     vp9_set_quantizer(cpi, q);
4666*fb1b10abSAndroid Build Coastguard Worker 
4667*fb1b10abSAndroid Build Coastguard Worker     if (loop_count == 0) setup_frame(cpi);
4668*fb1b10abSAndroid Build Coastguard Worker 
4669*fb1b10abSAndroid Build Coastguard Worker     // Variance adaptive and in frame q adjustment experiments are mutually
4670*fb1b10abSAndroid Build Coastguard Worker     // exclusive.
4671*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->aq_mode == VARIANCE_AQ) {
4672*fb1b10abSAndroid Build Coastguard Worker       vp9_vaq_frame_setup(cpi);
4673*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->aq_mode == EQUATOR360_AQ) {
4674*fb1b10abSAndroid Build Coastguard Worker       vp9_360aq_frame_setup(cpi);
4675*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->aq_mode == COMPLEXITY_AQ) {
4676*fb1b10abSAndroid Build Coastguard Worker       vp9_setup_in_frame_q_adj(cpi);
4677*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->aq_mode == LOOKAHEAD_AQ) {
4678*fb1b10abSAndroid Build Coastguard Worker       vp9_alt_ref_aq_setup_map(cpi->alt_ref_aq, cpi);
4679*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->aq_mode == PSNR_AQ) {
4680*fb1b10abSAndroid Build Coastguard Worker       vp9_psnr_aq_mode_setup(&cm->seg);
4681*fb1b10abSAndroid Build Coastguard Worker     }
4682*fb1b10abSAndroid Build Coastguard Worker 
4683*fb1b10abSAndroid Build Coastguard Worker     vp9_encode_frame(cpi);
4684*fb1b10abSAndroid Build Coastguard Worker 
4685*fb1b10abSAndroid Build Coastguard Worker     // Update the skip mb flag probabilities based on the distribution
4686*fb1b10abSAndroid Build Coastguard Worker     // seen in the last encoder iteration.
4687*fb1b10abSAndroid Build Coastguard Worker     // update_base_skip_probs(cpi);
4688*fb1b10abSAndroid Build Coastguard Worker 
4689*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
4690*fb1b10abSAndroid Build Coastguard Worker 
4691*fb1b10abSAndroid Build Coastguard Worker     // Dummy pack of the bitstream using up to date stats to get an
4692*fb1b10abSAndroid Build Coastguard Worker     // accurate estimate of output frame size to determine if we need
4693*fb1b10abSAndroid Build Coastguard Worker     // to recode.
4694*fb1b10abSAndroid Build Coastguard Worker     if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4695*fb1b10abSAndroid Build Coastguard Worker       save_coding_context(cpi);
4696*fb1b10abSAndroid Build Coastguard Worker       if (!cpi->sf.use_nonrd_pick_mode)
4697*fb1b10abSAndroid Build Coastguard Worker         vp9_pack_bitstream(cpi, dest, dest_size, size);
4698*fb1b10abSAndroid Build Coastguard Worker 
4699*fb1b10abSAndroid Build Coastguard Worker       rc->projected_frame_size = (int)(*size) << 3;
4700*fb1b10abSAndroid Build Coastguard Worker 
4701*fb1b10abSAndroid Build Coastguard Worker       if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
4702*fb1b10abSAndroid Build Coastguard Worker     }
4703*fb1b10abSAndroid Build Coastguard Worker 
4704*fb1b10abSAndroid Build Coastguard Worker     if (cpi->ext_ratectrl.ready &&
4705*fb1b10abSAndroid Build Coastguard Worker         (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_QP) != 0) {
4706*fb1b10abSAndroid Build Coastguard Worker       break;
4707*fb1b10abSAndroid Build Coastguard Worker     }
4708*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
4709*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.use_simple_encode_api) {
4710*fb1b10abSAndroid Build Coastguard Worker       // This part needs to be after save_coding_context() because
4711*fb1b10abSAndroid Build Coastguard Worker       // restore_coding_context will be called in the end of this function.
4712*fb1b10abSAndroid Build Coastguard Worker       // TODO(angiebird): This is a hack for making sure the encoder use the
4713*fb1b10abSAndroid Build Coastguard Worker       // external_quantize_index exactly. Avoid this kind of hack later.
4714*fb1b10abSAndroid Build Coastguard Worker       if (cpi->encode_command.use_external_quantize_index) {
4715*fb1b10abSAndroid Build Coastguard Worker         break;
4716*fb1b10abSAndroid Build Coastguard Worker       }
4717*fb1b10abSAndroid Build Coastguard Worker 
4718*fb1b10abSAndroid Build Coastguard Worker       if (cpi->encode_command.use_external_target_frame_bits) {
4719*fb1b10abSAndroid Build Coastguard Worker         const double percent_diff = get_bits_percent_diff(
4720*fb1b10abSAndroid Build Coastguard Worker             rc->this_frame_target, rc->projected_frame_size);
4721*fb1b10abSAndroid Build Coastguard Worker         update_rq_history(rq_history, rc->this_frame_target,
4722*fb1b10abSAndroid Build Coastguard Worker                           rc->projected_frame_size, q);
4723*fb1b10abSAndroid Build Coastguard Worker         loop_count += 1;
4724*fb1b10abSAndroid Build Coastguard Worker 
4725*fb1b10abSAndroid Build Coastguard Worker         rq_model_update(rq_history, rc->this_frame_target, rq_model);
4726*fb1b10abSAndroid Build Coastguard Worker 
4727*fb1b10abSAndroid Build Coastguard Worker         // Check if we hit the target bitrate.
4728*fb1b10abSAndroid Build Coastguard Worker         if (percent_diff <=
4729*fb1b10abSAndroid Build Coastguard Worker                 cpi->encode_command.target_frame_bits_error_percent ||
4730*fb1b10abSAndroid Build Coastguard Worker             rq_history->recode_count >= RATE_CTRL_MAX_RECODE_NUM ||
4731*fb1b10abSAndroid Build Coastguard Worker             rq_history->q_index_low >= rq_history->q_index_high) {
4732*fb1b10abSAndroid Build Coastguard Worker           break;
4733*fb1b10abSAndroid Build Coastguard Worker         }
4734*fb1b10abSAndroid Build Coastguard Worker 
4735*fb1b10abSAndroid Build Coastguard Worker         loop = 1;
4736*fb1b10abSAndroid Build Coastguard Worker         restore_coding_context(cpi);
4737*fb1b10abSAndroid Build Coastguard Worker         continue;
4738*fb1b10abSAndroid Build Coastguard Worker       }
4739*fb1b10abSAndroid Build Coastguard Worker     }
4740*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
4741*fb1b10abSAndroid Build Coastguard Worker 
4742*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->rc_mode == VPX_Q) {
4743*fb1b10abSAndroid Build Coastguard Worker       loop = 0;
4744*fb1b10abSAndroid Build Coastguard Worker     } else {
4745*fb1b10abSAndroid Build Coastguard Worker       if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
4746*fb1b10abSAndroid Build Coastguard Worker           (rc->projected_frame_size < rc->max_frame_bandwidth)) {
4747*fb1b10abSAndroid Build Coastguard Worker         int last_q = q;
4748*fb1b10abSAndroid Build Coastguard Worker         int64_t kf_err;
4749*fb1b10abSAndroid Build Coastguard Worker 
4750*fb1b10abSAndroid Build Coastguard Worker         int64_t high_err_target = cpi->ambient_err;
4751*fb1b10abSAndroid Build Coastguard Worker         int64_t low_err_target = cpi->ambient_err >> 1;
4752*fb1b10abSAndroid Build Coastguard Worker 
4753*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
4754*fb1b10abSAndroid Build Coastguard Worker         if (cm->use_highbitdepth) {
4755*fb1b10abSAndroid Build Coastguard Worker           kf_err = vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4756*fb1b10abSAndroid Build Coastguard Worker         } else {
4757*fb1b10abSAndroid Build Coastguard Worker           kf_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4758*fb1b10abSAndroid Build Coastguard Worker         }
4759*fb1b10abSAndroid Build Coastguard Worker #else
4760*fb1b10abSAndroid Build Coastguard Worker         kf_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4761*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
4762*fb1b10abSAndroid Build Coastguard Worker 
4763*fb1b10abSAndroid Build Coastguard Worker         // Prevent possible divide by zero error below for perfect KF
4764*fb1b10abSAndroid Build Coastguard Worker         kf_err += !kf_err;
4765*fb1b10abSAndroid Build Coastguard Worker 
4766*fb1b10abSAndroid Build Coastguard Worker         // The key frame is not good enough or we can afford
4767*fb1b10abSAndroid Build Coastguard Worker         // to make it better without undue risk of popping.
4768*fb1b10abSAndroid Build Coastguard Worker         if ((kf_err > high_err_target &&
4769*fb1b10abSAndroid Build Coastguard Worker              rc->projected_frame_size <= frame_over_shoot_limit) ||
4770*fb1b10abSAndroid Build Coastguard Worker             (kf_err > low_err_target &&
4771*fb1b10abSAndroid Build Coastguard Worker              rc->projected_frame_size <= frame_under_shoot_limit)) {
4772*fb1b10abSAndroid Build Coastguard Worker           // Lower q_high
4773*fb1b10abSAndroid Build Coastguard Worker           q_high = q > q_low ? q - 1 : q_low;
4774*fb1b10abSAndroid Build Coastguard Worker 
4775*fb1b10abSAndroid Build Coastguard Worker           // Adjust Q
4776*fb1b10abSAndroid Build Coastguard Worker           q = (int)((q * high_err_target) / kf_err);
4777*fb1b10abSAndroid Build Coastguard Worker           q = VPXMIN(q, (q_high + q_low) >> 1);
4778*fb1b10abSAndroid Build Coastguard Worker         } else if (kf_err < low_err_target &&
4779*fb1b10abSAndroid Build Coastguard Worker                    rc->projected_frame_size >= frame_under_shoot_limit) {
4780*fb1b10abSAndroid Build Coastguard Worker           // The key frame is much better than the previous frame
4781*fb1b10abSAndroid Build Coastguard Worker           // Raise q_low
4782*fb1b10abSAndroid Build Coastguard Worker           q_low = q < q_high ? q + 1 : q_high;
4783*fb1b10abSAndroid Build Coastguard Worker 
4784*fb1b10abSAndroid Build Coastguard Worker           // Adjust Q
4785*fb1b10abSAndroid Build Coastguard Worker           q = (int)((q * low_err_target) / kf_err);
4786*fb1b10abSAndroid Build Coastguard Worker           q = VPXMIN(q, (q_high + q_low + 1) >> 1);
4787*fb1b10abSAndroid Build Coastguard Worker         }
4788*fb1b10abSAndroid Build Coastguard Worker 
4789*fb1b10abSAndroid Build Coastguard Worker         // Clamp Q to upper and lower limits:
4790*fb1b10abSAndroid Build Coastguard Worker         q = clamp(q, q_low, q_high);
4791*fb1b10abSAndroid Build Coastguard Worker 
4792*fb1b10abSAndroid Build Coastguard Worker         loop = q != last_q;
4793*fb1b10abSAndroid Build Coastguard Worker       } else if (recode_loop_test(cpi, frame_over_shoot_limit,
4794*fb1b10abSAndroid Build Coastguard Worker                                   frame_under_shoot_limit, q,
4795*fb1b10abSAndroid Build Coastguard Worker                                   VPXMAX(q_high, top_index), bottom_index)) {
4796*fb1b10abSAndroid Build Coastguard Worker         // Is the projected frame size out of range and are we allowed
4797*fb1b10abSAndroid Build Coastguard Worker         // to attempt to recode.
4798*fb1b10abSAndroid Build Coastguard Worker         int last_q = q;
4799*fb1b10abSAndroid Build Coastguard Worker         int retries = 0;
4800*fb1b10abSAndroid Build Coastguard Worker         int qstep;
4801*fb1b10abSAndroid Build Coastguard Worker 
4802*fb1b10abSAndroid Build Coastguard Worker         if (cpi->resize_pending == 1) {
4803*fb1b10abSAndroid Build Coastguard Worker           // Change in frame size so go back around the recode loop.
4804*fb1b10abSAndroid Build Coastguard Worker           cpi->rc.frame_size_selector =
4805*fb1b10abSAndroid Build Coastguard Worker               SCALE_STEP1 - cpi->rc.frame_size_selector;
4806*fb1b10abSAndroid Build Coastguard Worker           cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector;
4807*fb1b10abSAndroid Build Coastguard Worker 
4808*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
4809*fb1b10abSAndroid Build Coastguard Worker           ++cpi->tot_recode_hits;
4810*fb1b10abSAndroid Build Coastguard Worker #endif
4811*fb1b10abSAndroid Build Coastguard Worker           ++loop_count;
4812*fb1b10abSAndroid Build Coastguard Worker           loop = 1;
4813*fb1b10abSAndroid Build Coastguard Worker           continue;
4814*fb1b10abSAndroid Build Coastguard Worker         }
4815*fb1b10abSAndroid Build Coastguard Worker 
4816*fb1b10abSAndroid Build Coastguard Worker         // Frame size out of permitted range:
4817*fb1b10abSAndroid Build Coastguard Worker         // Update correction factor & compute new Q to try...
4818*fb1b10abSAndroid Build Coastguard Worker 
4819*fb1b10abSAndroid Build Coastguard Worker         // Frame is too large
4820*fb1b10abSAndroid Build Coastguard Worker         if (rc->projected_frame_size > rc->this_frame_target) {
4821*fb1b10abSAndroid Build Coastguard Worker           // Special case if the projected size is > the max allowed.
4822*fb1b10abSAndroid Build Coastguard Worker           if ((q == q_high) &&
4823*fb1b10abSAndroid Build Coastguard Worker               ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
4824*fb1b10abSAndroid Build Coastguard Worker                (!rc->is_src_frame_alt_ref &&
4825*fb1b10abSAndroid Build Coastguard Worker                 (rc->projected_frame_size >=
4826*fb1b10abSAndroid Build Coastguard Worker                  big_rate_miss_high_threshold(cpi))))) {
4827*fb1b10abSAndroid Build Coastguard Worker             int max_rate = VPXMAX(1, VPXMIN(rc->max_frame_bandwidth,
4828*fb1b10abSAndroid Build Coastguard Worker                                             big_rate_miss_high_threshold(cpi)));
4829*fb1b10abSAndroid Build Coastguard Worker             double q_val_high;
4830*fb1b10abSAndroid Build Coastguard Worker             q_val_high = vp9_convert_qindex_to_q(q_high, cm->bit_depth);
4831*fb1b10abSAndroid Build Coastguard Worker             q_val_high =
4832*fb1b10abSAndroid Build Coastguard Worker                 q_val_high * ((double)rc->projected_frame_size / max_rate);
4833*fb1b10abSAndroid Build Coastguard Worker             q_high = vp9_convert_q_to_qindex(q_val_high, cm->bit_depth);
4834*fb1b10abSAndroid Build Coastguard Worker             q_high = clamp(q_high, rc->best_quality, rc->worst_quality);
4835*fb1b10abSAndroid Build Coastguard Worker           }
4836*fb1b10abSAndroid Build Coastguard Worker 
4837*fb1b10abSAndroid Build Coastguard Worker           // Raise Qlow as to at least the current value
4838*fb1b10abSAndroid Build Coastguard Worker           qstep =
4839*fb1b10abSAndroid Build Coastguard Worker               get_qstep_adj(rc->projected_frame_size, rc->this_frame_target);
4840*fb1b10abSAndroid Build Coastguard Worker           q_low = VPXMIN(q + qstep, q_high);
4841*fb1b10abSAndroid Build Coastguard Worker 
4842*fb1b10abSAndroid Build Coastguard Worker           if (undershoot_seen || loop_at_this_size > 1) {
4843*fb1b10abSAndroid Build Coastguard Worker             // Update rate_correction_factor unless
4844*fb1b10abSAndroid Build Coastguard Worker             vp9_rc_update_rate_correction_factors(cpi);
4845*fb1b10abSAndroid Build Coastguard Worker 
4846*fb1b10abSAndroid Build Coastguard Worker             q = (q_high + q_low + 1) / 2;
4847*fb1b10abSAndroid Build Coastguard Worker           } else {
4848*fb1b10abSAndroid Build Coastguard Worker             // Update rate_correction_factor unless
4849*fb1b10abSAndroid Build Coastguard Worker             vp9_rc_update_rate_correction_factors(cpi);
4850*fb1b10abSAndroid Build Coastguard Worker 
4851*fb1b10abSAndroid Build Coastguard Worker             q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4852*fb1b10abSAndroid Build Coastguard Worker                                   VPXMAX(q_high, top_index));
4853*fb1b10abSAndroid Build Coastguard Worker 
4854*fb1b10abSAndroid Build Coastguard Worker             while (q < q_low && retries < 10) {
4855*fb1b10abSAndroid Build Coastguard Worker               vp9_rc_update_rate_correction_factors(cpi);
4856*fb1b10abSAndroid Build Coastguard Worker               q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4857*fb1b10abSAndroid Build Coastguard Worker                                     VPXMAX(q_high, top_index));
4858*fb1b10abSAndroid Build Coastguard Worker               retries++;
4859*fb1b10abSAndroid Build Coastguard Worker             }
4860*fb1b10abSAndroid Build Coastguard Worker           }
4861*fb1b10abSAndroid Build Coastguard Worker 
4862*fb1b10abSAndroid Build Coastguard Worker           overshoot_seen = 1;
4863*fb1b10abSAndroid Build Coastguard Worker         } else {
4864*fb1b10abSAndroid Build Coastguard Worker           // Frame is too small
4865*fb1b10abSAndroid Build Coastguard Worker           qstep =
4866*fb1b10abSAndroid Build Coastguard Worker               get_qstep_adj(rc->this_frame_target, rc->projected_frame_size);
4867*fb1b10abSAndroid Build Coastguard Worker           q_high = VPXMAX(q - qstep, q_low);
4868*fb1b10abSAndroid Build Coastguard Worker 
4869*fb1b10abSAndroid Build Coastguard Worker           if (overshoot_seen || loop_at_this_size > 1) {
4870*fb1b10abSAndroid Build Coastguard Worker             vp9_rc_update_rate_correction_factors(cpi);
4871*fb1b10abSAndroid Build Coastguard Worker             q = (q_high + q_low) / 2;
4872*fb1b10abSAndroid Build Coastguard Worker           } else {
4873*fb1b10abSAndroid Build Coastguard Worker             vp9_rc_update_rate_correction_factors(cpi);
4874*fb1b10abSAndroid Build Coastguard Worker             q = vp9_rc_regulate_q(cpi, rc->this_frame_target,
4875*fb1b10abSAndroid Build Coastguard Worker                                   VPXMIN(q_low, bottom_index), top_index);
4876*fb1b10abSAndroid Build Coastguard Worker             // Special case reset for qlow for constrained quality.
4877*fb1b10abSAndroid Build Coastguard Worker             // This should only trigger where there is very substantial
4878*fb1b10abSAndroid Build Coastguard Worker             // undershoot on a frame and the auto cq level is above
4879*fb1b10abSAndroid Build Coastguard Worker             // the user passed in value.
4880*fb1b10abSAndroid Build Coastguard Worker             if (oxcf->rc_mode == VPX_CQ && q < q_low) {
4881*fb1b10abSAndroid Build Coastguard Worker               q_low = q;
4882*fb1b10abSAndroid Build Coastguard Worker             }
4883*fb1b10abSAndroid Build Coastguard Worker 
4884*fb1b10abSAndroid Build Coastguard Worker             while (q > q_high && retries < 10) {
4885*fb1b10abSAndroid Build Coastguard Worker               vp9_rc_update_rate_correction_factors(cpi);
4886*fb1b10abSAndroid Build Coastguard Worker               q = vp9_rc_regulate_q(cpi, rc->this_frame_target,
4887*fb1b10abSAndroid Build Coastguard Worker                                     VPXMIN(q_low, bottom_index), top_index);
4888*fb1b10abSAndroid Build Coastguard Worker               retries++;
4889*fb1b10abSAndroid Build Coastguard Worker             }
4890*fb1b10abSAndroid Build Coastguard Worker           }
4891*fb1b10abSAndroid Build Coastguard Worker           undershoot_seen = 1;
4892*fb1b10abSAndroid Build Coastguard Worker         }
4893*fb1b10abSAndroid Build Coastguard Worker 
4894*fb1b10abSAndroid Build Coastguard Worker         // Clamp Q to upper and lower limits:
4895*fb1b10abSAndroid Build Coastguard Worker         q = clamp(q, q_low, q_high);
4896*fb1b10abSAndroid Build Coastguard Worker 
4897*fb1b10abSAndroid Build Coastguard Worker         loop = (q != last_q);
4898*fb1b10abSAndroid Build Coastguard Worker       } else {
4899*fb1b10abSAndroid Build Coastguard Worker         loop = 0;
4900*fb1b10abSAndroid Build Coastguard Worker       }
4901*fb1b10abSAndroid Build Coastguard Worker     }
4902*fb1b10abSAndroid Build Coastguard Worker 
4903*fb1b10abSAndroid Build Coastguard Worker     // Special case for overlay frame.
4904*fb1b10abSAndroid Build Coastguard Worker     if (rc->is_src_frame_alt_ref &&
4905*fb1b10abSAndroid Build Coastguard Worker         rc->projected_frame_size < rc->max_frame_bandwidth)
4906*fb1b10abSAndroid Build Coastguard Worker       loop = 0;
4907*fb1b10abSAndroid Build Coastguard Worker 
4908*fb1b10abSAndroid Build Coastguard Worker     if (loop) {
4909*fb1b10abSAndroid Build Coastguard Worker       ++loop_count;
4910*fb1b10abSAndroid Build Coastguard Worker       ++loop_at_this_size;
4911*fb1b10abSAndroid Build Coastguard Worker 
4912*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
4913*fb1b10abSAndroid Build Coastguard Worker       ++cpi->tot_recode_hits;
4914*fb1b10abSAndroid Build Coastguard Worker #endif
4915*fb1b10abSAndroid Build Coastguard Worker     }
4916*fb1b10abSAndroid Build Coastguard Worker 
4917*fb1b10abSAndroid Build Coastguard Worker     if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF)
4918*fb1b10abSAndroid Build Coastguard Worker       if (loop) restore_coding_context(cpi);
4919*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
4920*fb1b10abSAndroid Build Coastguard Worker     if (loop) printf("\n Recoding:");
4921*fb1b10abSAndroid Build Coastguard Worker #endif
4922*fb1b10abSAndroid Build Coastguard Worker   } while (loop);
4923*fb1b10abSAndroid Build Coastguard Worker 
4924*fb1b10abSAndroid Build Coastguard Worker   rc->max_frame_bandwidth = orig_rc_max_frame_bandwidth;
4925*fb1b10abSAndroid Build Coastguard Worker 
4926*fb1b10abSAndroid Build Coastguard Worker #ifdef AGGRESSIVE_VBR
4927*fb1b10abSAndroid Build Coastguard Worker   if (two_pass_first_group_inter(cpi)) {
4928*fb1b10abSAndroid Build Coastguard Worker     cpi->twopass.active_worst_quality =
4929*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(q + qrange_adj, oxcf->worst_allowed_q);
4930*fb1b10abSAndroid Build Coastguard Worker   } else if (!frame_is_kf_gf_arf(cpi)) {
4931*fb1b10abSAndroid Build Coastguard Worker #else
4932*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_kf_gf_arf(cpi)) {
4933*fb1b10abSAndroid Build Coastguard Worker #endif
4934*fb1b10abSAndroid Build Coastguard Worker     // Have we been forced to adapt Q outside the expected range by an extreme
4935*fb1b10abSAndroid Build Coastguard Worker     // rate miss. If so adjust the active maxQ for the subsequent frames.
4936*fb1b10abSAndroid Build Coastguard Worker     if (!rc->is_src_frame_alt_ref && (q > cpi->twopass.active_worst_quality)) {
4937*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.active_worst_quality = q;
4938*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->vbr_corpus_complexity && q == q_low &&
4939*fb1b10abSAndroid Build Coastguard Worker                rc->projected_frame_size < rc->this_frame_target) {
4940*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.active_worst_quality =
4941*fb1b10abSAndroid Build Coastguard Worker           VPXMAX(q, cpi->twopass.active_worst_quality - 1);
4942*fb1b10abSAndroid Build Coastguard Worker     }
4943*fb1b10abSAndroid Build Coastguard Worker   }
4944*fb1b10abSAndroid Build Coastguard Worker 
4945*fb1b10abSAndroid Build Coastguard Worker   if (enable_acl) {
4946*fb1b10abSAndroid Build Coastguard Worker     // Skip recoding, if model diff is below threshold
4947*fb1b10abSAndroid Build Coastguard Worker     const int thresh = compute_context_model_thresh(cpi);
4948*fb1b10abSAndroid Build Coastguard Worker     const int diff = compute_context_model_diff(cm);
4949*fb1b10abSAndroid Build Coastguard Worker     if (diff >= thresh) {
4950*fb1b10abSAndroid Build Coastguard Worker       vp9_encode_frame(cpi);
4951*fb1b10abSAndroid Build Coastguard Worker     }
4952*fb1b10abSAndroid Build Coastguard Worker   }
4953*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4954*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
4955*fb1b10abSAndroid Build Coastguard Worker     restore_coding_context(cpi);
4956*fb1b10abSAndroid Build Coastguard Worker   }
4957*fb1b10abSAndroid Build Coastguard Worker }
4958*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
4959*fb1b10abSAndroid Build Coastguard Worker 
4960*fb1b10abSAndroid Build Coastguard Worker static void set_ext_overrides(VP9_COMP *cpi) {
4961*fb1b10abSAndroid Build Coastguard Worker   // Overrides the defaults with the externally supplied values with
4962*fb1b10abSAndroid Build Coastguard Worker   // vp9_update_reference() and vp9_update_entropy() calls
4963*fb1b10abSAndroid Build Coastguard Worker   // Note: The overrides are valid only for the next frame passed
4964*fb1b10abSAndroid Build Coastguard Worker   // to encode_frame_to_data_rate() function
4965*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_refresh_frame_context_pending) {
4966*fb1b10abSAndroid Build Coastguard Worker     cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context;
4967*fb1b10abSAndroid Build Coastguard Worker     cpi->ext_refresh_frame_context_pending = 0;
4968*fb1b10abSAndroid Build Coastguard Worker   }
4969*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_refresh_frame_flags_pending) {
4970*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
4971*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
4972*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
4973*fb1b10abSAndroid Build Coastguard Worker   }
4974*fb1b10abSAndroid Build Coastguard Worker }
4975*fb1b10abSAndroid Build Coastguard Worker 
4976*fb1b10abSAndroid Build Coastguard Worker YV12_BUFFER_CONFIG *vp9_scale_if_required(
4977*fb1b10abSAndroid Build Coastguard Worker     VP9_COMMON *cm, YV12_BUFFER_CONFIG *unscaled, YV12_BUFFER_CONFIG *scaled,
4978*fb1b10abSAndroid Build Coastguard Worker     int use_normative_scaler, INTERP_FILTER filter_type, int phase_scaler) {
4979*fb1b10abSAndroid Build Coastguard Worker   if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4980*fb1b10abSAndroid Build Coastguard Worker       cm->mi_rows * MI_SIZE != unscaled->y_height) {
4981*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
4982*fb1b10abSAndroid Build Coastguard Worker     if (use_normative_scaler && unscaled->y_width <= (scaled->y_width << 1) &&
4983*fb1b10abSAndroid Build Coastguard Worker         unscaled->y_height <= (scaled->y_height << 1))
4984*fb1b10abSAndroid Build Coastguard Worker       if (cm->bit_depth == VPX_BITS_8)
4985*fb1b10abSAndroid Build Coastguard Worker         vp9_scale_and_extend_frame(unscaled, scaled, filter_type, phase_scaler);
4986*fb1b10abSAndroid Build Coastguard Worker       else
4987*fb1b10abSAndroid Build Coastguard Worker         scale_and_extend_frame(unscaled, scaled, (int)cm->bit_depth,
4988*fb1b10abSAndroid Build Coastguard Worker                                filter_type, phase_scaler);
4989*fb1b10abSAndroid Build Coastguard Worker     else
4990*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_and_extend_frame_nonnormative(unscaled, scaled,
4991*fb1b10abSAndroid Build Coastguard Worker                                               (int)cm->bit_depth);
4992*fb1b10abSAndroid Build Coastguard Worker #else
4993*fb1b10abSAndroid Build Coastguard Worker     if (use_normative_scaler && unscaled->y_width <= (scaled->y_width << 1) &&
4994*fb1b10abSAndroid Build Coastguard Worker         unscaled->y_height <= (scaled->y_height << 1))
4995*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_and_extend_frame(unscaled, scaled, filter_type, phase_scaler);
4996*fb1b10abSAndroid Build Coastguard Worker     else
4997*fb1b10abSAndroid Build Coastguard Worker       vp9_scale_and_extend_frame_nonnormative(unscaled, scaled);
4998*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
4999*fb1b10abSAndroid Build Coastguard Worker     return scaled;
5000*fb1b10abSAndroid Build Coastguard Worker   } else {
5001*fb1b10abSAndroid Build Coastguard Worker     return unscaled;
5002*fb1b10abSAndroid Build Coastguard Worker   }
5003*fb1b10abSAndroid Build Coastguard Worker }
5004*fb1b10abSAndroid Build Coastguard Worker 
5005*fb1b10abSAndroid Build Coastguard Worker static void set_ref_sign_bias(VP9_COMP *cpi) {
5006*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
5007*fb1b10abSAndroid Build Coastguard Worker   RefCntBuffer *const ref_buffer = get_ref_cnt_buffer(cm, cm->new_fb_idx);
5008*fb1b10abSAndroid Build Coastguard Worker   const int cur_frame_index = ref_buffer->frame_index;
5009*fb1b10abSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref_frame;
5010*fb1b10abSAndroid Build Coastguard Worker 
5011*fb1b10abSAndroid Build Coastguard Worker   for (ref_frame = LAST_FRAME; ref_frame < MAX_REF_FRAMES; ++ref_frame) {
5012*fb1b10abSAndroid Build Coastguard Worker     const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
5013*fb1b10abSAndroid Build Coastguard Worker     const RefCntBuffer *const ref_cnt_buf =
5014*fb1b10abSAndroid Build Coastguard Worker         get_ref_cnt_buffer(&cpi->common, buf_idx);
5015*fb1b10abSAndroid Build Coastguard Worker     if (ref_cnt_buf) {
5016*fb1b10abSAndroid Build Coastguard Worker       cm->ref_frame_sign_bias[ref_frame] =
5017*fb1b10abSAndroid Build Coastguard Worker           cur_frame_index < ref_cnt_buf->frame_index;
5018*fb1b10abSAndroid Build Coastguard Worker     }
5019*fb1b10abSAndroid Build Coastguard Worker   }
5020*fb1b10abSAndroid Build Coastguard Worker }
5021*fb1b10abSAndroid Build Coastguard Worker 
5022*fb1b10abSAndroid Build Coastguard Worker static int setup_interp_filter_search_mask(VP9_COMP *cpi) {
5023*fb1b10abSAndroid Build Coastguard Worker   INTERP_FILTER ifilter;
5024*fb1b10abSAndroid Build Coastguard Worker   int ref_total[MAX_REF_FRAMES] = { 0 };
5025*fb1b10abSAndroid Build Coastguard Worker   MV_REFERENCE_FRAME ref;
5026*fb1b10abSAndroid Build Coastguard Worker   int mask = 0;
5027*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
5028*fb1b10abSAndroid Build Coastguard Worker     return mask;
5029*fb1b10abSAndroid Build Coastguard Worker   for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
5030*fb1b10abSAndroid Build Coastguard Worker     for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter)
5031*fb1b10abSAndroid Build Coastguard Worker       ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
5032*fb1b10abSAndroid Build Coastguard Worker 
5033*fb1b10abSAndroid Build Coastguard Worker   for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) {
5034*fb1b10abSAndroid Build Coastguard Worker     if ((ref_total[LAST_FRAME] &&
5035*fb1b10abSAndroid Build Coastguard Worker          cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
5036*fb1b10abSAndroid Build Coastguard Worker         (ref_total[GOLDEN_FRAME] == 0 ||
5037*fb1b10abSAndroid Build Coastguard Worker          cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 <
5038*fb1b10abSAndroid Build Coastguard Worker              ref_total[GOLDEN_FRAME]) &&
5039*fb1b10abSAndroid Build Coastguard Worker         (ref_total[ALTREF_FRAME] == 0 ||
5040*fb1b10abSAndroid Build Coastguard Worker          cpi->interp_filter_selected[ALTREF_FRAME][ifilter] * 50 <
5041*fb1b10abSAndroid Build Coastguard Worker              ref_total[ALTREF_FRAME]))
5042*fb1b10abSAndroid Build Coastguard Worker       mask |= 1 << ifilter;
5043*fb1b10abSAndroid Build Coastguard Worker   }
5044*fb1b10abSAndroid Build Coastguard Worker   return mask;
5045*fb1b10abSAndroid Build Coastguard Worker }
5046*fb1b10abSAndroid Build Coastguard Worker 
5047*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
5048*fb1b10abSAndroid Build Coastguard Worker // Baseline kernel weights for denoise
5049*fb1b10abSAndroid Build Coastguard Worker static uint8_t dn_kernel_3[9] = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
5050*fb1b10abSAndroid Build Coastguard Worker static uint8_t dn_kernel_5[25] = { 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 4,
5051*fb1b10abSAndroid Build Coastguard Worker                                    2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1 };
5052*fb1b10abSAndroid Build Coastguard Worker 
5053*fb1b10abSAndroid Build Coastguard Worker static INLINE void add_denoise_point(int centre_val, int data_val, int thresh,
5054*fb1b10abSAndroid Build Coastguard Worker                                      uint8_t point_weight, int *sum_val,
5055*fb1b10abSAndroid Build Coastguard Worker                                      int *sum_weight) {
5056*fb1b10abSAndroid Build Coastguard Worker   if (abs(centre_val - data_val) <= thresh) {
5057*fb1b10abSAndroid Build Coastguard Worker     *sum_weight += point_weight;
5058*fb1b10abSAndroid Build Coastguard Worker     *sum_val += (int)data_val * (int)point_weight;
5059*fb1b10abSAndroid Build Coastguard Worker   }
5060*fb1b10abSAndroid Build Coastguard Worker }
5061*fb1b10abSAndroid Build Coastguard Worker 
5062*fb1b10abSAndroid Build Coastguard Worker static void spatial_denoise_point(uint8_t *src_ptr, const int stride,
5063*fb1b10abSAndroid Build Coastguard Worker                                   const int strength) {
5064*fb1b10abSAndroid Build Coastguard Worker   int sum_weight = 0;
5065*fb1b10abSAndroid Build Coastguard Worker   int sum_val = 0;
5066*fb1b10abSAndroid Build Coastguard Worker   int thresh = strength;
5067*fb1b10abSAndroid Build Coastguard Worker   int kernel_size = 5;
5068*fb1b10abSAndroid Build Coastguard Worker   int half_k_size = 2;
5069*fb1b10abSAndroid Build Coastguard Worker   int i, j;
5070*fb1b10abSAndroid Build Coastguard Worker   int max_diff = 0;
5071*fb1b10abSAndroid Build Coastguard Worker   uint8_t *tmp_ptr;
5072*fb1b10abSAndroid Build Coastguard Worker   uint8_t *kernel_ptr;
5073*fb1b10abSAndroid Build Coastguard Worker 
5074*fb1b10abSAndroid Build Coastguard Worker   // Find the maximum deviation from the source point in the locale.
5075*fb1b10abSAndroid Build Coastguard Worker   tmp_ptr = src_ptr - (stride * (half_k_size + 1)) - (half_k_size + 1);
5076*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < kernel_size + 2; ++i) {
5077*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < kernel_size + 2; ++j) {
5078*fb1b10abSAndroid Build Coastguard Worker       max_diff = VPXMAX(max_diff, abs((int)*src_ptr - (int)tmp_ptr[j]));
5079*fb1b10abSAndroid Build Coastguard Worker     }
5080*fb1b10abSAndroid Build Coastguard Worker     tmp_ptr += stride;
5081*fb1b10abSAndroid Build Coastguard Worker   }
5082*fb1b10abSAndroid Build Coastguard Worker 
5083*fb1b10abSAndroid Build Coastguard Worker   // Select the kernel size.
5084*fb1b10abSAndroid Build Coastguard Worker   if (max_diff > (strength + (strength >> 1))) {
5085*fb1b10abSAndroid Build Coastguard Worker     kernel_size = 3;
5086*fb1b10abSAndroid Build Coastguard Worker     half_k_size = 1;
5087*fb1b10abSAndroid Build Coastguard Worker     thresh = thresh >> 1;
5088*fb1b10abSAndroid Build Coastguard Worker   }
5089*fb1b10abSAndroid Build Coastguard Worker   kernel_ptr = (kernel_size == 3) ? dn_kernel_3 : dn_kernel_5;
5090*fb1b10abSAndroid Build Coastguard Worker 
5091*fb1b10abSAndroid Build Coastguard Worker   // Apply the kernel
5092*fb1b10abSAndroid Build Coastguard Worker   tmp_ptr = src_ptr - (stride * half_k_size) - half_k_size;
5093*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < kernel_size; ++i) {
5094*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < kernel_size; ++j) {
5095*fb1b10abSAndroid Build Coastguard Worker       add_denoise_point((int)*src_ptr, (int)tmp_ptr[j], thresh, *kernel_ptr,
5096*fb1b10abSAndroid Build Coastguard Worker                         &sum_val, &sum_weight);
5097*fb1b10abSAndroid Build Coastguard Worker       ++kernel_ptr;
5098*fb1b10abSAndroid Build Coastguard Worker     }
5099*fb1b10abSAndroid Build Coastguard Worker     tmp_ptr += stride;
5100*fb1b10abSAndroid Build Coastguard Worker   }
5101*fb1b10abSAndroid Build Coastguard Worker 
5102*fb1b10abSAndroid Build Coastguard Worker   // Update the source value with the new filtered value
5103*fb1b10abSAndroid Build Coastguard Worker   *src_ptr = (uint8_t)((sum_val + (sum_weight >> 1)) / sum_weight);
5104*fb1b10abSAndroid Build Coastguard Worker }
5105*fb1b10abSAndroid Build Coastguard Worker 
5106*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5107*fb1b10abSAndroid Build Coastguard Worker static void highbd_spatial_denoise_point(uint16_t *src_ptr, const int stride,
5108*fb1b10abSAndroid Build Coastguard Worker                                          const int strength) {
5109*fb1b10abSAndroid Build Coastguard Worker   int sum_weight = 0;
5110*fb1b10abSAndroid Build Coastguard Worker   int sum_val = 0;
5111*fb1b10abSAndroid Build Coastguard Worker   int thresh = strength;
5112*fb1b10abSAndroid Build Coastguard Worker   int kernel_size = 5;
5113*fb1b10abSAndroid Build Coastguard Worker   int half_k_size = 2;
5114*fb1b10abSAndroid Build Coastguard Worker   int i, j;
5115*fb1b10abSAndroid Build Coastguard Worker   int max_diff = 0;
5116*fb1b10abSAndroid Build Coastguard Worker   uint16_t *tmp_ptr;
5117*fb1b10abSAndroid Build Coastguard Worker   uint8_t *kernel_ptr;
5118*fb1b10abSAndroid Build Coastguard Worker 
5119*fb1b10abSAndroid Build Coastguard Worker   // Find the maximum deviation from the source point in the locale.
5120*fb1b10abSAndroid Build Coastguard Worker   tmp_ptr = src_ptr - (stride * (half_k_size + 1)) - (half_k_size + 1);
5121*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < kernel_size + 2; ++i) {
5122*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < kernel_size + 2; ++j) {
5123*fb1b10abSAndroid Build Coastguard Worker       max_diff = VPXMAX(max_diff, abs((int)src_ptr - (int)tmp_ptr[j]));
5124*fb1b10abSAndroid Build Coastguard Worker     }
5125*fb1b10abSAndroid Build Coastguard Worker     tmp_ptr += stride;
5126*fb1b10abSAndroid Build Coastguard Worker   }
5127*fb1b10abSAndroid Build Coastguard Worker 
5128*fb1b10abSAndroid Build Coastguard Worker   // Select the kernel size.
5129*fb1b10abSAndroid Build Coastguard Worker   if (max_diff > (strength + (strength >> 1))) {
5130*fb1b10abSAndroid Build Coastguard Worker     kernel_size = 3;
5131*fb1b10abSAndroid Build Coastguard Worker     half_k_size = 1;
5132*fb1b10abSAndroid Build Coastguard Worker     thresh = thresh >> 1;
5133*fb1b10abSAndroid Build Coastguard Worker   }
5134*fb1b10abSAndroid Build Coastguard Worker   kernel_ptr = (kernel_size == 3) ? dn_kernel_3 : dn_kernel_5;
5135*fb1b10abSAndroid Build Coastguard Worker 
5136*fb1b10abSAndroid Build Coastguard Worker   // Apply the kernel
5137*fb1b10abSAndroid Build Coastguard Worker   tmp_ptr = src_ptr - (stride * half_k_size) - half_k_size;
5138*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < kernel_size; ++i) {
5139*fb1b10abSAndroid Build Coastguard Worker     for (j = 0; j < kernel_size; ++j) {
5140*fb1b10abSAndroid Build Coastguard Worker       add_denoise_point((int)*src_ptr, (int)tmp_ptr[j], thresh, *kernel_ptr,
5141*fb1b10abSAndroid Build Coastguard Worker                         &sum_val, &sum_weight);
5142*fb1b10abSAndroid Build Coastguard Worker       ++kernel_ptr;
5143*fb1b10abSAndroid Build Coastguard Worker     }
5144*fb1b10abSAndroid Build Coastguard Worker     tmp_ptr += stride;
5145*fb1b10abSAndroid Build Coastguard Worker   }
5146*fb1b10abSAndroid Build Coastguard Worker 
5147*fb1b10abSAndroid Build Coastguard Worker   // Update the source value with the new filtered value
5148*fb1b10abSAndroid Build Coastguard Worker   *src_ptr = (uint16_t)((sum_val + (sum_weight >> 1)) / sum_weight);
5149*fb1b10abSAndroid Build Coastguard Worker }
5150*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
5151*fb1b10abSAndroid Build Coastguard Worker 
5152*fb1b10abSAndroid Build Coastguard Worker // Apply thresholded spatial noise suppression to a given buffer.
5153*fb1b10abSAndroid Build Coastguard Worker static void spatial_denoise_buffer(VP9_COMP *cpi, uint8_t *buffer,
5154*fb1b10abSAndroid Build Coastguard Worker                                    const int stride, const int width,
5155*fb1b10abSAndroid Build Coastguard Worker                                    const int height, const int strength) {
5156*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
5157*fb1b10abSAndroid Build Coastguard Worker   uint8_t *src_ptr = buffer;
5158*fb1b10abSAndroid Build Coastguard Worker   int row;
5159*fb1b10abSAndroid Build Coastguard Worker   int col;
5160*fb1b10abSAndroid Build Coastguard Worker 
5161*fb1b10abSAndroid Build Coastguard Worker   for (row = 0; row < height; ++row) {
5162*fb1b10abSAndroid Build Coastguard Worker     for (col = 0; col < width; ++col) {
5163*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5164*fb1b10abSAndroid Build Coastguard Worker       if (cm->use_highbitdepth)
5165*fb1b10abSAndroid Build Coastguard Worker         highbd_spatial_denoise_point(CONVERT_TO_SHORTPTR(&src_ptr[col]), stride,
5166*fb1b10abSAndroid Build Coastguard Worker                                      strength);
5167*fb1b10abSAndroid Build Coastguard Worker       else
5168*fb1b10abSAndroid Build Coastguard Worker         spatial_denoise_point(&src_ptr[col], stride, strength);
5169*fb1b10abSAndroid Build Coastguard Worker #else
5170*fb1b10abSAndroid Build Coastguard Worker       spatial_denoise_point(&src_ptr[col], stride, strength);
5171*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
5172*fb1b10abSAndroid Build Coastguard Worker     }
5173*fb1b10abSAndroid Build Coastguard Worker     src_ptr += stride;
5174*fb1b10abSAndroid Build Coastguard Worker   }
5175*fb1b10abSAndroid Build Coastguard Worker }
5176*fb1b10abSAndroid Build Coastguard Worker 
5177*fb1b10abSAndroid Build Coastguard Worker // Apply thresholded spatial noise suppression to source.
5178*fb1b10abSAndroid Build Coastguard Worker static void spatial_denoise_frame(VP9_COMP *cpi) {
5179*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *src = cpi->Source;
5180*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
5181*fb1b10abSAndroid Build Coastguard Worker   TWO_PASS *const twopass = &cpi->twopass;
5182*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
5183*fb1b10abSAndroid Build Coastguard Worker 
5184*fb1b10abSAndroid Build Coastguard Worker   // Base the filter strength on the current active max Q.
5185*fb1b10abSAndroid Build Coastguard Worker   const int q = (int)(vp9_convert_qindex_to_q(twopass->active_worst_quality,
5186*fb1b10abSAndroid Build Coastguard Worker                                               cm->bit_depth));
5187*fb1b10abSAndroid Build Coastguard Worker   int strength =
5188*fb1b10abSAndroid Build Coastguard Worker       VPXMAX(oxcf->arnr_strength >> 2, VPXMIN(oxcf->arnr_strength, (q >> 4)));
5189*fb1b10abSAndroid Build Coastguard Worker 
5190*fb1b10abSAndroid Build Coastguard Worker   // Denoise each of Y,U and V buffers.
5191*fb1b10abSAndroid Build Coastguard Worker   spatial_denoise_buffer(cpi, src->y_buffer, src->y_stride, src->y_width,
5192*fb1b10abSAndroid Build Coastguard Worker                          src->y_height, strength);
5193*fb1b10abSAndroid Build Coastguard Worker 
5194*fb1b10abSAndroid Build Coastguard Worker   strength += (strength >> 1);
5195*fb1b10abSAndroid Build Coastguard Worker   spatial_denoise_buffer(cpi, src->u_buffer, src->uv_stride, src->uv_width,
5196*fb1b10abSAndroid Build Coastguard Worker                          src->uv_height, strength << 1);
5197*fb1b10abSAndroid Build Coastguard Worker 
5198*fb1b10abSAndroid Build Coastguard Worker   spatial_denoise_buffer(cpi, src->v_buffer, src->uv_stride, src->uv_width,
5199*fb1b10abSAndroid Build Coastguard Worker                          src->uv_height, strength << 1);
5200*fb1b10abSAndroid Build Coastguard Worker }
5201*fb1b10abSAndroid Build Coastguard Worker #endif  // ENABLE_KF_DENOISE
5202*fb1b10abSAndroid Build Coastguard Worker 
5203*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5204*fb1b10abSAndroid Build Coastguard Worker static void vp9_try_disable_lookahead_aq(VP9_COMP *cpi, size_t *size,
5205*fb1b10abSAndroid Build Coastguard Worker                                          uint8_t *dest, size_t dest_size) {
5206*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.seg.enabled)
5207*fb1b10abSAndroid Build Coastguard Worker     if (ALT_REF_AQ_PROTECT_GAIN) {
5208*fb1b10abSAndroid Build Coastguard Worker       size_t nsize = *size;
5209*fb1b10abSAndroid Build Coastguard Worker       int overhead;
5210*fb1b10abSAndroid Build Coastguard Worker 
5211*fb1b10abSAndroid Build Coastguard Worker       // TODO(yuryg): optimize this, as
5212*fb1b10abSAndroid Build Coastguard Worker       // we don't really need to repack
5213*fb1b10abSAndroid Build Coastguard Worker 
5214*fb1b10abSAndroid Build Coastguard Worker       save_coding_context(cpi);
5215*fb1b10abSAndroid Build Coastguard Worker       vp9_disable_segmentation(&cpi->common.seg);
5216*fb1b10abSAndroid Build Coastguard Worker       vp9_pack_bitstream(cpi, dest, dest_size, &nsize);
5217*fb1b10abSAndroid Build Coastguard Worker       restore_coding_context(cpi);
5218*fb1b10abSAndroid Build Coastguard Worker 
5219*fb1b10abSAndroid Build Coastguard Worker       overhead = (int)*size - (int)nsize;
5220*fb1b10abSAndroid Build Coastguard Worker 
5221*fb1b10abSAndroid Build Coastguard Worker       if (vp9_alt_ref_aq_disable_if(cpi->alt_ref_aq, overhead, (int)*size))
5222*fb1b10abSAndroid Build Coastguard Worker         vp9_encode_frame(cpi);
5223*fb1b10abSAndroid Build Coastguard Worker       else
5224*fb1b10abSAndroid Build Coastguard Worker         vp9_enable_segmentation(&cpi->common.seg);
5225*fb1b10abSAndroid Build Coastguard Worker     }
5226*fb1b10abSAndroid Build Coastguard Worker }
5227*fb1b10abSAndroid Build Coastguard Worker #endif
5228*fb1b10abSAndroid Build Coastguard Worker 
5229*fb1b10abSAndroid Build Coastguard Worker static void set_frame_index(VP9_COMP *cpi, VP9_COMMON *cm) {
5230*fb1b10abSAndroid Build Coastguard Worker   RefCntBuffer *const ref_buffer = get_ref_cnt_buffer(cm, cm->new_fb_idx);
5231*fb1b10abSAndroid Build Coastguard Worker 
5232*fb1b10abSAndroid Build Coastguard Worker   if (ref_buffer) {
5233*fb1b10abSAndroid Build Coastguard Worker     const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5234*fb1b10abSAndroid Build Coastguard Worker     ref_buffer->frame_index =
5235*fb1b10abSAndroid Build Coastguard Worker         cm->current_video_frame + gf_group->arf_src_offset[gf_group->index];
5236*fb1b10abSAndroid Build Coastguard Worker     ref_buffer->frame_coding_index = cm->current_frame_coding_index;
5237*fb1b10abSAndroid Build Coastguard Worker   }
5238*fb1b10abSAndroid Build Coastguard Worker }
5239*fb1b10abSAndroid Build Coastguard Worker 
5240*fb1b10abSAndroid Build Coastguard Worker static void set_mb_ssim_rdmult_scaling(VP9_COMP *cpi) {
5241*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
5242*fb1b10abSAndroid Build Coastguard Worker   ThreadData *td = &cpi->td;
5243*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCK *x = &td->mb;
5244*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *xd = &x->e_mbd;
5245*fb1b10abSAndroid Build Coastguard Worker   uint8_t *y_buffer = cpi->Source->y_buffer;
5246*fb1b10abSAndroid Build Coastguard Worker   const int y_stride = cpi->Source->y_stride;
5247*fb1b10abSAndroid Build Coastguard Worker   const int block_size = BLOCK_16X16;
5248*fb1b10abSAndroid Build Coastguard Worker 
5249*fb1b10abSAndroid Build Coastguard Worker   const int num_8x8_w = num_8x8_blocks_wide_lookup[block_size];
5250*fb1b10abSAndroid Build Coastguard Worker   const int num_8x8_h = num_8x8_blocks_high_lookup[block_size];
5251*fb1b10abSAndroid Build Coastguard Worker   const int num_cols = (cm->mi_cols + num_8x8_w - 1) / num_8x8_w;
5252*fb1b10abSAndroid Build Coastguard Worker   const int num_rows = (cm->mi_rows + num_8x8_h - 1) / num_8x8_h;
5253*fb1b10abSAndroid Build Coastguard Worker   double log_sum = 0.0;
5254*fb1b10abSAndroid Build Coastguard Worker   int row, col;
5255*fb1b10abSAndroid Build Coastguard Worker 
5256*fb1b10abSAndroid Build Coastguard Worker   // Loop through each 64x64 block.
5257*fb1b10abSAndroid Build Coastguard Worker   for (row = 0; row < num_rows; ++row) {
5258*fb1b10abSAndroid Build Coastguard Worker     for (col = 0; col < num_cols; ++col) {
5259*fb1b10abSAndroid Build Coastguard Worker       int mi_row, mi_col;
5260*fb1b10abSAndroid Build Coastguard Worker       double var = 0.0, num_of_var = 0.0;
5261*fb1b10abSAndroid Build Coastguard Worker       const int index = row * num_cols + col;
5262*fb1b10abSAndroid Build Coastguard Worker 
5263*fb1b10abSAndroid Build Coastguard Worker       for (mi_row = row * num_8x8_h;
5264*fb1b10abSAndroid Build Coastguard Worker            mi_row < cm->mi_rows && mi_row < (row + 1) * num_8x8_h; ++mi_row) {
5265*fb1b10abSAndroid Build Coastguard Worker         for (mi_col = col * num_8x8_w;
5266*fb1b10abSAndroid Build Coastguard Worker              mi_col < cm->mi_cols && mi_col < (col + 1) * num_8x8_w; ++mi_col) {
5267*fb1b10abSAndroid Build Coastguard Worker           struct buf_2d buf;
5268*fb1b10abSAndroid Build Coastguard Worker           const int row_offset_y = mi_row << 3;
5269*fb1b10abSAndroid Build Coastguard Worker           const int col_offset_y = mi_col << 3;
5270*fb1b10abSAndroid Build Coastguard Worker 
5271*fb1b10abSAndroid Build Coastguard Worker           buf.buf = y_buffer + row_offset_y * y_stride + col_offset_y;
5272*fb1b10abSAndroid Build Coastguard Worker           buf.stride = y_stride;
5273*fb1b10abSAndroid Build Coastguard Worker 
5274*fb1b10abSAndroid Build Coastguard Worker           // In order to make SSIM_VAR_SCALE in a same scale for both 8 bit
5275*fb1b10abSAndroid Build Coastguard Worker           // and high bit videos, the variance needs to be divided by 2.0 or
5276*fb1b10abSAndroid Build Coastguard Worker           // 64.0 separately.
5277*fb1b10abSAndroid Build Coastguard Worker           // TODO(sdeng): need to tune for 12bit videos.
5278*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5279*fb1b10abSAndroid Build Coastguard Worker           if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH)
5280*fb1b10abSAndroid Build Coastguard Worker             var += vp9_high_get_sby_variance(cpi, &buf, BLOCK_8X8, xd->bd);
5281*fb1b10abSAndroid Build Coastguard Worker           else
5282*fb1b10abSAndroid Build Coastguard Worker #endif
5283*fb1b10abSAndroid Build Coastguard Worker             var += vp9_get_sby_variance(cpi, &buf, BLOCK_8X8);
5284*fb1b10abSAndroid Build Coastguard Worker 
5285*fb1b10abSAndroid Build Coastguard Worker           num_of_var += 1.0;
5286*fb1b10abSAndroid Build Coastguard Worker         }
5287*fb1b10abSAndroid Build Coastguard Worker       }
5288*fb1b10abSAndroid Build Coastguard Worker       var = var / num_of_var / 64.0;
5289*fb1b10abSAndroid Build Coastguard Worker 
5290*fb1b10abSAndroid Build Coastguard Worker       // Curve fitting with an exponential model on all 16x16 blocks from the
5291*fb1b10abSAndroid Build Coastguard Worker       // Midres dataset.
5292*fb1b10abSAndroid Build Coastguard Worker       var = 67.035434 * (1 - exp(-0.0021489 * var)) + 17.492222;
5293*fb1b10abSAndroid Build Coastguard Worker       cpi->mi_ssim_rdmult_scaling_factors[index] = var;
5294*fb1b10abSAndroid Build Coastguard Worker       log_sum += log(var);
5295*fb1b10abSAndroid Build Coastguard Worker     }
5296*fb1b10abSAndroid Build Coastguard Worker   }
5297*fb1b10abSAndroid Build Coastguard Worker   log_sum = exp(log_sum / (double)(num_rows * num_cols));
5298*fb1b10abSAndroid Build Coastguard Worker 
5299*fb1b10abSAndroid Build Coastguard Worker   for (row = 0; row < num_rows; ++row) {
5300*fb1b10abSAndroid Build Coastguard Worker     for (col = 0; col < num_cols; ++col) {
5301*fb1b10abSAndroid Build Coastguard Worker       const int index = row * num_cols + col;
5302*fb1b10abSAndroid Build Coastguard Worker       cpi->mi_ssim_rdmult_scaling_factors[index] /= log_sum;
5303*fb1b10abSAndroid Build Coastguard Worker     }
5304*fb1b10abSAndroid Build Coastguard Worker   }
5305*fb1b10abSAndroid Build Coastguard Worker 
5306*fb1b10abSAndroid Build Coastguard Worker   (void)xd;
5307*fb1b10abSAndroid Build Coastguard Worker }
5308*fb1b10abSAndroid Build Coastguard Worker 
5309*fb1b10abSAndroid Build Coastguard Worker // Process the wiener variance in 16x16 block basis.
5310*fb1b10abSAndroid Build Coastguard Worker static int qsort_comp(const void *elem1, const void *elem2) {
5311*fb1b10abSAndroid Build Coastguard Worker   int a = *((const int *)elem1);
5312*fb1b10abSAndroid Build Coastguard Worker   int b = *((const int *)elem2);
5313*fb1b10abSAndroid Build Coastguard Worker   if (a > b) return 1;
5314*fb1b10abSAndroid Build Coastguard Worker   if (a < b) return -1;
5315*fb1b10abSAndroid Build Coastguard Worker   return 0;
5316*fb1b10abSAndroid Build Coastguard Worker }
5317*fb1b10abSAndroid Build Coastguard Worker 
5318*fb1b10abSAndroid Build Coastguard Worker static void init_mb_wiener_var_buffer(VP9_COMP *cpi) {
5319*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
5320*fb1b10abSAndroid Build Coastguard Worker 
5321*fb1b10abSAndroid Build Coastguard Worker   if (cpi->mb_wiener_variance && cpi->mb_wiener_var_rows >= cm->mb_rows &&
5322*fb1b10abSAndroid Build Coastguard Worker       cpi->mb_wiener_var_cols >= cm->mb_cols)
5323*fb1b10abSAndroid Build Coastguard Worker     return;
5324*fb1b10abSAndroid Build Coastguard Worker 
5325*fb1b10abSAndroid Build Coastguard Worker   vpx_free(cpi->mb_wiener_variance);
5326*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_variance = NULL;
5327*fb1b10abSAndroid Build Coastguard Worker 
5328*fb1b10abSAndroid Build Coastguard Worker   CHECK_MEM_ERROR(
5329*fb1b10abSAndroid Build Coastguard Worker       &cm->error, cpi->mb_wiener_variance,
5330*fb1b10abSAndroid Build Coastguard Worker       vpx_calloc(cm->mb_rows * cm->mb_cols, sizeof(*cpi->mb_wiener_variance)));
5331*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_var_rows = cm->mb_rows;
5332*fb1b10abSAndroid Build Coastguard Worker   cpi->mb_wiener_var_cols = cm->mb_cols;
5333*fb1b10abSAndroid Build Coastguard Worker }
5334*fb1b10abSAndroid Build Coastguard Worker 
5335*fb1b10abSAndroid Build Coastguard Worker static void set_mb_wiener_variance(VP9_COMP *cpi) {
5336*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
5337*fb1b10abSAndroid Build Coastguard Worker   uint8_t *buffer = cpi->Source->y_buffer;
5338*fb1b10abSAndroid Build Coastguard Worker   int buf_stride = cpi->Source->y_stride;
5339*fb1b10abSAndroid Build Coastguard Worker 
5340*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5341*fb1b10abSAndroid Build Coastguard Worker   ThreadData *td = &cpi->td;
5342*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCK *x = &td->mb;
5343*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *xd = &x->e_mbd;
5344*fb1b10abSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, uint16_t, zero_pred16[32 * 32]);
5345*fb1b10abSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, uint8_t, zero_pred8[32 * 32]);
5346*fb1b10abSAndroid Build Coastguard Worker   uint8_t *zero_pred;
5347*fb1b10abSAndroid Build Coastguard Worker #else
5348*fb1b10abSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, uint8_t, zero_pred[32 * 32]);
5349*fb1b10abSAndroid Build Coastguard Worker #endif
5350*fb1b10abSAndroid Build Coastguard Worker 
5351*fb1b10abSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, src_diff[32 * 32]);
5352*fb1b10abSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, tran_low_t, coeff[32 * 32]);
5353*fb1b10abSAndroid Build Coastguard Worker 
5354*fb1b10abSAndroid Build Coastguard Worker   int mb_row, mb_col, count = 0;
5355*fb1b10abSAndroid Build Coastguard Worker   // Hard coded operating block size
5356*fb1b10abSAndroid Build Coastguard Worker   const int block_size = 16;
5357*fb1b10abSAndroid Build Coastguard Worker   const int coeff_count = block_size * block_size;
5358*fb1b10abSAndroid Build Coastguard Worker   const TX_SIZE tx_size = TX_16X16;
5359*fb1b10abSAndroid Build Coastguard Worker 
5360*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5361*fb1b10abSAndroid Build Coastguard Worker   xd->cur_buf = cpi->Source;
5362*fb1b10abSAndroid Build Coastguard Worker   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5363*fb1b10abSAndroid Build Coastguard Worker     zero_pred = CONVERT_TO_BYTEPTR(zero_pred16);
5364*fb1b10abSAndroid Build Coastguard Worker     memset(zero_pred16, 0, sizeof(*zero_pred16) * coeff_count);
5365*fb1b10abSAndroid Build Coastguard Worker   } else {
5366*fb1b10abSAndroid Build Coastguard Worker     zero_pred = zero_pred8;
5367*fb1b10abSAndroid Build Coastguard Worker     memset(zero_pred8, 0, sizeof(*zero_pred8) * coeff_count);
5368*fb1b10abSAndroid Build Coastguard Worker   }
5369*fb1b10abSAndroid Build Coastguard Worker #else
5370*fb1b10abSAndroid Build Coastguard Worker   memset(zero_pred, 0, sizeof(*zero_pred) * coeff_count);
5371*fb1b10abSAndroid Build Coastguard Worker #endif
5372*fb1b10abSAndroid Build Coastguard Worker 
5373*fb1b10abSAndroid Build Coastguard Worker   cpi->norm_wiener_variance = 0;
5374*fb1b10abSAndroid Build Coastguard Worker 
5375*fb1b10abSAndroid Build Coastguard Worker   for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
5376*fb1b10abSAndroid Build Coastguard Worker     for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
5377*fb1b10abSAndroid Build Coastguard Worker       int idx;
5378*fb1b10abSAndroid Build Coastguard Worker       int16_t median_val = 0;
5379*fb1b10abSAndroid Build Coastguard Worker       uint8_t *mb_buffer =
5380*fb1b10abSAndroid Build Coastguard Worker           buffer + mb_row * block_size * buf_stride + mb_col * block_size;
5381*fb1b10abSAndroid Build Coastguard Worker       int64_t wiener_variance = 0;
5382*fb1b10abSAndroid Build Coastguard Worker 
5383*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5384*fb1b10abSAndroid Build Coastguard Worker       if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
5385*fb1b10abSAndroid Build Coastguard Worker         vpx_highbd_subtract_block(block_size, block_size, src_diff, block_size,
5386*fb1b10abSAndroid Build Coastguard Worker                                   mb_buffer, buf_stride, zero_pred, block_size,
5387*fb1b10abSAndroid Build Coastguard Worker                                   xd->bd);
5388*fb1b10abSAndroid Build Coastguard Worker         vp9_highbd_wht_fwd_txfm(src_diff, block_size, coeff, tx_size);
5389*fb1b10abSAndroid Build Coastguard Worker       } else {
5390*fb1b10abSAndroid Build Coastguard Worker         vpx_subtract_block(block_size, block_size, src_diff, block_size,
5391*fb1b10abSAndroid Build Coastguard Worker                            mb_buffer, buf_stride, zero_pred, block_size);
5392*fb1b10abSAndroid Build Coastguard Worker         vp9_wht_fwd_txfm(src_diff, block_size, coeff, tx_size);
5393*fb1b10abSAndroid Build Coastguard Worker       }
5394*fb1b10abSAndroid Build Coastguard Worker #else
5395*fb1b10abSAndroid Build Coastguard Worker       vpx_subtract_block(block_size, block_size, src_diff, block_size,
5396*fb1b10abSAndroid Build Coastguard Worker                          mb_buffer, buf_stride, zero_pred, block_size);
5397*fb1b10abSAndroid Build Coastguard Worker       vp9_wht_fwd_txfm(src_diff, block_size, coeff, tx_size);
5398*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
5399*fb1b10abSAndroid Build Coastguard Worker 
5400*fb1b10abSAndroid Build Coastguard Worker       coeff[0] = 0;
5401*fb1b10abSAndroid Build Coastguard Worker       for (idx = 1; idx < coeff_count; ++idx) coeff[idx] = abs(coeff[idx]);
5402*fb1b10abSAndroid Build Coastguard Worker 
5403*fb1b10abSAndroid Build Coastguard Worker       qsort(coeff, coeff_count - 1, sizeof(*coeff), qsort_comp);
5404*fb1b10abSAndroid Build Coastguard Worker 
5405*fb1b10abSAndroid Build Coastguard Worker       // Noise level estimation
5406*fb1b10abSAndroid Build Coastguard Worker       median_val = coeff[coeff_count / 2];
5407*fb1b10abSAndroid Build Coastguard Worker 
5408*fb1b10abSAndroid Build Coastguard Worker       // Wiener filter
5409*fb1b10abSAndroid Build Coastguard Worker       for (idx = 1; idx < coeff_count; ++idx) {
5410*fb1b10abSAndroid Build Coastguard Worker         int64_t sqr_coeff = (int64_t)coeff[idx] * coeff[idx];
5411*fb1b10abSAndroid Build Coastguard Worker         int64_t tmp_coeff = (int64_t)coeff[idx];
5412*fb1b10abSAndroid Build Coastguard Worker         if (median_val) {
5413*fb1b10abSAndroid Build Coastguard Worker           tmp_coeff = (sqr_coeff * coeff[idx]) /
5414*fb1b10abSAndroid Build Coastguard Worker                       (sqr_coeff + (int64_t)median_val * median_val);
5415*fb1b10abSAndroid Build Coastguard Worker         }
5416*fb1b10abSAndroid Build Coastguard Worker         wiener_variance += tmp_coeff * tmp_coeff;
5417*fb1b10abSAndroid Build Coastguard Worker       }
5418*fb1b10abSAndroid Build Coastguard Worker       cpi->mb_wiener_variance[mb_row * cm->mb_cols + mb_col] =
5419*fb1b10abSAndroid Build Coastguard Worker           wiener_variance / coeff_count;
5420*fb1b10abSAndroid Build Coastguard Worker       cpi->norm_wiener_variance +=
5421*fb1b10abSAndroid Build Coastguard Worker           cpi->mb_wiener_variance[mb_row * cm->mb_cols + mb_col];
5422*fb1b10abSAndroid Build Coastguard Worker       ++count;
5423*fb1b10abSAndroid Build Coastguard Worker     }
5424*fb1b10abSAndroid Build Coastguard Worker   }
5425*fb1b10abSAndroid Build Coastguard Worker 
5426*fb1b10abSAndroid Build Coastguard Worker   if (count) cpi->norm_wiener_variance /= count;
5427*fb1b10abSAndroid Build Coastguard Worker   cpi->norm_wiener_variance = VPXMAX(1, cpi->norm_wiener_variance);
5428*fb1b10abSAndroid Build Coastguard Worker }
5429*fb1b10abSAndroid Build Coastguard Worker 
5430*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5431*fb1b10abSAndroid Build Coastguard Worker static PSNR_STATS compute_psnr_stats(const YV12_BUFFER_CONFIG *source_frame,
5432*fb1b10abSAndroid Build Coastguard Worker                                      const YV12_BUFFER_CONFIG *coded_frame,
5433*fb1b10abSAndroid Build Coastguard Worker                                      uint32_t bit_depth,
5434*fb1b10abSAndroid Build Coastguard Worker                                      uint32_t input_bit_depth) {
5435*fb1b10abSAndroid Build Coastguard Worker   PSNR_STATS psnr;
5436*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5437*fb1b10abSAndroid Build Coastguard Worker   vpx_calc_highbd_psnr(source_frame, coded_frame, &psnr, bit_depth,
5438*fb1b10abSAndroid Build Coastguard Worker                        input_bit_depth);
5439*fb1b10abSAndroid Build Coastguard Worker #else   // CONFIG_VP9_HIGHBITDEPTH
5440*fb1b10abSAndroid Build Coastguard Worker   (void)bit_depth;
5441*fb1b10abSAndroid Build Coastguard Worker   (void)input_bit_depth;
5442*fb1b10abSAndroid Build Coastguard Worker   vpx_calc_psnr(source_frame, coded_frame, &psnr);
5443*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
5444*fb1b10abSAndroid Build Coastguard Worker   return psnr;
5445*fb1b10abSAndroid Build Coastguard Worker }
5446*fb1b10abSAndroid Build Coastguard Worker 
5447*fb1b10abSAndroid Build Coastguard Worker static void update_encode_frame_result_basic(
5448*fb1b10abSAndroid Build Coastguard Worker     FRAME_UPDATE_TYPE update_type, int show_idx, int quantize_index,
5449*fb1b10abSAndroid Build Coastguard Worker     ENCODE_FRAME_RESULT *encode_frame_result) {
5450*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->show_idx = show_idx;
5451*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->update_type = update_type;
5452*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->quantize_index = quantize_index;
5453*fb1b10abSAndroid Build Coastguard Worker }
5454*fb1b10abSAndroid Build Coastguard Worker 
5455*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
5456*fb1b10abSAndroid Build Coastguard Worker static void yv12_buffer_to_image_buffer(const YV12_BUFFER_CONFIG *yv12_buffer,
5457*fb1b10abSAndroid Build Coastguard Worker                                         IMAGE_BUFFER *image_buffer) {
5458*fb1b10abSAndroid Build Coastguard Worker   const uint8_t *src_buf_ls[3] = { yv12_buffer->y_buffer, yv12_buffer->u_buffer,
5459*fb1b10abSAndroid Build Coastguard Worker                                    yv12_buffer->v_buffer };
5460*fb1b10abSAndroid Build Coastguard Worker   const int src_stride_ls[3] = { yv12_buffer->y_stride, yv12_buffer->uv_stride,
5461*fb1b10abSAndroid Build Coastguard Worker                                  yv12_buffer->uv_stride };
5462*fb1b10abSAndroid Build Coastguard Worker   const int w_ls[3] = { yv12_buffer->y_crop_width, yv12_buffer->uv_crop_width,
5463*fb1b10abSAndroid Build Coastguard Worker                         yv12_buffer->uv_crop_width };
5464*fb1b10abSAndroid Build Coastguard Worker   const int h_ls[3] = { yv12_buffer->y_crop_height, yv12_buffer->uv_crop_height,
5465*fb1b10abSAndroid Build Coastguard Worker                         yv12_buffer->uv_crop_height };
5466*fb1b10abSAndroid Build Coastguard Worker   int plane;
5467*fb1b10abSAndroid Build Coastguard Worker   for (plane = 0; plane < 3; ++plane) {
5468*fb1b10abSAndroid Build Coastguard Worker     const int src_stride = src_stride_ls[plane];
5469*fb1b10abSAndroid Build Coastguard Worker     const int w = w_ls[plane];
5470*fb1b10abSAndroid Build Coastguard Worker     const int h = h_ls[plane];
5471*fb1b10abSAndroid Build Coastguard Worker     const uint8_t *src_buf = src_buf_ls[plane];
5472*fb1b10abSAndroid Build Coastguard Worker     uint8_t *dst_buf = image_buffer->plane_buffer[plane];
5473*fb1b10abSAndroid Build Coastguard Worker     int r;
5474*fb1b10abSAndroid Build Coastguard Worker     assert(image_buffer->plane_width[plane] == w);
5475*fb1b10abSAndroid Build Coastguard Worker     assert(image_buffer->plane_height[plane] == h);
5476*fb1b10abSAndroid Build Coastguard Worker     for (r = 0; r < h; ++r) {
5477*fb1b10abSAndroid Build Coastguard Worker       memcpy(dst_buf, src_buf, sizeof(*src_buf) * w);
5478*fb1b10abSAndroid Build Coastguard Worker       src_buf += src_stride;
5479*fb1b10abSAndroid Build Coastguard Worker       dst_buf += w;
5480*fb1b10abSAndroid Build Coastguard Worker     }
5481*fb1b10abSAndroid Build Coastguard Worker   }
5482*fb1b10abSAndroid Build Coastguard Worker }
5483*fb1b10abSAndroid Build Coastguard Worker 
5484*fb1b10abSAndroid Build Coastguard Worker // This function will update extra information specific for simple_encode APIs
5485*fb1b10abSAndroid Build Coastguard Worker static void update_encode_frame_result_simple_encode(
5486*fb1b10abSAndroid Build Coastguard Worker     int ref_frame_flags, FRAME_UPDATE_TYPE update_type,
5487*fb1b10abSAndroid Build Coastguard Worker     const YV12_BUFFER_CONFIG *source_frame, const RefCntBuffer *coded_frame_buf,
5488*fb1b10abSAndroid Build Coastguard Worker     RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES], int quantize_index,
5489*fb1b10abSAndroid Build Coastguard Worker     uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts,
5490*fb1b10abSAndroid Build Coastguard Worker     const PARTITION_INFO *partition_info,
5491*fb1b10abSAndroid Build Coastguard Worker     const MOTION_VECTOR_INFO *motion_vector_info,
5492*fb1b10abSAndroid Build Coastguard Worker     const TplDepStats *tpl_stats_info,
5493*fb1b10abSAndroid Build Coastguard Worker     ENCODE_FRAME_RESULT *encode_frame_result) {
5494*fb1b10abSAndroid Build Coastguard Worker   PSNR_STATS psnr;
5495*fb1b10abSAndroid Build Coastguard Worker   update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index,
5496*fb1b10abSAndroid Build Coastguard Worker                                    quantize_index, encode_frame_result);
5497*fb1b10abSAndroid Build Coastguard Worker   compute_psnr_stats(source_frame, &coded_frame_buf->buf, bit_depth,
5498*fb1b10abSAndroid Build Coastguard Worker                      input_bit_depth);
5499*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->frame_coding_index = coded_frame_buf->frame_coding_index;
5500*fb1b10abSAndroid Build Coastguard Worker 
5501*fb1b10abSAndroid Build Coastguard Worker   vp9_get_ref_frame_info(update_type, ref_frame_flags, ref_frame_bufs,
5502*fb1b10abSAndroid Build Coastguard Worker                          encode_frame_result->ref_frame_coding_indexes,
5503*fb1b10abSAndroid Build Coastguard Worker                          encode_frame_result->ref_frame_valid_list);
5504*fb1b10abSAndroid Build Coastguard Worker 
5505*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->psnr = psnr.psnr[0];
5506*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->sse = psnr.sse[0];
5507*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->frame_counts = *counts;
5508*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->partition_info = partition_info;
5509*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->motion_vector_info = motion_vector_info;
5510*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->tpl_stats_info = tpl_stats_info;
5511*fb1b10abSAndroid Build Coastguard Worker   if (encode_frame_result->coded_frame.allocated) {
5512*fb1b10abSAndroid Build Coastguard Worker     yv12_buffer_to_image_buffer(&coded_frame_buf->buf,
5513*fb1b10abSAndroid Build Coastguard Worker                                 &encode_frame_result->coded_frame);
5514*fb1b10abSAndroid Build Coastguard Worker   }
5515*fb1b10abSAndroid Build Coastguard Worker }
5516*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
5517*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
5518*fb1b10abSAndroid Build Coastguard Worker 
5519*fb1b10abSAndroid Build Coastguard Worker static void encode_frame_to_data_rate(
5520*fb1b10abSAndroid Build Coastguard Worker     VP9_COMP *cpi, size_t *size, uint8_t *dest, size_t dest_size,
5521*fb1b10abSAndroid Build Coastguard Worker     unsigned int *frame_flags, ENCODE_FRAME_RESULT *encode_frame_result) {
5522*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
5523*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
5524*fb1b10abSAndroid Build Coastguard Worker   struct segmentation *const seg = &cm->seg;
5525*fb1b10abSAndroid Build Coastguard Worker   TX_SIZE t;
5526*fb1b10abSAndroid Build Coastguard Worker 
5527*fb1b10abSAndroid Build Coastguard Worker   if (vp9_svc_check_skip_enhancement_layer(cpi)) return;
5528*fb1b10abSAndroid Build Coastguard Worker 
5529*fb1b10abSAndroid Build Coastguard Worker   set_ext_overrides(cpi);
5530*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
5531*fb1b10abSAndroid Build Coastguard Worker 
5532*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
5533*fb1b10abSAndroid Build Coastguard Worker   // Spatial denoise of key frame.
5534*fb1b10abSAndroid Build Coastguard Worker   if (is_spatial_denoise_enabled(cpi)) spatial_denoise_frame(cpi);
5535*fb1b10abSAndroid Build Coastguard Worker #endif
5536*fb1b10abSAndroid Build Coastguard Worker 
5537*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame == 0) {
5538*fb1b10abSAndroid Build Coastguard Worker     // Update frame index
5539*fb1b10abSAndroid Build Coastguard Worker     set_frame_index(cpi, cm);
5540*fb1b10abSAndroid Build Coastguard Worker 
5541*fb1b10abSAndroid Build Coastguard Worker     // Set the arf sign bias for this frame.
5542*fb1b10abSAndroid Build Coastguard Worker     set_ref_sign_bias(cpi);
5543*fb1b10abSAndroid Build Coastguard Worker   }
5544*fb1b10abSAndroid Build Coastguard Worker 
5545*fb1b10abSAndroid Build Coastguard Worker   // On the very first frame set the deadline_mode_previous_frame to
5546*fb1b10abSAndroid Build Coastguard Worker   // the current mode.
5547*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.current_video_frame == 0)
5548*fb1b10abSAndroid Build Coastguard Worker     cpi->deadline_mode_previous_frame = cpi->oxcf.mode;
5549*fb1b10abSAndroid Build Coastguard Worker 
5550*fb1b10abSAndroid Build Coastguard Worker   // Set default state for segment based loop filter update flags.
5551*fb1b10abSAndroid Build Coastguard Worker   cm->lf.mode_ref_delta_update = 0;
5552*fb1b10abSAndroid Build Coastguard Worker 
5553*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
5554*fb1b10abSAndroid Build Coastguard Worker     cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
5555*fb1b10abSAndroid Build Coastguard Worker 
5556*fb1b10abSAndroid Build Coastguard Worker   // Set various flags etc to special state if it is a key frame.
5557*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
5558*fb1b10abSAndroid Build Coastguard Worker     // Reset the loop filter deltas and segmentation map.
5559*fb1b10abSAndroid Build Coastguard Worker     vp9_reset_segment_features(&cm->seg);
5560*fb1b10abSAndroid Build Coastguard Worker 
5561*fb1b10abSAndroid Build Coastguard Worker     // If segmentation is enabled force a map update for key frames.
5562*fb1b10abSAndroid Build Coastguard Worker     if (seg->enabled) {
5563*fb1b10abSAndroid Build Coastguard Worker       seg->update_map = 1;
5564*fb1b10abSAndroid Build Coastguard Worker       seg->update_data = 1;
5565*fb1b10abSAndroid Build Coastguard Worker     }
5566*fb1b10abSAndroid Build Coastguard Worker 
5567*fb1b10abSAndroid Build Coastguard Worker     // The alternate reference frame cannot be active for a key frame.
5568*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.source_alt_ref_active = 0;
5569*fb1b10abSAndroid Build Coastguard Worker 
5570*fb1b10abSAndroid Build Coastguard Worker     cm->error_resilient_mode = oxcf->error_resilient_mode;
5571*fb1b10abSAndroid Build Coastguard Worker     cm->frame_parallel_decoding_mode = oxcf->frame_parallel_decoding_mode;
5572*fb1b10abSAndroid Build Coastguard Worker 
5573*fb1b10abSAndroid Build Coastguard Worker     // By default, encoder assumes decoder can use prev_mi.
5574*fb1b10abSAndroid Build Coastguard Worker     if (cm->error_resilient_mode) {
5575*fb1b10abSAndroid Build Coastguard Worker       cm->frame_parallel_decoding_mode = 1;
5576*fb1b10abSAndroid Build Coastguard Worker       cm->reset_frame_context = 0;
5577*fb1b10abSAndroid Build Coastguard Worker       cm->refresh_frame_context = 0;
5578*fb1b10abSAndroid Build Coastguard Worker     } else if (cm->intra_only) {
5579*fb1b10abSAndroid Build Coastguard Worker       // Only reset the current context.
5580*fb1b10abSAndroid Build Coastguard Worker       cm->reset_frame_context = 2;
5581*fb1b10abSAndroid Build Coastguard Worker     }
5582*fb1b10abSAndroid Build Coastguard Worker   }
5583*fb1b10abSAndroid Build Coastguard Worker 
5584*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->tuning == VP8_TUNE_SSIM) set_mb_ssim_rdmult_scaling(cpi);
5585*fb1b10abSAndroid Build Coastguard Worker 
5586*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->aq_mode == PERCEPTUAL_AQ) {
5587*fb1b10abSAndroid Build Coastguard Worker     init_mb_wiener_var_buffer(cpi);
5588*fb1b10abSAndroid Build Coastguard Worker     set_mb_wiener_variance(cpi);
5589*fb1b10abSAndroid Build Coastguard Worker   }
5590*fb1b10abSAndroid Build Coastguard Worker 
5591*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
5592*fb1b10abSAndroid Build Coastguard Worker 
5593*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
5594*fb1b10abSAndroid Build Coastguard Worker   memset(cpi->mode_chosen_counts, 0,
5595*fb1b10abSAndroid Build Coastguard Worker          MAX_MODES * sizeof(*cpi->mode_chosen_counts));
5596*fb1b10abSAndroid Build Coastguard Worker #endif
5597*fb1b10abSAndroid Build Coastguard Worker   // Backup to ensure consistency between recodes
5598*fb1b10abSAndroid Build Coastguard Worker   save_encode_params(cpi);
5599*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_ratectrl.ready &&
5600*fb1b10abSAndroid Build Coastguard Worker       (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_RDMULT) != 0 &&
5601*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_ratectrl.funcs.get_frame_rdmult != NULL) {
5602*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_err_t codec_status;
5603*fb1b10abSAndroid Build Coastguard Worker     const GF_GROUP *gf_group = &cpi->twopass.gf_group;
5604*fb1b10abSAndroid Build Coastguard Worker     FRAME_UPDATE_TYPE update_type = gf_group->update_type[gf_group->index];
5605*fb1b10abSAndroid Build Coastguard Worker     const int ref_frame_flags = get_ref_frame_flags(cpi);
5606*fb1b10abSAndroid Build Coastguard Worker     RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES];
5607*fb1b10abSAndroid Build Coastguard Worker     const RefCntBuffer *curr_frame_buf = get_ref_cnt_buffer(cm, cm->new_fb_idx);
5608*fb1b10abSAndroid Build Coastguard Worker     // index 0 of a gf group is always KEY/OVERLAY/GOLDEN.
5609*fb1b10abSAndroid Build Coastguard Worker     // index 1 refers to the first encoding frame in a gf group.
5610*fb1b10abSAndroid Build Coastguard Worker     // Therefore if it is ARF_UPDATE, it means this gf group uses alt ref.
5611*fb1b10abSAndroid Build Coastguard Worker     // See function define_gf_group_structure().
5612*fb1b10abSAndroid Build Coastguard Worker     const int use_alt_ref = gf_group->update_type[1] == ARF_UPDATE;
5613*fb1b10abSAndroid Build Coastguard Worker     int ext_rdmult = VPX_DEFAULT_RDMULT;
5614*fb1b10abSAndroid Build Coastguard Worker     get_ref_frame_bufs(cpi, ref_frame_bufs);
5615*fb1b10abSAndroid Build Coastguard Worker     codec_status = vp9_extrc_get_frame_rdmult(
5616*fb1b10abSAndroid Build Coastguard Worker         &cpi->ext_ratectrl, curr_frame_buf->frame_index,
5617*fb1b10abSAndroid Build Coastguard Worker         cm->current_frame_coding_index, gf_group->index, update_type,
5618*fb1b10abSAndroid Build Coastguard Worker         gf_group->gf_group_size, use_alt_ref, ref_frame_bufs, ref_frame_flags,
5619*fb1b10abSAndroid Build Coastguard Worker         &ext_rdmult);
5620*fb1b10abSAndroid Build Coastguard Worker     if (codec_status != VPX_CODEC_OK) {
5621*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, codec_status,
5622*fb1b10abSAndroid Build Coastguard Worker                          "vp9_extrc_get_frame_rdmult() failed");
5623*fb1b10abSAndroid Build Coastguard Worker     }
5624*fb1b10abSAndroid Build Coastguard Worker     cpi->ext_ratectrl.ext_rdmult = ext_rdmult;
5625*fb1b10abSAndroid Build Coastguard Worker   }
5626*fb1b10abSAndroid Build Coastguard Worker 
5627*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.recode_loop == DISALLOW_RECODE) {
5628*fb1b10abSAndroid Build Coastguard Worker     if (!encode_without_recode_loop(cpi, size, dest, dest_size)) return;
5629*fb1b10abSAndroid Build Coastguard Worker   } else {
5630*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5631*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
5632*fb1b10abSAndroid Build Coastguard Worker     encode_with_recode_loop(cpi, size, dest, dest_size,
5633*fb1b10abSAndroid Build Coastguard Worker                             &encode_frame_result->rq_history);
5634*fb1b10abSAndroid Build Coastguard Worker #else  // CONFIG_RATE_CTRL
5635*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5636*fb1b10abSAndroid Build Coastguard Worker     start_timing(cpi, encode_with_recode_loop_time);
5637*fb1b10abSAndroid Build Coastguard Worker #endif
5638*fb1b10abSAndroid Build Coastguard Worker     encode_with_recode_loop(cpi, size, dest, dest_size);
5639*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5640*fb1b10abSAndroid Build Coastguard Worker     end_timing(cpi, encode_with_recode_loop_time);
5641*fb1b10abSAndroid Build Coastguard Worker #endif
5642*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
5643*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
5644*fb1b10abSAndroid Build Coastguard Worker   }
5645*fb1b10abSAndroid Build Coastguard Worker 
5646*fb1b10abSAndroid Build Coastguard Worker   // TODO(jingning): When using show existing frame mode, we assume that the
5647*fb1b10abSAndroid Build Coastguard Worker   // current ARF will be directly used as the final reconstructed frame. This is
5648*fb1b10abSAndroid Build Coastguard Worker   // an encoder control scheme. One could in principle explore other
5649*fb1b10abSAndroid Build Coastguard Worker   // possibilities to arrange the reference frame buffer and their coding order.
5650*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_existing_frame) {
5651*fb1b10abSAndroid Build Coastguard Worker     ref_cnt_fb(cm->buffer_pool->frame_bufs, &cm->new_fb_idx,
5652*fb1b10abSAndroid Build Coastguard Worker                cm->ref_frame_map[cpi->alt_fb_idx]);
5653*fb1b10abSAndroid Build Coastguard Worker   }
5654*fb1b10abSAndroid Build Coastguard Worker 
5655*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5656*fb1b10abSAndroid Build Coastguard Worker   // Disable segmentation if it decrease rate/distortion ratio
5657*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
5658*fb1b10abSAndroid Build Coastguard Worker     vp9_try_disable_lookahead_aq(cpi, size, dest, dest_size);
5659*fb1b10abSAndroid Build Coastguard Worker #endif
5660*fb1b10abSAndroid Build Coastguard Worker 
5661*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
5662*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_DENOISED
5663*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->noise_sensitivity > 0 && denoise_svc(cpi)) {
5664*fb1b10abSAndroid Build Coastguard Worker     vpx_write_yuv_frame(yuv_denoised_file,
5665*fb1b10abSAndroid Build Coastguard Worker                         &cpi->denoiser.running_avg_y[INTRA_FRAME]);
5666*fb1b10abSAndroid Build Coastguard Worker   }
5667*fb1b10abSAndroid Build Coastguard Worker #endif
5668*fb1b10abSAndroid Build Coastguard Worker #endif
5669*fb1b10abSAndroid Build Coastguard Worker #ifdef OUTPUT_YUV_SKINMAP
5670*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.current_video_frame > 1) {
5671*fb1b10abSAndroid Build Coastguard Worker     vp9_output_skin_map(cpi, yuv_skinmap_file);
5672*fb1b10abSAndroid Build Coastguard Worker   }
5673*fb1b10abSAndroid Build Coastguard Worker #endif
5674*fb1b10abSAndroid Build Coastguard Worker 
5675*fb1b10abSAndroid Build Coastguard Worker   // Special case code to reduce pulsing when key frames are forced at a
5676*fb1b10abSAndroid Build Coastguard Worker   // fixed interval. Note the reconstruction error if it is the frame before
5677*fb1b10abSAndroid Build Coastguard Worker   // the force key frame
5678*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
5679*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5680*fb1b10abSAndroid Build Coastguard Worker     if (cm->use_highbitdepth) {
5681*fb1b10abSAndroid Build Coastguard Worker       cpi->ambient_err =
5682*fb1b10abSAndroid Build Coastguard Worker           vpx_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
5683*fb1b10abSAndroid Build Coastguard Worker     } else {
5684*fb1b10abSAndroid Build Coastguard Worker       cpi->ambient_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
5685*fb1b10abSAndroid Build Coastguard Worker     }
5686*fb1b10abSAndroid Build Coastguard Worker #else
5687*fb1b10abSAndroid Build Coastguard Worker     cpi->ambient_err = vpx_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
5688*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
5689*fb1b10abSAndroid Build Coastguard Worker   }
5690*fb1b10abSAndroid Build Coastguard Worker 
5691*fb1b10abSAndroid Build Coastguard Worker   // If the encoder forced a KEY_FRAME decision
5692*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) cpi->refresh_last_frame = 1;
5693*fb1b10abSAndroid Build Coastguard Worker 
5694*fb1b10abSAndroid Build Coastguard Worker   cm->frame_to_show = get_frame_new_buffer(cm);
5695*fb1b10abSAndroid Build Coastguard Worker   cm->frame_to_show->color_space = cm->color_space;
5696*fb1b10abSAndroid Build Coastguard Worker   cm->frame_to_show->color_range = cm->color_range;
5697*fb1b10abSAndroid Build Coastguard Worker   cm->frame_to_show->render_width = cm->render_width;
5698*fb1b10abSAndroid Build Coastguard Worker   cm->frame_to_show->render_height = cm->render_height;
5699*fb1b10abSAndroid Build Coastguard Worker 
5700*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5701*fb1b10abSAndroid Build Coastguard Worker   start_timing(cpi, loopfilter_frame_time);
5702*fb1b10abSAndroid Build Coastguard Worker #endif
5703*fb1b10abSAndroid Build Coastguard Worker   // Pick the loop filter level for the frame.
5704*fb1b10abSAndroid Build Coastguard Worker   loopfilter_frame(cpi, cm);
5705*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5706*fb1b10abSAndroid Build Coastguard Worker   end_timing(cpi, loopfilter_frame_time);
5707*fb1b10abSAndroid Build Coastguard Worker #endif
5708*fb1b10abSAndroid Build Coastguard Worker 
5709*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.use_post_encode_drop) save_coding_context(cpi);
5710*fb1b10abSAndroid Build Coastguard Worker 
5711*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5712*fb1b10abSAndroid Build Coastguard Worker   start_timing(cpi, vp9_pack_bitstream_time);
5713*fb1b10abSAndroid Build Coastguard Worker #endif
5714*fb1b10abSAndroid Build Coastguard Worker   // build the bitstream
5715*fb1b10abSAndroid Build Coastguard Worker   vp9_pack_bitstream(cpi, dest, dest_size, size);
5716*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
5717*fb1b10abSAndroid Build Coastguard Worker   end_timing(cpi, vp9_pack_bitstream_time);
5718*fb1b10abSAndroid Build Coastguard Worker #endif
5719*fb1b10abSAndroid Build Coastguard Worker 
5720*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_ratectrl.ready &&
5721*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_ratectrl.funcs.update_encodeframe_result != NULL) {
5722*fb1b10abSAndroid Build Coastguard Worker     vpx_codec_err_t codec_status = vp9_extrc_update_encodeframe_result(
5723*fb1b10abSAndroid Build Coastguard Worker         &cpi->ext_ratectrl, (*size) << 3, cm->base_qindex);
5724*fb1b10abSAndroid Build Coastguard Worker     if (codec_status != VPX_CODEC_OK) {
5725*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, codec_status,
5726*fb1b10abSAndroid Build Coastguard Worker                          "vp9_extrc_update_encodeframe_result() failed");
5727*fb1b10abSAndroid Build Coastguard Worker     }
5728*fb1b10abSAndroid Build Coastguard Worker   }
5729*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY
5730*fb1b10abSAndroid Build Coastguard Worker   (void)encode_frame_result;
5731*fb1b10abSAndroid Build Coastguard Worker   assert(encode_frame_result == NULL);
5732*fb1b10abSAndroid Build Coastguard Worker #else  // CONFIG_REALTIME_ONLY
5733*fb1b10abSAndroid Build Coastguard Worker   if (encode_frame_result != NULL) {
5734*fb1b10abSAndroid Build Coastguard Worker     const RefCntBuffer *coded_frame_buf =
5735*fb1b10abSAndroid Build Coastguard Worker         get_ref_cnt_buffer(cm, cm->new_fb_idx);
5736*fb1b10abSAndroid Build Coastguard Worker     RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES];
5737*fb1b10abSAndroid Build Coastguard Worker     FRAME_UPDATE_TYPE update_type =
5738*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index];
5739*fb1b10abSAndroid Build Coastguard Worker     int quantize_index = vp9_get_quantizer(cpi);
5740*fb1b10abSAndroid Build Coastguard Worker     get_ref_frame_bufs(cpi, ref_frame_bufs);
5741*fb1b10abSAndroid Build Coastguard Worker     // update_encode_frame_result() depends on twopass.gf_group.index and
5742*fb1b10abSAndroid Build Coastguard Worker     // cm->new_fb_idx, cpi->Source, cpi->lst_fb_idx, cpi->gld_fb_idx and
5743*fb1b10abSAndroid Build Coastguard Worker     // cpi->alt_fb_idx are updated for current frame and have
5744*fb1b10abSAndroid Build Coastguard Worker     // not been updated for the next frame yet.
5745*fb1b10abSAndroid Build Coastguard Worker     // The update locations are as follows.
5746*fb1b10abSAndroid Build Coastguard Worker     // 1) twopass.gf_group.index is initialized at define_gf_group by vp9_zero()
5747*fb1b10abSAndroid Build Coastguard Worker     // for the first frame in the gf_group and is updated for the next frame at
5748*fb1b10abSAndroid Build Coastguard Worker     // vp9_twopass_postencode_update().
5749*fb1b10abSAndroid Build Coastguard Worker     // 2) cpi->Source is updated at the beginning of vp9_get_compressed_data()
5750*fb1b10abSAndroid Build Coastguard Worker     // 3) cm->new_fb_idx is updated at the beginning of
5751*fb1b10abSAndroid Build Coastguard Worker     // vp9_get_compressed_data() by get_free_fb(cm).
5752*fb1b10abSAndroid Build Coastguard Worker     // 4) cpi->lst_fb_idx/gld_fb_idx/alt_fb_idx will be updated for the next
5753*fb1b10abSAndroid Build Coastguard Worker     // frame at vp9_update_reference_frames().
5754*fb1b10abSAndroid Build Coastguard Worker     // This function needs to be called before vp9_update_reference_frames().
5755*fb1b10abSAndroid Build Coastguard Worker     // TODO(angiebird): Improve the codebase to make the update of frame
5756*fb1b10abSAndroid Build Coastguard Worker     // dependent variables more robust.
5757*fb1b10abSAndroid Build Coastguard Worker 
5758*fb1b10abSAndroid Build Coastguard Worker     update_encode_frame_result_basic(update_type, coded_frame_buf->frame_index,
5759*fb1b10abSAndroid Build Coastguard Worker                                      quantize_index, encode_frame_result);
5760*fb1b10abSAndroid Build Coastguard Worker     if (cpi->ext_ratectrl.ready && cpi->ext_ratectrl.log_file) {
5761*fb1b10abSAndroid Build Coastguard Worker       PSNR_STATS psnr =
5762*fb1b10abSAndroid Build Coastguard Worker           compute_psnr_stats(cpi->Source, &coded_frame_buf->buf, cm->bit_depth,
5763*fb1b10abSAndroid Build Coastguard Worker                              cpi->oxcf.input_bit_depth);
5764*fb1b10abSAndroid Build Coastguard Worker       fprintf(cpi->ext_ratectrl.log_file,
5765*fb1b10abSAndroid Build Coastguard Worker               "ENCODE_FRAME_RESULT gop_index %d psnr %f bits %zu\n",
5766*fb1b10abSAndroid Build Coastguard Worker               cpi->twopass.gf_group.index, psnr.psnr[0], (*size) << 3);
5767*fb1b10abSAndroid Build Coastguard Worker     }
5768*fb1b10abSAndroid Build Coastguard Worker 
5769*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
5770*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.use_simple_encode_api) {
5771*fb1b10abSAndroid Build Coastguard Worker       const int ref_frame_flags = get_ref_frame_flags(cpi);
5772*fb1b10abSAndroid Build Coastguard Worker       update_encode_frame_result_simple_encode(
5773*fb1b10abSAndroid Build Coastguard Worker           ref_frame_flags,
5774*fb1b10abSAndroid Build Coastguard Worker           cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
5775*fb1b10abSAndroid Build Coastguard Worker           cpi->Source, coded_frame_buf, ref_frame_bufs, quantize_index,
5776*fb1b10abSAndroid Build Coastguard Worker           cm->bit_depth, cpi->oxcf.input_bit_depth, cpi->td.counts,
5777*fb1b10abSAndroid Build Coastguard Worker           cpi->partition_info, cpi->motion_vector_info, cpi->tpl_stats_info,
5778*fb1b10abSAndroid Build Coastguard Worker           encode_frame_result);
5779*fb1b10abSAndroid Build Coastguard Worker     }
5780*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
5781*fb1b10abSAndroid Build Coastguard Worker   }
5782*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_REALTIME_ONLY
5783*fb1b10abSAndroid Build Coastguard Worker 
5784*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.use_post_encode_drop && cm->base_qindex < cpi->rc.worst_quality &&
5785*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.spatial_layer_id == 0 && post_encode_drop_cbr(cpi, size)) {
5786*fb1b10abSAndroid Build Coastguard Worker     restore_coding_context(cpi);
5787*fb1b10abSAndroid Build Coastguard Worker     return;
5788*fb1b10abSAndroid Build Coastguard Worker   }
5789*fb1b10abSAndroid Build Coastguard Worker 
5790*fb1b10abSAndroid Build Coastguard Worker   cpi->last_frame_dropped = 0;
5791*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.last_layer_dropped[cpi->svc.spatial_layer_id] = 0;
5792*fb1b10abSAndroid Build Coastguard Worker   if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)
5793*fb1b10abSAndroid Build Coastguard Worker     cpi->svc.num_encoded_top_layer++;
5794*fb1b10abSAndroid Build Coastguard Worker 
5795*fb1b10abSAndroid Build Coastguard Worker   // Keep track of the frame buffer index updated/refreshed for the
5796*fb1b10abSAndroid Build Coastguard Worker   // current encoded TL0 superframe.
5797*fb1b10abSAndroid Build Coastguard Worker   if (cpi->svc.temporal_layer_id == 0) {
5798*fb1b10abSAndroid Build Coastguard Worker     if (cpi->refresh_last_frame)
5799*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->lst_fb_idx;
5800*fb1b10abSAndroid Build Coastguard Worker     else if (cpi->refresh_golden_frame)
5801*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->gld_fb_idx;
5802*fb1b10abSAndroid Build Coastguard Worker     else if (cpi->refresh_alt_ref_frame)
5803*fb1b10abSAndroid Build Coastguard Worker       cpi->svc.fb_idx_upd_tl0[cpi->svc.spatial_layer_id] = cpi->alt_fb_idx;
5804*fb1b10abSAndroid Build Coastguard Worker   }
5805*fb1b10abSAndroid Build Coastguard Worker 
5806*fb1b10abSAndroid Build Coastguard Worker   if (cm->seg.update_map) update_reference_segmentation_map(cpi);
5807*fb1b10abSAndroid Build Coastguard Worker 
5808*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) == 0) {
5809*fb1b10abSAndroid Build Coastguard Worker     release_scaled_references(cpi);
5810*fb1b10abSAndroid Build Coastguard Worker   }
5811*fb1b10abSAndroid Build Coastguard Worker   vp9_update_reference_frames(cpi);
5812*fb1b10abSAndroid Build Coastguard Worker 
5813*fb1b10abSAndroid Build Coastguard Worker   if (!cm->show_existing_frame) {
5814*fb1b10abSAndroid Build Coastguard Worker     for (t = TX_4X4; t <= TX_32X32; ++t) {
5815*fb1b10abSAndroid Build Coastguard Worker       full_to_model_counts(cpi->td.counts->coef[t],
5816*fb1b10abSAndroid Build Coastguard Worker                            cpi->td.rd_counts.coef_counts[t]);
5817*fb1b10abSAndroid Build Coastguard Worker     }
5818*fb1b10abSAndroid Build Coastguard Worker 
5819*fb1b10abSAndroid Build Coastguard Worker     if (!cm->error_resilient_mode && !cm->frame_parallel_decoding_mode) {
5820*fb1b10abSAndroid Build Coastguard Worker       if (!frame_is_intra_only(cm)) {
5821*fb1b10abSAndroid Build Coastguard Worker         vp9_adapt_mode_probs(cm);
5822*fb1b10abSAndroid Build Coastguard Worker         vp9_adapt_mv_probs(cm, cm->allow_high_precision_mv);
5823*fb1b10abSAndroid Build Coastguard Worker       }
5824*fb1b10abSAndroid Build Coastguard Worker       vp9_adapt_coef_probs(cm);
5825*fb1b10abSAndroid Build Coastguard Worker     }
5826*fb1b10abSAndroid Build Coastguard Worker   }
5827*fb1b10abSAndroid Build Coastguard Worker 
5828*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_flags_pending = 0;
5829*fb1b10abSAndroid Build Coastguard Worker 
5830*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_golden_frame == 1)
5831*fb1b10abSAndroid Build Coastguard Worker     cpi->frame_flags |= FRAMEFLAGS_GOLDEN;
5832*fb1b10abSAndroid Build Coastguard Worker   else
5833*fb1b10abSAndroid Build Coastguard Worker     cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
5834*fb1b10abSAndroid Build Coastguard Worker 
5835*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_alt_ref_frame == 1)
5836*fb1b10abSAndroid Build Coastguard Worker     cpi->frame_flags |= FRAMEFLAGS_ALTREF;
5837*fb1b10abSAndroid Build Coastguard Worker   else
5838*fb1b10abSAndroid Build Coastguard Worker     cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
5839*fb1b10abSAndroid Build Coastguard Worker 
5840*fb1b10abSAndroid Build Coastguard Worker   cpi->ref_frame_flags = get_ref_frame_flags(cpi);
5841*fb1b10abSAndroid Build Coastguard Worker 
5842*fb1b10abSAndroid Build Coastguard Worker   cm->last_frame_type = cm->frame_type;
5843*fb1b10abSAndroid Build Coastguard Worker 
5844*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_postencode_update(cpi, *size);
5845*fb1b10abSAndroid Build Coastguard Worker 
5846*fb1b10abSAndroid Build Coastguard Worker   if (cpi->compute_frame_low_motion_onepass && oxcf->pass == 0 &&
5847*fb1b10abSAndroid Build Coastguard Worker       !frame_is_intra_only(cm) &&
5848*fb1b10abSAndroid Build Coastguard Worker       (!cpi->use_svc ||
5849*fb1b10abSAndroid Build Coastguard Worker        (cpi->use_svc &&
5850*fb1b10abSAndroid Build Coastguard Worker         !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame &&
5851*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1))) {
5852*fb1b10abSAndroid Build Coastguard Worker     vp9_compute_frame_low_motion(cpi);
5853*fb1b10abSAndroid Build Coastguard Worker   }
5854*fb1b10abSAndroid Build Coastguard Worker 
5855*fb1b10abSAndroid Build Coastguard Worker   *size = VPXMAX(1, *size);
5856*fb1b10abSAndroid Build Coastguard Worker 
5857*fb1b10abSAndroid Build Coastguard Worker #if 0
5858*fb1b10abSAndroid Build Coastguard Worker   output_frame_level_debug_stats(cpi);
5859*fb1b10abSAndroid Build Coastguard Worker #endif
5860*fb1b10abSAndroid Build Coastguard Worker 
5861*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
5862*fb1b10abSAndroid Build Coastguard Worker     // Tell the caller that the frame was coded as a key frame
5863*fb1b10abSAndroid Build Coastguard Worker     *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
5864*fb1b10abSAndroid Build Coastguard Worker   } else {
5865*fb1b10abSAndroid Build Coastguard Worker     *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
5866*fb1b10abSAndroid Build Coastguard Worker   }
5867*fb1b10abSAndroid Build Coastguard Worker 
5868*fb1b10abSAndroid Build Coastguard Worker   // Clear the one shot update flags for segmentation map and mode/ref loop
5869*fb1b10abSAndroid Build Coastguard Worker   // filter deltas.
5870*fb1b10abSAndroid Build Coastguard Worker   cm->seg.update_map = 0;
5871*fb1b10abSAndroid Build Coastguard Worker   cm->seg.update_data = 0;
5872*fb1b10abSAndroid Build Coastguard Worker   cm->lf.mode_ref_delta_update = 0;
5873*fb1b10abSAndroid Build Coastguard Worker 
5874*fb1b10abSAndroid Build Coastguard Worker   // keep track of the last coded dimensions
5875*fb1b10abSAndroid Build Coastguard Worker   cm->last_width = cm->width;
5876*fb1b10abSAndroid Build Coastguard Worker   cm->last_height = cm->height;
5877*fb1b10abSAndroid Build Coastguard Worker 
5878*fb1b10abSAndroid Build Coastguard Worker   // reset to normal state now that we are done.
5879*fb1b10abSAndroid Build Coastguard Worker   if (!cm->show_existing_frame) {
5880*fb1b10abSAndroid Build Coastguard Worker     cm->last_show_frame = cm->show_frame;
5881*fb1b10abSAndroid Build Coastguard Worker     cm->prev_frame = cm->cur_frame;
5882*fb1b10abSAndroid Build Coastguard Worker   }
5883*fb1b10abSAndroid Build Coastguard Worker 
5884*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) {
5885*fb1b10abSAndroid Build Coastguard Worker     vp9_swap_mi_and_prev_mi(cm);
5886*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) vp9_inc_frame_in_layer(cpi);
5887*fb1b10abSAndroid Build Coastguard Worker   }
5888*fb1b10abSAndroid Build Coastguard Worker   update_frame_indexes(cm, cm->show_frame);
5889*fb1b10abSAndroid Build Coastguard Worker 
5890*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) {
5891*fb1b10abSAndroid Build Coastguard Worker     cpi->svc
5892*fb1b10abSAndroid Build Coastguard Worker         .layer_context[cpi->svc.spatial_layer_id *
5893*fb1b10abSAndroid Build Coastguard Worker                            cpi->svc.number_temporal_layers +
5894*fb1b10abSAndroid Build Coastguard Worker                        cpi->svc.temporal_layer_id]
5895*fb1b10abSAndroid Build Coastguard Worker         .last_frame_type = cm->frame_type;
5896*fb1b10abSAndroid Build Coastguard Worker     // Reset layer_sync back to 0 for next frame.
5897*fb1b10abSAndroid Build Coastguard Worker     cpi->svc.spatial_layer_sync[cpi->svc.spatial_layer_id] = 0;
5898*fb1b10abSAndroid Build Coastguard Worker   }
5899*fb1b10abSAndroid Build Coastguard Worker 
5900*fb1b10abSAndroid Build Coastguard Worker   cpi->force_update_segmentation = 0;
5901*fb1b10abSAndroid Build Coastguard Worker 
5902*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5903*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == LOOKAHEAD_AQ)
5904*fb1b10abSAndroid Build Coastguard Worker     vp9_alt_ref_aq_unset_all(cpi->alt_ref_aq, cpi);
5905*fb1b10abSAndroid Build Coastguard Worker #endif
5906*fb1b10abSAndroid Build Coastguard Worker 
5907*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.previous_frame_is_intra_only = cm->intra_only;
5908*fb1b10abSAndroid Build Coastguard Worker   cpi->svc.set_intra_only_frame = 0;
5909*fb1b10abSAndroid Build Coastguard Worker }
5910*fb1b10abSAndroid Build Coastguard Worker 
5911*fb1b10abSAndroid Build Coastguard Worker static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
5912*fb1b10abSAndroid Build Coastguard Worker                       size_t dest_size, unsigned int *frame_flags) {
5913*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_get_svc_params(cpi);
5914*fb1b10abSAndroid Build Coastguard Worker   encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags,
5915*fb1b10abSAndroid Build Coastguard Worker                             /*encode_frame_result = */ NULL);
5916*fb1b10abSAndroid Build Coastguard Worker }
5917*fb1b10abSAndroid Build Coastguard Worker 
5918*fb1b10abSAndroid Build Coastguard Worker static void Pass0Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
5919*fb1b10abSAndroid Build Coastguard Worker                         size_t dest_size, unsigned int *frame_flags) {
5920*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.rc_mode == VPX_CBR) {
5921*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_get_one_pass_cbr_params(cpi);
5922*fb1b10abSAndroid Build Coastguard Worker   } else {
5923*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_get_one_pass_vbr_params(cpi);
5924*fb1b10abSAndroid Build Coastguard Worker   }
5925*fb1b10abSAndroid Build Coastguard Worker   encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags,
5926*fb1b10abSAndroid Build Coastguard Worker                             /*encode_frame_result = */ NULL);
5927*fb1b10abSAndroid Build Coastguard Worker }
5928*fb1b10abSAndroid Build Coastguard Worker 
5929*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
5930*fb1b10abSAndroid Build Coastguard Worker static void Pass2Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
5931*fb1b10abSAndroid Build Coastguard Worker                         size_t dest_size, unsigned int *frame_flags,
5932*fb1b10abSAndroid Build Coastguard Worker                         ENCODE_FRAME_RESULT *encode_frame_result) {
5933*fb1b10abSAndroid Build Coastguard Worker   cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
5934*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
5935*fb1b10abSAndroid Build Coastguard Worker   mismatch_move_frame_idx_w();
5936*fb1b10abSAndroid Build Coastguard Worker #endif
5937*fb1b10abSAndroid Build Coastguard Worker   encode_frame_to_data_rate(cpi, size, dest, dest_size, frame_flags,
5938*fb1b10abSAndroid Build Coastguard Worker                             encode_frame_result);
5939*fb1b10abSAndroid Build Coastguard Worker }
5940*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
5941*fb1b10abSAndroid Build Coastguard Worker 
5942*fb1b10abSAndroid Build Coastguard Worker int vp9_receive_raw_frame(VP9_COMP *cpi, vpx_enc_frame_flags_t frame_flags,
5943*fb1b10abSAndroid Build Coastguard Worker                           YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
5944*fb1b10abSAndroid Build Coastguard Worker                           int64_t end_time) {
5945*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
5946*fb1b10abSAndroid Build Coastguard Worker   struct vpx_usec_timer timer;
5947*fb1b10abSAndroid Build Coastguard Worker   int res = 0;
5948*fb1b10abSAndroid Build Coastguard Worker   const int subsampling_x = sd->subsampling_x;
5949*fb1b10abSAndroid Build Coastguard Worker   const int subsampling_y = sd->subsampling_y;
5950*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
5951*fb1b10abSAndroid Build Coastguard Worker   const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
5952*fb1b10abSAndroid Build Coastguard Worker #else
5953*fb1b10abSAndroid Build Coastguard Worker   const int use_highbitdepth = 0;
5954*fb1b10abSAndroid Build Coastguard Worker #endif
5955*fb1b10abSAndroid Build Coastguard Worker 
5956*fb1b10abSAndroid Build Coastguard Worker   update_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
5957*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
5958*fb1b10abSAndroid Build Coastguard Worker   setup_denoiser_buffer(cpi);
5959*fb1b10abSAndroid Build Coastguard Worker #endif
5960*fb1b10abSAndroid Build Coastguard Worker 
5961*fb1b10abSAndroid Build Coastguard Worker   alloc_raw_frame_buffers(cpi);
5962*fb1b10abSAndroid Build Coastguard Worker 
5963*fb1b10abSAndroid Build Coastguard Worker   vpx_usec_timer_start(&timer);
5964*fb1b10abSAndroid Build Coastguard Worker 
5965*fb1b10abSAndroid Build Coastguard Worker   if (vp9_lookahead_push(cpi->lookahead, sd, time_stamp, end_time,
5966*fb1b10abSAndroid Build Coastguard Worker                          use_highbitdepth, frame_flags))
5967*fb1b10abSAndroid Build Coastguard Worker     res = -1;
5968*fb1b10abSAndroid Build Coastguard Worker   vpx_usec_timer_mark(&timer);
5969*fb1b10abSAndroid Build Coastguard Worker   cpi->time_receive_data += vpx_usec_timer_elapsed(&timer);
5970*fb1b10abSAndroid Build Coastguard Worker 
5971*fb1b10abSAndroid Build Coastguard Worker   if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) &&
5972*fb1b10abSAndroid Build Coastguard Worker       (subsampling_x != 1 || subsampling_y != 1)) {
5973*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_INVALID_PARAM,
5974*fb1b10abSAndroid Build Coastguard Worker                        "Non-4:2:0 color format requires profile 1 or 3");
5975*fb1b10abSAndroid Build Coastguard Worker     res = -1;
5976*fb1b10abSAndroid Build Coastguard Worker   }
5977*fb1b10abSAndroid Build Coastguard Worker   if ((cm->profile == PROFILE_1 || cm->profile == PROFILE_3) &&
5978*fb1b10abSAndroid Build Coastguard Worker       (subsampling_x == 1 && subsampling_y == 1)) {
5979*fb1b10abSAndroid Build Coastguard Worker     vpx_internal_error(&cm->error, VPX_CODEC_INVALID_PARAM,
5980*fb1b10abSAndroid Build Coastguard Worker                        "4:2:0 color format requires profile 0 or 2");
5981*fb1b10abSAndroid Build Coastguard Worker     res = -1;
5982*fb1b10abSAndroid Build Coastguard Worker   }
5983*fb1b10abSAndroid Build Coastguard Worker 
5984*fb1b10abSAndroid Build Coastguard Worker   return res;
5985*fb1b10abSAndroid Build Coastguard Worker }
5986*fb1b10abSAndroid Build Coastguard Worker 
5987*fb1b10abSAndroid Build Coastguard Worker static int frame_is_reference(const VP9_COMP *cpi) {
5988*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *cm = &cpi->common;
5989*fb1b10abSAndroid Build Coastguard Worker 
5990*fb1b10abSAndroid Build Coastguard Worker   return cm->frame_type == KEY_FRAME || cpi->refresh_last_frame ||
5991*fb1b10abSAndroid Build Coastguard Worker          cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame ||
5992*fb1b10abSAndroid Build Coastguard Worker          cm->refresh_frame_context || cm->lf.mode_ref_delta_update ||
5993*fb1b10abSAndroid Build Coastguard Worker          cm->seg.update_map || cm->seg.update_data;
5994*fb1b10abSAndroid Build Coastguard Worker }
5995*fb1b10abSAndroid Build Coastguard Worker 
5996*fb1b10abSAndroid Build Coastguard Worker static void adjust_frame_rate(VP9_COMP *cpi,
5997*fb1b10abSAndroid Build Coastguard Worker                               const struct lookahead_entry *source) {
5998*fb1b10abSAndroid Build Coastguard Worker   int64_t this_duration;
5999*fb1b10abSAndroid Build Coastguard Worker   int step = 0;
6000*fb1b10abSAndroid Build Coastguard Worker 
6001*fb1b10abSAndroid Build Coastguard Worker   if (source->ts_start == cpi->first_time_stamp_ever) {
6002*fb1b10abSAndroid Build Coastguard Worker     this_duration = source->ts_end - source->ts_start;
6003*fb1b10abSAndroid Build Coastguard Worker     step = 1;
6004*fb1b10abSAndroid Build Coastguard Worker   } else {
6005*fb1b10abSAndroid Build Coastguard Worker     int64_t last_duration =
6006*fb1b10abSAndroid Build Coastguard Worker         cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
6007*fb1b10abSAndroid Build Coastguard Worker 
6008*fb1b10abSAndroid Build Coastguard Worker     this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
6009*fb1b10abSAndroid Build Coastguard Worker 
6010*fb1b10abSAndroid Build Coastguard Worker     // do a step update if the duration changes by 10%
6011*fb1b10abSAndroid Build Coastguard Worker     if (last_duration)
6012*fb1b10abSAndroid Build Coastguard Worker       step = (int)((this_duration - last_duration) * 10 / last_duration);
6013*fb1b10abSAndroid Build Coastguard Worker   }
6014*fb1b10abSAndroid Build Coastguard Worker 
6015*fb1b10abSAndroid Build Coastguard Worker   if (this_duration) {
6016*fb1b10abSAndroid Build Coastguard Worker     if (step) {
6017*fb1b10abSAndroid Build Coastguard Worker       vp9_new_framerate(cpi, 10000000.0 / this_duration);
6018*fb1b10abSAndroid Build Coastguard Worker     } else {
6019*fb1b10abSAndroid Build Coastguard Worker       // Average this frame's rate into the last second's average
6020*fb1b10abSAndroid Build Coastguard Worker       // frame rate. If we haven't seen 1 second yet, then average
6021*fb1b10abSAndroid Build Coastguard Worker       // over the whole interval seen.
6022*fb1b10abSAndroid Build Coastguard Worker       const double interval = VPXMIN(
6023*fb1b10abSAndroid Build Coastguard Worker           (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
6024*fb1b10abSAndroid Build Coastguard Worker       double avg_duration = 10000000.0 / cpi->framerate;
6025*fb1b10abSAndroid Build Coastguard Worker       avg_duration *= (interval - avg_duration + this_duration);
6026*fb1b10abSAndroid Build Coastguard Worker       avg_duration /= interval;
6027*fb1b10abSAndroid Build Coastguard Worker 
6028*fb1b10abSAndroid Build Coastguard Worker       vp9_new_framerate(cpi, 10000000.0 / avg_duration);
6029*fb1b10abSAndroid Build Coastguard Worker     }
6030*fb1b10abSAndroid Build Coastguard Worker   }
6031*fb1b10abSAndroid Build Coastguard Worker   cpi->last_time_stamp_seen = source->ts_start;
6032*fb1b10abSAndroid Build Coastguard Worker   cpi->last_end_time_stamp_seen = source->ts_end;
6033*fb1b10abSAndroid Build Coastguard Worker }
6034*fb1b10abSAndroid Build Coastguard Worker 
6035*fb1b10abSAndroid Build Coastguard Worker // Returns 0 if this is not an alt ref else the offset of the source frame
6036*fb1b10abSAndroid Build Coastguard Worker // used as the arf midpoint.
6037*fb1b10abSAndroid Build Coastguard Worker static int get_arf_src_index(VP9_COMP *cpi) {
6038*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
6039*fb1b10abSAndroid Build Coastguard Worker   int arf_src_index = 0;
6040*fb1b10abSAndroid Build Coastguard Worker   if (is_altref_enabled(cpi)) {
6041*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.pass == 2) {
6042*fb1b10abSAndroid Build Coastguard Worker       const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
6043*fb1b10abSAndroid Build Coastguard Worker       if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
6044*fb1b10abSAndroid Build Coastguard Worker         arf_src_index = gf_group->arf_src_offset[gf_group->index];
6045*fb1b10abSAndroid Build Coastguard Worker       }
6046*fb1b10abSAndroid Build Coastguard Worker     } else if (rc->source_alt_ref_pending) {
6047*fb1b10abSAndroid Build Coastguard Worker       arf_src_index = rc->frames_till_gf_update_due;
6048*fb1b10abSAndroid Build Coastguard Worker     }
6049*fb1b10abSAndroid Build Coastguard Worker   }
6050*fb1b10abSAndroid Build Coastguard Worker   return arf_src_index;
6051*fb1b10abSAndroid Build Coastguard Worker }
6052*fb1b10abSAndroid Build Coastguard Worker 
6053*fb1b10abSAndroid Build Coastguard Worker static void check_src_altref(VP9_COMP *cpi,
6054*fb1b10abSAndroid Build Coastguard Worker                              const struct lookahead_entry *source) {
6055*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
6056*fb1b10abSAndroid Build Coastguard Worker 
6057*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 2) {
6058*fb1b10abSAndroid Build Coastguard Worker     const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
6059*fb1b10abSAndroid Build Coastguard Worker     rc->is_src_frame_alt_ref =
6060*fb1b10abSAndroid Build Coastguard Worker         (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
6061*fb1b10abSAndroid Build Coastguard Worker   } else {
6062*fb1b10abSAndroid Build Coastguard Worker     rc->is_src_frame_alt_ref =
6063*fb1b10abSAndroid Build Coastguard Worker         cpi->alt_ref_source && (source == cpi->alt_ref_source);
6064*fb1b10abSAndroid Build Coastguard Worker   }
6065*fb1b10abSAndroid Build Coastguard Worker 
6066*fb1b10abSAndroid Build Coastguard Worker   if (rc->is_src_frame_alt_ref) {
6067*fb1b10abSAndroid Build Coastguard Worker     // Current frame is an ARF overlay frame.
6068*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_ref_source = NULL;
6069*fb1b10abSAndroid Build Coastguard Worker 
6070*fb1b10abSAndroid Build Coastguard Worker     // Don't refresh the last buffer for an ARF overlay frame. It will
6071*fb1b10abSAndroid Build Coastguard Worker     // become the GF so preserve last as an alternative prediction option.
6072*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_last_frame = 0;
6073*fb1b10abSAndroid Build Coastguard Worker   }
6074*fb1b10abSAndroid Build Coastguard Worker }
6075*fb1b10abSAndroid Build Coastguard Worker 
6076*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
6077*fb1b10abSAndroid Build Coastguard Worker static void adjust_image_stat(double y, double u, double v, double all,
6078*fb1b10abSAndroid Build Coastguard Worker                               ImageStat *s) {
6079*fb1b10abSAndroid Build Coastguard Worker   s->stat[Y] += y;
6080*fb1b10abSAndroid Build Coastguard Worker   s->stat[U] += u;
6081*fb1b10abSAndroid Build Coastguard Worker   s->stat[V] += v;
6082*fb1b10abSAndroid Build Coastguard Worker   s->stat[ALL] += all;
6083*fb1b10abSAndroid Build Coastguard Worker   s->worst = VPXMIN(s->worst, all);
6084*fb1b10abSAndroid Build Coastguard Worker }
6085*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_INTERNAL_STATS
6086*fb1b10abSAndroid Build Coastguard Worker 
6087*fb1b10abSAndroid Build Coastguard Worker // Adjust the maximum allowable frame size for the target level.
6088*fb1b10abSAndroid Build Coastguard Worker static void level_rc_framerate(VP9_COMP *cpi, int arf_src_index) {
6089*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
6090*fb1b10abSAndroid Build Coastguard Worker   LevelConstraint *const ls = &cpi->level_constraint;
6091*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
6092*fb1b10abSAndroid Build Coastguard Worker   const double max_cpb_size = ls->max_cpb_size;
6093*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
6094*fb1b10abSAndroid Build Coastguard Worker   rc->max_frame_bandwidth = VPXMIN(rc->max_frame_bandwidth, ls->max_frame_size);
6095*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
6096*fb1b10abSAndroid Build Coastguard Worker     rc->max_frame_bandwidth =
6097*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.5));
6098*fb1b10abSAndroid Build Coastguard Worker   } else if (arf_src_index > 0) {
6099*fb1b10abSAndroid Build Coastguard Worker     rc->max_frame_bandwidth =
6100*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.4));
6101*fb1b10abSAndroid Build Coastguard Worker   } else {
6102*fb1b10abSAndroid Build Coastguard Worker     rc->max_frame_bandwidth =
6103*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(rc->max_frame_bandwidth, (int)(max_cpb_size * 0.2));
6104*fb1b10abSAndroid Build Coastguard Worker   }
6105*fb1b10abSAndroid Build Coastguard Worker }
6106*fb1b10abSAndroid Build Coastguard Worker 
6107*fb1b10abSAndroid Build Coastguard Worker static void update_level_info(VP9_COMP *cpi, size_t *size, int arf_src_index) {
6108*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
6109*fb1b10abSAndroid Build Coastguard Worker   Vp9LevelInfo *const level_info = &cpi->level_info;
6110*fb1b10abSAndroid Build Coastguard Worker   Vp9LevelSpec *const level_spec = &level_info->level_spec;
6111*fb1b10abSAndroid Build Coastguard Worker   Vp9LevelStats *const level_stats = &level_info->level_stats;
6112*fb1b10abSAndroid Build Coastguard Worker   int i, idx;
6113*fb1b10abSAndroid Build Coastguard Worker   uint64_t luma_samples, dur_end;
6114*fb1b10abSAndroid Build Coastguard Worker   const uint32_t luma_pic_size = cm->width * cm->height;
6115*fb1b10abSAndroid Build Coastguard Worker   const uint32_t luma_pic_breadth = VPXMAX(cm->width, cm->height);
6116*fb1b10abSAndroid Build Coastguard Worker   LevelConstraint *const level_constraint = &cpi->level_constraint;
6117*fb1b10abSAndroid Build Coastguard Worker   const int8_t level_index = level_constraint->level_index;
6118*fb1b10abSAndroid Build Coastguard Worker   double cpb_data_size;
6119*fb1b10abSAndroid Build Coastguard Worker 
6120*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
6121*fb1b10abSAndroid Build Coastguard Worker 
6122*fb1b10abSAndroid Build Coastguard Worker   // update level_stats
6123*fb1b10abSAndroid Build Coastguard Worker   level_stats->total_compressed_size += *size;
6124*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) {
6125*fb1b10abSAndroid Build Coastguard Worker     level_stats->total_uncompressed_size +=
6126*fb1b10abSAndroid Build Coastguard Worker         luma_pic_size +
6127*fb1b10abSAndroid Build Coastguard Worker         2 * (luma_pic_size >> (cm->subsampling_x + cm->subsampling_y));
6128*fb1b10abSAndroid Build Coastguard Worker     level_stats->time_encoded =
6129*fb1b10abSAndroid Build Coastguard Worker         (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
6130*fb1b10abSAndroid Build Coastguard Worker         (double)TICKS_PER_SEC;
6131*fb1b10abSAndroid Build Coastguard Worker   }
6132*fb1b10abSAndroid Build Coastguard Worker 
6133*fb1b10abSAndroid Build Coastguard Worker   if (arf_src_index > 0) {
6134*fb1b10abSAndroid Build Coastguard Worker     if (!level_stats->seen_first_altref) {
6135*fb1b10abSAndroid Build Coastguard Worker       level_stats->seen_first_altref = 1;
6136*fb1b10abSAndroid Build Coastguard Worker     } else if (level_stats->frames_since_last_altref <
6137*fb1b10abSAndroid Build Coastguard Worker                level_spec->min_altref_distance) {
6138*fb1b10abSAndroid Build Coastguard Worker       level_spec->min_altref_distance = level_stats->frames_since_last_altref;
6139*fb1b10abSAndroid Build Coastguard Worker     }
6140*fb1b10abSAndroid Build Coastguard Worker     level_stats->frames_since_last_altref = 0;
6141*fb1b10abSAndroid Build Coastguard Worker   } else {
6142*fb1b10abSAndroid Build Coastguard Worker     ++level_stats->frames_since_last_altref;
6143*fb1b10abSAndroid Build Coastguard Worker   }
6144*fb1b10abSAndroid Build Coastguard Worker 
6145*fb1b10abSAndroid Build Coastguard Worker   if (level_stats->frame_window_buffer.len < FRAME_WINDOW_SIZE - 1) {
6146*fb1b10abSAndroid Build Coastguard Worker     idx = (level_stats->frame_window_buffer.start +
6147*fb1b10abSAndroid Build Coastguard Worker            level_stats->frame_window_buffer.len++) %
6148*fb1b10abSAndroid Build Coastguard Worker           FRAME_WINDOW_SIZE;
6149*fb1b10abSAndroid Build Coastguard Worker   } else {
6150*fb1b10abSAndroid Build Coastguard Worker     idx = level_stats->frame_window_buffer.start;
6151*fb1b10abSAndroid Build Coastguard Worker     level_stats->frame_window_buffer.start = (idx + 1) % FRAME_WINDOW_SIZE;
6152*fb1b10abSAndroid Build Coastguard Worker   }
6153*fb1b10abSAndroid Build Coastguard Worker   level_stats->frame_window_buffer.buf[idx].ts = cpi->last_time_stamp_seen;
6154*fb1b10abSAndroid Build Coastguard Worker   level_stats->frame_window_buffer.buf[idx].size = (uint32_t)(*size);
6155*fb1b10abSAndroid Build Coastguard Worker   level_stats->frame_window_buffer.buf[idx].luma_samples = luma_pic_size;
6156*fb1b10abSAndroid Build Coastguard Worker 
6157*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
6158*fb1b10abSAndroid Build Coastguard Worker     level_stats->ref_refresh_map = 0;
6159*fb1b10abSAndroid Build Coastguard Worker   } else {
6160*fb1b10abSAndroid Build Coastguard Worker     int count = 0;
6161*fb1b10abSAndroid Build Coastguard Worker     level_stats->ref_refresh_map |= vp9_get_refresh_mask(cpi);
6162*fb1b10abSAndroid Build Coastguard Worker     // Also need to consider the case where the encoder refers to a buffer
6163*fb1b10abSAndroid Build Coastguard Worker     // that has been implicitly refreshed after encoding a keyframe.
6164*fb1b10abSAndroid Build Coastguard Worker     if (!cm->intra_only) {
6165*fb1b10abSAndroid Build Coastguard Worker       level_stats->ref_refresh_map |= (1 << cpi->lst_fb_idx);
6166*fb1b10abSAndroid Build Coastguard Worker       level_stats->ref_refresh_map |= (1 << cpi->gld_fb_idx);
6167*fb1b10abSAndroid Build Coastguard Worker       level_stats->ref_refresh_map |= (1 << cpi->alt_fb_idx);
6168*fb1b10abSAndroid Build Coastguard Worker     }
6169*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < REF_FRAMES; ++i) {
6170*fb1b10abSAndroid Build Coastguard Worker       count += (level_stats->ref_refresh_map >> i) & 1;
6171*fb1b10abSAndroid Build Coastguard Worker     }
6172*fb1b10abSAndroid Build Coastguard Worker     if (count > level_spec->max_ref_frame_buffers) {
6173*fb1b10abSAndroid Build Coastguard Worker       level_spec->max_ref_frame_buffers = count;
6174*fb1b10abSAndroid Build Coastguard Worker     }
6175*fb1b10abSAndroid Build Coastguard Worker   }
6176*fb1b10abSAndroid Build Coastguard Worker 
6177*fb1b10abSAndroid Build Coastguard Worker   // update average_bitrate
6178*fb1b10abSAndroid Build Coastguard Worker   level_spec->average_bitrate = (double)level_stats->total_compressed_size /
6179*fb1b10abSAndroid Build Coastguard Worker                                 125.0 / level_stats->time_encoded;
6180*fb1b10abSAndroid Build Coastguard Worker 
6181*fb1b10abSAndroid Build Coastguard Worker   // update max_luma_sample_rate
6182*fb1b10abSAndroid Build Coastguard Worker   luma_samples = 0;
6183*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < level_stats->frame_window_buffer.len; ++i) {
6184*fb1b10abSAndroid Build Coastguard Worker     idx = (level_stats->frame_window_buffer.start +
6185*fb1b10abSAndroid Build Coastguard Worker            level_stats->frame_window_buffer.len - 1 - i) %
6186*fb1b10abSAndroid Build Coastguard Worker           FRAME_WINDOW_SIZE;
6187*fb1b10abSAndroid Build Coastguard Worker     if (i == 0) {
6188*fb1b10abSAndroid Build Coastguard Worker       dur_end = level_stats->frame_window_buffer.buf[idx].ts;
6189*fb1b10abSAndroid Build Coastguard Worker     }
6190*fb1b10abSAndroid Build Coastguard Worker     if (dur_end - level_stats->frame_window_buffer.buf[idx].ts >=
6191*fb1b10abSAndroid Build Coastguard Worker         TICKS_PER_SEC) {
6192*fb1b10abSAndroid Build Coastguard Worker       break;
6193*fb1b10abSAndroid Build Coastguard Worker     }
6194*fb1b10abSAndroid Build Coastguard Worker     luma_samples += level_stats->frame_window_buffer.buf[idx].luma_samples;
6195*fb1b10abSAndroid Build Coastguard Worker   }
6196*fb1b10abSAndroid Build Coastguard Worker   if (luma_samples > level_spec->max_luma_sample_rate) {
6197*fb1b10abSAndroid Build Coastguard Worker     level_spec->max_luma_sample_rate = luma_samples;
6198*fb1b10abSAndroid Build Coastguard Worker   }
6199*fb1b10abSAndroid Build Coastguard Worker 
6200*fb1b10abSAndroid Build Coastguard Worker   // update max_cpb_size
6201*fb1b10abSAndroid Build Coastguard Worker   cpb_data_size = 0;
6202*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < CPB_WINDOW_SIZE; ++i) {
6203*fb1b10abSAndroid Build Coastguard Worker     if (i >= level_stats->frame_window_buffer.len) break;
6204*fb1b10abSAndroid Build Coastguard Worker     idx = (level_stats->frame_window_buffer.start +
6205*fb1b10abSAndroid Build Coastguard Worker            level_stats->frame_window_buffer.len - 1 - i) %
6206*fb1b10abSAndroid Build Coastguard Worker           FRAME_WINDOW_SIZE;
6207*fb1b10abSAndroid Build Coastguard Worker     cpb_data_size += level_stats->frame_window_buffer.buf[idx].size;
6208*fb1b10abSAndroid Build Coastguard Worker   }
6209*fb1b10abSAndroid Build Coastguard Worker   cpb_data_size = cpb_data_size / 125.0;
6210*fb1b10abSAndroid Build Coastguard Worker   if (cpb_data_size > level_spec->max_cpb_size) {
6211*fb1b10abSAndroid Build Coastguard Worker     level_spec->max_cpb_size = cpb_data_size;
6212*fb1b10abSAndroid Build Coastguard Worker   }
6213*fb1b10abSAndroid Build Coastguard Worker 
6214*fb1b10abSAndroid Build Coastguard Worker   // update max_luma_picture_size
6215*fb1b10abSAndroid Build Coastguard Worker   if (luma_pic_size > level_spec->max_luma_picture_size) {
6216*fb1b10abSAndroid Build Coastguard Worker     level_spec->max_luma_picture_size = luma_pic_size;
6217*fb1b10abSAndroid Build Coastguard Worker   }
6218*fb1b10abSAndroid Build Coastguard Worker 
6219*fb1b10abSAndroid Build Coastguard Worker   // update max_luma_picture_breadth
6220*fb1b10abSAndroid Build Coastguard Worker   if (luma_pic_breadth > level_spec->max_luma_picture_breadth) {
6221*fb1b10abSAndroid Build Coastguard Worker     level_spec->max_luma_picture_breadth = luma_pic_breadth;
6222*fb1b10abSAndroid Build Coastguard Worker   }
6223*fb1b10abSAndroid Build Coastguard Worker 
6224*fb1b10abSAndroid Build Coastguard Worker   // update compression_ratio
6225*fb1b10abSAndroid Build Coastguard Worker   level_spec->compression_ratio = (double)level_stats->total_uncompressed_size *
6226*fb1b10abSAndroid Build Coastguard Worker                                   cm->bit_depth /
6227*fb1b10abSAndroid Build Coastguard Worker                                   level_stats->total_compressed_size / 8.0;
6228*fb1b10abSAndroid Build Coastguard Worker 
6229*fb1b10abSAndroid Build Coastguard Worker   // update max_col_tiles
6230*fb1b10abSAndroid Build Coastguard Worker   if (level_spec->max_col_tiles < (1 << cm->log2_tile_cols)) {
6231*fb1b10abSAndroid Build Coastguard Worker     level_spec->max_col_tiles = (1 << cm->log2_tile_cols);
6232*fb1b10abSAndroid Build Coastguard Worker   }
6233*fb1b10abSAndroid Build Coastguard Worker 
6234*fb1b10abSAndroid Build Coastguard Worker   if (level_index >= 0 && level_constraint->fail_flag == 0) {
6235*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->max_luma_picture_size >
6236*fb1b10abSAndroid Build Coastguard Worker         vp9_level_defs[level_index].max_luma_picture_size) {
6237*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << LUMA_PIC_SIZE_TOO_LARGE);
6238*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6239*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6240*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6241*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[LUMA_PIC_SIZE_TOO_LARGE]);
6242*fb1b10abSAndroid Build Coastguard Worker     }
6243*fb1b10abSAndroid Build Coastguard Worker 
6244*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->max_luma_picture_breadth >
6245*fb1b10abSAndroid Build Coastguard Worker         vp9_level_defs[level_index].max_luma_picture_breadth) {
6246*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << LUMA_PIC_BREADTH_TOO_LARGE);
6247*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6248*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6249*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6250*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[LUMA_PIC_BREADTH_TOO_LARGE]);
6251*fb1b10abSAndroid Build Coastguard Worker     }
6252*fb1b10abSAndroid Build Coastguard Worker 
6253*fb1b10abSAndroid Build Coastguard Worker     if ((double)level_spec->max_luma_sample_rate >
6254*fb1b10abSAndroid Build Coastguard Worker         (double)vp9_level_defs[level_index].max_luma_sample_rate *
6255*fb1b10abSAndroid Build Coastguard Worker             (1 + SAMPLE_RATE_GRACE_P)) {
6256*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << LUMA_SAMPLE_RATE_TOO_LARGE);
6257*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6258*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6259*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6260*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[LUMA_SAMPLE_RATE_TOO_LARGE]);
6261*fb1b10abSAndroid Build Coastguard Worker     }
6262*fb1b10abSAndroid Build Coastguard Worker 
6263*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->max_col_tiles > vp9_level_defs[level_index].max_col_tiles) {
6264*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << TOO_MANY_COLUMN_TILE);
6265*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6266*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6267*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6268*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[TOO_MANY_COLUMN_TILE]);
6269*fb1b10abSAndroid Build Coastguard Worker     }
6270*fb1b10abSAndroid Build Coastguard Worker 
6271*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->min_altref_distance <
6272*fb1b10abSAndroid Build Coastguard Worker         vp9_level_defs[level_index].min_altref_distance) {
6273*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << ALTREF_DIST_TOO_SMALL);
6274*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6275*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6276*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6277*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[ALTREF_DIST_TOO_SMALL]);
6278*fb1b10abSAndroid Build Coastguard Worker     }
6279*fb1b10abSAndroid Build Coastguard Worker 
6280*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->max_ref_frame_buffers >
6281*fb1b10abSAndroid Build Coastguard Worker         vp9_level_defs[level_index].max_ref_frame_buffers) {
6282*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << TOO_MANY_REF_BUFFER);
6283*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6284*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6285*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6286*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[TOO_MANY_REF_BUFFER]);
6287*fb1b10abSAndroid Build Coastguard Worker     }
6288*fb1b10abSAndroid Build Coastguard Worker 
6289*fb1b10abSAndroid Build Coastguard Worker     if (level_spec->max_cpb_size > vp9_level_defs[level_index].max_cpb_size) {
6290*fb1b10abSAndroid Build Coastguard Worker       level_constraint->fail_flag |= (1 << CPB_TOO_LARGE);
6291*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&cm->error, VPX_CODEC_ERROR,
6292*fb1b10abSAndroid Build Coastguard Worker                          "Failed to encode to the target level %d. %s",
6293*fb1b10abSAndroid Build Coastguard Worker                          vp9_level_defs[level_index].level,
6294*fb1b10abSAndroid Build Coastguard Worker                          level_fail_messages[CPB_TOO_LARGE]);
6295*fb1b10abSAndroid Build Coastguard Worker     }
6296*fb1b10abSAndroid Build Coastguard Worker 
6297*fb1b10abSAndroid Build Coastguard Worker     // Set an upper bound for the next frame size. It will be used in
6298*fb1b10abSAndroid Build Coastguard Worker     // level_rc_framerate() before encoding the next frame.
6299*fb1b10abSAndroid Build Coastguard Worker     cpb_data_size = 0;
6300*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < CPB_WINDOW_SIZE - 1; ++i) {
6301*fb1b10abSAndroid Build Coastguard Worker       if (i >= level_stats->frame_window_buffer.len) break;
6302*fb1b10abSAndroid Build Coastguard Worker       idx = (level_stats->frame_window_buffer.start +
6303*fb1b10abSAndroid Build Coastguard Worker              level_stats->frame_window_buffer.len - 1 - i) %
6304*fb1b10abSAndroid Build Coastguard Worker             FRAME_WINDOW_SIZE;
6305*fb1b10abSAndroid Build Coastguard Worker       cpb_data_size += level_stats->frame_window_buffer.buf[idx].size;
6306*fb1b10abSAndroid Build Coastguard Worker     }
6307*fb1b10abSAndroid Build Coastguard Worker     cpb_data_size = cpb_data_size / 125.0;
6308*fb1b10abSAndroid Build Coastguard Worker     level_constraint->max_frame_size =
6309*fb1b10abSAndroid Build Coastguard Worker         (int)((vp9_level_defs[level_index].max_cpb_size - cpb_data_size) *
6310*fb1b10abSAndroid Build Coastguard Worker               1000.0);
6311*fb1b10abSAndroid Build Coastguard Worker     if (level_stats->frame_window_buffer.len < CPB_WINDOW_SIZE - 1)
6312*fb1b10abSAndroid Build Coastguard Worker       level_constraint->max_frame_size >>= 1;
6313*fb1b10abSAndroid Build Coastguard Worker   }
6314*fb1b10abSAndroid Build Coastguard Worker }
6315*fb1b10abSAndroid Build Coastguard Worker 
6316*fb1b10abSAndroid Build Coastguard Worker void vp9_get_ref_frame_info(FRAME_UPDATE_TYPE update_type, int ref_frame_flags,
6317*fb1b10abSAndroid Build Coastguard Worker                             RefCntBuffer *ref_frame_bufs[MAX_INTER_REF_FRAMES],
6318*fb1b10abSAndroid Build Coastguard Worker                             int *ref_frame_coding_indexes,
6319*fb1b10abSAndroid Build Coastguard Worker                             int *ref_frame_valid_list) {
6320*fb1b10abSAndroid Build Coastguard Worker   if (update_type != KF_UPDATE) {
6321*fb1b10abSAndroid Build Coastguard Worker     const VP9_REFFRAME inter_ref_flags[MAX_INTER_REF_FRAMES] = { VP9_LAST_FLAG,
6322*fb1b10abSAndroid Build Coastguard Worker                                                                  VP9_GOLD_FLAG,
6323*fb1b10abSAndroid Build Coastguard Worker                                                                  VP9_ALT_FLAG };
6324*fb1b10abSAndroid Build Coastguard Worker     int i;
6325*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
6326*fb1b10abSAndroid Build Coastguard Worker       assert(ref_frame_bufs[i] != NULL);
6327*fb1b10abSAndroid Build Coastguard Worker       ref_frame_coding_indexes[i] = ref_frame_bufs[i]->frame_coding_index;
6328*fb1b10abSAndroid Build Coastguard Worker       ref_frame_valid_list[i] = (ref_frame_flags & inter_ref_flags[i]) != 0;
6329*fb1b10abSAndroid Build Coastguard Worker     }
6330*fb1b10abSAndroid Build Coastguard Worker   } else {
6331*fb1b10abSAndroid Build Coastguard Worker     // No reference frame is available when this is a key frame.
6332*fb1b10abSAndroid Build Coastguard Worker     int i;
6333*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < MAX_INTER_REF_FRAMES; ++i) {
6334*fb1b10abSAndroid Build Coastguard Worker       ref_frame_coding_indexes[i] = -1;
6335*fb1b10abSAndroid Build Coastguard Worker       ref_frame_valid_list[i] = 0;
6336*fb1b10abSAndroid Build Coastguard Worker     }
6337*fb1b10abSAndroid Build Coastguard Worker   }
6338*fb1b10abSAndroid Build Coastguard Worker }
6339*fb1b10abSAndroid Build Coastguard Worker 
6340*fb1b10abSAndroid Build Coastguard Worker void vp9_init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) {
6341*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->show_idx = -1;  // Actual encoding doesn't happen.
6342*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
6343*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->frame_coding_index = -1;
6344*fb1b10abSAndroid Build Coastguard Worker   vp9_zero(encode_frame_result->coded_frame);
6345*fb1b10abSAndroid Build Coastguard Worker   encode_frame_result->coded_frame.allocated = 0;
6346*fb1b10abSAndroid Build Coastguard Worker   init_rq_history(&encode_frame_result->rq_history);
6347*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
6348*fb1b10abSAndroid Build Coastguard Worker }
6349*fb1b10abSAndroid Build Coastguard Worker 
6350*fb1b10abSAndroid Build Coastguard Worker // Returns if TPL stats need to be calculated.
6351*fb1b10abSAndroid Build Coastguard Worker static INLINE int should_run_tpl(VP9_COMP *cpi, int gf_group_index) {
6352*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
6353*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->sf.enable_tpl_model) return 0;
6354*fb1b10abSAndroid Build Coastguard Worker   // If there is an ARF for this GOP, TPL stats is always calculated.
6355*fb1b10abSAndroid Build Coastguard Worker   if (gf_group_index == 1 &&
6356*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.gf_group.update_type[gf_group_index] == ARF_UPDATE)
6357*fb1b10abSAndroid Build Coastguard Worker     return 1;
6358*fb1b10abSAndroid Build Coastguard Worker   // If this GOP doesn't have an ARF, TPL stats is still calculated, only when
6359*fb1b10abSAndroid Build Coastguard Worker   // external rate control is used.
6360*fb1b10abSAndroid Build Coastguard Worker   if (cpi->ext_ratectrl.ready &&
6361*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_ratectrl.funcs.send_tpl_gop_stats != NULL &&
6362*fb1b10abSAndroid Build Coastguard Worker       rc->frames_till_gf_update_due == rc->baseline_gf_interval &&
6363*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.gf_group.update_type[1] != ARF_UPDATE) {
6364*fb1b10abSAndroid Build Coastguard Worker     return 1;
6365*fb1b10abSAndroid Build Coastguard Worker   }
6366*fb1b10abSAndroid Build Coastguard Worker   return 0;
6367*fb1b10abSAndroid Build Coastguard Worker }
6368*fb1b10abSAndroid Build Coastguard Worker 
6369*fb1b10abSAndroid Build Coastguard Worker int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
6370*fb1b10abSAndroid Build Coastguard Worker                             size_t *size, uint8_t *dest, size_t dest_size,
6371*fb1b10abSAndroid Build Coastguard Worker                             int64_t *time_stamp, int64_t *time_end, int flush,
6372*fb1b10abSAndroid Build Coastguard Worker                             ENCODE_FRAME_RESULT *encode_frame_result) {
6373*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
6374*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
6375*fb1b10abSAndroid Build Coastguard Worker   BufferPool *const pool = cm->buffer_pool;
6376*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
6377*fb1b10abSAndroid Build Coastguard Worker   struct vpx_usec_timer cmptimer;
6378*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *force_src_buffer = NULL;
6379*fb1b10abSAndroid Build Coastguard Worker   struct lookahead_entry *last_source = NULL;
6380*fb1b10abSAndroid Build Coastguard Worker   struct lookahead_entry *source = NULL;
6381*fb1b10abSAndroid Build Coastguard Worker   int arf_src_index;
6382*fb1b10abSAndroid Build Coastguard Worker   const int gf_group_index = cpi->twopass.gf_group.index;
6383*fb1b10abSAndroid Build Coastguard Worker   int i;
6384*fb1b10abSAndroid Build Coastguard Worker 
6385*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6386*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 2) start_timing(cpi, vp9_get_compressed_data_time);
6387*fb1b10abSAndroid Build Coastguard Worker #endif
6388*fb1b10abSAndroid Build Coastguard Worker 
6389*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) {
6390*fb1b10abSAndroid Build Coastguard Worker     vp9_one_pass_svc_start_layer(cpi);
6391*fb1b10abSAndroid Build Coastguard Worker   }
6392*fb1b10abSAndroid Build Coastguard Worker 
6393*fb1b10abSAndroid Build Coastguard Worker   vpx_usec_timer_start(&cmptimer);
6394*fb1b10abSAndroid Build Coastguard Worker 
6395*fb1b10abSAndroid Build Coastguard Worker   vp9_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
6396*fb1b10abSAndroid Build Coastguard Worker 
6397*fb1b10abSAndroid Build Coastguard Worker   // Is multi-arf enabled.
6398*fb1b10abSAndroid Build Coastguard Worker   // Note that at the moment multi_arf is only configured for 2 pass VBR and
6399*fb1b10abSAndroid Build Coastguard Worker   // will not work properly with svc.
6400*fb1b10abSAndroid Build Coastguard Worker   // Enable the Jingning's new "multi_layer_arf" code if "enable_auto_arf"
6401*fb1b10abSAndroid Build Coastguard Worker   // is greater than or equal to 2.
6402*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 2) && !cpi->use_svc && (cpi->oxcf.enable_auto_arf >= 2))
6403*fb1b10abSAndroid Build Coastguard Worker     cpi->multi_layer_arf = 1;
6404*fb1b10abSAndroid Build Coastguard Worker   else
6405*fb1b10abSAndroid Build Coastguard Worker     cpi->multi_layer_arf = 0;
6406*fb1b10abSAndroid Build Coastguard Worker 
6407*fb1b10abSAndroid Build Coastguard Worker   // Normal defaults
6408*fb1b10abSAndroid Build Coastguard Worker   cm->reset_frame_context = 0;
6409*fb1b10abSAndroid Build Coastguard Worker   cm->refresh_frame_context = 1;
6410*fb1b10abSAndroid Build Coastguard Worker   if (!is_one_pass_svc(cpi)) {
6411*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_last_frame = 1;
6412*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_golden_frame = 0;
6413*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_alt_ref_frame = 0;
6414*fb1b10abSAndroid Build Coastguard Worker   }
6415*fb1b10abSAndroid Build Coastguard Worker 
6416*fb1b10abSAndroid Build Coastguard Worker   // Should we encode an arf frame.
6417*fb1b10abSAndroid Build Coastguard Worker   arf_src_index = get_arf_src_index(cpi);
6418*fb1b10abSAndroid Build Coastguard Worker 
6419*fb1b10abSAndroid Build Coastguard Worker   if (arf_src_index) {
6420*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i <= arf_src_index; ++i) {
6421*fb1b10abSAndroid Build Coastguard Worker       struct lookahead_entry *e = vp9_lookahead_peek(cpi->lookahead, i);
6422*fb1b10abSAndroid Build Coastguard Worker       // Avoid creating an alt-ref if there's a forced keyframe pending.
6423*fb1b10abSAndroid Build Coastguard Worker       if (e == NULL) {
6424*fb1b10abSAndroid Build Coastguard Worker         break;
6425*fb1b10abSAndroid Build Coastguard Worker       } else if (e->flags == VPX_EFLAG_FORCE_KF) {
6426*fb1b10abSAndroid Build Coastguard Worker         arf_src_index = 0;
6427*fb1b10abSAndroid Build Coastguard Worker         flush = 1;
6428*fb1b10abSAndroid Build Coastguard Worker         break;
6429*fb1b10abSAndroid Build Coastguard Worker       }
6430*fb1b10abSAndroid Build Coastguard Worker     }
6431*fb1b10abSAndroid Build Coastguard Worker   }
6432*fb1b10abSAndroid Build Coastguard Worker 
6433*fb1b10abSAndroid Build Coastguard Worker   // Clear arf index stack before group of pictures processing starts.
6434*fb1b10abSAndroid Build Coastguard Worker   if (gf_group_index == 1) {
6435*fb1b10abSAndroid Build Coastguard Worker     stack_init(cpi->twopass.gf_group.arf_index_stack, MAX_LAG_BUFFERS * 2);
6436*fb1b10abSAndroid Build Coastguard Worker     cpi->twopass.gf_group.stack_size = 0;
6437*fb1b10abSAndroid Build Coastguard Worker   }
6438*fb1b10abSAndroid Build Coastguard Worker 
6439*fb1b10abSAndroid Build Coastguard Worker   if (arf_src_index) {
6440*fb1b10abSAndroid Build Coastguard Worker     if (!(cpi->ext_ratectrl.ready &&
6441*fb1b10abSAndroid Build Coastguard Worker           (cpi->ext_ratectrl.funcs.rc_type & VPX_RC_GOP) != 0 &&
6442*fb1b10abSAndroid Build Coastguard Worker           cpi->ext_ratectrl.funcs.get_gop_decision != NULL)) {
6443*fb1b10abSAndroid Build Coastguard Worker       // This assert only makes sense when not using external RC.
6444*fb1b10abSAndroid Build Coastguard Worker       assert(arf_src_index <= rc->frames_to_key);
6445*fb1b10abSAndroid Build Coastguard Worker     }
6446*fb1b10abSAndroid Build Coastguard Worker     if ((source = vp9_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
6447*fb1b10abSAndroid Build Coastguard Worker       cpi->alt_ref_source = source;
6448*fb1b10abSAndroid Build Coastguard Worker 
6449*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
6450*fb1b10abSAndroid Build Coastguard Worker       if ((oxcf->mode != REALTIME) && (oxcf->arnr_max_frames > 0) &&
6451*fb1b10abSAndroid Build Coastguard Worker           (oxcf->arnr_strength > 0)) {
6452*fb1b10abSAndroid Build Coastguard Worker         int bitrate = cpi->rc.avg_frame_bandwidth / 40;
6453*fb1b10abSAndroid Build Coastguard Worker         int not_low_bitrate = bitrate > ALT_REF_AQ_LOW_BITRATE_BOUNDARY;
6454*fb1b10abSAndroid Build Coastguard Worker 
6455*fb1b10abSAndroid Build Coastguard Worker         int not_last_frame = (cpi->lookahead->sz - arf_src_index > 1);
6456*fb1b10abSAndroid Build Coastguard Worker         not_last_frame |= ALT_REF_AQ_APPLY_TO_LAST_FRAME;
6457*fb1b10abSAndroid Build Coastguard Worker 
6458*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6459*fb1b10abSAndroid Build Coastguard Worker         start_timing(cpi, vp9_temporal_filter_time);
6460*fb1b10abSAndroid Build Coastguard Worker #endif
6461*fb1b10abSAndroid Build Coastguard Worker         // Produce the filtered ARF frame.
6462*fb1b10abSAndroid Build Coastguard Worker         vp9_temporal_filter(cpi, arf_src_index);
6463*fb1b10abSAndroid Build Coastguard Worker         vpx_extend_frame_borders(&cpi->tf_buffer);
6464*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6465*fb1b10abSAndroid Build Coastguard Worker         end_timing(cpi, vp9_temporal_filter_time);
6466*fb1b10abSAndroid Build Coastguard Worker #endif
6467*fb1b10abSAndroid Build Coastguard Worker 
6468*fb1b10abSAndroid Build Coastguard Worker         // for small bitrates segmentation overhead usually
6469*fb1b10abSAndroid Build Coastguard Worker         // eats all bitrate gain from enabling delta quantizers
6470*fb1b10abSAndroid Build Coastguard Worker         if (cpi->oxcf.alt_ref_aq != 0 && not_low_bitrate && not_last_frame)
6471*fb1b10abSAndroid Build Coastguard Worker           vp9_alt_ref_aq_setup_mode(cpi->alt_ref_aq, cpi);
6472*fb1b10abSAndroid Build Coastguard Worker 
6473*fb1b10abSAndroid Build Coastguard Worker         force_src_buffer = &cpi->tf_buffer;
6474*fb1b10abSAndroid Build Coastguard Worker       }
6475*fb1b10abSAndroid Build Coastguard Worker #endif
6476*fb1b10abSAndroid Build Coastguard Worker       cm->show_frame = 0;
6477*fb1b10abSAndroid Build Coastguard Worker       cm->intra_only = 0;
6478*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 1;
6479*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 0;
6480*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 0;
6481*fb1b10abSAndroid Build Coastguard Worker       rc->is_src_frame_alt_ref = 0;
6482*fb1b10abSAndroid Build Coastguard Worker       rc->source_alt_ref_pending = 0;
6483*fb1b10abSAndroid Build Coastguard Worker     } else {
6484*fb1b10abSAndroid Build Coastguard Worker       rc->source_alt_ref_pending = 0;
6485*fb1b10abSAndroid Build Coastguard Worker     }
6486*fb1b10abSAndroid Build Coastguard Worker   }
6487*fb1b10abSAndroid Build Coastguard Worker 
6488*fb1b10abSAndroid Build Coastguard Worker   if (!source) {
6489*fb1b10abSAndroid Build Coastguard Worker     // Get last frame source.
6490*fb1b10abSAndroid Build Coastguard Worker     if (cm->current_video_frame > 0) {
6491*fb1b10abSAndroid Build Coastguard Worker       if ((last_source = vp9_lookahead_peek(cpi->lookahead, -1)) == NULL)
6492*fb1b10abSAndroid Build Coastguard Worker         return -1;
6493*fb1b10abSAndroid Build Coastguard Worker     }
6494*fb1b10abSAndroid Build Coastguard Worker 
6495*fb1b10abSAndroid Build Coastguard Worker     // Read in the source frame.
6496*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc || cpi->svc.set_intra_only_frame)
6497*fb1b10abSAndroid Build Coastguard Worker       source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush);
6498*fb1b10abSAndroid Build Coastguard Worker     else
6499*fb1b10abSAndroid Build Coastguard Worker       source = vp9_lookahead_pop(cpi->lookahead, flush);
6500*fb1b10abSAndroid Build Coastguard Worker 
6501*fb1b10abSAndroid Build Coastguard Worker     if (source != NULL) {
6502*fb1b10abSAndroid Build Coastguard Worker       cm->show_frame = 1;
6503*fb1b10abSAndroid Build Coastguard Worker       cm->intra_only = 0;
6504*fb1b10abSAndroid Build Coastguard Worker       // If the flags indicate intra frame, but if the current picture is for
6505*fb1b10abSAndroid Build Coastguard Worker       // spatial layer above first_spatial_layer_to_encode, it should not be an
6506*fb1b10abSAndroid Build Coastguard Worker       // intra picture.
6507*fb1b10abSAndroid Build Coastguard Worker       if ((source->flags & VPX_EFLAG_FORCE_KF) && cpi->use_svc &&
6508*fb1b10abSAndroid Build Coastguard Worker           cpi->svc.spatial_layer_id > cpi->svc.first_spatial_layer_to_encode) {
6509*fb1b10abSAndroid Build Coastguard Worker         source->flags &= ~(unsigned int)(VPX_EFLAG_FORCE_KF);
6510*fb1b10abSAndroid Build Coastguard Worker       }
6511*fb1b10abSAndroid Build Coastguard Worker 
6512*fb1b10abSAndroid Build Coastguard Worker       // Check to see if the frame should be encoded as an arf overlay.
6513*fb1b10abSAndroid Build Coastguard Worker       check_src_altref(cpi, source);
6514*fb1b10abSAndroid Build Coastguard Worker     }
6515*fb1b10abSAndroid Build Coastguard Worker   }
6516*fb1b10abSAndroid Build Coastguard Worker 
6517*fb1b10abSAndroid Build Coastguard Worker   if (source) {
6518*fb1b10abSAndroid Build Coastguard Worker     cpi->un_scaled_source = cpi->Source =
6519*fb1b10abSAndroid Build Coastguard Worker         force_src_buffer ? force_src_buffer : &source->img;
6520*fb1b10abSAndroid Build Coastguard Worker 
6521*fb1b10abSAndroid Build Coastguard Worker #ifdef ENABLE_KF_DENOISE
6522*fb1b10abSAndroid Build Coastguard Worker     // Copy of raw source for metrics calculation.
6523*fb1b10abSAndroid Build Coastguard Worker     if (is_psnr_calc_enabled(cpi))
6524*fb1b10abSAndroid Build Coastguard Worker       vp9_copy_and_extend_frame(cpi->Source, &cpi->raw_unscaled_source);
6525*fb1b10abSAndroid Build Coastguard Worker #endif
6526*fb1b10abSAndroid Build Coastguard Worker 
6527*fb1b10abSAndroid Build Coastguard Worker     cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL;
6528*fb1b10abSAndroid Build Coastguard Worker 
6529*fb1b10abSAndroid Build Coastguard Worker     *time_stamp = source->ts_start;
6530*fb1b10abSAndroid Build Coastguard Worker     *time_end = source->ts_end;
6531*fb1b10abSAndroid Build Coastguard Worker     *frame_flags = (source->flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
6532*fb1b10abSAndroid Build Coastguard Worker   } else {
6533*fb1b10abSAndroid Build Coastguard Worker     *size = 0;
6534*fb1b10abSAndroid Build Coastguard Worker     return -1;
6535*fb1b10abSAndroid Build Coastguard Worker   }
6536*fb1b10abSAndroid Build Coastguard Worker 
6537*fb1b10abSAndroid Build Coastguard Worker   if (source->ts_start < cpi->first_time_stamp_ever) {
6538*fb1b10abSAndroid Build Coastguard Worker     cpi->first_time_stamp_ever = source->ts_start;
6539*fb1b10abSAndroid Build Coastguard Worker     cpi->last_end_time_stamp_seen = source->ts_start;
6540*fb1b10abSAndroid Build Coastguard Worker   }
6541*fb1b10abSAndroid Build Coastguard Worker 
6542*fb1b10abSAndroid Build Coastguard Worker   // Clear down mmx registers
6543*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
6544*fb1b10abSAndroid Build Coastguard Worker 
6545*fb1b10abSAndroid Build Coastguard Worker   // adjust frame rates based on timestamps given
6546*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) {
6547*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc && cpi->svc.use_set_ref_frame_config &&
6548*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.duration[cpi->svc.spatial_layer_id] > 0)
6549*fb1b10abSAndroid Build Coastguard Worker       vp9_svc_adjust_frame_rate(cpi);
6550*fb1b10abSAndroid Build Coastguard Worker     else
6551*fb1b10abSAndroid Build Coastguard Worker       adjust_frame_rate(cpi, source);
6552*fb1b10abSAndroid Build Coastguard Worker   }
6553*fb1b10abSAndroid Build Coastguard Worker 
6554*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) {
6555*fb1b10abSAndroid Build Coastguard Worker     vp9_update_temporal_layer_framerate(cpi);
6556*fb1b10abSAndroid Build Coastguard Worker     vp9_restore_layer_context(cpi);
6557*fb1b10abSAndroid Build Coastguard Worker   }
6558*fb1b10abSAndroid Build Coastguard Worker 
6559*fb1b10abSAndroid Build Coastguard Worker   // Find a free buffer for the new frame, releasing the reference previously
6560*fb1b10abSAndroid Build Coastguard Worker   // held.
6561*fb1b10abSAndroid Build Coastguard Worker   if (cm->new_fb_idx != INVALID_IDX) {
6562*fb1b10abSAndroid Build Coastguard Worker     --pool->frame_bufs[cm->new_fb_idx].ref_count;
6563*fb1b10abSAndroid Build Coastguard Worker   }
6564*fb1b10abSAndroid Build Coastguard Worker   cm->new_fb_idx = get_free_fb(cm);
6565*fb1b10abSAndroid Build Coastguard Worker 
6566*fb1b10abSAndroid Build Coastguard Worker   if (cm->new_fb_idx == INVALID_IDX) return -1;
6567*fb1b10abSAndroid Build Coastguard Worker   cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
6568*fb1b10abSAndroid Build Coastguard Worker   // If the frame buffer for current frame is the same as previous frame, MV in
6569*fb1b10abSAndroid Build Coastguard Worker   // the base layer shouldn't be used as it'll cause data race.
6570*fb1b10abSAndroid Build Coastguard Worker   if (cpi->svc.spatial_layer_id > 0 && cm->cur_frame == cm->prev_frame) {
6571*fb1b10abSAndroid Build Coastguard Worker     cpi->svc.use_base_mv = 0;
6572*fb1b10abSAndroid Build Coastguard Worker   }
6573*fb1b10abSAndroid Build Coastguard Worker   // Start with a 0 size frame.
6574*fb1b10abSAndroid Build Coastguard Worker   *size = 0;
6575*fb1b10abSAndroid Build Coastguard Worker 
6576*fb1b10abSAndroid Build Coastguard Worker   cpi->frame_flags = *frame_flags;
6577*fb1b10abSAndroid Build Coastguard Worker 
6578*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
6579*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 2) && !cpi->use_svc) {
6580*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6581*fb1b10abSAndroid Build Coastguard Worker     start_timing(cpi, vp9_rc_get_second_pass_params_time);
6582*fb1b10abSAndroid Build Coastguard Worker #endif
6583*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_get_second_pass_params(cpi);
6584*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6585*fb1b10abSAndroid Build Coastguard Worker     end_timing(cpi, vp9_rc_get_second_pass_params_time);
6586*fb1b10abSAndroid Build Coastguard Worker #endif
6587*fb1b10abSAndroid Build Coastguard Worker   } else if (oxcf->pass == 1) {
6588*fb1b10abSAndroid Build Coastguard Worker     set_frame_size(cpi);
6589*fb1b10abSAndroid Build Coastguard Worker   }
6590*fb1b10abSAndroid Build Coastguard Worker 
6591*fb1b10abSAndroid Build Coastguard Worker   // Key frame temporal filtering
6592*fb1b10abSAndroid Build Coastguard Worker   const int is_key_temporal_filter_enabled =
6593*fb1b10abSAndroid Build Coastguard Worker       oxcf->enable_keyframe_filtering && cpi->oxcf.mode != REALTIME &&
6594*fb1b10abSAndroid Build Coastguard Worker       (oxcf->pass != 1) && !cpi->use_svc &&
6595*fb1b10abSAndroid Build Coastguard Worker       !is_lossless_requested(&cpi->oxcf) && cm->frame_type == KEY_FRAME &&
6596*fb1b10abSAndroid Build Coastguard Worker       (oxcf->arnr_max_frames > 0) && (oxcf->arnr_strength > 0) &&
6597*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.speed < 2;
6598*fb1b10abSAndroid Build Coastguard Worker   // Save the pointer to the original source image.
6599*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG *source_buffer = cpi->un_scaled_source;
6600*fb1b10abSAndroid Build Coastguard Worker 
6601*fb1b10abSAndroid Build Coastguard Worker   if (is_key_temporal_filter_enabled && source != NULL) {
6602*fb1b10abSAndroid Build Coastguard Worker     // Produce the filtered Key frame. Set distance to -1 since the key frame
6603*fb1b10abSAndroid Build Coastguard Worker     // is already popped out.
6604*fb1b10abSAndroid Build Coastguard Worker     vp9_temporal_filter(cpi, -1);
6605*fb1b10abSAndroid Build Coastguard Worker     vpx_extend_frame_borders(&cpi->tf_buffer);
6606*fb1b10abSAndroid Build Coastguard Worker     force_src_buffer = &cpi->tf_buffer;
6607*fb1b10abSAndroid Build Coastguard Worker     cpi->un_scaled_source = cpi->Source =
6608*fb1b10abSAndroid Build Coastguard Worker         force_src_buffer ? force_src_buffer : &source->img;
6609*fb1b10abSAndroid Build Coastguard Worker   }
6610*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
6611*fb1b10abSAndroid Build Coastguard Worker 
6612*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass != 1 && cpi->level_constraint.level_index >= 0 &&
6613*fb1b10abSAndroid Build Coastguard Worker       cpi->level_constraint.fail_flag == 0)
6614*fb1b10abSAndroid Build Coastguard Worker     level_rc_framerate(cpi, arf_src_index);
6615*fb1b10abSAndroid Build Coastguard Worker 
6616*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass != 0 || cpi->use_svc || frame_is_intra_only(cm) == 1) {
6617*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < REFS_PER_FRAME; ++i) cpi->scaled_ref_idx[i] = INVALID_IDX;
6618*fb1b10abSAndroid Build Coastguard Worker   }
6619*fb1b10abSAndroid Build Coastguard Worker 
6620*fb1b10abSAndroid Build Coastguard Worker   if (cpi->kmeans_data_arr_alloc == 0) {
6621*fb1b10abSAndroid Build Coastguard Worker     const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
6622*fb1b10abSAndroid Build Coastguard Worker     const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows);
6623*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MULTITHREAD
6624*fb1b10abSAndroid Build Coastguard Worker     pthread_mutex_init(&cpi->kmeans_mutex, NULL);
6625*fb1b10abSAndroid Build Coastguard Worker #endif
6626*fb1b10abSAndroid Build Coastguard Worker     CHECK_MEM_ERROR(
6627*fb1b10abSAndroid Build Coastguard Worker         &cm->error, cpi->kmeans_data_arr,
6628*fb1b10abSAndroid Build Coastguard Worker         vpx_calloc(mi_rows * mi_cols, sizeof(*cpi->kmeans_data_arr)));
6629*fb1b10abSAndroid Build Coastguard Worker     cpi->kmeans_data_stride = mi_cols;
6630*fb1b10abSAndroid Build Coastguard Worker     cpi->kmeans_data_arr_alloc = 1;
6631*fb1b10abSAndroid Build Coastguard Worker   }
6632*fb1b10abSAndroid Build Coastguard Worker 
6633*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_NON_GREEDY_MV
6634*fb1b10abSAndroid Build Coastguard Worker   {
6635*fb1b10abSAndroid Build Coastguard Worker     const int mi_cols = mi_cols_aligned_to_sb(cm->mi_cols);
6636*fb1b10abSAndroid Build Coastguard Worker     const int mi_rows = mi_cols_aligned_to_sb(cm->mi_rows);
6637*fb1b10abSAndroid Build Coastguard Worker     Status status = vp9_alloc_motion_field_info(
6638*fb1b10abSAndroid Build Coastguard Worker         &cpi->motion_field_info, MAX_ARF_GOP_SIZE, mi_rows, mi_cols);
6639*fb1b10abSAndroid Build Coastguard Worker     if (status == STATUS_FAILED) {
6640*fb1b10abSAndroid Build Coastguard Worker       vpx_internal_error(&(cm)->error, VPX_CODEC_MEM_ERROR,
6641*fb1b10abSAndroid Build Coastguard Worker                          "vp9_alloc_motion_field_info failed");
6642*fb1b10abSAndroid Build Coastguard Worker     }
6643*fb1b10abSAndroid Build Coastguard Worker   }
6644*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_NON_GREEDY_MV
6645*fb1b10abSAndroid Build Coastguard Worker 
6646*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6647*fb1b10abSAndroid Build Coastguard Worker   start_timing(cpi, setup_tpl_stats_time);
6648*fb1b10abSAndroid Build Coastguard Worker #endif
6649*fb1b10abSAndroid Build Coastguard Worker   if (should_run_tpl(cpi, cpi->twopass.gf_group.index)) {
6650*fb1b10abSAndroid Build Coastguard Worker     vp9_init_tpl_buffer(cpi);
6651*fb1b10abSAndroid Build Coastguard Worker     vp9_estimate_tpl_qp_gop(cpi);
6652*fb1b10abSAndroid Build Coastguard Worker     vp9_setup_tpl_stats(cpi);
6653*fb1b10abSAndroid Build Coastguard Worker   }
6654*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6655*fb1b10abSAndroid Build Coastguard Worker   end_timing(cpi, setup_tpl_stats_time);
6656*fb1b10abSAndroid Build Coastguard Worker #endif
6657*fb1b10abSAndroid Build Coastguard Worker 
6658*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_BITSTREAM_DEBUG
6659*fb1b10abSAndroid Build Coastguard Worker   assert(cpi->oxcf.max_threads == 0 &&
6660*fb1b10abSAndroid Build Coastguard Worker          "bitstream debug tool does not support multithreading");
6661*fb1b10abSAndroid Build Coastguard Worker   bitstream_queue_record_write();
6662*fb1b10abSAndroid Build Coastguard Worker #endif
6663*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
6664*fb1b10abSAndroid Build Coastguard Worker   bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame);
6665*fb1b10abSAndroid Build Coastguard Worker #endif
6666*fb1b10abSAndroid Build Coastguard Worker 
6667*fb1b10abSAndroid Build Coastguard Worker   cpi->td.mb.fp_src_pred = 0;
6668*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_REALTIME_ONLY
6669*fb1b10abSAndroid Build Coastguard Worker   (void)encode_frame_result;
6670*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) {
6671*fb1b10abSAndroid Build Coastguard Worker     SvcEncode(cpi, size, dest, dest_size, frame_flags);
6672*fb1b10abSAndroid Build Coastguard Worker   } else {
6673*fb1b10abSAndroid Build Coastguard Worker     // One pass encode
6674*fb1b10abSAndroid Build Coastguard Worker     Pass0Encode(cpi, size, dest, dest_size, frame_flags);
6675*fb1b10abSAndroid Build Coastguard Worker   }
6676*fb1b10abSAndroid Build Coastguard Worker #else  // !CONFIG_REALTIME_ONLY
6677*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 1 && !cpi->use_svc) {
6678*fb1b10abSAndroid Build Coastguard Worker     const int lossless = is_lossless_requested(oxcf);
6679*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6680*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.use_highbitdepth)
6681*fb1b10abSAndroid Build Coastguard Worker       cpi->td.mb.fwd_txfm4x4 =
6682*fb1b10abSAndroid Build Coastguard Worker           lossless ? vp9_highbd_fwht4x4 : vpx_highbd_fdct4x4;
6683*fb1b10abSAndroid Build Coastguard Worker     else
6684*fb1b10abSAndroid Build Coastguard Worker       cpi->td.mb.fwd_txfm4x4 = lossless ? vp9_fwht4x4 : vpx_fdct4x4;
6685*fb1b10abSAndroid Build Coastguard Worker     cpi->td.mb.highbd_inv_txfm_add =
6686*fb1b10abSAndroid Build Coastguard Worker         lossless ? vp9_highbd_iwht4x4_add : vp9_highbd_idct4x4_add;
6687*fb1b10abSAndroid Build Coastguard Worker #else
6688*fb1b10abSAndroid Build Coastguard Worker     cpi->td.mb.fwd_txfm4x4 = lossless ? vp9_fwht4x4 : vpx_fdct4x4;
6689*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
6690*fb1b10abSAndroid Build Coastguard Worker     cpi->td.mb.inv_txfm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add;
6691*fb1b10abSAndroid Build Coastguard Worker     vp9_first_pass(cpi, source);
6692*fb1b10abSAndroid Build Coastguard Worker   } else if (oxcf->pass == 2 && !cpi->use_svc) {
6693*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6694*fb1b10abSAndroid Build Coastguard Worker     // Accumulate 2nd pass time in 2-pass case.
6695*fb1b10abSAndroid Build Coastguard Worker     start_timing(cpi, Pass2Encode_time);
6696*fb1b10abSAndroid Build Coastguard Worker #endif
6697*fb1b10abSAndroid Build Coastguard Worker     Pass2Encode(cpi, size, dest, dest_size, frame_flags, encode_frame_result);
6698*fb1b10abSAndroid Build Coastguard Worker     vp9_twopass_postencode_update(cpi);
6699*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6700*fb1b10abSAndroid Build Coastguard Worker     end_timing(cpi, Pass2Encode_time);
6701*fb1b10abSAndroid Build Coastguard Worker #endif
6702*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->use_svc) {
6703*fb1b10abSAndroid Build Coastguard Worker     SvcEncode(cpi, size, dest, dest_size, frame_flags);
6704*fb1b10abSAndroid Build Coastguard Worker   } else {
6705*fb1b10abSAndroid Build Coastguard Worker     // One pass encode
6706*fb1b10abSAndroid Build Coastguard Worker     Pass0Encode(cpi, size, dest, dest_size, frame_flags);
6707*fb1b10abSAndroid Build Coastguard Worker   }
6708*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_REALTIME_ONLY
6709*fb1b10abSAndroid Build Coastguard Worker 
6710*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) cm->cur_show_frame_fb_idx = cm->new_fb_idx;
6711*fb1b10abSAndroid Build Coastguard Worker 
6712*fb1b10abSAndroid Build Coastguard Worker   if (cm->refresh_frame_context)
6713*fb1b10abSAndroid Build Coastguard Worker     cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
6714*fb1b10abSAndroid Build Coastguard Worker 
6715*fb1b10abSAndroid Build Coastguard Worker   // No frame encoded, or frame was dropped, release scaled references.
6716*fb1b10abSAndroid Build Coastguard Worker   if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
6717*fb1b10abSAndroid Build Coastguard Worker     release_scaled_references(cpi);
6718*fb1b10abSAndroid Build Coastguard Worker   }
6719*fb1b10abSAndroid Build Coastguard Worker 
6720*fb1b10abSAndroid Build Coastguard Worker   if (*size > 0) {
6721*fb1b10abSAndroid Build Coastguard Worker     cpi->droppable = !frame_is_reference(cpi);
6722*fb1b10abSAndroid Build Coastguard Worker   }
6723*fb1b10abSAndroid Build Coastguard Worker 
6724*fb1b10abSAndroid Build Coastguard Worker   // Save layer specific state.
6725*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi) || ((cpi->svc.number_temporal_layers > 1 ||
6726*fb1b10abSAndroid Build Coastguard Worker                                 cpi->svc.number_spatial_layers > 1) &&
6727*fb1b10abSAndroid Build Coastguard Worker                                oxcf->pass == 2)) {
6728*fb1b10abSAndroid Build Coastguard Worker     vp9_save_layer_context(cpi);
6729*fb1b10abSAndroid Build Coastguard Worker   }
6730*fb1b10abSAndroid Build Coastguard Worker 
6731*fb1b10abSAndroid Build Coastguard Worker   if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)
6732*fb1b10abSAndroid Build Coastguard Worker     cpi->fixed_qp_onepass = 0;
6733*fb1b10abSAndroid Build Coastguard Worker 
6734*fb1b10abSAndroid Build Coastguard Worker   vpx_usec_timer_mark(&cmptimer);
6735*fb1b10abSAndroid Build Coastguard Worker   cpi->time_compress_data += vpx_usec_timer_elapsed(&cmptimer);
6736*fb1b10abSAndroid Build Coastguard Worker 
6737*fb1b10abSAndroid Build Coastguard Worker   if (cpi->keep_level_stats && oxcf->pass != 1)
6738*fb1b10abSAndroid Build Coastguard Worker     update_level_info(cpi, size, arf_src_index);
6739*fb1b10abSAndroid Build Coastguard Worker 
6740*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_REALTIME_ONLY
6741*fb1b10abSAndroid Build Coastguard Worker   if (is_key_temporal_filter_enabled && cpi->b_calculate_psnr) {
6742*fb1b10abSAndroid Build Coastguard Worker     cpi->raw_source_frame = vp9_scale_if_required(
6743*fb1b10abSAndroid Build Coastguard Worker         cm, source_buffer, &cpi->scaled_source, (oxcf->pass == 0), EIGHTTAP, 0);
6744*fb1b10abSAndroid Build Coastguard Worker   }
6745*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_REALTIME_ONLY
6746*fb1b10abSAndroid Build Coastguard Worker 
6747*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_INTERNAL_STATS
6748*fb1b10abSAndroid Build Coastguard Worker 
6749*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass != 1 && !cpi->last_frame_dropped) {
6750*fb1b10abSAndroid Build Coastguard Worker     double samples = 0.0;
6751*fb1b10abSAndroid Build Coastguard Worker     cpi->bytes += *size;
6752*fb1b10abSAndroid Build Coastguard Worker 
6753*fb1b10abSAndroid Build Coastguard Worker     if (cm->show_frame) {
6754*fb1b10abSAndroid Build Coastguard Worker       uint32_t bit_depth = 8;
6755*fb1b10abSAndroid Build Coastguard Worker       uint32_t in_bit_depth = 8;
6756*fb1b10abSAndroid Build Coastguard Worker       cpi->count++;
6757*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6758*fb1b10abSAndroid Build Coastguard Worker       if (cm->use_highbitdepth) {
6759*fb1b10abSAndroid Build Coastguard Worker         in_bit_depth = cpi->oxcf.input_bit_depth;
6760*fb1b10abSAndroid Build Coastguard Worker         bit_depth = cm->bit_depth;
6761*fb1b10abSAndroid Build Coastguard Worker       }
6762*fb1b10abSAndroid Build Coastguard Worker #endif
6763*fb1b10abSAndroid Build Coastguard Worker 
6764*fb1b10abSAndroid Build Coastguard Worker       if (cpi->b_calculate_psnr) {
6765*fb1b10abSAndroid Build Coastguard Worker         YV12_BUFFER_CONFIG *orig = cpi->raw_source_frame;
6766*fb1b10abSAndroid Build Coastguard Worker         YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show;
6767*fb1b10abSAndroid Build Coastguard Worker         YV12_BUFFER_CONFIG *pp = &cm->post_proc_buffer;
6768*fb1b10abSAndroid Build Coastguard Worker         PSNR_STATS psnr;
6769*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6770*fb1b10abSAndroid Build Coastguard Worker         vpx_calc_highbd_psnr(orig, recon, &psnr, cpi->td.mb.e_mbd.bd,
6771*fb1b10abSAndroid Build Coastguard Worker                              in_bit_depth);
6772*fb1b10abSAndroid Build Coastguard Worker #else
6773*fb1b10abSAndroid Build Coastguard Worker         vpx_calc_psnr(orig, recon, &psnr);
6774*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
6775*fb1b10abSAndroid Build Coastguard Worker 
6776*fb1b10abSAndroid Build Coastguard Worker         adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3],
6777*fb1b10abSAndroid Build Coastguard Worker                           psnr.psnr[0], &cpi->psnr);
6778*fb1b10abSAndroid Build Coastguard Worker         cpi->total_sq_error += psnr.sse[0];
6779*fb1b10abSAndroid Build Coastguard Worker         cpi->total_samples += psnr.samples[0];
6780*fb1b10abSAndroid Build Coastguard Worker         samples = psnr.samples[0];
6781*fb1b10abSAndroid Build Coastguard Worker 
6782*fb1b10abSAndroid Build Coastguard Worker         {
6783*fb1b10abSAndroid Build Coastguard Worker           PSNR_STATS psnr2;
6784*fb1b10abSAndroid Build Coastguard Worker           double frame_ssim2 = 0, weight = 0;
6785*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC
6786*fb1b10abSAndroid Build Coastguard Worker           if (vpx_alloc_frame_buffer(
6787*fb1b10abSAndroid Build Coastguard Worker                   pp, recon->y_crop_width, recon->y_crop_height,
6788*fb1b10abSAndroid Build Coastguard Worker                   cm->subsampling_x, cm->subsampling_y,
6789*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6790*fb1b10abSAndroid Build Coastguard Worker                   cm->use_highbitdepth,
6791*fb1b10abSAndroid Build Coastguard Worker #endif
6792*fb1b10abSAndroid Build Coastguard Worker                   VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment) < 0) {
6793*fb1b10abSAndroid Build Coastguard Worker             vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
6794*fb1b10abSAndroid Build Coastguard Worker                                "Failed to allocate post processing buffer");
6795*fb1b10abSAndroid Build Coastguard Worker           }
6796*fb1b10abSAndroid Build Coastguard Worker           {
6797*fb1b10abSAndroid Build Coastguard Worker             vp9_ppflags_t ppflags;
6798*fb1b10abSAndroid Build Coastguard Worker             ppflags.post_proc_flag = VP9D_DEBLOCK;
6799*fb1b10abSAndroid Build Coastguard Worker             ppflags.deblocking_level = 0;  // not used in vp9_post_proc_frame()
6800*fb1b10abSAndroid Build Coastguard Worker             ppflags.noise_level = 0;       // not used in vp9_post_proc_frame()
6801*fb1b10abSAndroid Build Coastguard Worker             vp9_post_proc_frame(cm, pp, &ppflags,
6802*fb1b10abSAndroid Build Coastguard Worker                                 cpi->un_scaled_source->y_width);
6803*fb1b10abSAndroid Build Coastguard Worker           }
6804*fb1b10abSAndroid Build Coastguard Worker #endif
6805*fb1b10abSAndroid Build Coastguard Worker           vpx_clear_system_state();
6806*fb1b10abSAndroid Build Coastguard Worker 
6807*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6808*fb1b10abSAndroid Build Coastguard Worker           vpx_calc_highbd_psnr(orig, pp, &psnr2, cpi->td.mb.e_mbd.bd,
6809*fb1b10abSAndroid Build Coastguard Worker                                cpi->oxcf.input_bit_depth);
6810*fb1b10abSAndroid Build Coastguard Worker #else
6811*fb1b10abSAndroid Build Coastguard Worker           vpx_calc_psnr(orig, pp, &psnr2);
6812*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
6813*fb1b10abSAndroid Build Coastguard Worker 
6814*fb1b10abSAndroid Build Coastguard Worker           cpi->totalp_sq_error += psnr2.sse[0];
6815*fb1b10abSAndroid Build Coastguard Worker           cpi->totalp_samples += psnr2.samples[0];
6816*fb1b10abSAndroid Build Coastguard Worker           adjust_image_stat(psnr2.psnr[1], psnr2.psnr[2], psnr2.psnr[3],
6817*fb1b10abSAndroid Build Coastguard Worker                             psnr2.psnr[0], &cpi->psnrp);
6818*fb1b10abSAndroid Build Coastguard Worker 
6819*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6820*fb1b10abSAndroid Build Coastguard Worker           if (cm->use_highbitdepth) {
6821*fb1b10abSAndroid Build Coastguard Worker             frame_ssim2 = vpx_highbd_calc_ssim(orig, recon, &weight, bit_depth,
6822*fb1b10abSAndroid Build Coastguard Worker                                                in_bit_depth);
6823*fb1b10abSAndroid Build Coastguard Worker           } else {
6824*fb1b10abSAndroid Build Coastguard Worker             frame_ssim2 = vpx_calc_ssim(orig, recon, &weight);
6825*fb1b10abSAndroid Build Coastguard Worker           }
6826*fb1b10abSAndroid Build Coastguard Worker #else
6827*fb1b10abSAndroid Build Coastguard Worker           frame_ssim2 = vpx_calc_ssim(orig, recon, &weight);
6828*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
6829*fb1b10abSAndroid Build Coastguard Worker 
6830*fb1b10abSAndroid Build Coastguard Worker           cpi->worst_ssim = VPXMIN(cpi->worst_ssim, frame_ssim2);
6831*fb1b10abSAndroid Build Coastguard Worker           cpi->summed_quality += frame_ssim2 * weight;
6832*fb1b10abSAndroid Build Coastguard Worker           cpi->summed_weights += weight;
6833*fb1b10abSAndroid Build Coastguard Worker 
6834*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6835*fb1b10abSAndroid Build Coastguard Worker           if (cm->use_highbitdepth) {
6836*fb1b10abSAndroid Build Coastguard Worker             frame_ssim2 = vpx_highbd_calc_ssim(orig, pp, &weight, bit_depth,
6837*fb1b10abSAndroid Build Coastguard Worker                                                in_bit_depth);
6838*fb1b10abSAndroid Build Coastguard Worker           } else {
6839*fb1b10abSAndroid Build Coastguard Worker             frame_ssim2 = vpx_calc_ssim(orig, pp, &weight);
6840*fb1b10abSAndroid Build Coastguard Worker           }
6841*fb1b10abSAndroid Build Coastguard Worker #else
6842*fb1b10abSAndroid Build Coastguard Worker           frame_ssim2 = vpx_calc_ssim(orig, pp, &weight);
6843*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
6844*fb1b10abSAndroid Build Coastguard Worker 
6845*fb1b10abSAndroid Build Coastguard Worker           cpi->summedp_quality += frame_ssim2 * weight;
6846*fb1b10abSAndroid Build Coastguard Worker           cpi->summedp_weights += weight;
6847*fb1b10abSAndroid Build Coastguard Worker #if 0
6848*fb1b10abSAndroid Build Coastguard Worker           if (cm->show_frame) {
6849*fb1b10abSAndroid Build Coastguard Worker             FILE *f = fopen("q_used.stt", "a");
6850*fb1b10abSAndroid Build Coastguard Worker             fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
6851*fb1b10abSAndroid Build Coastguard Worker                     cpi->common.current_video_frame, psnr2.psnr[1],
6852*fb1b10abSAndroid Build Coastguard Worker                     psnr2.psnr[2], psnr2.psnr[3], psnr2.psnr[0], frame_ssim2);
6853*fb1b10abSAndroid Build Coastguard Worker             fclose(f);
6854*fb1b10abSAndroid Build Coastguard Worker           }
6855*fb1b10abSAndroid Build Coastguard Worker #endif
6856*fb1b10abSAndroid Build Coastguard Worker         }
6857*fb1b10abSAndroid Build Coastguard Worker       }
6858*fb1b10abSAndroid Build Coastguard Worker       if (cpi->b_calculate_blockiness) {
6859*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6860*fb1b10abSAndroid Build Coastguard Worker         if (!cm->use_highbitdepth)
6861*fb1b10abSAndroid Build Coastguard Worker #endif
6862*fb1b10abSAndroid Build Coastguard Worker         {
6863*fb1b10abSAndroid Build Coastguard Worker           double frame_blockiness = vp9_get_blockiness(
6864*fb1b10abSAndroid Build Coastguard Worker               cpi->Source->y_buffer, cpi->Source->y_stride,
6865*fb1b10abSAndroid Build Coastguard Worker               cm->frame_to_show->y_buffer, cm->frame_to_show->y_stride,
6866*fb1b10abSAndroid Build Coastguard Worker               cpi->Source->y_width, cpi->Source->y_height);
6867*fb1b10abSAndroid Build Coastguard Worker           cpi->worst_blockiness =
6868*fb1b10abSAndroid Build Coastguard Worker               VPXMAX(cpi->worst_blockiness, frame_blockiness);
6869*fb1b10abSAndroid Build Coastguard Worker           cpi->total_blockiness += frame_blockiness;
6870*fb1b10abSAndroid Build Coastguard Worker         }
6871*fb1b10abSAndroid Build Coastguard Worker       }
6872*fb1b10abSAndroid Build Coastguard Worker 
6873*fb1b10abSAndroid Build Coastguard Worker       if (cpi->b_calculate_consistency) {
6874*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
6875*fb1b10abSAndroid Build Coastguard Worker         if (!cm->use_highbitdepth)
6876*fb1b10abSAndroid Build Coastguard Worker #endif
6877*fb1b10abSAndroid Build Coastguard Worker         {
6878*fb1b10abSAndroid Build Coastguard Worker           double this_inconsistency = vpx_get_ssim_metrics(
6879*fb1b10abSAndroid Build Coastguard Worker               cpi->Source->y_buffer, cpi->Source->y_stride,
6880*fb1b10abSAndroid Build Coastguard Worker               cm->frame_to_show->y_buffer, cm->frame_to_show->y_stride,
6881*fb1b10abSAndroid Build Coastguard Worker               cpi->Source->y_width, cpi->Source->y_height, cpi->ssim_vars,
6882*fb1b10abSAndroid Build Coastguard Worker               &cpi->metrics, 1);
6883*fb1b10abSAndroid Build Coastguard Worker 
6884*fb1b10abSAndroid Build Coastguard Worker           const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
6885*fb1b10abSAndroid Build Coastguard Worker           double consistency =
6886*fb1b10abSAndroid Build Coastguard Worker               vpx_sse_to_psnr(samples, peak, (double)cpi->total_inconsistency);
6887*fb1b10abSAndroid Build Coastguard Worker           if (consistency > 0.0)
6888*fb1b10abSAndroid Build Coastguard Worker             cpi->worst_consistency =
6889*fb1b10abSAndroid Build Coastguard Worker                 VPXMIN(cpi->worst_consistency, consistency);
6890*fb1b10abSAndroid Build Coastguard Worker           cpi->total_inconsistency += this_inconsistency;
6891*fb1b10abSAndroid Build Coastguard Worker         }
6892*fb1b10abSAndroid Build Coastguard Worker       }
6893*fb1b10abSAndroid Build Coastguard Worker 
6894*fb1b10abSAndroid Build Coastguard Worker       {
6895*fb1b10abSAndroid Build Coastguard Worker         double y, u, v, frame_all;
6896*fb1b10abSAndroid Build Coastguard Worker         frame_all = vpx_calc_fastssim(cpi->Source, cm->frame_to_show, &y, &u,
6897*fb1b10abSAndroid Build Coastguard Worker                                       &v, bit_depth, in_bit_depth);
6898*fb1b10abSAndroid Build Coastguard Worker         adjust_image_stat(y, u, v, frame_all, &cpi->fastssim);
6899*fb1b10abSAndroid Build Coastguard Worker       }
6900*fb1b10abSAndroid Build Coastguard Worker       {
6901*fb1b10abSAndroid Build Coastguard Worker         double y, u, v, frame_all;
6902*fb1b10abSAndroid Build Coastguard Worker         frame_all = vpx_psnrhvs(cpi->Source, cm->frame_to_show, &y, &u, &v,
6903*fb1b10abSAndroid Build Coastguard Worker                                 bit_depth, in_bit_depth);
6904*fb1b10abSAndroid Build Coastguard Worker         adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs);
6905*fb1b10abSAndroid Build Coastguard Worker       }
6906*fb1b10abSAndroid Build Coastguard Worker     }
6907*fb1b10abSAndroid Build Coastguard Worker   }
6908*fb1b10abSAndroid Build Coastguard Worker 
6909*fb1b10abSAndroid Build Coastguard Worker #endif
6910*fb1b10abSAndroid Build Coastguard Worker 
6911*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_COLLECT_COMPONENT_TIMING
6912*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 2) end_timing(cpi, vp9_get_compressed_data_time);
6913*fb1b10abSAndroid Build Coastguard Worker 
6914*fb1b10abSAndroid Build Coastguard Worker   // Print out timing information.
6915*fb1b10abSAndroid Build Coastguard Worker   // Note: Use "cpi->frame_component_time[0] > 100 us" to avoid showing of
6916*fb1b10abSAndroid Build Coastguard Worker   // show_existing_frame and lag-in-frames.
6917*fb1b10abSAndroid Build Coastguard Worker   //  if (cpi->frame_component_time[0] > 100)
6918*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 2) {
6919*fb1b10abSAndroid Build Coastguard Worker     uint64_t frame_total = 0, total = 0;
6920*fb1b10abSAndroid Build Coastguard Worker     int i;
6921*fb1b10abSAndroid Build Coastguard Worker 
6922*fb1b10abSAndroid Build Coastguard Worker     fprintf(stderr,
6923*fb1b10abSAndroid Build Coastguard Worker             "\n Frame number: %d, Frame type: %s, Show Frame: %d, Q: %d\n",
6924*fb1b10abSAndroid Build Coastguard Worker             cm->current_video_frame, get_frame_type_enum(cm->frame_type),
6925*fb1b10abSAndroid Build Coastguard Worker             cm->show_frame, cm->base_qindex);
6926*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < kTimingComponents; i++) {
6927*fb1b10abSAndroid Build Coastguard Worker       cpi->component_time[i] += cpi->frame_component_time[i];
6928*fb1b10abSAndroid Build Coastguard Worker       // Use vp9_get_compressed_data_time (i = 0) as the total time.
6929*fb1b10abSAndroid Build Coastguard Worker       if (i == 0) {
6930*fb1b10abSAndroid Build Coastguard Worker         frame_total = cpi->frame_component_time[0];
6931*fb1b10abSAndroid Build Coastguard Worker         total = cpi->component_time[0];
6932*fb1b10abSAndroid Build Coastguard Worker       }
6933*fb1b10abSAndroid Build Coastguard Worker       fprintf(stderr,
6934*fb1b10abSAndroid Build Coastguard Worker               " %50s:  %15" PRId64 " us [%6.2f%%] (total: %15" PRId64
6935*fb1b10abSAndroid Build Coastguard Worker               " us [%6.2f%%])\n",
6936*fb1b10abSAndroid Build Coastguard Worker               get_component_name(i), cpi->frame_component_time[i],
6937*fb1b10abSAndroid Build Coastguard Worker               (float)((float)cpi->frame_component_time[i] * 100.0 /
6938*fb1b10abSAndroid Build Coastguard Worker                       (float)frame_total),
6939*fb1b10abSAndroid Build Coastguard Worker               cpi->component_time[i],
6940*fb1b10abSAndroid Build Coastguard Worker               (float)((float)cpi->component_time[i] * 100.0 / (float)total));
6941*fb1b10abSAndroid Build Coastguard Worker       cpi->frame_component_time[i] = 0;
6942*fb1b10abSAndroid Build Coastguard Worker     }
6943*fb1b10abSAndroid Build Coastguard Worker   }
6944*fb1b10abSAndroid Build Coastguard Worker #endif
6945*fb1b10abSAndroid Build Coastguard Worker 
6946*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) {
6947*fb1b10abSAndroid Build Coastguard Worker     if (cm->show_frame) {
6948*fb1b10abSAndroid Build Coastguard Worker       ++cpi->svc.spatial_layer_to_encode;
6949*fb1b10abSAndroid Build Coastguard Worker       if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers)
6950*fb1b10abSAndroid Build Coastguard Worker         cpi->svc.spatial_layer_to_encode = 0;
6951*fb1b10abSAndroid Build Coastguard Worker     }
6952*fb1b10abSAndroid Build Coastguard Worker   }
6953*fb1b10abSAndroid Build Coastguard Worker 
6954*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
6955*fb1b10abSAndroid Build Coastguard Worker   return 0;
6956*fb1b10abSAndroid Build Coastguard Worker }
6957*fb1b10abSAndroid Build Coastguard Worker 
6958*fb1b10abSAndroid Build Coastguard Worker int vp9_get_preview_raw_frame(VP9_COMP *cpi, YV12_BUFFER_CONFIG *dest,
6959*fb1b10abSAndroid Build Coastguard Worker                               vp9_ppflags_t *flags) {
6960*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
6961*fb1b10abSAndroid Build Coastguard Worker #if !CONFIG_VP9_POSTPROC
6962*fb1b10abSAndroid Build Coastguard Worker   (void)flags;
6963*fb1b10abSAndroid Build Coastguard Worker #endif
6964*fb1b10abSAndroid Build Coastguard Worker 
6965*fb1b10abSAndroid Build Coastguard Worker   if (!cm->show_frame) {
6966*fb1b10abSAndroid Build Coastguard Worker     return -1;
6967*fb1b10abSAndroid Build Coastguard Worker   } else {
6968*fb1b10abSAndroid Build Coastguard Worker     int ret;
6969*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_POSTPROC
6970*fb1b10abSAndroid Build Coastguard Worker     ret = vp9_post_proc_frame(cm, dest, flags, cpi->un_scaled_source->y_width);
6971*fb1b10abSAndroid Build Coastguard Worker #else
6972*fb1b10abSAndroid Build Coastguard Worker     if (cm->frame_to_show) {
6973*fb1b10abSAndroid Build Coastguard Worker       *dest = *cm->frame_to_show;
6974*fb1b10abSAndroid Build Coastguard Worker       dest->y_width = cm->width;
6975*fb1b10abSAndroid Build Coastguard Worker       dest->y_height = cm->height;
6976*fb1b10abSAndroid Build Coastguard Worker       dest->uv_width = cm->width >> cm->subsampling_x;
6977*fb1b10abSAndroid Build Coastguard Worker       dest->uv_height = cm->height >> cm->subsampling_y;
6978*fb1b10abSAndroid Build Coastguard Worker       ret = 0;
6979*fb1b10abSAndroid Build Coastguard Worker     } else {
6980*fb1b10abSAndroid Build Coastguard Worker       ret = -1;
6981*fb1b10abSAndroid Build Coastguard Worker     }
6982*fb1b10abSAndroid Build Coastguard Worker #endif  // !CONFIG_VP9_POSTPROC
6983*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
6984*fb1b10abSAndroid Build Coastguard Worker     return ret;
6985*fb1b10abSAndroid Build Coastguard Worker   }
6986*fb1b10abSAndroid Build Coastguard Worker }
6987*fb1b10abSAndroid Build Coastguard Worker 
6988*fb1b10abSAndroid Build Coastguard Worker int vp9_set_internal_size(VP9_COMP *cpi, VPX_SCALING_MODE horiz_mode,
6989*fb1b10abSAndroid Build Coastguard Worker                           VPX_SCALING_MODE vert_mode) {
6990*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
6991*fb1b10abSAndroid Build Coastguard Worker   int hr = 0, hs = 0, vr = 0, vs = 0;
6992*fb1b10abSAndroid Build Coastguard Worker 
6993*fb1b10abSAndroid Build Coastguard Worker   if (horiz_mode > VP8E_ONETWO || vert_mode > VP8E_ONETWO) return -1;
6994*fb1b10abSAndroid Build Coastguard Worker 
6995*fb1b10abSAndroid Build Coastguard Worker   Scale2Ratio(horiz_mode, &hr, &hs);
6996*fb1b10abSAndroid Build Coastguard Worker   Scale2Ratio(vert_mode, &vr, &vs);
6997*fb1b10abSAndroid Build Coastguard Worker 
6998*fb1b10abSAndroid Build Coastguard Worker   // always go to the next whole number
6999*fb1b10abSAndroid Build Coastguard Worker   cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
7000*fb1b10abSAndroid Build Coastguard Worker   cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
7001*fb1b10abSAndroid Build Coastguard Worker   if (cm->current_video_frame) {
7002*fb1b10abSAndroid Build Coastguard Worker     assert(cm->width <= cpi->initial_width);
7003*fb1b10abSAndroid Build Coastguard Worker     assert(cm->height <= cpi->initial_height);
7004*fb1b10abSAndroid Build Coastguard Worker   }
7005*fb1b10abSAndroid Build Coastguard Worker 
7006*fb1b10abSAndroid Build Coastguard Worker   update_frame_size(cpi);
7007*fb1b10abSAndroid Build Coastguard Worker 
7008*fb1b10abSAndroid Build Coastguard Worker   return 0;
7009*fb1b10abSAndroid Build Coastguard Worker }
7010*fb1b10abSAndroid Build Coastguard Worker 
7011*fb1b10abSAndroid Build Coastguard Worker int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width,
7012*fb1b10abSAndroid Build Coastguard Worker                          unsigned int height) {
7013*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
7014*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
7015*fb1b10abSAndroid Build Coastguard Worker   update_initial_width(cpi, cm->use_highbitdepth, cpi->common.subsampling_x,
7016*fb1b10abSAndroid Build Coastguard Worker                        cpi->common.subsampling_y);
7017*fb1b10abSAndroid Build Coastguard Worker #else
7018*fb1b10abSAndroid Build Coastguard Worker   update_initial_width(cpi, 0, cpi->common.subsampling_x,
7019*fb1b10abSAndroid Build Coastguard Worker                        cpi->common.subsampling_y);
7020*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_VP9_HIGHBITDEPTH
7021*fb1b10abSAndroid Build Coastguard Worker 
7022*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
7023*fb1b10abSAndroid Build Coastguard Worker   setup_denoiser_buffer(cpi);
7024*fb1b10abSAndroid Build Coastguard Worker #endif
7025*fb1b10abSAndroid Build Coastguard Worker   alloc_raw_frame_buffers(cpi);
7026*fb1b10abSAndroid Build Coastguard Worker   if (width) {
7027*fb1b10abSAndroid Build Coastguard Worker     cm->width = width;
7028*fb1b10abSAndroid Build Coastguard Worker     if (cm->width > cpi->initial_width) {
7029*fb1b10abSAndroid Build Coastguard Worker       cm->width = cpi->initial_width;
7030*fb1b10abSAndroid Build Coastguard Worker     }
7031*fb1b10abSAndroid Build Coastguard Worker   }
7032*fb1b10abSAndroid Build Coastguard Worker 
7033*fb1b10abSAndroid Build Coastguard Worker   if (height) {
7034*fb1b10abSAndroid Build Coastguard Worker     cm->height = height;
7035*fb1b10abSAndroid Build Coastguard Worker     if (cm->height > cpi->initial_height) {
7036*fb1b10abSAndroid Build Coastguard Worker       cm->height = cpi->initial_height;
7037*fb1b10abSAndroid Build Coastguard Worker     }
7038*fb1b10abSAndroid Build Coastguard Worker   }
7039*fb1b10abSAndroid Build Coastguard Worker   assert(cm->width <= cpi->initial_width);
7040*fb1b10abSAndroid Build Coastguard Worker   assert(cm->height <= cpi->initial_height);
7041*fb1b10abSAndroid Build Coastguard Worker 
7042*fb1b10abSAndroid Build Coastguard Worker   update_frame_size(cpi);
7043*fb1b10abSAndroid Build Coastguard Worker 
7044*fb1b10abSAndroid Build Coastguard Worker   return 0;
7045*fb1b10abSAndroid Build Coastguard Worker }
7046*fb1b10abSAndroid Build Coastguard Worker 
7047*fb1b10abSAndroid Build Coastguard Worker void vp9_set_svc(VP9_COMP *cpi, int use_svc) {
7048*fb1b10abSAndroid Build Coastguard Worker   cpi->use_svc = use_svc;
7049*fb1b10abSAndroid Build Coastguard Worker   return;
7050*fb1b10abSAndroid Build Coastguard Worker }
7051*fb1b10abSAndroid Build Coastguard Worker 
7052*fb1b10abSAndroid Build Coastguard Worker int vp9_get_quantizer(const VP9_COMP *cpi) { return cpi->common.base_qindex; }
7053*fb1b10abSAndroid Build Coastguard Worker 
7054*fb1b10abSAndroid Build Coastguard Worker void vp9_apply_encoding_flags(VP9_COMP *cpi, vpx_enc_frame_flags_t flags) {
7055*fb1b10abSAndroid Build Coastguard Worker   if (flags &
7056*fb1b10abSAndroid Build Coastguard Worker       (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF)) {
7057*fb1b10abSAndroid Build Coastguard Worker     int ref = 7;
7058*fb1b10abSAndroid Build Coastguard Worker 
7059*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_REF_LAST) ref ^= VP9_LAST_FLAG;
7060*fb1b10abSAndroid Build Coastguard Worker 
7061*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_REF_GF) ref ^= VP9_GOLD_FLAG;
7062*fb1b10abSAndroid Build Coastguard Worker 
7063*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_REF_ARF) ref ^= VP9_ALT_FLAG;
7064*fb1b10abSAndroid Build Coastguard Worker 
7065*fb1b10abSAndroid Build Coastguard Worker     vp9_use_as_reference(cpi, ref);
7066*fb1b10abSAndroid Build Coastguard Worker   }
7067*fb1b10abSAndroid Build Coastguard Worker 
7068*fb1b10abSAndroid Build Coastguard Worker   if (flags &
7069*fb1b10abSAndroid Build Coastguard Worker       (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
7070*fb1b10abSAndroid Build Coastguard Worker        VP8_EFLAG_FORCE_GF | VP8_EFLAG_FORCE_ARF)) {
7071*fb1b10abSAndroid Build Coastguard Worker     int upd = 7;
7072*fb1b10abSAndroid Build Coastguard Worker 
7073*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_UPD_LAST) upd ^= VP9_LAST_FLAG;
7074*fb1b10abSAndroid Build Coastguard Worker 
7075*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_UPD_GF) upd ^= VP9_GOLD_FLAG;
7076*fb1b10abSAndroid Build Coastguard Worker 
7077*fb1b10abSAndroid Build Coastguard Worker     if (flags & VP8_EFLAG_NO_UPD_ARF) upd ^= VP9_ALT_FLAG;
7078*fb1b10abSAndroid Build Coastguard Worker 
7079*fb1b10abSAndroid Build Coastguard Worker     vp9_update_reference(cpi, upd);
7080*fb1b10abSAndroid Build Coastguard Worker   }
7081*fb1b10abSAndroid Build Coastguard Worker 
7082*fb1b10abSAndroid Build Coastguard Worker   if (flags & VP8_EFLAG_NO_UPD_ENTROPY) {
7083*fb1b10abSAndroid Build Coastguard Worker     vp9_update_entropy(cpi, 0);
7084*fb1b10abSAndroid Build Coastguard Worker   }
7085*fb1b10abSAndroid Build Coastguard Worker }
7086*fb1b10abSAndroid Build Coastguard Worker 
7087*fb1b10abSAndroid Build Coastguard Worker void vp9_set_row_mt(VP9_COMP *cpi) {
7088*fb1b10abSAndroid Build Coastguard Worker   // Enable row based multi-threading for supported modes of encoding
7089*fb1b10abSAndroid Build Coastguard Worker   cpi->row_mt = 0;
7090*fb1b10abSAndroid Build Coastguard Worker   if (((cpi->oxcf.mode == GOOD || cpi->oxcf.mode == BEST) &&
7091*fb1b10abSAndroid Build Coastguard Worker        cpi->oxcf.speed < 5 && cpi->oxcf.pass == 1) &&
7092*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.row_mt && !cpi->use_svc)
7093*fb1b10abSAndroid Build Coastguard Worker     cpi->row_mt = 1;
7094*fb1b10abSAndroid Build Coastguard Worker 
7095*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.mode == GOOD && cpi->oxcf.speed < 5 &&
7096*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.pass == 0 || cpi->oxcf.pass == 2) && cpi->oxcf.row_mt &&
7097*fb1b10abSAndroid Build Coastguard Worker       !cpi->use_svc)
7098*fb1b10abSAndroid Build Coastguard Worker     cpi->row_mt = 1;
7099*fb1b10abSAndroid Build Coastguard Worker 
7100*fb1b10abSAndroid Build Coastguard Worker   // In realtime mode, enable row based multi-threading for all the speed levels
7101*fb1b10abSAndroid Build Coastguard Worker   // where non-rd path is used.
7102*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.mode == REALTIME && cpi->oxcf.speed >= 5 && cpi->oxcf.row_mt) {
7103*fb1b10abSAndroid Build Coastguard Worker     cpi->row_mt = 1;
7104*fb1b10abSAndroid Build Coastguard Worker   }
7105*fb1b10abSAndroid Build Coastguard Worker 
7106*fb1b10abSAndroid Build Coastguard Worker   if (cpi->row_mt)
7107*fb1b10abSAndroid Build Coastguard Worker     cpi->row_mt_bit_exact = 1;
7108*fb1b10abSAndroid Build Coastguard Worker   else
7109*fb1b10abSAndroid Build Coastguard Worker     cpi->row_mt_bit_exact = 0;
7110*fb1b10abSAndroid Build Coastguard Worker }
7111