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