xref: /aosp_15_r20/external/libvpx/vp9/encoder/vp9_ratectrl.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <limits.h>
13*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
14*fb1b10abSAndroid Build Coastguard Worker #include <stdint.h>
15*fb1b10abSAndroid Build Coastguard Worker #include <stdio.h>
16*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
17*fb1b10abSAndroid Build Coastguard Worker #include <string.h>
18*fb1b10abSAndroid Build Coastguard Worker 
19*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
22*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/system_state.h"
24*fb1b10abSAndroid Build Coastguard Worker 
25*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_alloccommon.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_blockd.h"
27*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_common.h"
28*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_entropymode.h"
29*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_onyxc_int.h"
30*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_quant_common.h"
31*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_seg_common.h"
32*fb1b10abSAndroid Build Coastguard Worker 
33*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_aq_cyclicrefresh.h"
34*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemv.h"
35*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encoder.h"
36*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_ext_ratectrl.h"
37*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_firstpass.h"
38*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_ratectrl.h"
39*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_svc_layercontext.h"
40*fb1b10abSAndroid Build Coastguard Worker 
41*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_codec.h"
42*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_ext_ratectrl.h"
43*fb1b10abSAndroid Build Coastguard Worker #include "vpx/internal/vpx_codec_internal.h"
44*fb1b10abSAndroid Build Coastguard Worker 
45*fb1b10abSAndroid Build Coastguard Worker // Max rate per frame for 1080P and below encodes if no level requirement given.
46*fb1b10abSAndroid Build Coastguard Worker // For larger formats limit to MAX_MB_RATE bits per MB
47*fb1b10abSAndroid Build Coastguard Worker // 4Mbits is derived from the level requirement for level 4 (1080P 30) which
48*fb1b10abSAndroid Build Coastguard Worker // requires that HW can sustain a rate of 16Mbits over a 4 frame group.
49*fb1b10abSAndroid Build Coastguard Worker // If a lower level requirement is specified then this may over ride this value.
50*fb1b10abSAndroid Build Coastguard Worker #define MAX_MB_RATE 250
51*fb1b10abSAndroid Build Coastguard Worker #define MAXRATE_1080P 4000000
52*fb1b10abSAndroid Build Coastguard Worker 
53*fb1b10abSAndroid Build Coastguard Worker #define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1
54*fb1b10abSAndroid Build Coastguard Worker 
55*fb1b10abSAndroid Build Coastguard Worker #define MIN_BPB_FACTOR 0.005
56*fb1b10abSAndroid Build Coastguard Worker #define MAX_BPB_FACTOR 50
57*fb1b10abSAndroid Build Coastguard Worker 
58*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
59*fb1b10abSAndroid Build Coastguard Worker #define ASSIGN_MINQ_TABLE(bit_depth, name)       \
60*fb1b10abSAndroid Build Coastguard Worker   do {                                           \
61*fb1b10abSAndroid Build Coastguard Worker     switch (bit_depth) {                         \
62*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_8: name = name##_8; break;   \
63*fb1b10abSAndroid Build Coastguard Worker       case VPX_BITS_10: name = name##_10; break; \
64*fb1b10abSAndroid Build Coastguard Worker       default:                                   \
65*fb1b10abSAndroid Build Coastguard Worker         assert(bit_depth == VPX_BITS_12);        \
66*fb1b10abSAndroid Build Coastguard Worker         name = name##_12;                        \
67*fb1b10abSAndroid Build Coastguard Worker         break;                                   \
68*fb1b10abSAndroid Build Coastguard Worker     }                                            \
69*fb1b10abSAndroid Build Coastguard Worker   } while (0)
70*fb1b10abSAndroid Build Coastguard Worker #else
71*fb1b10abSAndroid Build Coastguard Worker #define ASSIGN_MINQ_TABLE(bit_depth, name) \
72*fb1b10abSAndroid Build Coastguard Worker   do {                                     \
73*fb1b10abSAndroid Build Coastguard Worker     (void)bit_depth;                       \
74*fb1b10abSAndroid Build Coastguard Worker     name = name##_8;                       \
75*fb1b10abSAndroid Build Coastguard Worker   } while (0)
76*fb1b10abSAndroid Build Coastguard Worker #endif
77*fb1b10abSAndroid Build Coastguard Worker 
78*fb1b10abSAndroid Build Coastguard Worker // Tables relating active max Q to active min Q
79*fb1b10abSAndroid Build Coastguard Worker static int kf_low_motion_minq_8[QINDEX_RANGE];
80*fb1b10abSAndroid Build Coastguard Worker static int kf_high_motion_minq_8[QINDEX_RANGE];
81*fb1b10abSAndroid Build Coastguard Worker static int arfgf_low_motion_minq_8[QINDEX_RANGE];
82*fb1b10abSAndroid Build Coastguard Worker static int arfgf_high_motion_minq_8[QINDEX_RANGE];
83*fb1b10abSAndroid Build Coastguard Worker static int inter_minq_8[QINDEX_RANGE];
84*fb1b10abSAndroid Build Coastguard Worker static int rtc_minq_8[QINDEX_RANGE];
85*fb1b10abSAndroid Build Coastguard Worker 
86*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
87*fb1b10abSAndroid Build Coastguard Worker static int kf_low_motion_minq_10[QINDEX_RANGE];
88*fb1b10abSAndroid Build Coastguard Worker static int kf_high_motion_minq_10[QINDEX_RANGE];
89*fb1b10abSAndroid Build Coastguard Worker static int arfgf_low_motion_minq_10[QINDEX_RANGE];
90*fb1b10abSAndroid Build Coastguard Worker static int arfgf_high_motion_minq_10[QINDEX_RANGE];
91*fb1b10abSAndroid Build Coastguard Worker static int inter_minq_10[QINDEX_RANGE];
92*fb1b10abSAndroid Build Coastguard Worker static int rtc_minq_10[QINDEX_RANGE];
93*fb1b10abSAndroid Build Coastguard Worker static int kf_low_motion_minq_12[QINDEX_RANGE];
94*fb1b10abSAndroid Build Coastguard Worker static int kf_high_motion_minq_12[QINDEX_RANGE];
95*fb1b10abSAndroid Build Coastguard Worker static int arfgf_low_motion_minq_12[QINDEX_RANGE];
96*fb1b10abSAndroid Build Coastguard Worker static int arfgf_high_motion_minq_12[QINDEX_RANGE];
97*fb1b10abSAndroid Build Coastguard Worker static int inter_minq_12[QINDEX_RANGE];
98*fb1b10abSAndroid Build Coastguard Worker static int rtc_minq_12[QINDEX_RANGE];
99*fb1b10abSAndroid Build Coastguard Worker #endif
100*fb1b10abSAndroid Build Coastguard Worker 
101*fb1b10abSAndroid Build Coastguard Worker #ifdef AGGRESSIVE_VBR
102*fb1b10abSAndroid Build Coastguard Worker static int gf_high = 2400;
103*fb1b10abSAndroid Build Coastguard Worker static int gf_low = 400;
104*fb1b10abSAndroid Build Coastguard Worker static int kf_high = 4000;
105*fb1b10abSAndroid Build Coastguard Worker static int kf_low = 400;
106*fb1b10abSAndroid Build Coastguard Worker #else
107*fb1b10abSAndroid Build Coastguard Worker static int gf_high = 2000;
108*fb1b10abSAndroid Build Coastguard Worker static int gf_low = 400;
109*fb1b10abSAndroid Build Coastguard Worker static int kf_high = 4800;
110*fb1b10abSAndroid Build Coastguard Worker static int kf_low = 300;
111*fb1b10abSAndroid Build Coastguard Worker #endif
112*fb1b10abSAndroid Build Coastguard Worker 
113*fb1b10abSAndroid Build Coastguard Worker // Functions to compute the active minq lookup table entries based on a
114*fb1b10abSAndroid Build Coastguard Worker // formulaic approach to facilitate easier adjustment of the Q tables.
115*fb1b10abSAndroid Build Coastguard Worker // The formulae were derived from computing a 3rd order polynomial best
116*fb1b10abSAndroid Build Coastguard Worker // fit to the original data (after plotting real maxq vs minq (not q index))
get_minq_index(double maxq,double x3,double x2,double x1,vpx_bit_depth_t bit_depth)117*fb1b10abSAndroid Build Coastguard Worker static int get_minq_index(double maxq, double x3, double x2, double x1,
118*fb1b10abSAndroid Build Coastguard Worker                           vpx_bit_depth_t bit_depth) {
119*fb1b10abSAndroid Build Coastguard Worker   int i;
120*fb1b10abSAndroid Build Coastguard Worker   const double minqtarget = VPXMIN(((x3 * maxq + x2) * maxq + x1) * maxq, maxq);
121*fb1b10abSAndroid Build Coastguard Worker 
122*fb1b10abSAndroid Build Coastguard Worker   // Special case handling to deal with the step from q2.0
123*fb1b10abSAndroid Build Coastguard Worker   // down to lossless mode represented by q 1.0.
124*fb1b10abSAndroid Build Coastguard Worker   if (minqtarget <= 2.0) return 0;
125*fb1b10abSAndroid Build Coastguard Worker 
126*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < QINDEX_RANGE; i++) {
127*fb1b10abSAndroid Build Coastguard Worker     if (minqtarget <= vp9_convert_qindex_to_q(i, bit_depth)) return i;
128*fb1b10abSAndroid Build Coastguard Worker   }
129*fb1b10abSAndroid Build Coastguard Worker 
130*fb1b10abSAndroid Build Coastguard Worker   return QINDEX_RANGE - 1;
131*fb1b10abSAndroid Build Coastguard Worker }
132*fb1b10abSAndroid Build Coastguard Worker 
init_minq_luts(int * kf_low_m,int * kf_high_m,int * arfgf_low,int * arfgf_high,int * inter,int * rtc,vpx_bit_depth_t bit_depth)133*fb1b10abSAndroid Build Coastguard Worker static void init_minq_luts(int *kf_low_m, int *kf_high_m, int *arfgf_low,
134*fb1b10abSAndroid Build Coastguard Worker                            int *arfgf_high, int *inter, int *rtc,
135*fb1b10abSAndroid Build Coastguard Worker                            vpx_bit_depth_t bit_depth) {
136*fb1b10abSAndroid Build Coastguard Worker   int i;
137*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < QINDEX_RANGE; i++) {
138*fb1b10abSAndroid Build Coastguard Worker     const double maxq = vp9_convert_qindex_to_q(i, bit_depth);
139*fb1b10abSAndroid Build Coastguard Worker     kf_low_m[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.150, bit_depth);
140*fb1b10abSAndroid Build Coastguard Worker     kf_high_m[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.45, bit_depth);
141*fb1b10abSAndroid Build Coastguard Worker #ifdef AGGRESSIVE_VBR
142*fb1b10abSAndroid Build Coastguard Worker     arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.275, bit_depth);
143*fb1b10abSAndroid Build Coastguard Worker     inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.80, bit_depth);
144*fb1b10abSAndroid Build Coastguard Worker #else
145*fb1b10abSAndroid Build Coastguard Worker     arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth);
146*fb1b10abSAndroid Build Coastguard Worker     inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
147*fb1b10abSAndroid Build Coastguard Worker #endif
148*fb1b10abSAndroid Build Coastguard Worker     arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
149*fb1b10abSAndroid Build Coastguard Worker     rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
150*fb1b10abSAndroid Build Coastguard Worker   }
151*fb1b10abSAndroid Build Coastguard Worker }
152*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_init_minq_luts(void)153*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_init_minq_luts(void) {
154*fb1b10abSAndroid Build Coastguard Worker   init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8,
155*fb1b10abSAndroid Build Coastguard Worker                  arfgf_low_motion_minq_8, arfgf_high_motion_minq_8,
156*fb1b10abSAndroid Build Coastguard Worker                  inter_minq_8, rtc_minq_8, VPX_BITS_8);
157*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
158*fb1b10abSAndroid Build Coastguard Worker   init_minq_luts(kf_low_motion_minq_10, kf_high_motion_minq_10,
159*fb1b10abSAndroid Build Coastguard Worker                  arfgf_low_motion_minq_10, arfgf_high_motion_minq_10,
160*fb1b10abSAndroid Build Coastguard Worker                  inter_minq_10, rtc_minq_10, VPX_BITS_10);
161*fb1b10abSAndroid Build Coastguard Worker   init_minq_luts(kf_low_motion_minq_12, kf_high_motion_minq_12,
162*fb1b10abSAndroid Build Coastguard Worker                  arfgf_low_motion_minq_12, arfgf_high_motion_minq_12,
163*fb1b10abSAndroid Build Coastguard Worker                  inter_minq_12, rtc_minq_12, VPX_BITS_12);
164*fb1b10abSAndroid Build Coastguard Worker #endif
165*fb1b10abSAndroid Build Coastguard Worker }
166*fb1b10abSAndroid Build Coastguard Worker 
167*fb1b10abSAndroid Build Coastguard Worker // These functions use formulaic calculations to make playing with the
168*fb1b10abSAndroid Build Coastguard Worker // quantizer tables easier. If necessary they can be replaced by lookup
169*fb1b10abSAndroid Build Coastguard Worker // tables if and when things settle down in the experimental bitstream
vp9_convert_qindex_to_q(int qindex,vpx_bit_depth_t bit_depth)170*fb1b10abSAndroid Build Coastguard Worker double vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth) {
171*fb1b10abSAndroid Build Coastguard Worker // Convert the index to a real Q value (scaled down to match old Q values)
172*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
173*fb1b10abSAndroid Build Coastguard Worker   switch (bit_depth) {
174*fb1b10abSAndroid Build Coastguard Worker     case VPX_BITS_8: return vp9_ac_quant(qindex, 0, bit_depth) / 4.0;
175*fb1b10abSAndroid Build Coastguard Worker     case VPX_BITS_10: return vp9_ac_quant(qindex, 0, bit_depth) / 16.0;
176*fb1b10abSAndroid Build Coastguard Worker     default:
177*fb1b10abSAndroid Build Coastguard Worker       assert(bit_depth == VPX_BITS_12);
178*fb1b10abSAndroid Build Coastguard Worker       return vp9_ac_quant(qindex, 0, bit_depth) / 64.0;
179*fb1b10abSAndroid Build Coastguard Worker   }
180*fb1b10abSAndroid Build Coastguard Worker #else
181*fb1b10abSAndroid Build Coastguard Worker   return vp9_ac_quant(qindex, 0, bit_depth) / 4.0;
182*fb1b10abSAndroid Build Coastguard Worker #endif
183*fb1b10abSAndroid Build Coastguard Worker }
184*fb1b10abSAndroid Build Coastguard Worker 
vp9_convert_q_to_qindex(double q_val,vpx_bit_depth_t bit_depth)185*fb1b10abSAndroid Build Coastguard Worker int vp9_convert_q_to_qindex(double q_val, vpx_bit_depth_t bit_depth) {
186*fb1b10abSAndroid Build Coastguard Worker   int i;
187*fb1b10abSAndroid Build Coastguard Worker 
188*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < QINDEX_RANGE; ++i)
189*fb1b10abSAndroid Build Coastguard Worker     if (vp9_convert_qindex_to_q(i, bit_depth) >= q_val) break;
190*fb1b10abSAndroid Build Coastguard Worker 
191*fb1b10abSAndroid Build Coastguard Worker   if (i == QINDEX_RANGE) i--;
192*fb1b10abSAndroid Build Coastguard Worker 
193*fb1b10abSAndroid Build Coastguard Worker   return i;
194*fb1b10abSAndroid Build Coastguard Worker }
195*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_bits_per_mb(FRAME_TYPE frame_type,int qindex,double correction_factor,vpx_bit_depth_t bit_depth)196*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,
197*fb1b10abSAndroid Build Coastguard Worker                        double correction_factor, vpx_bit_depth_t bit_depth) {
198*fb1b10abSAndroid Build Coastguard Worker   const double q = vp9_convert_qindex_to_q(qindex, bit_depth);
199*fb1b10abSAndroid Build Coastguard Worker   int enumerator = frame_type == KEY_FRAME ? 2700000 : 1800000;
200*fb1b10abSAndroid Build Coastguard Worker 
201*fb1b10abSAndroid Build Coastguard Worker   assert(correction_factor <= MAX_BPB_FACTOR &&
202*fb1b10abSAndroid Build Coastguard Worker          correction_factor >= MIN_BPB_FACTOR);
203*fb1b10abSAndroid Build Coastguard Worker 
204*fb1b10abSAndroid Build Coastguard Worker   // q based adjustment to baseline enumerator
205*fb1b10abSAndroid Build Coastguard Worker   enumerator += (int)(enumerator * q) >> 12;
206*fb1b10abSAndroid Build Coastguard Worker   return (int)(enumerator * correction_factor / q);
207*fb1b10abSAndroid Build Coastguard Worker }
208*fb1b10abSAndroid Build Coastguard Worker 
vp9_estimate_bits_at_q(FRAME_TYPE frame_type,int q,int mbs,double correction_factor,vpx_bit_depth_t bit_depth)209*fb1b10abSAndroid Build Coastguard Worker int vp9_estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs,
210*fb1b10abSAndroid Build Coastguard Worker                            double correction_factor,
211*fb1b10abSAndroid Build Coastguard Worker                            vpx_bit_depth_t bit_depth) {
212*fb1b10abSAndroid Build Coastguard Worker   const int bpm =
213*fb1b10abSAndroid Build Coastguard Worker       (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor, bit_depth));
214*fb1b10abSAndroid Build Coastguard Worker   return VPXMAX(FRAME_OVERHEAD_BITS,
215*fb1b10abSAndroid Build Coastguard Worker                 (int)(((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS));
216*fb1b10abSAndroid Build Coastguard Worker }
217*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_clamp_pframe_target_size(const VP9_COMP * const cpi,int target)218*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
219*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
220*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
221*fb1b10abSAndroid Build Coastguard Worker 
222*fb1b10abSAndroid Build Coastguard Worker   const int min_frame_target =
223*fb1b10abSAndroid Build Coastguard Worker       VPXMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
224*fb1b10abSAndroid Build Coastguard Worker   if (target < min_frame_target) target = min_frame_target;
225*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
226*fb1b10abSAndroid Build Coastguard Worker     // If there is an active ARF at this location use the minimum
227*fb1b10abSAndroid Build Coastguard Worker     // bits on this frame even if it is a constructed arf.
228*fb1b10abSAndroid Build Coastguard Worker     // The active maximum quantizer insures that an appropriate
229*fb1b10abSAndroid Build Coastguard Worker     // number of bits will be spent if needed for constructed ARFs.
230*fb1b10abSAndroid Build Coastguard Worker     target = min_frame_target;
231*fb1b10abSAndroid Build Coastguard Worker   }
232*fb1b10abSAndroid Build Coastguard Worker 
233*fb1b10abSAndroid Build Coastguard Worker   // Clip the frame target to the maximum allowed value.
234*fb1b10abSAndroid Build Coastguard Worker   if (target > rc->max_frame_bandwidth) target = rc->max_frame_bandwidth;
235*fb1b10abSAndroid Build Coastguard Worker 
236*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_max_inter_bitrate_pct) {
237*fb1b10abSAndroid Build Coastguard Worker     const int64_t max_rate =
238*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100;
239*fb1b10abSAndroid Build Coastguard Worker     // target is of type int and VPXMIN cannot evaluate to larger than target
240*fb1b10abSAndroid Build Coastguard Worker     target = (int)VPXMIN(target, max_rate);
241*fb1b10abSAndroid Build Coastguard Worker   }
242*fb1b10abSAndroid Build Coastguard Worker   return target;
243*fb1b10abSAndroid Build Coastguard Worker }
244*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_clamp_iframe_target_size(const VP9_COMP * const cpi,int target)245*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) {
246*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
247*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
248*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_max_intra_bitrate_pct) {
249*fb1b10abSAndroid Build Coastguard Worker     const int64_t max_rate =
250*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->avg_frame_bandwidth * oxcf->rc_max_intra_bitrate_pct / 100;
251*fb1b10abSAndroid Build Coastguard Worker     target = (int)VPXMIN(target, max_rate);
252*fb1b10abSAndroid Build Coastguard Worker   }
253*fb1b10abSAndroid Build Coastguard Worker   if (target > rc->max_frame_bandwidth) target = rc->max_frame_bandwidth;
254*fb1b10abSAndroid Build Coastguard Worker   return target;
255*fb1b10abSAndroid Build Coastguard Worker }
256*fb1b10abSAndroid Build Coastguard Worker 
257*fb1b10abSAndroid Build Coastguard Worker // TODO(marpan/jianj): bits_off_target and buffer_level are used in the same
258*fb1b10abSAndroid Build Coastguard Worker // way for CBR mode, for the buffering updates below. Look into removing one
259*fb1b10abSAndroid Build Coastguard Worker // of these (i.e., bits_off_target).
260*fb1b10abSAndroid Build Coastguard Worker // Update the buffer level before encoding with the per-frame-bandwidth,
vp9_update_buffer_level_preencode(VP9_COMP * cpi)261*fb1b10abSAndroid Build Coastguard Worker void vp9_update_buffer_level_preencode(VP9_COMP *cpi) {
262*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
263*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target += rc->avg_frame_bandwidth;
264*fb1b10abSAndroid Build Coastguard Worker   // Clip the buffer level to the maximum specified buffer size.
265*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size);
266*fb1b10abSAndroid Build Coastguard Worker   rc->buffer_level = rc->bits_off_target;
267*fb1b10abSAndroid Build Coastguard Worker }
268*fb1b10abSAndroid Build Coastguard Worker 
269*fb1b10abSAndroid Build Coastguard Worker // Update the buffer level before encoding with the per-frame-bandwidth
270*fb1b10abSAndroid Build Coastguard Worker // for SVC. The current and all upper temporal layers are updated, needed
271*fb1b10abSAndroid Build Coastguard Worker // for the layered rate control which involves cumulative buffer levels for
272*fb1b10abSAndroid Build Coastguard Worker // the temporal layers. Allow for using the timestamp(pts) delta for the
273*fb1b10abSAndroid Build Coastguard Worker // framerate when the set_ref_frame_config is used.
vp9_update_buffer_level_svc_preencode(VP9_COMP * cpi)274*fb1b10abSAndroid Build Coastguard Worker void vp9_update_buffer_level_svc_preencode(VP9_COMP *cpi) {
275*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
276*fb1b10abSAndroid Build Coastguard Worker   int i;
277*fb1b10abSAndroid Build Coastguard Worker   // Set this to 1 to use timestamp delta for "framerate" under
278*fb1b10abSAndroid Build Coastguard Worker   // ref_frame_config usage.
279*fb1b10abSAndroid Build Coastguard Worker   int use_timestamp = 1;
280*fb1b10abSAndroid Build Coastguard Worker   const int64_t ts_delta =
281*fb1b10abSAndroid Build Coastguard Worker       svc->time_stamp_superframe - svc->time_stamp_prev[svc->spatial_layer_id];
282*fb1b10abSAndroid Build Coastguard Worker   for (i = svc->temporal_layer_id; i < svc->number_temporal_layers; ++i) {
283*fb1b10abSAndroid Build Coastguard Worker     const int layer =
284*fb1b10abSAndroid Build Coastguard Worker         LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, svc->number_temporal_layers);
285*fb1b10abSAndroid Build Coastguard Worker     LAYER_CONTEXT *const lc = &svc->layer_context[layer];
286*fb1b10abSAndroid Build Coastguard Worker     RATE_CONTROL *const lrc = &lc->rc;
287*fb1b10abSAndroid Build Coastguard Worker     if (use_timestamp && cpi->svc.use_set_ref_frame_config &&
288*fb1b10abSAndroid Build Coastguard Worker         svc->number_temporal_layers == 1 && ts_delta > 0 &&
289*fb1b10abSAndroid Build Coastguard Worker         svc->current_superframe > 0) {
290*fb1b10abSAndroid Build Coastguard Worker       // TODO(marpan): This may need to be modified for temporal layers.
291*fb1b10abSAndroid Build Coastguard Worker       const double framerate_pts = 10000000.0 / ts_delta;
292*fb1b10abSAndroid Build Coastguard Worker       lrc->bits_off_target += saturate_cast_double_to_int(
293*fb1b10abSAndroid Build Coastguard Worker           round(lc->target_bandwidth / framerate_pts));
294*fb1b10abSAndroid Build Coastguard Worker     } else {
295*fb1b10abSAndroid Build Coastguard Worker       lrc->bits_off_target += saturate_cast_double_to_int(
296*fb1b10abSAndroid Build Coastguard Worker           round(lc->target_bandwidth / lc->framerate));
297*fb1b10abSAndroid Build Coastguard Worker     }
298*fb1b10abSAndroid Build Coastguard Worker     // Clip buffer level to maximum buffer size for the layer.
299*fb1b10abSAndroid Build Coastguard Worker     lrc->bits_off_target =
300*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
301*fb1b10abSAndroid Build Coastguard Worker     lrc->buffer_level = lrc->bits_off_target;
302*fb1b10abSAndroid Build Coastguard Worker     if (i == svc->temporal_layer_id) {
303*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.bits_off_target = lrc->bits_off_target;
304*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.buffer_level = lrc->buffer_level;
305*fb1b10abSAndroid Build Coastguard Worker     }
306*fb1b10abSAndroid Build Coastguard Worker   }
307*fb1b10abSAndroid Build Coastguard Worker }
308*fb1b10abSAndroid Build Coastguard Worker 
309*fb1b10abSAndroid Build Coastguard Worker // Update the buffer level for higher temporal layers, given the encoded current
310*fb1b10abSAndroid Build Coastguard Worker // temporal layer.
update_layer_buffer_level_postencode(SVC * svc,int encoded_frame_size)311*fb1b10abSAndroid Build Coastguard Worker static void update_layer_buffer_level_postencode(SVC *svc,
312*fb1b10abSAndroid Build Coastguard Worker                                                  int encoded_frame_size) {
313*fb1b10abSAndroid Build Coastguard Worker   int i = 0;
314*fb1b10abSAndroid Build Coastguard Worker   const int current_temporal_layer = svc->temporal_layer_id;
315*fb1b10abSAndroid Build Coastguard Worker   for (i = current_temporal_layer + 1; i < svc->number_temporal_layers; ++i) {
316*fb1b10abSAndroid Build Coastguard Worker     const int layer =
317*fb1b10abSAndroid Build Coastguard Worker         LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, svc->number_temporal_layers);
318*fb1b10abSAndroid Build Coastguard Worker     LAYER_CONTEXT *lc = &svc->layer_context[layer];
319*fb1b10abSAndroid Build Coastguard Worker     RATE_CONTROL *lrc = &lc->rc;
320*fb1b10abSAndroid Build Coastguard Worker     lrc->bits_off_target -= encoded_frame_size;
321*fb1b10abSAndroid Build Coastguard Worker     // Clip buffer level to maximum buffer size for the layer.
322*fb1b10abSAndroid Build Coastguard Worker     lrc->bits_off_target =
323*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
324*fb1b10abSAndroid Build Coastguard Worker     lrc->buffer_level = lrc->bits_off_target;
325*fb1b10abSAndroid Build Coastguard Worker   }
326*fb1b10abSAndroid Build Coastguard Worker }
327*fb1b10abSAndroid Build Coastguard Worker 
328*fb1b10abSAndroid Build Coastguard Worker // Update the buffer level after encoding with encoded frame size.
update_buffer_level_postencode(VP9_COMP * cpi,int encoded_frame_size)329*fb1b10abSAndroid Build Coastguard Worker static void update_buffer_level_postencode(VP9_COMP *cpi,
330*fb1b10abSAndroid Build Coastguard Worker                                            int encoded_frame_size) {
331*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
332*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target -= encoded_frame_size;
333*fb1b10abSAndroid Build Coastguard Worker   // Clip the buffer level to the maximum specified buffer size.
334*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target = VPXMIN(rc->bits_off_target, rc->maximum_buffer_size);
335*fb1b10abSAndroid Build Coastguard Worker   // For screen-content mode, and if frame-dropper is off, don't let buffer
336*fb1b10abSAndroid Build Coastguard Worker   // level go below threshold, given here as -rc->maximum_ buffer_size.
337*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
338*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.drop_frames_water_mark == 0)
339*fb1b10abSAndroid Build Coastguard Worker     rc->bits_off_target = VPXMAX(rc->bits_off_target, -rc->maximum_buffer_size);
340*fb1b10abSAndroid Build Coastguard Worker 
341*fb1b10abSAndroid Build Coastguard Worker   rc->buffer_level = rc->bits_off_target;
342*fb1b10abSAndroid Build Coastguard Worker 
343*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) {
344*fb1b10abSAndroid Build Coastguard Worker     update_layer_buffer_level_postencode(&cpi->svc, encoded_frame_size);
345*fb1b10abSAndroid Build Coastguard Worker   }
346*fb1b10abSAndroid Build Coastguard Worker }
347*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_get_default_min_gf_interval(int width,int height,double framerate)348*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_get_default_min_gf_interval(int width, int height,
349*fb1b10abSAndroid Build Coastguard Worker                                        double framerate) {
350*fb1b10abSAndroid Build Coastguard Worker   // Assume we do not need any constraint lower than 4K 20 fps
351*fb1b10abSAndroid Build Coastguard Worker   static const double factor_safe = 3840 * 2160 * 20.0;
352*fb1b10abSAndroid Build Coastguard Worker   const double factor = width * height * framerate;
353*fb1b10abSAndroid Build Coastguard Worker   const int default_interval =
354*fb1b10abSAndroid Build Coastguard Worker       clamp((int)round(framerate * 0.125), MIN_GF_INTERVAL, MAX_GF_INTERVAL);
355*fb1b10abSAndroid Build Coastguard Worker 
356*fb1b10abSAndroid Build Coastguard Worker   if (factor <= factor_safe)
357*fb1b10abSAndroid Build Coastguard Worker     return default_interval;
358*fb1b10abSAndroid Build Coastguard Worker   else
359*fb1b10abSAndroid Build Coastguard Worker     return VPXMAX(default_interval,
360*fb1b10abSAndroid Build Coastguard Worker                   (int)round(MIN_GF_INTERVAL * factor / factor_safe));
361*fb1b10abSAndroid Build Coastguard Worker   // Note this logic makes:
362*fb1b10abSAndroid Build Coastguard Worker   // 4K24: 5
363*fb1b10abSAndroid Build Coastguard Worker   // 4K30: 6
364*fb1b10abSAndroid Build Coastguard Worker   // 4K60: 12
365*fb1b10abSAndroid Build Coastguard Worker }
366*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_get_default_max_gf_interval(double framerate,int min_gf_interval)367*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_get_default_max_gf_interval(double framerate, int min_gf_interval) {
368*fb1b10abSAndroid Build Coastguard Worker   int interval = VPXMIN(MAX_GF_INTERVAL, (int)round(framerate * 0.75));
369*fb1b10abSAndroid Build Coastguard Worker   interval += (interval & 0x01);  // Round to even value
370*fb1b10abSAndroid Build Coastguard Worker   return VPXMAX(interval, min_gf_interval);
371*fb1b10abSAndroid Build Coastguard Worker }
372*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_init(const VP9EncoderConfig * oxcf,int pass,RATE_CONTROL * rc)373*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
374*fb1b10abSAndroid Build Coastguard Worker   int i;
375*fb1b10abSAndroid Build Coastguard Worker 
376*fb1b10abSAndroid Build Coastguard Worker   if (pass == 0 && oxcf->rc_mode == VPX_CBR) {
377*fb1b10abSAndroid Build Coastguard Worker     rc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
378*fb1b10abSAndroid Build Coastguard Worker     rc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
379*fb1b10abSAndroid Build Coastguard Worker   } else {
380*fb1b10abSAndroid Build Coastguard Worker     rc->avg_frame_qindex[KEY_FRAME] =
381*fb1b10abSAndroid Build Coastguard Worker         (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2;
382*fb1b10abSAndroid Build Coastguard Worker     rc->avg_frame_qindex[INTER_FRAME] =
383*fb1b10abSAndroid Build Coastguard Worker         (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2;
384*fb1b10abSAndroid Build Coastguard Worker   }
385*fb1b10abSAndroid Build Coastguard Worker 
386*fb1b10abSAndroid Build Coastguard Worker   rc->last_q[KEY_FRAME] = oxcf->best_allowed_q;
387*fb1b10abSAndroid Build Coastguard Worker   rc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
388*fb1b10abSAndroid Build Coastguard Worker 
389*fb1b10abSAndroid Build Coastguard Worker   rc->buffer_level = rc->starting_buffer_level;
390*fb1b10abSAndroid Build Coastguard Worker   rc->bits_off_target = rc->starting_buffer_level;
391*fb1b10abSAndroid Build Coastguard Worker 
392*fb1b10abSAndroid Build Coastguard Worker   rc->rolling_target_bits = rc->avg_frame_bandwidth;
393*fb1b10abSAndroid Build Coastguard Worker   rc->rolling_actual_bits = rc->avg_frame_bandwidth;
394*fb1b10abSAndroid Build Coastguard Worker   rc->long_rolling_target_bits = rc->avg_frame_bandwidth;
395*fb1b10abSAndroid Build Coastguard Worker   rc->long_rolling_actual_bits = rc->avg_frame_bandwidth;
396*fb1b10abSAndroid Build Coastguard Worker 
397*fb1b10abSAndroid Build Coastguard Worker   rc->total_actual_bits = 0;
398*fb1b10abSAndroid Build Coastguard Worker   rc->total_target_bits = 0;
399*fb1b10abSAndroid Build Coastguard Worker   rc->total_target_vs_actual = 0;
400*fb1b10abSAndroid Build Coastguard Worker   rc->avg_frame_low_motion = 0;
401*fb1b10abSAndroid Build Coastguard Worker   rc->count_last_scene_change = 0;
402*fb1b10abSAndroid Build Coastguard Worker   rc->af_ratio_onepass_vbr = 10;
403*fb1b10abSAndroid Build Coastguard Worker   rc->prev_avg_source_sad_lag = 0;
404*fb1b10abSAndroid Build Coastguard Worker   rc->high_source_sad = 0;
405*fb1b10abSAndroid Build Coastguard Worker   rc->reset_high_source_sad = 0;
406*fb1b10abSAndroid Build Coastguard Worker   rc->high_source_sad_lagindex = -1;
407*fb1b10abSAndroid Build Coastguard Worker   rc->high_num_blocks_with_motion = 0;
408*fb1b10abSAndroid Build Coastguard Worker   rc->hybrid_intra_scene_change = 0;
409*fb1b10abSAndroid Build Coastguard Worker   rc->re_encode_maxq_scene_change = 0;
410*fb1b10abSAndroid Build Coastguard Worker   rc->alt_ref_gf_group = 0;
411*fb1b10abSAndroid Build Coastguard Worker   rc->last_frame_is_src_altref = 0;
412*fb1b10abSAndroid Build Coastguard Worker   rc->fac_active_worst_inter = 150;
413*fb1b10abSAndroid Build Coastguard Worker   rc->fac_active_worst_gf = 100;
414*fb1b10abSAndroid Build Coastguard Worker   rc->force_qpmin = 0;
415*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < MAX_LAG_BUFFERS; ++i) rc->avg_source_sad[i] = 0;
416*fb1b10abSAndroid Build Coastguard Worker   rc->frames_to_key = 0;
417*fb1b10abSAndroid Build Coastguard Worker   rc->frames_since_key = 8;  // Sensible default for first frame.
418*fb1b10abSAndroid Build Coastguard Worker   rc->this_key_frame_forced = 0;
419*fb1b10abSAndroid Build Coastguard Worker   rc->next_key_frame_forced = 0;
420*fb1b10abSAndroid Build Coastguard Worker   rc->source_alt_ref_pending = 0;
421*fb1b10abSAndroid Build Coastguard Worker   rc->source_alt_ref_active = 0;
422*fb1b10abSAndroid Build Coastguard Worker 
423*fb1b10abSAndroid Build Coastguard Worker   rc->frames_till_gf_update_due = 0;
424*fb1b10abSAndroid Build Coastguard Worker   rc->constrain_gf_key_freq_onepass_vbr = 1;
425*fb1b10abSAndroid Build Coastguard Worker   rc->ni_av_qi = oxcf->worst_allowed_q;
426*fb1b10abSAndroid Build Coastguard Worker   rc->ni_tot_qi = 0;
427*fb1b10abSAndroid Build Coastguard Worker   rc->ni_frames = 0;
428*fb1b10abSAndroid Build Coastguard Worker 
429*fb1b10abSAndroid Build Coastguard Worker   rc->tot_q = 0.0;
430*fb1b10abSAndroid Build Coastguard Worker   rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q, oxcf->bit_depth);
431*fb1b10abSAndroid Build Coastguard Worker 
432*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
433*fb1b10abSAndroid Build Coastguard Worker     rc->rate_correction_factors[i] = 1.0;
434*fb1b10abSAndroid Build Coastguard Worker     rc->damped_adjustment[i] = 0;
435*fb1b10abSAndroid Build Coastguard Worker   }
436*fb1b10abSAndroid Build Coastguard Worker 
437*fb1b10abSAndroid Build Coastguard Worker   rc->min_gf_interval = oxcf->min_gf_interval;
438*fb1b10abSAndroid Build Coastguard Worker   rc->max_gf_interval = oxcf->max_gf_interval;
439*fb1b10abSAndroid Build Coastguard Worker   if (rc->min_gf_interval == 0)
440*fb1b10abSAndroid Build Coastguard Worker     rc->min_gf_interval = vp9_rc_get_default_min_gf_interval(
441*fb1b10abSAndroid Build Coastguard Worker         oxcf->width, oxcf->height, oxcf->init_framerate);
442*fb1b10abSAndroid Build Coastguard Worker   if (rc->max_gf_interval == 0)
443*fb1b10abSAndroid Build Coastguard Worker     rc->max_gf_interval = vp9_rc_get_default_max_gf_interval(
444*fb1b10abSAndroid Build Coastguard Worker         oxcf->init_framerate, rc->min_gf_interval);
445*fb1b10abSAndroid Build Coastguard Worker   rc->baseline_gf_interval = (rc->min_gf_interval + rc->max_gf_interval) / 2;
446*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
447*fb1b10abSAndroid Build Coastguard Worker     rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
448*fb1b10abSAndroid Build Coastguard Worker   } else {
449*fb1b10abSAndroid Build Coastguard Worker     rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH;
450*fb1b10abSAndroid Build Coastguard Worker   }
451*fb1b10abSAndroid Build Coastguard Worker 
452*fb1b10abSAndroid Build Coastguard Worker   rc->force_max_q = 0;
453*fb1b10abSAndroid Build Coastguard Worker   rc->last_post_encode_dropped_scene_change = 0;
454*fb1b10abSAndroid Build Coastguard Worker   rc->use_post_encode_drop = 0;
455*fb1b10abSAndroid Build Coastguard Worker   rc->ext_use_post_encode_drop = 0;
456*fb1b10abSAndroid Build Coastguard Worker   rc->disable_overshoot_maxq_cbr = 0;
457*fb1b10abSAndroid Build Coastguard Worker   rc->arf_active_best_quality_adjustment_factor = 1.0;
458*fb1b10abSAndroid Build Coastguard Worker   rc->arf_increase_active_best_quality = 0;
459*fb1b10abSAndroid Build Coastguard Worker   rc->preserve_arf_as_gld = 0;
460*fb1b10abSAndroid Build Coastguard Worker   rc->preserve_next_arf_as_gld = 0;
461*fb1b10abSAndroid Build Coastguard Worker   rc->show_arf_as_gld = 0;
462*fb1b10abSAndroid Build Coastguard Worker }
463*fb1b10abSAndroid Build Coastguard Worker 
check_buffer_above_thresh(VP9_COMP * cpi,int drop_mark)464*fb1b10abSAndroid Build Coastguard Worker static int check_buffer_above_thresh(VP9_COMP *cpi, int drop_mark) {
465*fb1b10abSAndroid Build Coastguard Worker   SVC *svc = &cpi->svc;
466*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->use_svc || cpi->svc.framedrop_mode != FULL_SUPERFRAME_DROP) {
467*fb1b10abSAndroid Build Coastguard Worker     RATE_CONTROL *const rc = &cpi->rc;
468*fb1b10abSAndroid Build Coastguard Worker     return (rc->buffer_level > drop_mark);
469*fb1b10abSAndroid Build Coastguard Worker   } else {
470*fb1b10abSAndroid Build Coastguard Worker     int i;
471*fb1b10abSAndroid Build Coastguard Worker     // For SVC in the FULL_SUPERFRAME_DROP): the condition on
472*fb1b10abSAndroid Build Coastguard Worker     // buffer (if its above threshold, so no drop) is checked on current and
473*fb1b10abSAndroid Build Coastguard Worker     // upper spatial layers. If any spatial layer is not above threshold then
474*fb1b10abSAndroid Build Coastguard Worker     // we return 0.
475*fb1b10abSAndroid Build Coastguard Worker     for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) {
476*fb1b10abSAndroid Build Coastguard Worker       const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id,
477*fb1b10abSAndroid Build Coastguard Worker                                          svc->number_temporal_layers);
478*fb1b10abSAndroid Build Coastguard Worker       LAYER_CONTEXT *lc = &svc->layer_context[layer];
479*fb1b10abSAndroid Build Coastguard Worker       RATE_CONTROL *lrc = &lc->rc;
480*fb1b10abSAndroid Build Coastguard Worker       // Exclude check for layer whose bitrate is 0.
481*fb1b10abSAndroid Build Coastguard Worker       if (lc->target_bandwidth > 0) {
482*fb1b10abSAndroid Build Coastguard Worker         const int drop_mark_layer = (int)(cpi->svc.framedrop_thresh[i] *
483*fb1b10abSAndroid Build Coastguard Worker                                           lrc->optimal_buffer_level / 100);
484*fb1b10abSAndroid Build Coastguard Worker         if (!(lrc->buffer_level > drop_mark_layer)) return 0;
485*fb1b10abSAndroid Build Coastguard Worker       }
486*fb1b10abSAndroid Build Coastguard Worker     }
487*fb1b10abSAndroid Build Coastguard Worker     return 1;
488*fb1b10abSAndroid Build Coastguard Worker   }
489*fb1b10abSAndroid Build Coastguard Worker }
490*fb1b10abSAndroid Build Coastguard Worker 
check_buffer_below_thresh(VP9_COMP * cpi,int drop_mark)491*fb1b10abSAndroid Build Coastguard Worker static int check_buffer_below_thresh(VP9_COMP *cpi, int drop_mark) {
492*fb1b10abSAndroid Build Coastguard Worker   SVC *svc = &cpi->svc;
493*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->use_svc || cpi->svc.framedrop_mode == LAYER_DROP) {
494*fb1b10abSAndroid Build Coastguard Worker     RATE_CONTROL *const rc = &cpi->rc;
495*fb1b10abSAndroid Build Coastguard Worker     return (rc->buffer_level <= drop_mark);
496*fb1b10abSAndroid Build Coastguard Worker   } else {
497*fb1b10abSAndroid Build Coastguard Worker     int i;
498*fb1b10abSAndroid Build Coastguard Worker     // For SVC in the constrained framedrop mode (svc->framedrop_mode =
499*fb1b10abSAndroid Build Coastguard Worker     // CONSTRAINED_LAYER_DROP or FULL_SUPERFRAME_DROP): the condition on
500*fb1b10abSAndroid Build Coastguard Worker     // buffer (if its below threshold, so drop frame) is checked on current
501*fb1b10abSAndroid Build Coastguard Worker     // and upper spatial layers. For FULL_SUPERFRAME_DROP mode if any
502*fb1b10abSAndroid Build Coastguard Worker     // spatial layer is <= threshold, then we return 1 (drop).
503*fb1b10abSAndroid Build Coastguard Worker     for (i = svc->spatial_layer_id; i < svc->number_spatial_layers; ++i) {
504*fb1b10abSAndroid Build Coastguard Worker       const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id,
505*fb1b10abSAndroid Build Coastguard Worker                                          svc->number_temporal_layers);
506*fb1b10abSAndroid Build Coastguard Worker       LAYER_CONTEXT *lc = &svc->layer_context[layer];
507*fb1b10abSAndroid Build Coastguard Worker       RATE_CONTROL *lrc = &lc->rc;
508*fb1b10abSAndroid Build Coastguard Worker       // Exclude check for layer whose bitrate is 0.
509*fb1b10abSAndroid Build Coastguard Worker       if (lc->target_bandwidth > 0) {
510*fb1b10abSAndroid Build Coastguard Worker         const int drop_mark_layer = (int)(cpi->svc.framedrop_thresh[i] *
511*fb1b10abSAndroid Build Coastguard Worker                                           lrc->optimal_buffer_level / 100);
512*fb1b10abSAndroid Build Coastguard Worker         if (cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP) {
513*fb1b10abSAndroid Build Coastguard Worker           if (lrc->buffer_level <= drop_mark_layer) return 1;
514*fb1b10abSAndroid Build Coastguard Worker         } else {
515*fb1b10abSAndroid Build Coastguard Worker           if (!(lrc->buffer_level <= drop_mark_layer)) return 0;
516*fb1b10abSAndroid Build Coastguard Worker         }
517*fb1b10abSAndroid Build Coastguard Worker       }
518*fb1b10abSAndroid Build Coastguard Worker     }
519*fb1b10abSAndroid Build Coastguard Worker     if (cpi->svc.framedrop_mode == FULL_SUPERFRAME_DROP)
520*fb1b10abSAndroid Build Coastguard Worker       return 0;
521*fb1b10abSAndroid Build Coastguard Worker     else
522*fb1b10abSAndroid Build Coastguard Worker       return 1;
523*fb1b10abSAndroid Build Coastguard Worker   }
524*fb1b10abSAndroid Build Coastguard Worker }
525*fb1b10abSAndroid Build Coastguard Worker 
vp9_test_drop(VP9_COMP * cpi)526*fb1b10abSAndroid Build Coastguard Worker int vp9_test_drop(VP9_COMP *cpi) {
527*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
528*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
529*fb1b10abSAndroid Build Coastguard Worker   SVC *svc = &cpi->svc;
530*fb1b10abSAndroid Build Coastguard Worker   int drop_frames_water_mark = oxcf->drop_frames_water_mark;
531*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) {
532*fb1b10abSAndroid Build Coastguard Worker     // If we have dropped max_consec_drop frames, then we don't
533*fb1b10abSAndroid Build Coastguard Worker     // drop this spatial layer, and reset counter to 0.
534*fb1b10abSAndroid Build Coastguard Worker     if (svc->drop_count[svc->spatial_layer_id] == svc->max_consec_drop) {
535*fb1b10abSAndroid Build Coastguard Worker       svc->drop_count[svc->spatial_layer_id] = 0;
536*fb1b10abSAndroid Build Coastguard Worker       return 0;
537*fb1b10abSAndroid Build Coastguard Worker     } else {
538*fb1b10abSAndroid Build Coastguard Worker       drop_frames_water_mark = svc->framedrop_thresh[svc->spatial_layer_id];
539*fb1b10abSAndroid Build Coastguard Worker     }
540*fb1b10abSAndroid Build Coastguard Worker   }
541*fb1b10abSAndroid Build Coastguard Worker   if (!drop_frames_water_mark ||
542*fb1b10abSAndroid Build Coastguard Worker       (svc->spatial_layer_id > 0 &&
543*fb1b10abSAndroid Build Coastguard Worker        svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
544*fb1b10abSAndroid Build Coastguard Worker     return 0;
545*fb1b10abSAndroid Build Coastguard Worker   } else {
546*fb1b10abSAndroid Build Coastguard Worker     if ((rc->buffer_level < 0 && svc->framedrop_mode != FULL_SUPERFRAME_DROP) ||
547*fb1b10abSAndroid Build Coastguard Worker         (check_buffer_below_thresh(cpi, -1) &&
548*fb1b10abSAndroid Build Coastguard Worker          svc->framedrop_mode == FULL_SUPERFRAME_DROP)) {
549*fb1b10abSAndroid Build Coastguard Worker       // Always drop if buffer is below 0.
550*fb1b10abSAndroid Build Coastguard Worker       return 1;
551*fb1b10abSAndroid Build Coastguard Worker     } else {
552*fb1b10abSAndroid Build Coastguard Worker       // If buffer is below drop_mark, for now just drop every other frame
553*fb1b10abSAndroid Build Coastguard Worker       // (starting with the next frame) until it increases back over drop_mark.
554*fb1b10abSAndroid Build Coastguard Worker       int drop_mark =
555*fb1b10abSAndroid Build Coastguard Worker           (int)(drop_frames_water_mark * rc->optimal_buffer_level / 100);
556*fb1b10abSAndroid Build Coastguard Worker       if (check_buffer_above_thresh(cpi, drop_mark) &&
557*fb1b10abSAndroid Build Coastguard Worker           (rc->decimation_factor > 0)) {
558*fb1b10abSAndroid Build Coastguard Worker         --rc->decimation_factor;
559*fb1b10abSAndroid Build Coastguard Worker       } else if (check_buffer_below_thresh(cpi, drop_mark) &&
560*fb1b10abSAndroid Build Coastguard Worker                  rc->decimation_factor == 0) {
561*fb1b10abSAndroid Build Coastguard Worker         rc->decimation_factor = 1;
562*fb1b10abSAndroid Build Coastguard Worker       }
563*fb1b10abSAndroid Build Coastguard Worker       if (rc->decimation_factor > 0) {
564*fb1b10abSAndroid Build Coastguard Worker         if (rc->decimation_count > 0) {
565*fb1b10abSAndroid Build Coastguard Worker           --rc->decimation_count;
566*fb1b10abSAndroid Build Coastguard Worker           return 1;
567*fb1b10abSAndroid Build Coastguard Worker         } else {
568*fb1b10abSAndroid Build Coastguard Worker           rc->decimation_count = rc->decimation_factor;
569*fb1b10abSAndroid Build Coastguard Worker           return 0;
570*fb1b10abSAndroid Build Coastguard Worker         }
571*fb1b10abSAndroid Build Coastguard Worker       } else {
572*fb1b10abSAndroid Build Coastguard Worker         rc->decimation_count = 0;
573*fb1b10abSAndroid Build Coastguard Worker         return 0;
574*fb1b10abSAndroid Build Coastguard Worker       }
575*fb1b10abSAndroid Build Coastguard Worker     }
576*fb1b10abSAndroid Build Coastguard Worker   }
577*fb1b10abSAndroid Build Coastguard Worker }
578*fb1b10abSAndroid Build Coastguard Worker 
post_encode_drop_cbr(VP9_COMP * cpi,size_t * size)579*fb1b10abSAndroid Build Coastguard Worker int post_encode_drop_cbr(VP9_COMP *cpi, size_t *size) {
580*fb1b10abSAndroid Build Coastguard Worker   size_t frame_size = *size << 3;
581*fb1b10abSAndroid Build Coastguard Worker   int64_t new_buffer_level =
582*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.buffer_level + cpi->rc.avg_frame_bandwidth - (int64_t)frame_size;
583*fb1b10abSAndroid Build Coastguard Worker 
584*fb1b10abSAndroid Build Coastguard Worker   // For now we drop if new buffer level (given the encoded frame size) goes
585*fb1b10abSAndroid Build Coastguard Worker   // below 0.
586*fb1b10abSAndroid Build Coastguard Worker   if (new_buffer_level < 0) {
587*fb1b10abSAndroid Build Coastguard Worker     *size = 0;
588*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_postencode_update_drop_frame(cpi);
589*fb1b10abSAndroid Build Coastguard Worker     // Update flag to use for next frame.
590*fb1b10abSAndroid Build Coastguard Worker     if (cpi->rc.high_source_sad ||
591*fb1b10abSAndroid Build Coastguard Worker         (cpi->use_svc && cpi->svc.high_source_sad_superframe))
592*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.last_post_encode_dropped_scene_change = 1;
593*fb1b10abSAndroid Build Coastguard Worker     // Force max_q on next fame.
594*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.force_max_q = 1;
595*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.avg_frame_qindex[INTER_FRAME] = cpi->rc.worst_quality;
596*fb1b10abSAndroid Build Coastguard Worker     cpi->last_frame_dropped = 1;
597*fb1b10abSAndroid Build Coastguard Worker     cpi->ext_refresh_frame_flags_pending = 0;
598*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
599*fb1b10abSAndroid Build Coastguard Worker       SVC *svc = &cpi->svc;
600*fb1b10abSAndroid Build Coastguard Worker       int sl = 0;
601*fb1b10abSAndroid Build Coastguard Worker       int tl = 0;
602*fb1b10abSAndroid Build Coastguard Worker       svc->last_layer_dropped[svc->spatial_layer_id] = 1;
603*fb1b10abSAndroid Build Coastguard Worker       svc->drop_spatial_layer[svc->spatial_layer_id] = 1;
604*fb1b10abSAndroid Build Coastguard Worker       svc->drop_count[svc->spatial_layer_id]++;
605*fb1b10abSAndroid Build Coastguard Worker       svc->skip_enhancement_layer = 1;
606*fb1b10abSAndroid Build Coastguard Worker       // Postencode drop is only checked on base spatial layer,
607*fb1b10abSAndroid Build Coastguard Worker       // for now if max-q is set on base we force it on all layers.
608*fb1b10abSAndroid Build Coastguard Worker       for (sl = 0; sl < svc->number_spatial_layers; ++sl) {
609*fb1b10abSAndroid Build Coastguard Worker         for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
610*fb1b10abSAndroid Build Coastguard Worker           const int layer =
611*fb1b10abSAndroid Build Coastguard Worker               LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
612*fb1b10abSAndroid Build Coastguard Worker           LAYER_CONTEXT *lc = &svc->layer_context[layer];
613*fb1b10abSAndroid Build Coastguard Worker           RATE_CONTROL *lrc = &lc->rc;
614*fb1b10abSAndroid Build Coastguard Worker           lrc->force_max_q = 1;
615*fb1b10abSAndroid Build Coastguard Worker           lrc->avg_frame_qindex[INTER_FRAME] = cpi->rc.worst_quality;
616*fb1b10abSAndroid Build Coastguard Worker         }
617*fb1b10abSAndroid Build Coastguard Worker       }
618*fb1b10abSAndroid Build Coastguard Worker     }
619*fb1b10abSAndroid Build Coastguard Worker     return 1;
620*fb1b10abSAndroid Build Coastguard Worker   }
621*fb1b10abSAndroid Build Coastguard Worker 
622*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.force_max_q = 0;
623*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.last_post_encode_dropped_scene_change = 0;
624*fb1b10abSAndroid Build Coastguard Worker   return 0;
625*fb1b10abSAndroid Build Coastguard Worker }
626*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_drop_frame(VP9_COMP * cpi)627*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_drop_frame(VP9_COMP *cpi) {
628*fb1b10abSAndroid Build Coastguard Worker   SVC *svc = &cpi->svc;
629*fb1b10abSAndroid Build Coastguard Worker   int svc_prev_layer_dropped = 0;
630*fb1b10abSAndroid Build Coastguard Worker   // In the constrained or full_superframe framedrop mode for svc
631*fb1b10abSAndroid Build Coastguard Worker   // (framedrop_mode != (LAYER_DROP && CONSTRAINED_FROM_ABOVE)),
632*fb1b10abSAndroid Build Coastguard Worker   // if the previous spatial layer was dropped, drop the current spatial layer.
633*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && svc->spatial_layer_id > 0 &&
634*fb1b10abSAndroid Build Coastguard Worker       svc->drop_spatial_layer[svc->spatial_layer_id - 1])
635*fb1b10abSAndroid Build Coastguard Worker     svc_prev_layer_dropped = 1;
636*fb1b10abSAndroid Build Coastguard Worker   if ((svc_prev_layer_dropped && svc->framedrop_mode != LAYER_DROP &&
637*fb1b10abSAndroid Build Coastguard Worker        svc->framedrop_mode != CONSTRAINED_FROM_ABOVE_DROP) ||
638*fb1b10abSAndroid Build Coastguard Worker       svc->force_drop_constrained_from_above[svc->spatial_layer_id] ||
639*fb1b10abSAndroid Build Coastguard Worker       vp9_test_drop(cpi)) {
640*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_postencode_update_drop_frame(cpi);
641*fb1b10abSAndroid Build Coastguard Worker     cpi->ext_refresh_frame_flags_pending = 0;
642*fb1b10abSAndroid Build Coastguard Worker     cpi->last_frame_dropped = 1;
643*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
644*fb1b10abSAndroid Build Coastguard Worker       svc->last_layer_dropped[svc->spatial_layer_id] = 1;
645*fb1b10abSAndroid Build Coastguard Worker       svc->drop_spatial_layer[svc->spatial_layer_id] = 1;
646*fb1b10abSAndroid Build Coastguard Worker       svc->drop_count[svc->spatial_layer_id]++;
647*fb1b10abSAndroid Build Coastguard Worker       svc->skip_enhancement_layer = 1;
648*fb1b10abSAndroid Build Coastguard Worker       if (svc->framedrop_mode == LAYER_DROP ||
649*fb1b10abSAndroid Build Coastguard Worker           (svc->framedrop_mode == CONSTRAINED_FROM_ABOVE_DROP &&
650*fb1b10abSAndroid Build Coastguard Worker            svc->force_drop_constrained_from_above[svc->number_spatial_layers -
651*fb1b10abSAndroid Build Coastguard Worker                                                   1] == 0) ||
652*fb1b10abSAndroid Build Coastguard Worker           svc->drop_spatial_layer[0] == 0) {
653*fb1b10abSAndroid Build Coastguard Worker         // For the case of constrained drop mode where full superframe is
654*fb1b10abSAndroid Build Coastguard Worker         // dropped, we don't increment the svc frame counters.
655*fb1b10abSAndroid Build Coastguard Worker         // In particular temporal layer counter (which is incremented in
656*fb1b10abSAndroid Build Coastguard Worker         // vp9_inc_frame_in_layer()) won't be incremented, so on a dropped
657*fb1b10abSAndroid Build Coastguard Worker         // frame we try the same temporal_layer_id on next incoming frame.
658*fb1b10abSAndroid Build Coastguard Worker         // This is to avoid an issue with temporal alignment with full
659*fb1b10abSAndroid Build Coastguard Worker         // superframe dropping.
660*fb1b10abSAndroid Build Coastguard Worker         vp9_inc_frame_in_layer(cpi);
661*fb1b10abSAndroid Build Coastguard Worker       }
662*fb1b10abSAndroid Build Coastguard Worker       if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
663*fb1b10abSAndroid Build Coastguard Worker         int i;
664*fb1b10abSAndroid Build Coastguard Worker         int all_layers_drop = 1;
665*fb1b10abSAndroid Build Coastguard Worker         for (i = 0; i < svc->spatial_layer_id; i++) {
666*fb1b10abSAndroid Build Coastguard Worker           if (svc->drop_spatial_layer[i] == 0) {
667*fb1b10abSAndroid Build Coastguard Worker             all_layers_drop = 0;
668*fb1b10abSAndroid Build Coastguard Worker             break;
669*fb1b10abSAndroid Build Coastguard Worker           }
670*fb1b10abSAndroid Build Coastguard Worker         }
671*fb1b10abSAndroid Build Coastguard Worker         if (all_layers_drop == 1) svc->skip_enhancement_layer = 0;
672*fb1b10abSAndroid Build Coastguard Worker       }
673*fb1b10abSAndroid Build Coastguard Worker     }
674*fb1b10abSAndroid Build Coastguard Worker     return 1;
675*fb1b10abSAndroid Build Coastguard Worker   }
676*fb1b10abSAndroid Build Coastguard Worker   return 0;
677*fb1b10abSAndroid Build Coastguard Worker }
678*fb1b10abSAndroid Build Coastguard Worker 
adjust_q_cbr(const VP9_COMP * cpi,int q)679*fb1b10abSAndroid Build Coastguard Worker static int adjust_q_cbr(const VP9_COMP *cpi, int q) {
680*fb1b10abSAndroid Build Coastguard Worker   // This makes sure q is between oscillating Qs to prevent resonance.
681*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->rc.reset_high_source_sad &&
682*fb1b10abSAndroid Build Coastguard Worker       (!cpi->oxcf.gf_cbr_boost_pct ||
683*fb1b10abSAndroid Build Coastguard Worker        !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame)) &&
684*fb1b10abSAndroid Build Coastguard Worker       (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
685*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.q_1_frame != cpi->rc.q_2_frame) {
686*fb1b10abSAndroid Build Coastguard Worker     int qclamp = clamp(q, VPXMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
687*fb1b10abSAndroid Build Coastguard Worker                        VPXMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame));
688*fb1b10abSAndroid Build Coastguard Worker     // If the previous frame had overshoot and the current q needs to increase
689*fb1b10abSAndroid Build Coastguard Worker     // above the clamped value, reduce the clamp for faster reaction to
690*fb1b10abSAndroid Build Coastguard Worker     // overshoot.
691*fb1b10abSAndroid Build Coastguard Worker     if (cpi->rc.rc_1_frame == -1 && q > qclamp)
692*fb1b10abSAndroid Build Coastguard Worker       q = (q + qclamp) >> 1;
693*fb1b10abSAndroid Build Coastguard Worker     else
694*fb1b10abSAndroid Build Coastguard Worker       q = qclamp;
695*fb1b10abSAndroid Build Coastguard Worker   }
696*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
697*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
698*fb1b10abSAndroid Build Coastguard Worker     vp9_cyclic_refresh_limit_q(cpi, &q);
699*fb1b10abSAndroid Build Coastguard Worker   return VPXMAX(VPXMIN(q, cpi->rc.worst_quality), cpi->rc.best_quality);
700*fb1b10abSAndroid Build Coastguard Worker }
701*fb1b10abSAndroid Build Coastguard Worker 
get_rate_correction_factor(const VP9_COMP * cpi)702*fb1b10abSAndroid Build Coastguard Worker static double get_rate_correction_factor(const VP9_COMP *cpi) {
703*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
704*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
705*fb1b10abSAndroid Build Coastguard Worker   double rcf;
706*fb1b10abSAndroid Build Coastguard Worker 
707*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
708*fb1b10abSAndroid Build Coastguard Worker     rcf = rc->rate_correction_factors[KF_STD];
709*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->oxcf.pass == 2) {
710*fb1b10abSAndroid Build Coastguard Worker     RATE_FACTOR_LEVEL rf_lvl =
711*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
712*fb1b10abSAndroid Build Coastguard Worker     rcf = rc->rate_correction_factors[rf_lvl];
713*fb1b10abSAndroid Build Coastguard Worker   } else {
714*fb1b10abSAndroid Build Coastguard Worker     if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
715*fb1b10abSAndroid Build Coastguard Worker         !rc->is_src_frame_alt_ref && !cpi->use_svc &&
716*fb1b10abSAndroid Build Coastguard Worker         (cpi->oxcf.rc_mode != VPX_CBR || cpi->oxcf.gf_cbr_boost_pct > 100))
717*fb1b10abSAndroid Build Coastguard Worker       rcf = rc->rate_correction_factors[GF_ARF_STD];
718*fb1b10abSAndroid Build Coastguard Worker     else
719*fb1b10abSAndroid Build Coastguard Worker       rcf = rc->rate_correction_factors[INTER_NORMAL];
720*fb1b10abSAndroid Build Coastguard Worker   }
721*fb1b10abSAndroid Build Coastguard Worker   rcf *= rcf_mult[rc->frame_size_selector];
722*fb1b10abSAndroid Build Coastguard Worker   return fclamp(rcf, MIN_BPB_FACTOR, MAX_BPB_FACTOR);
723*fb1b10abSAndroid Build Coastguard Worker }
724*fb1b10abSAndroid Build Coastguard Worker 
set_rate_correction_factor(VP9_COMP * cpi,double factor)725*fb1b10abSAndroid Build Coastguard Worker static void set_rate_correction_factor(VP9_COMP *cpi, double factor) {
726*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
727*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
728*fb1b10abSAndroid Build Coastguard Worker 
729*fb1b10abSAndroid Build Coastguard Worker   // Normalize RCF to account for the size-dependent scaling factor.
730*fb1b10abSAndroid Build Coastguard Worker   factor /= rcf_mult[cpi->rc.frame_size_selector];
731*fb1b10abSAndroid Build Coastguard Worker 
732*fb1b10abSAndroid Build Coastguard Worker   factor = fclamp(factor, MIN_BPB_FACTOR, MAX_BPB_FACTOR);
733*fb1b10abSAndroid Build Coastguard Worker 
734*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
735*fb1b10abSAndroid Build Coastguard Worker     rc->rate_correction_factors[KF_STD] = factor;
736*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->oxcf.pass == 2) {
737*fb1b10abSAndroid Build Coastguard Worker     RATE_FACTOR_LEVEL rf_lvl =
738*fb1b10abSAndroid Build Coastguard Worker         cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
739*fb1b10abSAndroid Build Coastguard Worker     rc->rate_correction_factors[rf_lvl] = factor;
740*fb1b10abSAndroid Build Coastguard Worker   } else {
741*fb1b10abSAndroid Build Coastguard Worker     if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
742*fb1b10abSAndroid Build Coastguard Worker         !rc->is_src_frame_alt_ref && !cpi->use_svc &&
743*fb1b10abSAndroid Build Coastguard Worker         (cpi->oxcf.rc_mode != VPX_CBR || cpi->oxcf.gf_cbr_boost_pct > 100))
744*fb1b10abSAndroid Build Coastguard Worker       rc->rate_correction_factors[GF_ARF_STD] = factor;
745*fb1b10abSAndroid Build Coastguard Worker     else
746*fb1b10abSAndroid Build Coastguard Worker       rc->rate_correction_factors[INTER_NORMAL] = factor;
747*fb1b10abSAndroid Build Coastguard Worker   }
748*fb1b10abSAndroid Build Coastguard Worker }
749*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_update_rate_correction_factors(VP9_COMP * cpi)750*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi) {
751*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
752*fb1b10abSAndroid Build Coastguard Worker   int correction_factor = 100;
753*fb1b10abSAndroid Build Coastguard Worker   double rate_correction_factor = get_rate_correction_factor(cpi);
754*fb1b10abSAndroid Build Coastguard Worker   double adjustment_limit;
755*fb1b10abSAndroid Build Coastguard Worker   RATE_FACTOR_LEVEL rf_lvl =
756*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
757*fb1b10abSAndroid Build Coastguard Worker 
758*fb1b10abSAndroid Build Coastguard Worker   int projected_size_based_on_q = 0;
759*fb1b10abSAndroid Build Coastguard Worker 
760*fb1b10abSAndroid Build Coastguard Worker   // Do not update the rate factors for arf overlay frames.
761*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.is_src_frame_alt_ref) return;
762*fb1b10abSAndroid Build Coastguard Worker 
763*fb1b10abSAndroid Build Coastguard Worker   // Clear down mmx registers to allow floating point in what follows
764*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
765*fb1b10abSAndroid Build Coastguard Worker 
766*fb1b10abSAndroid Build Coastguard Worker   // Work out how big we would have expected the frame to be at this Q given
767*fb1b10abSAndroid Build Coastguard Worker   // the current correction factor.
768*fb1b10abSAndroid Build Coastguard Worker   // Stay in double to avoid int overflow when values are large
769*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->common.seg.enabled) {
770*fb1b10abSAndroid Build Coastguard Worker     projected_size_based_on_q =
771*fb1b10abSAndroid Build Coastguard Worker         vp9_cyclic_refresh_estimate_bits_at_q(cpi, rate_correction_factor);
772*fb1b10abSAndroid Build Coastguard Worker   } else {
773*fb1b10abSAndroid Build Coastguard Worker     FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type;
774*fb1b10abSAndroid Build Coastguard Worker     projected_size_based_on_q =
775*fb1b10abSAndroid Build Coastguard Worker         vp9_estimate_bits_at_q(frame_type, cm->base_qindex, cm->MBs,
776*fb1b10abSAndroid Build Coastguard Worker                                rate_correction_factor, cm->bit_depth);
777*fb1b10abSAndroid Build Coastguard Worker   }
778*fb1b10abSAndroid Build Coastguard Worker   // Work out a size correction factor.
779*fb1b10abSAndroid Build Coastguard Worker   if (projected_size_based_on_q > FRAME_OVERHEAD_BITS)
780*fb1b10abSAndroid Build Coastguard Worker     correction_factor = (int)((100 * (int64_t)cpi->rc.projected_frame_size) /
781*fb1b10abSAndroid Build Coastguard Worker                               projected_size_based_on_q);
782*fb1b10abSAndroid Build Coastguard Worker 
783*fb1b10abSAndroid Build Coastguard Worker   // Do not use damped adjustment for the first frame of each frame type
784*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->rc.damped_adjustment[rf_lvl]) {
785*fb1b10abSAndroid Build Coastguard Worker     adjustment_limit = 1.0;
786*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.damped_adjustment[rf_lvl] = 1;
787*fb1b10abSAndroid Build Coastguard Worker   } else {
788*fb1b10abSAndroid Build Coastguard Worker     // More heavily damped adjustment used if we have been oscillating either
789*fb1b10abSAndroid Build Coastguard Worker     // side of target.
790*fb1b10abSAndroid Build Coastguard Worker     adjustment_limit =
791*fb1b10abSAndroid Build Coastguard Worker         0.25 + 0.5 * VPXMIN(1, fabs(log10(0.01 * correction_factor)));
792*fb1b10abSAndroid Build Coastguard Worker   }
793*fb1b10abSAndroid Build Coastguard Worker 
794*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.q_2_frame = cpi->rc.q_1_frame;
795*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.q_1_frame = cm->base_qindex;
796*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.rc_2_frame = cpi->rc.rc_1_frame;
797*fb1b10abSAndroid Build Coastguard Worker   if (correction_factor > 110)
798*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_1_frame = -1;
799*fb1b10abSAndroid Build Coastguard Worker   else if (correction_factor < 90)
800*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_1_frame = 1;
801*fb1b10abSAndroid Build Coastguard Worker   else
802*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_1_frame = 0;
803*fb1b10abSAndroid Build Coastguard Worker 
804*fb1b10abSAndroid Build Coastguard Worker   // Turn off oscilation detection in the case of massive overshoot.
805*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.rc_1_frame == -1 && cpi->rc.rc_2_frame == 1 &&
806*fb1b10abSAndroid Build Coastguard Worker       correction_factor > 1000) {
807*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_2_frame = 0;
808*fb1b10abSAndroid Build Coastguard Worker   }
809*fb1b10abSAndroid Build Coastguard Worker 
810*fb1b10abSAndroid Build Coastguard Worker   if (correction_factor > 102) {
811*fb1b10abSAndroid Build Coastguard Worker     // We are not already at the worst allowable quality
812*fb1b10abSAndroid Build Coastguard Worker     correction_factor =
813*fb1b10abSAndroid Build Coastguard Worker         (int)(100 + ((correction_factor - 100) * adjustment_limit));
814*fb1b10abSAndroid Build Coastguard Worker     rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
815*fb1b10abSAndroid Build Coastguard Worker     // Keep rate_correction_factor within limits
816*fb1b10abSAndroid Build Coastguard Worker     if (rate_correction_factor > MAX_BPB_FACTOR)
817*fb1b10abSAndroid Build Coastguard Worker       rate_correction_factor = MAX_BPB_FACTOR;
818*fb1b10abSAndroid Build Coastguard Worker   } else if (correction_factor < 99) {
819*fb1b10abSAndroid Build Coastguard Worker     // We are not already at the best allowable quality
820*fb1b10abSAndroid Build Coastguard Worker     correction_factor =
821*fb1b10abSAndroid Build Coastguard Worker         (int)(100 - ((100 - correction_factor) * adjustment_limit));
822*fb1b10abSAndroid Build Coastguard Worker     rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
823*fb1b10abSAndroid Build Coastguard Worker 
824*fb1b10abSAndroid Build Coastguard Worker     // Keep rate_correction_factor within limits
825*fb1b10abSAndroid Build Coastguard Worker     if (rate_correction_factor < MIN_BPB_FACTOR)
826*fb1b10abSAndroid Build Coastguard Worker       rate_correction_factor = MIN_BPB_FACTOR;
827*fb1b10abSAndroid Build Coastguard Worker   }
828*fb1b10abSAndroid Build Coastguard Worker 
829*fb1b10abSAndroid Build Coastguard Worker   set_rate_correction_factor(cpi, rate_correction_factor);
830*fb1b10abSAndroid Build Coastguard Worker }
831*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_regulate_q(const VP9_COMP * cpi,int target_bits_per_frame,int active_best_quality,int active_worst_quality)832*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
833*fb1b10abSAndroid Build Coastguard Worker                       int active_best_quality, int active_worst_quality) {
834*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
835*fb1b10abSAndroid Build Coastguard Worker   CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
836*fb1b10abSAndroid Build Coastguard Worker   int q = active_worst_quality;
837*fb1b10abSAndroid Build Coastguard Worker   int last_error = INT_MAX;
838*fb1b10abSAndroid Build Coastguard Worker   int i, target_bits_per_mb, bits_per_mb_at_this_q;
839*fb1b10abSAndroid Build Coastguard Worker   const double correction_factor = get_rate_correction_factor(cpi);
840*fb1b10abSAndroid Build Coastguard Worker 
841*fb1b10abSAndroid Build Coastguard Worker   // Calculate required scaling factor based on target frame size and size of
842*fb1b10abSAndroid Build Coastguard Worker   // frame produced using previous Q.
843*fb1b10abSAndroid Build Coastguard Worker   target_bits_per_mb =
844*fb1b10abSAndroid Build Coastguard Worker       (int)(((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs);
845*fb1b10abSAndroid Build Coastguard Worker 
846*fb1b10abSAndroid Build Coastguard Worker   i = active_best_quality;
847*fb1b10abSAndroid Build Coastguard Worker 
848*fb1b10abSAndroid Build Coastguard Worker   do {
849*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cr->apply_cyclic_refresh &&
850*fb1b10abSAndroid Build Coastguard Worker         (!cpi->oxcf.gf_cbr_boost_pct || !cpi->refresh_golden_frame)) {
851*fb1b10abSAndroid Build Coastguard Worker       bits_per_mb_at_this_q =
852*fb1b10abSAndroid Build Coastguard Worker           (int)vp9_cyclic_refresh_rc_bits_per_mb(cpi, i, correction_factor);
853*fb1b10abSAndroid Build Coastguard Worker     } else {
854*fb1b10abSAndroid Build Coastguard Worker       FRAME_TYPE frame_type = cm->intra_only ? KEY_FRAME : cm->frame_type;
855*fb1b10abSAndroid Build Coastguard Worker       bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(
856*fb1b10abSAndroid Build Coastguard Worker           frame_type, i, correction_factor, cm->bit_depth);
857*fb1b10abSAndroid Build Coastguard Worker     }
858*fb1b10abSAndroid Build Coastguard Worker 
859*fb1b10abSAndroid Build Coastguard Worker     if (bits_per_mb_at_this_q <= target_bits_per_mb) {
860*fb1b10abSAndroid Build Coastguard Worker       if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error)
861*fb1b10abSAndroid Build Coastguard Worker         q = i;
862*fb1b10abSAndroid Build Coastguard Worker       else
863*fb1b10abSAndroid Build Coastguard Worker         q = i - 1;
864*fb1b10abSAndroid Build Coastguard Worker 
865*fb1b10abSAndroid Build Coastguard Worker       break;
866*fb1b10abSAndroid Build Coastguard Worker     } else {
867*fb1b10abSAndroid Build Coastguard Worker       last_error = bits_per_mb_at_this_q - target_bits_per_mb;
868*fb1b10abSAndroid Build Coastguard Worker     }
869*fb1b10abSAndroid Build Coastguard Worker   } while (++i <= active_worst_quality);
870*fb1b10abSAndroid Build Coastguard Worker 
871*fb1b10abSAndroid Build Coastguard Worker   // Adjustment to q for CBR mode.
872*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.rc_mode == VPX_CBR) return adjust_q_cbr(cpi, q);
873*fb1b10abSAndroid Build Coastguard Worker 
874*fb1b10abSAndroid Build Coastguard Worker   return q;
875*fb1b10abSAndroid Build Coastguard Worker }
876*fb1b10abSAndroid Build Coastguard Worker 
get_active_quality(int q,int gfu_boost,int low,int high,int * low_motion_minq,int * high_motion_minq)877*fb1b10abSAndroid Build Coastguard Worker static int get_active_quality(int q, int gfu_boost, int low, int high,
878*fb1b10abSAndroid Build Coastguard Worker                               int *low_motion_minq, int *high_motion_minq) {
879*fb1b10abSAndroid Build Coastguard Worker   if (gfu_boost > high) {
880*fb1b10abSAndroid Build Coastguard Worker     return low_motion_minq[q];
881*fb1b10abSAndroid Build Coastguard Worker   } else if (gfu_boost < low) {
882*fb1b10abSAndroid Build Coastguard Worker     return high_motion_minq[q];
883*fb1b10abSAndroid Build Coastguard Worker   } else {
884*fb1b10abSAndroid Build Coastguard Worker     const int gap = high - low;
885*fb1b10abSAndroid Build Coastguard Worker     const int offset = high - gfu_boost;
886*fb1b10abSAndroid Build Coastguard Worker     const int qdiff = high_motion_minq[q] - low_motion_minq[q];
887*fb1b10abSAndroid Build Coastguard Worker     const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap;
888*fb1b10abSAndroid Build Coastguard Worker     return low_motion_minq[q] + adjustment;
889*fb1b10abSAndroid Build Coastguard Worker   }
890*fb1b10abSAndroid Build Coastguard Worker }
891*fb1b10abSAndroid Build Coastguard Worker 
get_kf_active_quality(const RATE_CONTROL * const rc,int q,vpx_bit_depth_t bit_depth)892*fb1b10abSAndroid Build Coastguard Worker static int get_kf_active_quality(const RATE_CONTROL *const rc, int q,
893*fb1b10abSAndroid Build Coastguard Worker                                  vpx_bit_depth_t bit_depth) {
894*fb1b10abSAndroid Build Coastguard Worker   int *kf_low_motion_minq;
895*fb1b10abSAndroid Build Coastguard Worker   int *kf_high_motion_minq;
896*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(bit_depth, kf_low_motion_minq);
897*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(bit_depth, kf_high_motion_minq);
898*fb1b10abSAndroid Build Coastguard Worker   return get_active_quality(q, rc->kf_boost, kf_low, kf_high,
899*fb1b10abSAndroid Build Coastguard Worker                             kf_low_motion_minq, kf_high_motion_minq);
900*fb1b10abSAndroid Build Coastguard Worker }
901*fb1b10abSAndroid Build Coastguard Worker 
get_gf_active_quality(const VP9_COMP * const cpi,int q,vpx_bit_depth_t bit_depth)902*fb1b10abSAndroid Build Coastguard Worker static int get_gf_active_quality(const VP9_COMP *const cpi, int q,
903*fb1b10abSAndroid Build Coastguard Worker                                  vpx_bit_depth_t bit_depth) {
904*fb1b10abSAndroid Build Coastguard Worker   const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
905*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
906*fb1b10abSAndroid Build Coastguard Worker 
907*fb1b10abSAndroid Build Coastguard Worker   int *arfgf_low_motion_minq;
908*fb1b10abSAndroid Build Coastguard Worker   int *arfgf_high_motion_minq;
909*fb1b10abSAndroid Build Coastguard Worker   const int gfu_boost = cpi->multi_layer_arf
910*fb1b10abSAndroid Build Coastguard Worker                             ? gf_group->gfu_boost[gf_group->index]
911*fb1b10abSAndroid Build Coastguard Worker                             : rc->gfu_boost;
912*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(bit_depth, arfgf_low_motion_minq);
913*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(bit_depth, arfgf_high_motion_minq);
914*fb1b10abSAndroid Build Coastguard Worker   return get_active_quality(q, gfu_boost, gf_low, gf_high,
915*fb1b10abSAndroid Build Coastguard Worker                             arfgf_low_motion_minq, arfgf_high_motion_minq);
916*fb1b10abSAndroid Build Coastguard Worker }
917*fb1b10abSAndroid Build Coastguard Worker 
calc_active_worst_quality_one_pass_vbr(const VP9_COMP * cpi)918*fb1b10abSAndroid Build Coastguard Worker static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) {
919*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
920*fb1b10abSAndroid Build Coastguard Worker   const unsigned int curr_frame = cpi->common.current_video_frame;
921*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality;
922*fb1b10abSAndroid Build Coastguard Worker 
923*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.frame_type == KEY_FRAME) {
924*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality =
925*fb1b10abSAndroid Build Coastguard Worker         curr_frame == 0 ? rc->worst_quality : rc->last_q[KEY_FRAME] << 1;
926*fb1b10abSAndroid Build Coastguard Worker   } else {
927*fb1b10abSAndroid Build Coastguard Worker     if (!rc->is_src_frame_alt_ref && !cpi->use_svc &&
928*fb1b10abSAndroid Build Coastguard Worker         (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
929*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality =
930*fb1b10abSAndroid Build Coastguard Worker           curr_frame == 1
931*fb1b10abSAndroid Build Coastguard Worker               ? rc->last_q[KEY_FRAME] * 5 >> 2
932*fb1b10abSAndroid Build Coastguard Worker               : rc->last_q[INTER_FRAME] * rc->fac_active_worst_gf / 100;
933*fb1b10abSAndroid Build Coastguard Worker     } else {
934*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality = curr_frame == 1
935*fb1b10abSAndroid Build Coastguard Worker                                  ? rc->last_q[KEY_FRAME] << 1
936*fb1b10abSAndroid Build Coastguard Worker                                  : rc->avg_frame_qindex[INTER_FRAME] *
937*fb1b10abSAndroid Build Coastguard Worker                                        rc->fac_active_worst_inter / 100;
938*fb1b10abSAndroid Build Coastguard Worker     }
939*fb1b10abSAndroid Build Coastguard Worker   }
940*fb1b10abSAndroid Build Coastguard Worker   return VPXMIN(active_worst_quality, rc->worst_quality);
941*fb1b10abSAndroid Build Coastguard Worker }
942*fb1b10abSAndroid Build Coastguard Worker 
943*fb1b10abSAndroid Build Coastguard Worker // Adjust active_worst_quality level based on buffer level.
calc_active_worst_quality_one_pass_cbr(const VP9_COMP * cpi)944*fb1b10abSAndroid Build Coastguard Worker static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
945*fb1b10abSAndroid Build Coastguard Worker   // Adjust active_worst_quality: If buffer is above the optimal/target level,
946*fb1b10abSAndroid Build Coastguard Worker   // bring active_worst_quality down depending on fullness of buffer.
947*fb1b10abSAndroid Build Coastguard Worker   // If buffer is below the optimal level, let the active_worst_quality go from
948*fb1b10abSAndroid Build Coastguard Worker   // ambient Q (at buffer = optimal level) to worst_quality level
949*fb1b10abSAndroid Build Coastguard Worker   // (at buffer = critical level).
950*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
951*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
952*fb1b10abSAndroid Build Coastguard Worker   // Buffer level below which we push active_worst to worst_quality.
953*fb1b10abSAndroid Build Coastguard Worker   int64_t critical_level = rc->optimal_buffer_level >> 3;
954*fb1b10abSAndroid Build Coastguard Worker   int64_t buff_lvl_step = 0;
955*fb1b10abSAndroid Build Coastguard Worker   int adjustment = 0;
956*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality;
957*fb1b10abSAndroid Build Coastguard Worker   int ambient_qp;
958*fb1b10abSAndroid Build Coastguard Worker   unsigned int num_frames_weight_key = 5 * cpi->svc.number_temporal_layers;
959*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) || rc->reset_high_source_sad || rc->force_max_q)
960*fb1b10abSAndroid Build Coastguard Worker     return rc->worst_quality;
961*fb1b10abSAndroid Build Coastguard Worker   // For ambient_qp we use minimum of avg_frame_qindex[KEY_FRAME/INTER_FRAME]
962*fb1b10abSAndroid Build Coastguard Worker   // for the first few frames following key frame. These are both initialized
963*fb1b10abSAndroid Build Coastguard Worker   // to worst_quality and updated with (3/4, 1/4) average in postencode_update.
964*fb1b10abSAndroid Build Coastguard Worker   // So for first few frames following key, the qp of that key frame is weighted
965*fb1b10abSAndroid Build Coastguard Worker   // into the active_worst_quality setting.
966*fb1b10abSAndroid Build Coastguard Worker   ambient_qp = (cm->current_video_frame < num_frames_weight_key)
967*fb1b10abSAndroid Build Coastguard Worker                    ? VPXMIN(rc->avg_frame_qindex[INTER_FRAME],
968*fb1b10abSAndroid Build Coastguard Worker                             rc->avg_frame_qindex[KEY_FRAME])
969*fb1b10abSAndroid Build Coastguard Worker                    : rc->avg_frame_qindex[INTER_FRAME];
970*fb1b10abSAndroid Build Coastguard Worker   active_worst_quality = VPXMIN(rc->worst_quality, (ambient_qp * 5) >> 2);
971*fb1b10abSAndroid Build Coastguard Worker   // For SVC if the current base spatial layer was key frame, use the QP from
972*fb1b10abSAndroid Build Coastguard Worker   // that base layer for ambient_qp.
973*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) {
974*fb1b10abSAndroid Build Coastguard Worker     int layer = LAYER_IDS_TO_IDX(0, cpi->svc.temporal_layer_id,
975*fb1b10abSAndroid Build Coastguard Worker                                  cpi->svc.number_temporal_layers);
976*fb1b10abSAndroid Build Coastguard Worker     const LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
977*fb1b10abSAndroid Build Coastguard Worker     if (lc->is_key_frame) {
978*fb1b10abSAndroid Build Coastguard Worker       const RATE_CONTROL *lrc = &lc->rc;
979*fb1b10abSAndroid Build Coastguard Worker       ambient_qp = VPXMIN(ambient_qp, lrc->last_q[KEY_FRAME]);
980*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality = VPXMIN(rc->worst_quality, (ambient_qp * 9) >> 3);
981*fb1b10abSAndroid Build Coastguard Worker     }
982*fb1b10abSAndroid Build Coastguard Worker   }
983*fb1b10abSAndroid Build Coastguard Worker   if (rc->buffer_level > rc->optimal_buffer_level) {
984*fb1b10abSAndroid Build Coastguard Worker     // Adjust down.
985*fb1b10abSAndroid Build Coastguard Worker     // Maximum limit for down adjustment ~30%; make it lower for screen content.
986*fb1b10abSAndroid Build Coastguard Worker     int max_adjustment_down = active_worst_quality / 3;
987*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.content == VP9E_CONTENT_SCREEN)
988*fb1b10abSAndroid Build Coastguard Worker       max_adjustment_down = active_worst_quality >> 3;
989*fb1b10abSAndroid Build Coastguard Worker     if (max_adjustment_down) {
990*fb1b10abSAndroid Build Coastguard Worker       buff_lvl_step = ((rc->maximum_buffer_size - rc->optimal_buffer_level) /
991*fb1b10abSAndroid Build Coastguard Worker                        max_adjustment_down);
992*fb1b10abSAndroid Build Coastguard Worker       if (buff_lvl_step)
993*fb1b10abSAndroid Build Coastguard Worker         adjustment = (int)((rc->buffer_level - rc->optimal_buffer_level) /
994*fb1b10abSAndroid Build Coastguard Worker                            buff_lvl_step);
995*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality -= adjustment;
996*fb1b10abSAndroid Build Coastguard Worker     }
997*fb1b10abSAndroid Build Coastguard Worker   } else if (rc->buffer_level > critical_level) {
998*fb1b10abSAndroid Build Coastguard Worker     // Adjust up from ambient Q.
999*fb1b10abSAndroid Build Coastguard Worker     if (critical_level) {
1000*fb1b10abSAndroid Build Coastguard Worker       buff_lvl_step = (rc->optimal_buffer_level - critical_level);
1001*fb1b10abSAndroid Build Coastguard Worker       if (buff_lvl_step) {
1002*fb1b10abSAndroid Build Coastguard Worker         adjustment = (int)((rc->worst_quality - ambient_qp) *
1003*fb1b10abSAndroid Build Coastguard Worker                            (rc->optimal_buffer_level - rc->buffer_level) /
1004*fb1b10abSAndroid Build Coastguard Worker                            buff_lvl_step);
1005*fb1b10abSAndroid Build Coastguard Worker       }
1006*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality = ambient_qp + adjustment;
1007*fb1b10abSAndroid Build Coastguard Worker     }
1008*fb1b10abSAndroid Build Coastguard Worker   } else {
1009*fb1b10abSAndroid Build Coastguard Worker     // Set to worst_quality if buffer is below critical level.
1010*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality = rc->worst_quality;
1011*fb1b10abSAndroid Build Coastguard Worker   }
1012*fb1b10abSAndroid Build Coastguard Worker   return active_worst_quality;
1013*fb1b10abSAndroid Build Coastguard Worker }
1014*fb1b10abSAndroid Build Coastguard Worker 
rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP * cpi,int * bottom_index,int * top_index)1015*fb1b10abSAndroid Build Coastguard Worker static int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi,
1016*fb1b10abSAndroid Build Coastguard Worker                                              int *bottom_index,
1017*fb1b10abSAndroid Build Coastguard Worker                                              int *top_index) {
1018*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1019*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1020*fb1b10abSAndroid Build Coastguard Worker   int active_best_quality;
1021*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi);
1022*fb1b10abSAndroid Build Coastguard Worker   int q;
1023*fb1b10abSAndroid Build Coastguard Worker   int *rtc_minq;
1024*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(cm->bit_depth, rtc_minq);
1025*fb1b10abSAndroid Build Coastguard Worker 
1026*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
1027*fb1b10abSAndroid Build Coastguard Worker     active_best_quality = rc->best_quality;
1028*fb1b10abSAndroid Build Coastguard Worker     // Handle the special case for key frames forced when we have reached
1029*fb1b10abSAndroid Build Coastguard Worker     // the maximum key frame interval. Here force the Q to a range
1030*fb1b10abSAndroid Build Coastguard Worker     // based on the ambient Q to reduce the risk of popping.
1031*fb1b10abSAndroid Build Coastguard Worker     if (rc->this_key_frame_forced) {
1032*fb1b10abSAndroid Build Coastguard Worker       int qindex = rc->last_boosted_qindex;
1033*fb1b10abSAndroid Build Coastguard Worker       double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1034*fb1b10abSAndroid Build Coastguard Worker       int delta_qindex = vp9_compute_qdelta(
1035*fb1b10abSAndroid Build Coastguard Worker           rc, last_boosted_q, (last_boosted_q * 0.75), cm->bit_depth);
1036*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1037*fb1b10abSAndroid Build Coastguard Worker     } else if (cm->current_video_frame > 0) {
1038*fb1b10abSAndroid Build Coastguard Worker       // not first frame of one pass and kf_boost is set
1039*fb1b10abSAndroid Build Coastguard Worker       double q_adj_factor = 1.0;
1040*fb1b10abSAndroid Build Coastguard Worker       double q_val;
1041*fb1b10abSAndroid Build Coastguard Worker 
1042*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = get_kf_active_quality(
1043*fb1b10abSAndroid Build Coastguard Worker           rc, rc->avg_frame_qindex[KEY_FRAME], cm->bit_depth);
1044*fb1b10abSAndroid Build Coastguard Worker 
1045*fb1b10abSAndroid Build Coastguard Worker       // Allow somewhat lower kf minq with small image formats.
1046*fb1b10abSAndroid Build Coastguard Worker       if ((cm->width * cm->height) <= (352 * 288)) {
1047*fb1b10abSAndroid Build Coastguard Worker         q_adj_factor -= 0.25;
1048*fb1b10abSAndroid Build Coastguard Worker       }
1049*fb1b10abSAndroid Build Coastguard Worker 
1050*fb1b10abSAndroid Build Coastguard Worker       // Convert the adjustment factor to a qindex delta
1051*fb1b10abSAndroid Build Coastguard Worker       // on active_best_quality.
1052*fb1b10abSAndroid Build Coastguard Worker       q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
1053*fb1b10abSAndroid Build Coastguard Worker       active_best_quality +=
1054*fb1b10abSAndroid Build Coastguard Worker           vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth);
1055*fb1b10abSAndroid Build Coastguard Worker     }
1056*fb1b10abSAndroid Build Coastguard Worker   } else if (!rc->is_src_frame_alt_ref && !cpi->use_svc &&
1057*fb1b10abSAndroid Build Coastguard Worker              cpi->oxcf.gf_cbr_boost_pct &&
1058*fb1b10abSAndroid Build Coastguard Worker              (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
1059*fb1b10abSAndroid Build Coastguard Worker     // Use the lower of active_worst_quality and recent
1060*fb1b10abSAndroid Build Coastguard Worker     // average Q as basis for GF/ARF best Q limit unless last frame was
1061*fb1b10abSAndroid Build Coastguard Worker     // a key frame.
1062*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_since_key > 1 &&
1063*fb1b10abSAndroid Build Coastguard Worker         rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
1064*fb1b10abSAndroid Build Coastguard Worker       q = rc->avg_frame_qindex[INTER_FRAME];
1065*fb1b10abSAndroid Build Coastguard Worker     } else {
1066*fb1b10abSAndroid Build Coastguard Worker       q = active_worst_quality;
1067*fb1b10abSAndroid Build Coastguard Worker     }
1068*fb1b10abSAndroid Build Coastguard Worker     active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
1069*fb1b10abSAndroid Build Coastguard Worker   } else {
1070*fb1b10abSAndroid Build Coastguard Worker     // Use the lower of active_worst_quality and recent/average Q.
1071*fb1b10abSAndroid Build Coastguard Worker     if (cm->current_video_frame > 1) {
1072*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality)
1073*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = rtc_minq[rc->avg_frame_qindex[INTER_FRAME]];
1074*fb1b10abSAndroid Build Coastguard Worker       else
1075*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = rtc_minq[active_worst_quality];
1076*fb1b10abSAndroid Build Coastguard Worker     } else {
1077*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_qindex[KEY_FRAME] < active_worst_quality)
1078*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = rtc_minq[rc->avg_frame_qindex[KEY_FRAME]];
1079*fb1b10abSAndroid Build Coastguard Worker       else
1080*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = rtc_minq[active_worst_quality];
1081*fb1b10abSAndroid Build Coastguard Worker     }
1082*fb1b10abSAndroid Build Coastguard Worker   }
1083*fb1b10abSAndroid Build Coastguard Worker 
1084*fb1b10abSAndroid Build Coastguard Worker   // Clip the active best and worst quality values to limits
1085*fb1b10abSAndroid Build Coastguard Worker   active_best_quality =
1086*fb1b10abSAndroid Build Coastguard Worker       clamp(active_best_quality, rc->best_quality, rc->worst_quality);
1087*fb1b10abSAndroid Build Coastguard Worker   active_worst_quality =
1088*fb1b10abSAndroid Build Coastguard Worker       clamp(active_worst_quality, active_best_quality, rc->worst_quality);
1089*fb1b10abSAndroid Build Coastguard Worker 
1090*fb1b10abSAndroid Build Coastguard Worker   *top_index = active_worst_quality;
1091*fb1b10abSAndroid Build Coastguard Worker   *bottom_index = active_best_quality;
1092*fb1b10abSAndroid Build Coastguard Worker 
1093*fb1b10abSAndroid Build Coastguard Worker   // Special case code to try and match quality with forced key frames
1094*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) && rc->this_key_frame_forced) {
1095*fb1b10abSAndroid Build Coastguard Worker     q = rc->last_boosted_qindex;
1096*fb1b10abSAndroid Build Coastguard Worker   } else {
1097*fb1b10abSAndroid Build Coastguard Worker     q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality,
1098*fb1b10abSAndroid Build Coastguard Worker                           active_worst_quality);
1099*fb1b10abSAndroid Build Coastguard Worker     if (q > *top_index) {
1100*fb1b10abSAndroid Build Coastguard Worker       // Special case when we are targeting the max allowed rate
1101*fb1b10abSAndroid Build Coastguard Worker       if (rc->this_frame_target >= rc->max_frame_bandwidth)
1102*fb1b10abSAndroid Build Coastguard Worker         *top_index = q;
1103*fb1b10abSAndroid Build Coastguard Worker       else
1104*fb1b10abSAndroid Build Coastguard Worker         q = *top_index;
1105*fb1b10abSAndroid Build Coastguard Worker     }
1106*fb1b10abSAndroid Build Coastguard Worker   }
1107*fb1b10abSAndroid Build Coastguard Worker 
1108*fb1b10abSAndroid Build Coastguard Worker   assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality);
1109*fb1b10abSAndroid Build Coastguard Worker   assert(*bottom_index <= rc->worst_quality &&
1110*fb1b10abSAndroid Build Coastguard Worker          *bottom_index >= rc->best_quality);
1111*fb1b10abSAndroid Build Coastguard Worker   assert(q <= rc->worst_quality && q >= rc->best_quality);
1112*fb1b10abSAndroid Build Coastguard Worker   return q;
1113*fb1b10abSAndroid Build Coastguard Worker }
1114*fb1b10abSAndroid Build Coastguard Worker 
get_active_cq_level_one_pass(const RATE_CONTROL * rc,const VP9EncoderConfig * const oxcf)1115*fb1b10abSAndroid Build Coastguard Worker static int get_active_cq_level_one_pass(const RATE_CONTROL *rc,
1116*fb1b10abSAndroid Build Coastguard Worker                                         const VP9EncoderConfig *const oxcf) {
1117*fb1b10abSAndroid Build Coastguard Worker   static const double cq_adjust_threshold = 0.1;
1118*fb1b10abSAndroid Build Coastguard Worker   int active_cq_level = oxcf->cq_level;
1119*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_mode == VPX_CQ && rc->total_target_bits > 0) {
1120*fb1b10abSAndroid Build Coastguard Worker     const double x = (double)rc->total_actual_bits / rc->total_target_bits;
1121*fb1b10abSAndroid Build Coastguard Worker     if (x < cq_adjust_threshold) {
1122*fb1b10abSAndroid Build Coastguard Worker       active_cq_level = (int)(active_cq_level * x / cq_adjust_threshold);
1123*fb1b10abSAndroid Build Coastguard Worker     }
1124*fb1b10abSAndroid Build Coastguard Worker   }
1125*fb1b10abSAndroid Build Coastguard Worker   return active_cq_level;
1126*fb1b10abSAndroid Build Coastguard Worker }
1127*fb1b10abSAndroid Build Coastguard Worker 
1128*fb1b10abSAndroid Build Coastguard Worker #define SMOOTH_PCT_MIN 0.1
1129*fb1b10abSAndroid Build Coastguard Worker #define SMOOTH_PCT_DIV 0.05
get_active_cq_level_two_pass(const TWO_PASS * twopass,const RATE_CONTROL * rc,const VP9EncoderConfig * const oxcf)1130*fb1b10abSAndroid Build Coastguard Worker static int get_active_cq_level_two_pass(const TWO_PASS *twopass,
1131*fb1b10abSAndroid Build Coastguard Worker                                         const RATE_CONTROL *rc,
1132*fb1b10abSAndroid Build Coastguard Worker                                         const VP9EncoderConfig *const oxcf) {
1133*fb1b10abSAndroid Build Coastguard Worker   static const double cq_adjust_threshold = 0.1;
1134*fb1b10abSAndroid Build Coastguard Worker   int active_cq_level = oxcf->cq_level;
1135*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_mode == VPX_CQ) {
1136*fb1b10abSAndroid Build Coastguard Worker     if (twopass->mb_smooth_pct > SMOOTH_PCT_MIN) {
1137*fb1b10abSAndroid Build Coastguard Worker       active_cq_level -=
1138*fb1b10abSAndroid Build Coastguard Worker           (int)((twopass->mb_smooth_pct - SMOOTH_PCT_MIN) / SMOOTH_PCT_DIV);
1139*fb1b10abSAndroid Build Coastguard Worker       active_cq_level = VPXMAX(active_cq_level, 0);
1140*fb1b10abSAndroid Build Coastguard Worker     }
1141*fb1b10abSAndroid Build Coastguard Worker     if (rc->total_target_bits > 0) {
1142*fb1b10abSAndroid Build Coastguard Worker       const double x = (double)rc->total_actual_bits / rc->total_target_bits;
1143*fb1b10abSAndroid Build Coastguard Worker       if (x < cq_adjust_threshold) {
1144*fb1b10abSAndroid Build Coastguard Worker         active_cq_level = (int)(active_cq_level * x / cq_adjust_threshold);
1145*fb1b10abSAndroid Build Coastguard Worker       }
1146*fb1b10abSAndroid Build Coastguard Worker     }
1147*fb1b10abSAndroid Build Coastguard Worker   }
1148*fb1b10abSAndroid Build Coastguard Worker   return active_cq_level;
1149*fb1b10abSAndroid Build Coastguard Worker }
1150*fb1b10abSAndroid Build Coastguard Worker 
rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP * cpi,int * bottom_index,int * top_index)1151*fb1b10abSAndroid Build Coastguard Worker static int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi,
1152*fb1b10abSAndroid Build Coastguard Worker                                              int *bottom_index,
1153*fb1b10abSAndroid Build Coastguard Worker                                              int *top_index) {
1154*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1155*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1156*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1157*fb1b10abSAndroid Build Coastguard Worker   const int cq_level = get_active_cq_level_one_pass(rc, oxcf);
1158*fb1b10abSAndroid Build Coastguard Worker   int active_best_quality;
1159*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi);
1160*fb1b10abSAndroid Build Coastguard Worker   int q;
1161*fb1b10abSAndroid Build Coastguard Worker   int *inter_minq;
1162*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
1163*fb1b10abSAndroid Build Coastguard Worker 
1164*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
1165*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->rc_mode == VPX_Q) {
1166*fb1b10abSAndroid Build Coastguard Worker       int qindex = cq_level;
1167*fb1b10abSAndroid Build Coastguard Worker       double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1168*fb1b10abSAndroid Build Coastguard Worker       int delta_qindex =
1169*fb1b10abSAndroid Build Coastguard Worker           vp9_compute_qdelta(rc, qstart, qstart * 0.25, cm->bit_depth);
1170*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1171*fb1b10abSAndroid Build Coastguard Worker     } else if (rc->this_key_frame_forced) {
1172*fb1b10abSAndroid Build Coastguard Worker       // Handle the special case for key frames forced when we have reached
1173*fb1b10abSAndroid Build Coastguard Worker       // the maximum key frame interval. Here force the Q to a range
1174*fb1b10abSAndroid Build Coastguard Worker       // based on the ambient Q to reduce the risk of popping.
1175*fb1b10abSAndroid Build Coastguard Worker       int qindex = rc->last_boosted_qindex;
1176*fb1b10abSAndroid Build Coastguard Worker       double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1177*fb1b10abSAndroid Build Coastguard Worker       int delta_qindex = vp9_compute_qdelta(
1178*fb1b10abSAndroid Build Coastguard Worker           rc, last_boosted_q, last_boosted_q * 0.75, cm->bit_depth);
1179*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1180*fb1b10abSAndroid Build Coastguard Worker     } else {
1181*fb1b10abSAndroid Build Coastguard Worker       // not first frame of one pass and kf_boost is set
1182*fb1b10abSAndroid Build Coastguard Worker       double q_adj_factor = 1.0;
1183*fb1b10abSAndroid Build Coastguard Worker       double q_val;
1184*fb1b10abSAndroid Build Coastguard Worker 
1185*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = get_kf_active_quality(
1186*fb1b10abSAndroid Build Coastguard Worker           rc, rc->avg_frame_qindex[KEY_FRAME], cm->bit_depth);
1187*fb1b10abSAndroid Build Coastguard Worker 
1188*fb1b10abSAndroid Build Coastguard Worker       // Allow somewhat lower kf minq with small image formats.
1189*fb1b10abSAndroid Build Coastguard Worker       if ((cm->width * cm->height) <= (352 * 288)) {
1190*fb1b10abSAndroid Build Coastguard Worker         q_adj_factor -= 0.25;
1191*fb1b10abSAndroid Build Coastguard Worker       }
1192*fb1b10abSAndroid Build Coastguard Worker 
1193*fb1b10abSAndroid Build Coastguard Worker       // Convert the adjustment factor to a qindex delta
1194*fb1b10abSAndroid Build Coastguard Worker       // on active_best_quality.
1195*fb1b10abSAndroid Build Coastguard Worker       q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
1196*fb1b10abSAndroid Build Coastguard Worker       active_best_quality +=
1197*fb1b10abSAndroid Build Coastguard Worker           vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth);
1198*fb1b10abSAndroid Build Coastguard Worker     }
1199*fb1b10abSAndroid Build Coastguard Worker   } else if (!rc->is_src_frame_alt_ref &&
1200*fb1b10abSAndroid Build Coastguard Worker              (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
1201*fb1b10abSAndroid Build Coastguard Worker     // Use the lower of active_worst_quality and recent
1202*fb1b10abSAndroid Build Coastguard Worker     // average Q as basis for GF/ARF best Q limit unless last frame was
1203*fb1b10abSAndroid Build Coastguard Worker     // a key frame.
1204*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_since_key > 1) {
1205*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
1206*fb1b10abSAndroid Build Coastguard Worker         q = rc->avg_frame_qindex[INTER_FRAME];
1207*fb1b10abSAndroid Build Coastguard Worker       } else {
1208*fb1b10abSAndroid Build Coastguard Worker         q = active_worst_quality;
1209*fb1b10abSAndroid Build Coastguard Worker       }
1210*fb1b10abSAndroid Build Coastguard Worker     } else {
1211*fb1b10abSAndroid Build Coastguard Worker       q = rc->avg_frame_qindex[KEY_FRAME];
1212*fb1b10abSAndroid Build Coastguard Worker     }
1213*fb1b10abSAndroid Build Coastguard Worker     // For constrained quality don't allow Q less than the cq level
1214*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->rc_mode == VPX_CQ) {
1215*fb1b10abSAndroid Build Coastguard Worker       if (q < cq_level) q = cq_level;
1216*fb1b10abSAndroid Build Coastguard Worker 
1217*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
1218*fb1b10abSAndroid Build Coastguard Worker 
1219*fb1b10abSAndroid Build Coastguard Worker       // Constrained quality use slightly lower active best.
1220*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = active_best_quality * 15 / 16;
1221*fb1b10abSAndroid Build Coastguard Worker 
1222*fb1b10abSAndroid Build Coastguard Worker     } else if (oxcf->rc_mode == VPX_Q) {
1223*fb1b10abSAndroid Build Coastguard Worker       int qindex = cq_level;
1224*fb1b10abSAndroid Build Coastguard Worker       double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1225*fb1b10abSAndroid Build Coastguard Worker       int delta_qindex;
1226*fb1b10abSAndroid Build Coastguard Worker       if (cpi->refresh_alt_ref_frame)
1227*fb1b10abSAndroid Build Coastguard Worker         delta_qindex =
1228*fb1b10abSAndroid Build Coastguard Worker             vp9_compute_qdelta(rc, qstart, qstart * 0.40, cm->bit_depth);
1229*fb1b10abSAndroid Build Coastguard Worker       else
1230*fb1b10abSAndroid Build Coastguard Worker         delta_qindex =
1231*fb1b10abSAndroid Build Coastguard Worker             vp9_compute_qdelta(rc, qstart, qstart * 0.50, cm->bit_depth);
1232*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1233*fb1b10abSAndroid Build Coastguard Worker     } else {
1234*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
1235*fb1b10abSAndroid Build Coastguard Worker     }
1236*fb1b10abSAndroid Build Coastguard Worker   } else {
1237*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->rc_mode == VPX_Q) {
1238*fb1b10abSAndroid Build Coastguard Worker       int qindex = cq_level;
1239*fb1b10abSAndroid Build Coastguard Worker       double qstart = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1240*fb1b10abSAndroid Build Coastguard Worker       double delta_rate[FIXED_GF_INTERVAL] = { 0.50, 1.0, 0.85, 1.0,
1241*fb1b10abSAndroid Build Coastguard Worker                                                0.70, 1.0, 0.85, 1.0 };
1242*fb1b10abSAndroid Build Coastguard Worker       int delta_qindex = vp9_compute_qdelta(
1243*fb1b10abSAndroid Build Coastguard Worker           rc, qstart,
1244*fb1b10abSAndroid Build Coastguard Worker           qstart * delta_rate[cm->current_video_frame % FIXED_GF_INTERVAL],
1245*fb1b10abSAndroid Build Coastguard Worker           cm->bit_depth);
1246*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1247*fb1b10abSAndroid Build Coastguard Worker     } else {
1248*fb1b10abSAndroid Build Coastguard Worker       // Use the min of the average Q and active_worst_quality as basis for
1249*fb1b10abSAndroid Build Coastguard Worker       // active_best.
1250*fb1b10abSAndroid Build Coastguard Worker       if (cm->current_video_frame > 1) {
1251*fb1b10abSAndroid Build Coastguard Worker         q = VPXMIN(rc->avg_frame_qindex[INTER_FRAME], active_worst_quality);
1252*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = inter_minq[q];
1253*fb1b10abSAndroid Build Coastguard Worker       } else {
1254*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]];
1255*fb1b10abSAndroid Build Coastguard Worker       }
1256*fb1b10abSAndroid Build Coastguard Worker       // For the constrained quality mode we don't want
1257*fb1b10abSAndroid Build Coastguard Worker       // q to fall below the cq level.
1258*fb1b10abSAndroid Build Coastguard Worker       if ((oxcf->rc_mode == VPX_CQ) && (active_best_quality < cq_level)) {
1259*fb1b10abSAndroid Build Coastguard Worker         active_best_quality = cq_level;
1260*fb1b10abSAndroid Build Coastguard Worker       }
1261*fb1b10abSAndroid Build Coastguard Worker     }
1262*fb1b10abSAndroid Build Coastguard Worker   }
1263*fb1b10abSAndroid Build Coastguard Worker 
1264*fb1b10abSAndroid Build Coastguard Worker   // Clip the active best and worst quality values to limits
1265*fb1b10abSAndroid Build Coastguard Worker   active_best_quality =
1266*fb1b10abSAndroid Build Coastguard Worker       clamp(active_best_quality, rc->best_quality, rc->worst_quality);
1267*fb1b10abSAndroid Build Coastguard Worker   active_worst_quality =
1268*fb1b10abSAndroid Build Coastguard Worker       clamp(active_worst_quality, active_best_quality, rc->worst_quality);
1269*fb1b10abSAndroid Build Coastguard Worker 
1270*fb1b10abSAndroid Build Coastguard Worker   *top_index = active_worst_quality;
1271*fb1b10abSAndroid Build Coastguard Worker   *bottom_index = active_best_quality;
1272*fb1b10abSAndroid Build Coastguard Worker 
1273*fb1b10abSAndroid Build Coastguard Worker #if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
1274*fb1b10abSAndroid Build Coastguard Worker   {
1275*fb1b10abSAndroid Build Coastguard Worker     int qdelta = 0;
1276*fb1b10abSAndroid Build Coastguard Worker     vpx_clear_system_state();
1277*fb1b10abSAndroid Build Coastguard Worker 
1278*fb1b10abSAndroid Build Coastguard Worker     // Limit Q range for the adaptive loop.
1279*fb1b10abSAndroid Build Coastguard Worker     if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced &&
1280*fb1b10abSAndroid Build Coastguard Worker         !(cm->current_video_frame == 0)) {
1281*fb1b10abSAndroid Build Coastguard Worker       qdelta = vp9_compute_qdelta_by_rate(
1282*fb1b10abSAndroid Build Coastguard Worker           &cpi->rc, cm->frame_type, active_worst_quality, 2.0, cm->bit_depth);
1283*fb1b10abSAndroid Build Coastguard Worker     } else if (!rc->is_src_frame_alt_ref &&
1284*fb1b10abSAndroid Build Coastguard Worker                (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
1285*fb1b10abSAndroid Build Coastguard Worker       qdelta = vp9_compute_qdelta_by_rate(
1286*fb1b10abSAndroid Build Coastguard Worker           &cpi->rc, cm->frame_type, active_worst_quality, 1.75, cm->bit_depth);
1287*fb1b10abSAndroid Build Coastguard Worker     }
1288*fb1b10abSAndroid Build Coastguard Worker     if (rc->high_source_sad && cpi->sf.use_altref_onepass) qdelta = 0;
1289*fb1b10abSAndroid Build Coastguard Worker     *top_index = active_worst_quality + qdelta;
1290*fb1b10abSAndroid Build Coastguard Worker     *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index;
1291*fb1b10abSAndroid Build Coastguard Worker   }
1292*fb1b10abSAndroid Build Coastguard Worker #endif
1293*fb1b10abSAndroid Build Coastguard Worker 
1294*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_mode == VPX_Q) {
1295*fb1b10abSAndroid Build Coastguard Worker     q = active_best_quality;
1296*fb1b10abSAndroid Build Coastguard Worker     // Special case code to try and match quality with forced key frames
1297*fb1b10abSAndroid Build Coastguard Worker   } else if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced) {
1298*fb1b10abSAndroid Build Coastguard Worker     q = rc->last_boosted_qindex;
1299*fb1b10abSAndroid Build Coastguard Worker   } else {
1300*fb1b10abSAndroid Build Coastguard Worker     q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality,
1301*fb1b10abSAndroid Build Coastguard Worker                           active_worst_quality);
1302*fb1b10abSAndroid Build Coastguard Worker     if (q > *top_index) {
1303*fb1b10abSAndroid Build Coastguard Worker       // Special case when we are targeting the max allowed rate
1304*fb1b10abSAndroid Build Coastguard Worker       if (rc->this_frame_target >= rc->max_frame_bandwidth)
1305*fb1b10abSAndroid Build Coastguard Worker         *top_index = q;
1306*fb1b10abSAndroid Build Coastguard Worker       else
1307*fb1b10abSAndroid Build Coastguard Worker         q = *top_index;
1308*fb1b10abSAndroid Build Coastguard Worker     }
1309*fb1b10abSAndroid Build Coastguard Worker   }
1310*fb1b10abSAndroid Build Coastguard Worker 
1311*fb1b10abSAndroid Build Coastguard Worker   assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality);
1312*fb1b10abSAndroid Build Coastguard Worker   assert(*bottom_index <= rc->worst_quality &&
1313*fb1b10abSAndroid Build Coastguard Worker          *bottom_index >= rc->best_quality);
1314*fb1b10abSAndroid Build Coastguard Worker   assert(q <= rc->worst_quality && q >= rc->best_quality);
1315*fb1b10abSAndroid Build Coastguard Worker   return q;
1316*fb1b10abSAndroid Build Coastguard Worker }
1317*fb1b10abSAndroid Build Coastguard Worker 
vp9_frame_type_qdelta(const VP9_COMP * cpi,int rf_level,int q)1318*fb1b10abSAndroid Build Coastguard Worker int vp9_frame_type_qdelta(const VP9_COMP *cpi, int rf_level, int q) {
1319*fb1b10abSAndroid Build Coastguard Worker   static const double rate_factor_deltas[RATE_FACTOR_LEVELS] = {
1320*fb1b10abSAndroid Build Coastguard Worker     1.00,  // INTER_NORMAL
1321*fb1b10abSAndroid Build Coastguard Worker     1.00,  // INTER_HIGH
1322*fb1b10abSAndroid Build Coastguard Worker     1.50,  // GF_ARF_LOW
1323*fb1b10abSAndroid Build Coastguard Worker     1.75,  // GF_ARF_STD
1324*fb1b10abSAndroid Build Coastguard Worker     2.00,  // KF_STD
1325*fb1b10abSAndroid Build Coastguard Worker   };
1326*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1327*fb1b10abSAndroid Build Coastguard Worker 
1328*fb1b10abSAndroid Build Coastguard Worker   int qdelta = vp9_compute_qdelta_by_rate(
1329*fb1b10abSAndroid Build Coastguard Worker       &cpi->rc, cm->frame_type, q, rate_factor_deltas[rf_level], cm->bit_depth);
1330*fb1b10abSAndroid Build Coastguard Worker   return qdelta;
1331*fb1b10abSAndroid Build Coastguard Worker }
1332*fb1b10abSAndroid Build Coastguard Worker 
1333*fb1b10abSAndroid Build Coastguard Worker #define STATIC_MOTION_THRESH 95
1334*fb1b10abSAndroid Build Coastguard Worker 
pick_kf_q_bound_two_pass(const VP9_COMP * cpi,int * bottom_index,int * top_index)1335*fb1b10abSAndroid Build Coastguard Worker static void pick_kf_q_bound_two_pass(const VP9_COMP *cpi, int *bottom_index,
1336*fb1b10abSAndroid Build Coastguard Worker                                      int *top_index) {
1337*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1338*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1339*fb1b10abSAndroid Build Coastguard Worker   int active_best_quality;
1340*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality = cpi->twopass.active_worst_quality;
1341*fb1b10abSAndroid Build Coastguard Worker 
1342*fb1b10abSAndroid Build Coastguard Worker   if (rc->this_key_frame_forced) {
1343*fb1b10abSAndroid Build Coastguard Worker     // Handle the special case for key frames forced when we have reached
1344*fb1b10abSAndroid Build Coastguard Worker     // the maximum key frame interval. Here force the Q to a range
1345*fb1b10abSAndroid Build Coastguard Worker     // based on the ambient Q to reduce the risk of popping.
1346*fb1b10abSAndroid Build Coastguard Worker     double last_boosted_q;
1347*fb1b10abSAndroid Build Coastguard Worker     int delta_qindex;
1348*fb1b10abSAndroid Build Coastguard Worker     int qindex;
1349*fb1b10abSAndroid Build Coastguard Worker 
1350*fb1b10abSAndroid Build Coastguard Worker     if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) {
1351*fb1b10abSAndroid Build Coastguard Worker       qindex = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex);
1352*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = qindex;
1353*fb1b10abSAndroid Build Coastguard Worker       last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1354*fb1b10abSAndroid Build Coastguard Worker       delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
1355*fb1b10abSAndroid Build Coastguard Worker                                         last_boosted_q * 1.25, cm->bit_depth);
1356*fb1b10abSAndroid Build Coastguard Worker       active_worst_quality =
1357*fb1b10abSAndroid Build Coastguard Worker           VPXMIN(qindex + delta_qindex, active_worst_quality);
1358*fb1b10abSAndroid Build Coastguard Worker     } else {
1359*fb1b10abSAndroid Build Coastguard Worker       qindex = rc->last_boosted_qindex;
1360*fb1b10abSAndroid Build Coastguard Worker       last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1361*fb1b10abSAndroid Build Coastguard Worker       delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
1362*fb1b10abSAndroid Build Coastguard Worker                                         last_boosted_q * 0.75, cm->bit_depth);
1363*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = VPXMAX(qindex + delta_qindex, rc->best_quality);
1364*fb1b10abSAndroid Build Coastguard Worker     }
1365*fb1b10abSAndroid Build Coastguard Worker   } else {
1366*fb1b10abSAndroid Build Coastguard Worker     // Not forced keyframe.
1367*fb1b10abSAndroid Build Coastguard Worker     double q_adj_factor = 1.0;
1368*fb1b10abSAndroid Build Coastguard Worker     double q_val;
1369*fb1b10abSAndroid Build Coastguard Worker     // Baseline value derived from cpi->active_worst_quality and kf boost.
1370*fb1b10abSAndroid Build Coastguard Worker     active_best_quality =
1371*fb1b10abSAndroid Build Coastguard Worker         get_kf_active_quality(rc, active_worst_quality, cm->bit_depth);
1372*fb1b10abSAndroid Build Coastguard Worker     if (cpi->twopass.kf_zeromotion_pct >= STATIC_KF_GROUP_THRESH) {
1373*fb1b10abSAndroid Build Coastguard Worker       active_best_quality /= 4;
1374*fb1b10abSAndroid Build Coastguard Worker     }
1375*fb1b10abSAndroid Build Coastguard Worker 
1376*fb1b10abSAndroid Build Coastguard Worker     // Don't allow the active min to be lossless (q0) unlesss the max q
1377*fb1b10abSAndroid Build Coastguard Worker     // already indicates lossless.
1378*fb1b10abSAndroid Build Coastguard Worker     active_best_quality =
1379*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(active_worst_quality, VPXMAX(1, active_best_quality));
1380*fb1b10abSAndroid Build Coastguard Worker 
1381*fb1b10abSAndroid Build Coastguard Worker     // Allow somewhat lower kf minq with small image formats.
1382*fb1b10abSAndroid Build Coastguard Worker     if ((cm->width * cm->height) <= (352 * 288)) {
1383*fb1b10abSAndroid Build Coastguard Worker       q_adj_factor -= 0.25;
1384*fb1b10abSAndroid Build Coastguard Worker     }
1385*fb1b10abSAndroid Build Coastguard Worker 
1386*fb1b10abSAndroid Build Coastguard Worker     // Make a further adjustment based on the kf zero motion measure.
1387*fb1b10abSAndroid Build Coastguard Worker     q_adj_factor += 0.05 - (0.001 * (double)cpi->twopass.kf_zeromotion_pct);
1388*fb1b10abSAndroid Build Coastguard Worker 
1389*fb1b10abSAndroid Build Coastguard Worker     // Convert the adjustment factor to a qindex delta
1390*fb1b10abSAndroid Build Coastguard Worker     // on active_best_quality.
1391*fb1b10abSAndroid Build Coastguard Worker     q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
1392*fb1b10abSAndroid Build Coastguard Worker     active_best_quality +=
1393*fb1b10abSAndroid Build Coastguard Worker         vp9_compute_qdelta(rc, q_val, q_val * q_adj_factor, cm->bit_depth);
1394*fb1b10abSAndroid Build Coastguard Worker   }
1395*fb1b10abSAndroid Build Coastguard Worker   *top_index = active_worst_quality;
1396*fb1b10abSAndroid Build Coastguard Worker   *bottom_index = active_best_quality;
1397*fb1b10abSAndroid Build Coastguard Worker }
1398*fb1b10abSAndroid Build Coastguard Worker 
rc_constant_q(const VP9_COMP * cpi,int * bottom_index,int * top_index,int gf_group_index)1399*fb1b10abSAndroid Build Coastguard Worker static int rc_constant_q(const VP9_COMP *cpi, int *bottom_index, int *top_index,
1400*fb1b10abSAndroid Build Coastguard Worker                          int gf_group_index) {
1401*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1402*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1403*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1404*fb1b10abSAndroid Build Coastguard Worker   const GF_GROUP *gf_group = &cpi->twopass.gf_group;
1405*fb1b10abSAndroid Build Coastguard Worker   const int is_intra_frame = frame_is_intra_only(cm);
1406*fb1b10abSAndroid Build Coastguard Worker 
1407*fb1b10abSAndroid Build Coastguard Worker   const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf);
1408*fb1b10abSAndroid Build Coastguard Worker 
1409*fb1b10abSAndroid Build Coastguard Worker   int q = cq_level;
1410*fb1b10abSAndroid Build Coastguard Worker   int active_best_quality = cq_level;
1411*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality = cq_level;
1412*fb1b10abSAndroid Build Coastguard Worker 
1413*fb1b10abSAndroid Build Coastguard Worker   // Key frame qp decision
1414*fb1b10abSAndroid Build Coastguard Worker   if (is_intra_frame && rc->frames_to_key > 1)
1415*fb1b10abSAndroid Build Coastguard Worker     pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality);
1416*fb1b10abSAndroid Build Coastguard Worker 
1417*fb1b10abSAndroid Build Coastguard Worker   // ARF / GF qp decision
1418*fb1b10abSAndroid Build Coastguard Worker   if (!is_intra_frame && !rc->is_src_frame_alt_ref &&
1419*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame) {
1420*fb1b10abSAndroid Build Coastguard Worker     active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
1421*fb1b10abSAndroid Build Coastguard Worker 
1422*fb1b10abSAndroid Build Coastguard Worker     // Modify best quality for second level arfs. For mode VPX_Q this
1423*fb1b10abSAndroid Build Coastguard Worker     // becomes the baseline frame q.
1424*fb1b10abSAndroid Build Coastguard Worker     if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) {
1425*fb1b10abSAndroid Build Coastguard Worker       const int layer_depth = gf_group->layer_depth[gf_group_index];
1426*fb1b10abSAndroid Build Coastguard Worker       // linearly fit the frame q depending on the layer depth index from
1427*fb1b10abSAndroid Build Coastguard Worker       // the base layer ARF.
1428*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = ((layer_depth - 1) * cq_level +
1429*fb1b10abSAndroid Build Coastguard Worker                              active_best_quality + layer_depth / 2) /
1430*fb1b10abSAndroid Build Coastguard Worker                             layer_depth;
1431*fb1b10abSAndroid Build Coastguard Worker     }
1432*fb1b10abSAndroid Build Coastguard Worker   }
1433*fb1b10abSAndroid Build Coastguard Worker 
1434*fb1b10abSAndroid Build Coastguard Worker   q = active_best_quality;
1435*fb1b10abSAndroid Build Coastguard Worker   *top_index = active_worst_quality;
1436*fb1b10abSAndroid Build Coastguard Worker   *bottom_index = active_best_quality;
1437*fb1b10abSAndroid Build Coastguard Worker   return q;
1438*fb1b10abSAndroid Build Coastguard Worker }
1439*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_pick_q_and_bounds_two_pass(const VP9_COMP * cpi,int * bottom_index,int * top_index,int gf_group_index)1440*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
1441*fb1b10abSAndroid Build Coastguard Worker                                       int *top_index, int gf_group_index) {
1442*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1443*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
1444*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1445*fb1b10abSAndroid Build Coastguard Worker   const GF_GROUP *gf_group = &cpi->twopass.gf_group;
1446*fb1b10abSAndroid Build Coastguard Worker   const int cq_level = get_active_cq_level_two_pass(&cpi->twopass, rc, oxcf);
1447*fb1b10abSAndroid Build Coastguard Worker   int active_best_quality;
1448*fb1b10abSAndroid Build Coastguard Worker   int active_worst_quality = cpi->twopass.active_worst_quality;
1449*fb1b10abSAndroid Build Coastguard Worker   int q;
1450*fb1b10abSAndroid Build Coastguard Worker   int *inter_minq;
1451*fb1b10abSAndroid Build Coastguard Worker   int arf_active_best_quality_hl;
1452*fb1b10abSAndroid Build Coastguard Worker   int *arfgf_high_motion_minq, *arfgf_low_motion_minq;
1453*fb1b10abSAndroid Build Coastguard Worker   const int boost_frame =
1454*fb1b10abSAndroid Build Coastguard Worker       !rc->is_src_frame_alt_ref &&
1455*fb1b10abSAndroid Build Coastguard Worker       (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame);
1456*fb1b10abSAndroid Build Coastguard Worker 
1457*fb1b10abSAndroid Build Coastguard Worker   ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
1458*fb1b10abSAndroid Build Coastguard Worker 
1459*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_mode == VPX_Q)
1460*fb1b10abSAndroid Build Coastguard Worker     return rc_constant_q(cpi, bottom_index, top_index, gf_group_index);
1461*fb1b10abSAndroid Build Coastguard Worker 
1462*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
1463*fb1b10abSAndroid Build Coastguard Worker     pick_kf_q_bound_two_pass(cpi, &active_best_quality, &active_worst_quality);
1464*fb1b10abSAndroid Build Coastguard Worker   } else if (boost_frame) {
1465*fb1b10abSAndroid Build Coastguard Worker     // Use the lower of active_worst_quality and recent
1466*fb1b10abSAndroid Build Coastguard Worker     // average Q as basis for GF/ARF best Q limit unless last frame was
1467*fb1b10abSAndroid Build Coastguard Worker     // a key frame.
1468*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_since_key > 1 &&
1469*fb1b10abSAndroid Build Coastguard Worker         rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
1470*fb1b10abSAndroid Build Coastguard Worker       q = rc->avg_frame_qindex[INTER_FRAME];
1471*fb1b10abSAndroid Build Coastguard Worker     } else {
1472*fb1b10abSAndroid Build Coastguard Worker       q = active_worst_quality;
1473*fb1b10abSAndroid Build Coastguard Worker     }
1474*fb1b10abSAndroid Build Coastguard Worker     // For constrained quality don't allow Q less than the cq level
1475*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->rc_mode == VPX_CQ) {
1476*fb1b10abSAndroid Build Coastguard Worker       if (q < cq_level) q = cq_level;
1477*fb1b10abSAndroid Build Coastguard Worker     }
1478*fb1b10abSAndroid Build Coastguard Worker     active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
1479*fb1b10abSAndroid Build Coastguard Worker     arf_active_best_quality_hl = active_best_quality;
1480*fb1b10abSAndroid Build Coastguard Worker 
1481*fb1b10abSAndroid Build Coastguard Worker     if (rc->arf_increase_active_best_quality == 1) {
1482*fb1b10abSAndroid Build Coastguard Worker       ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_high_motion_minq);
1483*fb1b10abSAndroid Build Coastguard Worker       arf_active_best_quality_hl = arfgf_high_motion_minq[q];
1484*fb1b10abSAndroid Build Coastguard Worker     } else if (rc->arf_increase_active_best_quality == -1) {
1485*fb1b10abSAndroid Build Coastguard Worker       ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_low_motion_minq);
1486*fb1b10abSAndroid Build Coastguard Worker       arf_active_best_quality_hl = arfgf_low_motion_minq[q];
1487*fb1b10abSAndroid Build Coastguard Worker     }
1488*fb1b10abSAndroid Build Coastguard Worker     active_best_quality =
1489*fb1b10abSAndroid Build Coastguard Worker         (int)((double)active_best_quality *
1490*fb1b10abSAndroid Build Coastguard Worker                   rc->arf_active_best_quality_adjustment_factor +
1491*fb1b10abSAndroid Build Coastguard Worker               (double)arf_active_best_quality_hl *
1492*fb1b10abSAndroid Build Coastguard Worker                   (1.0 - rc->arf_active_best_quality_adjustment_factor));
1493*fb1b10abSAndroid Build Coastguard Worker 
1494*fb1b10abSAndroid Build Coastguard Worker     // Modify best quality for second level arfs. For mode VPX_Q this
1495*fb1b10abSAndroid Build Coastguard Worker     // becomes the baseline frame q.
1496*fb1b10abSAndroid Build Coastguard Worker     if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) {
1497*fb1b10abSAndroid Build Coastguard Worker       const int layer_depth = gf_group->layer_depth[gf_group_index];
1498*fb1b10abSAndroid Build Coastguard Worker       // linearly fit the frame q depending on the layer depth index from
1499*fb1b10abSAndroid Build Coastguard Worker       // the base layer ARF.
1500*fb1b10abSAndroid Build Coastguard Worker       active_best_quality =
1501*fb1b10abSAndroid Build Coastguard Worker           ((layer_depth - 1) * q + active_best_quality + layer_depth / 2) /
1502*fb1b10abSAndroid Build Coastguard Worker           layer_depth;
1503*fb1b10abSAndroid Build Coastguard Worker     }
1504*fb1b10abSAndroid Build Coastguard Worker   } else {
1505*fb1b10abSAndroid Build Coastguard Worker     active_best_quality = inter_minq[active_worst_quality];
1506*fb1b10abSAndroid Build Coastguard Worker 
1507*fb1b10abSAndroid Build Coastguard Worker     // For the constrained quality mode we don't want
1508*fb1b10abSAndroid Build Coastguard Worker     // q to fall below the cq level.
1509*fb1b10abSAndroid Build Coastguard Worker     if ((oxcf->rc_mode == VPX_CQ) && (active_best_quality < cq_level)) {
1510*fb1b10abSAndroid Build Coastguard Worker       active_best_quality = cq_level;
1511*fb1b10abSAndroid Build Coastguard Worker     }
1512*fb1b10abSAndroid Build Coastguard Worker   }
1513*fb1b10abSAndroid Build Coastguard Worker 
1514*fb1b10abSAndroid Build Coastguard Worker   // Extension to max or min Q if undershoot or overshoot is outside
1515*fb1b10abSAndroid Build Coastguard Worker   // the permitted range.
1516*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) || boost_frame) {
1517*fb1b10abSAndroid Build Coastguard Worker     const int layer_depth = gf_group->layer_depth[gf_group_index];
1518*fb1b10abSAndroid Build Coastguard Worker     active_best_quality -=
1519*fb1b10abSAndroid Build Coastguard Worker         (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast);
1520*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality += (cpi->twopass.extend_maxq / 2);
1521*fb1b10abSAndroid Build Coastguard Worker 
1522*fb1b10abSAndroid Build Coastguard Worker     if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) {
1523*fb1b10abSAndroid Build Coastguard Worker       assert(layer_depth > 1);
1524*fb1b10abSAndroid Build Coastguard Worker       active_best_quality =
1525*fb1b10abSAndroid Build Coastguard Worker           VPXMAX(active_best_quality,
1526*fb1b10abSAndroid Build Coastguard Worker                  cpi->twopass.last_qindex_of_arf_layer[layer_depth - 1]);
1527*fb1b10abSAndroid Build Coastguard Worker     }
1528*fb1b10abSAndroid Build Coastguard Worker   } else {
1529*fb1b10abSAndroid Build Coastguard Worker     const int max_layer_depth = gf_group->max_layer_depth;
1530*fb1b10abSAndroid Build Coastguard Worker     assert(max_layer_depth > 0);
1531*fb1b10abSAndroid Build Coastguard Worker 
1532*fb1b10abSAndroid Build Coastguard Worker     active_best_quality -=
1533*fb1b10abSAndroid Build Coastguard Worker         (cpi->twopass.extend_minq + cpi->twopass.extend_minq_fast) / 2;
1534*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality += cpi->twopass.extend_maxq;
1535*fb1b10abSAndroid Build Coastguard Worker 
1536*fb1b10abSAndroid Build Coastguard Worker     // For normal frames do not allow an active minq lower than the q used for
1537*fb1b10abSAndroid Build Coastguard Worker     // the last boosted frame.
1538*fb1b10abSAndroid Build Coastguard Worker     active_best_quality =
1539*fb1b10abSAndroid Build Coastguard Worker         VPXMAX(active_best_quality,
1540*fb1b10abSAndroid Build Coastguard Worker                cpi->twopass.last_qindex_of_arf_layer[max_layer_depth - 1]);
1541*fb1b10abSAndroid Build Coastguard Worker   }
1542*fb1b10abSAndroid Build Coastguard Worker 
1543*fb1b10abSAndroid Build Coastguard Worker #if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
1544*fb1b10abSAndroid Build Coastguard Worker   vpx_clear_system_state();
1545*fb1b10abSAndroid Build Coastguard Worker   // Static forced key frames Q restrictions dealt with elsewhere.
1546*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm) || !rc->this_key_frame_forced ||
1547*fb1b10abSAndroid Build Coastguard Worker       cpi->twopass.last_kfgroup_zeromotion_pct < STATIC_MOTION_THRESH) {
1548*fb1b10abSAndroid Build Coastguard Worker     int qdelta = vp9_frame_type_qdelta(cpi, gf_group->rf_level[gf_group_index],
1549*fb1b10abSAndroid Build Coastguard Worker                                        active_worst_quality);
1550*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality =
1551*fb1b10abSAndroid Build Coastguard Worker         VPXMAX(active_worst_quality + qdelta, active_best_quality);
1552*fb1b10abSAndroid Build Coastguard Worker   }
1553*fb1b10abSAndroid Build Coastguard Worker #endif
1554*fb1b10abSAndroid Build Coastguard Worker 
1555*fb1b10abSAndroid Build Coastguard Worker   // Modify active_best_quality for downscaled normal frames.
1556*fb1b10abSAndroid Build Coastguard Worker   if (rc->frame_size_selector != UNSCALED && !frame_is_kf_gf_arf(cpi)) {
1557*fb1b10abSAndroid Build Coastguard Worker     int qdelta = vp9_compute_qdelta_by_rate(
1558*fb1b10abSAndroid Build Coastguard Worker         rc, cm->frame_type, active_best_quality, 2.0, cm->bit_depth);
1559*fb1b10abSAndroid Build Coastguard Worker     active_best_quality =
1560*fb1b10abSAndroid Build Coastguard Worker         VPXMAX(active_best_quality + qdelta, rc->best_quality);
1561*fb1b10abSAndroid Build Coastguard Worker   }
1562*fb1b10abSAndroid Build Coastguard Worker 
1563*fb1b10abSAndroid Build Coastguard Worker   active_best_quality =
1564*fb1b10abSAndroid Build Coastguard Worker       clamp(active_best_quality, rc->best_quality, rc->worst_quality);
1565*fb1b10abSAndroid Build Coastguard Worker   active_worst_quality =
1566*fb1b10abSAndroid Build Coastguard Worker       clamp(active_worst_quality, active_best_quality, rc->worst_quality);
1567*fb1b10abSAndroid Build Coastguard Worker 
1568*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm) && rc->this_key_frame_forced) {
1569*fb1b10abSAndroid Build Coastguard Worker     // If static since last kf use better of last boosted and last kf q.
1570*fb1b10abSAndroid Build Coastguard Worker     if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) {
1571*fb1b10abSAndroid Build Coastguard Worker       q = VPXMIN(rc->last_kf_qindex, rc->last_boosted_qindex);
1572*fb1b10abSAndroid Build Coastguard Worker     } else {
1573*fb1b10abSAndroid Build Coastguard Worker       q = rc->last_boosted_qindex;
1574*fb1b10abSAndroid Build Coastguard Worker     }
1575*fb1b10abSAndroid Build Coastguard Worker   } else if (frame_is_intra_only(cm) && !rc->this_key_frame_forced) {
1576*fb1b10abSAndroid Build Coastguard Worker     q = active_best_quality;
1577*fb1b10abSAndroid Build Coastguard Worker   } else {
1578*fb1b10abSAndroid Build Coastguard Worker     q = vp9_rc_regulate_q(cpi, rc->this_frame_target, active_best_quality,
1579*fb1b10abSAndroid Build Coastguard Worker                           active_worst_quality);
1580*fb1b10abSAndroid Build Coastguard Worker     if (q > active_worst_quality) {
1581*fb1b10abSAndroid Build Coastguard Worker       // Special case when we are targeting the max allowed rate.
1582*fb1b10abSAndroid Build Coastguard Worker       if (rc->this_frame_target >= rc->max_frame_bandwidth)
1583*fb1b10abSAndroid Build Coastguard Worker         active_worst_quality = q;
1584*fb1b10abSAndroid Build Coastguard Worker       else
1585*fb1b10abSAndroid Build Coastguard Worker         q = active_worst_quality;
1586*fb1b10abSAndroid Build Coastguard Worker     }
1587*fb1b10abSAndroid Build Coastguard Worker   }
1588*fb1b10abSAndroid Build Coastguard Worker 
1589*fb1b10abSAndroid Build Coastguard Worker   *top_index = active_worst_quality;
1590*fb1b10abSAndroid Build Coastguard Worker   *bottom_index = active_best_quality;
1591*fb1b10abSAndroid Build Coastguard Worker 
1592*fb1b10abSAndroid Build Coastguard Worker   assert(*top_index <= rc->worst_quality && *top_index >= rc->best_quality);
1593*fb1b10abSAndroid Build Coastguard Worker   assert(*bottom_index <= rc->worst_quality &&
1594*fb1b10abSAndroid Build Coastguard Worker          *bottom_index >= rc->best_quality);
1595*fb1b10abSAndroid Build Coastguard Worker   assert(q <= rc->worst_quality && q >= rc->best_quality);
1596*fb1b10abSAndroid Build Coastguard Worker   return q;
1597*fb1b10abSAndroid Build Coastguard Worker }
1598*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_pick_q_and_bounds(const VP9_COMP * cpi,int * bottom_index,int * top_index)1599*fb1b10abSAndroid Build Coastguard Worker int vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi, int *bottom_index,
1600*fb1b10abSAndroid Build Coastguard Worker                              int *top_index) {
1601*fb1b10abSAndroid Build Coastguard Worker   int q;
1602*fb1b10abSAndroid Build Coastguard Worker   const int gf_group_index = cpi->twopass.gf_group.index;
1603*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.pass == 0) {
1604*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_CBR)
1605*fb1b10abSAndroid Build Coastguard Worker       q = rc_pick_q_and_bounds_one_pass_cbr(cpi, bottom_index, top_index);
1606*fb1b10abSAndroid Build Coastguard Worker     else
1607*fb1b10abSAndroid Build Coastguard Worker       q = rc_pick_q_and_bounds_one_pass_vbr(cpi, bottom_index, top_index);
1608*fb1b10abSAndroid Build Coastguard Worker   } else {
1609*fb1b10abSAndroid Build Coastguard Worker     q = vp9_rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index,
1610*fb1b10abSAndroid Build Coastguard Worker                                           gf_group_index);
1611*fb1b10abSAndroid Build Coastguard Worker   }
1612*fb1b10abSAndroid Build Coastguard Worker   if (cpi->sf.use_nonrd_pick_mode) {
1613*fb1b10abSAndroid Build Coastguard Worker     if (cpi->sf.force_frame_boost == 1) q -= cpi->sf.max_delta_qindex;
1614*fb1b10abSAndroid Build Coastguard Worker 
1615*fb1b10abSAndroid Build Coastguard Worker     if (q < *bottom_index)
1616*fb1b10abSAndroid Build Coastguard Worker       *bottom_index = q;
1617*fb1b10abSAndroid Build Coastguard Worker     else if (q > *top_index)
1618*fb1b10abSAndroid Build Coastguard Worker       *top_index = q;
1619*fb1b10abSAndroid Build Coastguard Worker   }
1620*fb1b10abSAndroid Build Coastguard Worker   return q;
1621*fb1b10abSAndroid Build Coastguard Worker }
1622*fb1b10abSAndroid Build Coastguard Worker 
vp9_configure_buffer_updates(VP9_COMP * cpi,int gf_group_index)1623*fb1b10abSAndroid Build Coastguard Worker void vp9_configure_buffer_updates(VP9_COMP *cpi, int gf_group_index) {
1624*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
1625*fb1b10abSAndroid Build Coastguard Worker   TWO_PASS *const twopass = &cpi->twopass;
1626*fb1b10abSAndroid Build Coastguard Worker 
1627*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.is_src_frame_alt_ref = 0;
1628*fb1b10abSAndroid Build Coastguard Worker   cm->show_existing_frame = 0;
1629*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.show_arf_as_gld = 0;
1630*fb1b10abSAndroid Build Coastguard Worker   switch (twopass->gf_group.update_type[gf_group_index]) {
1631*fb1b10abSAndroid Build Coastguard Worker     case KF_UPDATE:
1632*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 1;
1633*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 1;
1634*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 1;
1635*fb1b10abSAndroid Build Coastguard Worker       break;
1636*fb1b10abSAndroid Build Coastguard Worker     case LF_UPDATE:
1637*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 1;
1638*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 0;
1639*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 0;
1640*fb1b10abSAndroid Build Coastguard Worker       break;
1641*fb1b10abSAndroid Build Coastguard Worker     case GF_UPDATE:
1642*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 1;
1643*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 1;
1644*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 0;
1645*fb1b10abSAndroid Build Coastguard Worker       break;
1646*fb1b10abSAndroid Build Coastguard Worker     case OVERLAY_UPDATE:
1647*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 0;
1648*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 1;
1649*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 0;
1650*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.is_src_frame_alt_ref = 1;
1651*fb1b10abSAndroid Build Coastguard Worker       if (cpi->rc.preserve_arf_as_gld) {
1652*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.show_arf_as_gld = 1;
1653*fb1b10abSAndroid Build Coastguard Worker         cpi->refresh_golden_frame = 0;
1654*fb1b10abSAndroid Build Coastguard Worker         cm->show_existing_frame = 1;
1655*fb1b10abSAndroid Build Coastguard Worker         cm->refresh_frame_context = 0;
1656*fb1b10abSAndroid Build Coastguard Worker       }
1657*fb1b10abSAndroid Build Coastguard Worker       break;
1658*fb1b10abSAndroid Build Coastguard Worker     case MID_OVERLAY_UPDATE:
1659*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 1;
1660*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 0;
1661*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 0;
1662*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.is_src_frame_alt_ref = 1;
1663*fb1b10abSAndroid Build Coastguard Worker       break;
1664*fb1b10abSAndroid Build Coastguard Worker     case USE_BUF_FRAME:
1665*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 0;
1666*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 0;
1667*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 0;
1668*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.is_src_frame_alt_ref = 1;
1669*fb1b10abSAndroid Build Coastguard Worker       cm->show_existing_frame = 1;
1670*fb1b10abSAndroid Build Coastguard Worker       cm->refresh_frame_context = 0;
1671*fb1b10abSAndroid Build Coastguard Worker       break;
1672*fb1b10abSAndroid Build Coastguard Worker     default:
1673*fb1b10abSAndroid Build Coastguard Worker       assert(twopass->gf_group.update_type[gf_group_index] == ARF_UPDATE);
1674*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_last_frame = 0;
1675*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 0;
1676*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_alt_ref_frame = 1;
1677*fb1b10abSAndroid Build Coastguard Worker       break;
1678*fb1b10abSAndroid Build Coastguard Worker   }
1679*fb1b10abSAndroid Build Coastguard Worker }
1680*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_compute_frame_size_bounds(const VP9_COMP * cpi,int frame_target,int * frame_under_shoot_limit,int * frame_over_shoot_limit)1681*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi, int frame_target,
1682*fb1b10abSAndroid Build Coastguard Worker                                       int *frame_under_shoot_limit,
1683*fb1b10abSAndroid Build Coastguard Worker                                       int *frame_over_shoot_limit) {
1684*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.rc_mode == VPX_Q) {
1685*fb1b10abSAndroid Build Coastguard Worker     *frame_under_shoot_limit = 0;
1686*fb1b10abSAndroid Build Coastguard Worker     *frame_over_shoot_limit = INT_MAX;
1687*fb1b10abSAndroid Build Coastguard Worker   } else {
1688*fb1b10abSAndroid Build Coastguard Worker     // For very small rate targets where the fractional adjustment
1689*fb1b10abSAndroid Build Coastguard Worker     // may be tiny make sure there is at least a minimum range.
1690*fb1b10abSAndroid Build Coastguard Worker     const int tol_low =
1691*fb1b10abSAndroid Build Coastguard Worker         (int)(((int64_t)cpi->sf.recode_tolerance_low * frame_target) / 100);
1692*fb1b10abSAndroid Build Coastguard Worker     const int tol_high =
1693*fb1b10abSAndroid Build Coastguard Worker         (int)(((int64_t)cpi->sf.recode_tolerance_high * frame_target) / 100);
1694*fb1b10abSAndroid Build Coastguard Worker     *frame_under_shoot_limit = VPXMAX(frame_target - tol_low - 100, 0);
1695*fb1b10abSAndroid Build Coastguard Worker     *frame_over_shoot_limit =
1696*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(frame_target + tol_high + 100, cpi->rc.max_frame_bandwidth);
1697*fb1b10abSAndroid Build Coastguard Worker   }
1698*fb1b10abSAndroid Build Coastguard Worker }
1699*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_set_frame_target(VP9_COMP * cpi,int target)1700*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_set_frame_target(VP9_COMP *cpi, int target) {
1701*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1702*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
1703*fb1b10abSAndroid Build Coastguard Worker 
1704*fb1b10abSAndroid Build Coastguard Worker   rc->this_frame_target = target;
1705*fb1b10abSAndroid Build Coastguard Worker 
1706*fb1b10abSAndroid Build Coastguard Worker   // Modify frame size target when down-scaling.
1707*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC &&
1708*fb1b10abSAndroid Build Coastguard Worker       rc->frame_size_selector != UNSCALED) {
1709*fb1b10abSAndroid Build Coastguard Worker     rc->this_frame_target = (int)(rc->this_frame_target *
1710*fb1b10abSAndroid Build Coastguard Worker                                   rate_thresh_mult[rc->frame_size_selector]);
1711*fb1b10abSAndroid Build Coastguard Worker   }
1712*fb1b10abSAndroid Build Coastguard Worker 
1713*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
1714*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.use_simple_encode_api) {
1715*fb1b10abSAndroid Build Coastguard Worker     if (cpi->encode_command.use_external_target_frame_bits) {
1716*fb1b10abSAndroid Build Coastguard Worker       rc->this_frame_target = cpi->encode_command.target_frame_bits;
1717*fb1b10abSAndroid Build Coastguard Worker     }
1718*fb1b10abSAndroid Build Coastguard Worker   }
1719*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
1720*fb1b10abSAndroid Build Coastguard Worker 
1721*fb1b10abSAndroid Build Coastguard Worker   // Target rate per SB64 (including partial SB64s.
1722*fb1b10abSAndroid Build Coastguard Worker   const int64_t sb64_target_rate =
1723*fb1b10abSAndroid Build Coastguard Worker       ((int64_t)rc->this_frame_target * 64 * 64) / (cm->width * cm->height);
1724*fb1b10abSAndroid Build Coastguard Worker   rc->sb64_target_rate = (int)VPXMIN(sb64_target_rate, INT_MAX);
1725*fb1b10abSAndroid Build Coastguard Worker }
1726*fb1b10abSAndroid Build Coastguard Worker 
update_alt_ref_frame_stats(VP9_COMP * cpi)1727*fb1b10abSAndroid Build Coastguard Worker static void update_alt_ref_frame_stats(VP9_COMP *cpi) {
1728*fb1b10abSAndroid Build Coastguard Worker   // this frame refreshes means next frames don't unless specified by user
1729*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
1730*fb1b10abSAndroid Build Coastguard Worker   rc->frames_since_golden = 0;
1731*fb1b10abSAndroid Build Coastguard Worker 
1732*fb1b10abSAndroid Build Coastguard Worker   // Mark the alt ref as done (setting to 0 means no further alt refs pending).
1733*fb1b10abSAndroid Build Coastguard Worker   rc->source_alt_ref_pending = 0;
1734*fb1b10abSAndroid Build Coastguard Worker 
1735*fb1b10abSAndroid Build Coastguard Worker   // Set the alternate reference frame active flag
1736*fb1b10abSAndroid Build Coastguard Worker   rc->source_alt_ref_active = 1;
1737*fb1b10abSAndroid Build Coastguard Worker }
1738*fb1b10abSAndroid Build Coastguard Worker 
update_golden_frame_stats(VP9_COMP * cpi)1739*fb1b10abSAndroid Build Coastguard Worker static void update_golden_frame_stats(VP9_COMP *cpi) {
1740*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
1741*fb1b10abSAndroid Build Coastguard Worker 
1742*fb1b10abSAndroid Build Coastguard Worker   // Update the Golden frame usage counts.
1743*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_golden_frame) {
1744*fb1b10abSAndroid Build Coastguard Worker     // this frame refreshes means next frames don't unless specified by user
1745*fb1b10abSAndroid Build Coastguard Worker     rc->frames_since_golden = 0;
1746*fb1b10abSAndroid Build Coastguard Worker 
1747*fb1b10abSAndroid Build Coastguard Worker     // If we are not using alt ref in the up and coming group clear the arf
1748*fb1b10abSAndroid Build Coastguard Worker     // active flag. In multi arf group case, if the index is not 0 then
1749*fb1b10abSAndroid Build Coastguard Worker     // we are overlaying a mid group arf so should not reset the flag.
1750*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.pass == 2) {
1751*fb1b10abSAndroid Build Coastguard Worker       if (!rc->source_alt_ref_pending && (cpi->twopass.gf_group.index == 0))
1752*fb1b10abSAndroid Build Coastguard Worker         rc->source_alt_ref_active = 0;
1753*fb1b10abSAndroid Build Coastguard Worker     } else if (!rc->source_alt_ref_pending) {
1754*fb1b10abSAndroid Build Coastguard Worker       rc->source_alt_ref_active = 0;
1755*fb1b10abSAndroid Build Coastguard Worker     }
1756*fb1b10abSAndroid Build Coastguard Worker 
1757*fb1b10abSAndroid Build Coastguard Worker     // Decrement count down till next gf
1758*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
1759*fb1b10abSAndroid Build Coastguard Worker 
1760*fb1b10abSAndroid Build Coastguard Worker   } else if (!cpi->refresh_alt_ref_frame) {
1761*fb1b10abSAndroid Build Coastguard Worker     // Decrement count down till next gf
1762*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
1763*fb1b10abSAndroid Build Coastguard Worker 
1764*fb1b10abSAndroid Build Coastguard Worker     rc->frames_since_golden++;
1765*fb1b10abSAndroid Build Coastguard Worker 
1766*fb1b10abSAndroid Build Coastguard Worker     if (rc->show_arf_as_gld) {
1767*fb1b10abSAndroid Build Coastguard Worker       rc->frames_since_golden = 0;
1768*fb1b10abSAndroid Build Coastguard Worker       // If we are not using alt ref in the up and coming group clear the arf
1769*fb1b10abSAndroid Build Coastguard Worker       // active flag. In multi arf group case, if the index is not 0 then
1770*fb1b10abSAndroid Build Coastguard Worker       // we are overlaying a mid group arf so should not reset the flag.
1771*fb1b10abSAndroid Build Coastguard Worker       if (!rc->source_alt_ref_pending && (cpi->twopass.gf_group.index == 0))
1772*fb1b10abSAndroid Build Coastguard Worker         rc->source_alt_ref_active = 0;
1773*fb1b10abSAndroid Build Coastguard Worker     }
1774*fb1b10abSAndroid Build Coastguard Worker   }
1775*fb1b10abSAndroid Build Coastguard Worker }
1776*fb1b10abSAndroid Build Coastguard Worker 
update_altref_usage(VP9_COMP * const cpi)1777*fb1b10abSAndroid Build Coastguard Worker static void update_altref_usage(VP9_COMP *const cpi) {
1778*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1779*fb1b10abSAndroid Build Coastguard Worker   int sum_ref_frame_usage = 0;
1780*fb1b10abSAndroid Build Coastguard Worker   int arf_frame_usage = 0;
1781*fb1b10abSAndroid Build Coastguard Worker   int mi_row, mi_col;
1782*fb1b10abSAndroid Build Coastguard Worker   if (cpi->rc.alt_ref_gf_group && !cpi->rc.is_src_frame_alt_ref &&
1783*fb1b10abSAndroid Build Coastguard Worker       !cpi->refresh_golden_frame && !cpi->refresh_alt_ref_frame)
1784*fb1b10abSAndroid Build Coastguard Worker     for (mi_row = 0; mi_row < cm->mi_rows; mi_row += 8) {
1785*fb1b10abSAndroid Build Coastguard Worker       for (mi_col = 0; mi_col < cm->mi_cols; mi_col += 8) {
1786*fb1b10abSAndroid Build Coastguard Worker         int sboffset = ((cm->mi_cols + 7) >> 3) * (mi_row >> 3) + (mi_col >> 3);
1787*fb1b10abSAndroid Build Coastguard Worker         sum_ref_frame_usage += cpi->count_arf_frame_usage[sboffset] +
1788*fb1b10abSAndroid Build Coastguard Worker                                cpi->count_lastgolden_frame_usage[sboffset];
1789*fb1b10abSAndroid Build Coastguard Worker         arf_frame_usage += cpi->count_arf_frame_usage[sboffset];
1790*fb1b10abSAndroid Build Coastguard Worker       }
1791*fb1b10abSAndroid Build Coastguard Worker     }
1792*fb1b10abSAndroid Build Coastguard Worker   if (sum_ref_frame_usage > 0) {
1793*fb1b10abSAndroid Build Coastguard Worker     double altref_count = 100.0 * arf_frame_usage / sum_ref_frame_usage;
1794*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.perc_arf_usage =
1795*fb1b10abSAndroid Build Coastguard Worker         0.75 * cpi->rc.perc_arf_usage + 0.25 * altref_count;
1796*fb1b10abSAndroid Build Coastguard Worker   }
1797*fb1b10abSAndroid Build Coastguard Worker }
1798*fb1b10abSAndroid Build Coastguard Worker 
vp9_compute_frame_low_motion(VP9_COMP * const cpi)1799*fb1b10abSAndroid Build Coastguard Worker void vp9_compute_frame_low_motion(VP9_COMP *const cpi) {
1800*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
1801*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
1802*fb1b10abSAndroid Build Coastguard Worker   int mi_row, mi_col;
1803*fb1b10abSAndroid Build Coastguard Worker   MODE_INFO **mi = cm->mi_grid_visible;
1804*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
1805*fb1b10abSAndroid Build Coastguard Worker   const int rows = cm->mi_rows, cols = cm->mi_cols;
1806*fb1b10abSAndroid Build Coastguard Worker   int cnt_zeromv = 0;
1807*fb1b10abSAndroid Build Coastguard Worker   for (mi_row = 0; mi_row < rows; mi_row++) {
1808*fb1b10abSAndroid Build Coastguard Worker     for (mi_col = 0; mi_col < cols; mi_col++) {
1809*fb1b10abSAndroid Build Coastguard Worker       if (mi[0]->ref_frame[0] == LAST_FRAME &&
1810*fb1b10abSAndroid Build Coastguard Worker           abs(mi[0]->mv[0].as_mv.row) < 16 && abs(mi[0]->mv[0].as_mv.col) < 16)
1811*fb1b10abSAndroid Build Coastguard Worker         cnt_zeromv++;
1812*fb1b10abSAndroid Build Coastguard Worker       mi++;
1813*fb1b10abSAndroid Build Coastguard Worker     }
1814*fb1b10abSAndroid Build Coastguard Worker     mi += 8;
1815*fb1b10abSAndroid Build Coastguard Worker   }
1816*fb1b10abSAndroid Build Coastguard Worker   cnt_zeromv = 100 * cnt_zeromv / (rows * cols);
1817*fb1b10abSAndroid Build Coastguard Worker   rc->avg_frame_low_motion = (3 * rc->avg_frame_low_motion + cnt_zeromv) >> 2;
1818*fb1b10abSAndroid Build Coastguard Worker 
1819*fb1b10abSAndroid Build Coastguard Worker   // For SVC: set avg_frame_low_motion (only computed on top spatial layer)
1820*fb1b10abSAndroid Build Coastguard Worker   // to all lower spatial layers.
1821*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && svc->spatial_layer_id == svc->number_spatial_layers - 1) {
1822*fb1b10abSAndroid Build Coastguard Worker     int i;
1823*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < svc->number_spatial_layers - 1; ++i) {
1824*fb1b10abSAndroid Build Coastguard Worker       const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id,
1825*fb1b10abSAndroid Build Coastguard Worker                                          svc->number_temporal_layers);
1826*fb1b10abSAndroid Build Coastguard Worker       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
1827*fb1b10abSAndroid Build Coastguard Worker       RATE_CONTROL *const lrc = &lc->rc;
1828*fb1b10abSAndroid Build Coastguard Worker       lrc->avg_frame_low_motion = rc->avg_frame_low_motion;
1829*fb1b10abSAndroid Build Coastguard Worker     }
1830*fb1b10abSAndroid Build Coastguard Worker   }
1831*fb1b10abSAndroid Build Coastguard Worker }
1832*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_postencode_update(VP9_COMP * cpi,uint64_t bytes_used)1833*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
1834*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
1835*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1836*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
1837*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
1838*fb1b10abSAndroid Build Coastguard Worker   const int qindex = cm->base_qindex;
1839*fb1b10abSAndroid Build Coastguard Worker   const GF_GROUP *gf_group = &cpi->twopass.gf_group;
1840*fb1b10abSAndroid Build Coastguard Worker   const int gf_group_index = cpi->twopass.gf_group.index;
1841*fb1b10abSAndroid Build Coastguard Worker   const int layer_depth = gf_group->layer_depth[gf_group_index];
1842*fb1b10abSAndroid Build Coastguard Worker 
1843*fb1b10abSAndroid Build Coastguard Worker   // Update rate control heuristics
1844*fb1b10abSAndroid Build Coastguard Worker   rc->projected_frame_size = (int)(bytes_used << 3);
1845*fb1b10abSAndroid Build Coastguard Worker 
1846*fb1b10abSAndroid Build Coastguard Worker   // Post encode loop adjustment of Q prediction.
1847*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_update_rate_correction_factors(cpi);
1848*fb1b10abSAndroid Build Coastguard Worker 
1849*fb1b10abSAndroid Build Coastguard Worker   // Keep a record of last Q and ambient average Q.
1850*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) {
1851*fb1b10abSAndroid Build Coastguard Worker     rc->last_q[KEY_FRAME] = qindex;
1852*fb1b10abSAndroid Build Coastguard Worker     rc->avg_frame_qindex[KEY_FRAME] =
1853*fb1b10abSAndroid Build Coastguard Worker         ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2);
1854*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
1855*fb1b10abSAndroid Build Coastguard Worker       int i;
1856*fb1b10abSAndroid Build Coastguard Worker       for (i = 0; i < svc->number_temporal_layers; ++i) {
1857*fb1b10abSAndroid Build Coastguard Worker         const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i,
1858*fb1b10abSAndroid Build Coastguard Worker                                            svc->number_temporal_layers);
1859*fb1b10abSAndroid Build Coastguard Worker         LAYER_CONTEXT *lc = &svc->layer_context[layer];
1860*fb1b10abSAndroid Build Coastguard Worker         RATE_CONTROL *lrc = &lc->rc;
1861*fb1b10abSAndroid Build Coastguard Worker         lrc->last_q[KEY_FRAME] = rc->last_q[KEY_FRAME];
1862*fb1b10abSAndroid Build Coastguard Worker         lrc->avg_frame_qindex[KEY_FRAME] = rc->avg_frame_qindex[KEY_FRAME];
1863*fb1b10abSAndroid Build Coastguard Worker       }
1864*fb1b10abSAndroid Build Coastguard Worker     }
1865*fb1b10abSAndroid Build Coastguard Worker   } else {
1866*fb1b10abSAndroid Build Coastguard Worker     if ((cpi->use_svc) ||
1867*fb1b10abSAndroid Build Coastguard Worker         (!rc->is_src_frame_alt_ref &&
1868*fb1b10abSAndroid Build Coastguard Worker          !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))) {
1869*fb1b10abSAndroid Build Coastguard Worker       rc->last_q[INTER_FRAME] = qindex;
1870*fb1b10abSAndroid Build Coastguard Worker       rc->avg_frame_qindex[INTER_FRAME] =
1871*fb1b10abSAndroid Build Coastguard Worker           ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2);
1872*fb1b10abSAndroid Build Coastguard Worker       rc->ni_frames++;
1873*fb1b10abSAndroid Build Coastguard Worker       rc->tot_q += vp9_convert_qindex_to_q(qindex, cm->bit_depth);
1874*fb1b10abSAndroid Build Coastguard Worker       rc->avg_q = rc->tot_q / rc->ni_frames;
1875*fb1b10abSAndroid Build Coastguard Worker       // Calculate the average Q for normal inter frames (not key or GFU
1876*fb1b10abSAndroid Build Coastguard Worker       // frames).
1877*fb1b10abSAndroid Build Coastguard Worker       rc->ni_tot_qi += qindex;
1878*fb1b10abSAndroid Build Coastguard Worker       rc->ni_av_qi = rc->ni_tot_qi / rc->ni_frames;
1879*fb1b10abSAndroid Build Coastguard Worker     }
1880*fb1b10abSAndroid Build Coastguard Worker   }
1881*fb1b10abSAndroid Build Coastguard Worker 
1882*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) vp9_svc_adjust_avg_frame_qindex(cpi);
1883*fb1b10abSAndroid Build Coastguard Worker 
1884*fb1b10abSAndroid Build Coastguard Worker   // Keep record of last boosted (KF/KF/ARF) Q value.
1885*fb1b10abSAndroid Build Coastguard Worker   // If the current frame is coded at a lower Q then we also update it.
1886*fb1b10abSAndroid Build Coastguard Worker   // If all mbs in this group are skipped only update if the Q value is
1887*fb1b10abSAndroid Build Coastguard Worker   // better than that already stored.
1888*fb1b10abSAndroid Build Coastguard Worker   // This is used to help set quality in forced key frames to reduce popping
1889*fb1b10abSAndroid Build Coastguard Worker   if ((qindex < rc->last_boosted_qindex) || (cm->frame_type == KEY_FRAME) ||
1890*fb1b10abSAndroid Build Coastguard Worker       (!rc->constrained_gf_group &&
1891*fb1b10abSAndroid Build Coastguard Worker        (cpi->refresh_alt_ref_frame ||
1892*fb1b10abSAndroid Build Coastguard Worker         (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) {
1893*fb1b10abSAndroid Build Coastguard Worker     rc->last_boosted_qindex = qindex;
1894*fb1b10abSAndroid Build Coastguard Worker   }
1895*fb1b10abSAndroid Build Coastguard Worker 
1896*fb1b10abSAndroid Build Coastguard Worker   if ((qindex < cpi->twopass.last_qindex_of_arf_layer[layer_depth]) ||
1897*fb1b10abSAndroid Build Coastguard Worker       (cm->frame_type == KEY_FRAME) ||
1898*fb1b10abSAndroid Build Coastguard Worker       (!rc->constrained_gf_group &&
1899*fb1b10abSAndroid Build Coastguard Worker        (cpi->refresh_alt_ref_frame ||
1900*fb1b10abSAndroid Build Coastguard Worker         (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) {
1901*fb1b10abSAndroid Build Coastguard Worker     cpi->twopass.last_qindex_of_arf_layer[layer_depth] = qindex;
1902*fb1b10abSAndroid Build Coastguard Worker   }
1903*fb1b10abSAndroid Build Coastguard Worker 
1904*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) rc->last_kf_qindex = qindex;
1905*fb1b10abSAndroid Build Coastguard Worker 
1906*fb1b10abSAndroid Build Coastguard Worker   update_buffer_level_postencode(cpi, rc->projected_frame_size);
1907*fb1b10abSAndroid Build Coastguard Worker 
1908*fb1b10abSAndroid Build Coastguard Worker   // Rolling monitors of whether we are over or underspending used to help
1909*fb1b10abSAndroid Build Coastguard Worker   // regulate min and Max Q in two pass.
1910*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm)) {
1911*fb1b10abSAndroid Build Coastguard Worker     rc->rolling_target_bits = (int)ROUND64_POWER_OF_TWO(
1912*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->rolling_target_bits * 3 + rc->this_frame_target, 2);
1913*fb1b10abSAndroid Build Coastguard Worker     rc->rolling_actual_bits = (int)ROUND64_POWER_OF_TWO(
1914*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->rolling_actual_bits * 3 + rc->projected_frame_size, 2);
1915*fb1b10abSAndroid Build Coastguard Worker     rc->long_rolling_target_bits = (int)ROUND64_POWER_OF_TWO(
1916*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->long_rolling_target_bits * 31 + rc->this_frame_target, 5);
1917*fb1b10abSAndroid Build Coastguard Worker     rc->long_rolling_actual_bits = (int)ROUND64_POWER_OF_TWO(
1918*fb1b10abSAndroid Build Coastguard Worker         (int64_t)rc->long_rolling_actual_bits * 31 + rc->projected_frame_size,
1919*fb1b10abSAndroid Build Coastguard Worker         5);
1920*fb1b10abSAndroid Build Coastguard Worker   }
1921*fb1b10abSAndroid Build Coastguard Worker 
1922*fb1b10abSAndroid Build Coastguard Worker   // Actual bits spent
1923*fb1b10abSAndroid Build Coastguard Worker   rc->total_actual_bits += rc->projected_frame_size;
1924*fb1b10abSAndroid Build Coastguard Worker   rc->total_target_bits += cm->show_frame ? rc->avg_frame_bandwidth : 0;
1925*fb1b10abSAndroid Build Coastguard Worker 
1926*fb1b10abSAndroid Build Coastguard Worker   rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
1927*fb1b10abSAndroid Build Coastguard Worker 
1928*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->use_svc) {
1929*fb1b10abSAndroid Build Coastguard Worker     if (is_altref_enabled(cpi) && cpi->refresh_alt_ref_frame &&
1930*fb1b10abSAndroid Build Coastguard Worker         (!frame_is_intra_only(cm)))
1931*fb1b10abSAndroid Build Coastguard Worker       // Update the alternate reference frame stats as appropriate.
1932*fb1b10abSAndroid Build Coastguard Worker       update_alt_ref_frame_stats(cpi);
1933*fb1b10abSAndroid Build Coastguard Worker     else
1934*fb1b10abSAndroid Build Coastguard Worker       // Update the Golden frame stats as appropriate.
1935*fb1b10abSAndroid Build Coastguard Worker       update_golden_frame_stats(cpi);
1936*fb1b10abSAndroid Build Coastguard Worker   }
1937*fb1b10abSAndroid Build Coastguard Worker 
1938*fb1b10abSAndroid Build Coastguard Worker   // If second (long term) temporal reference is used for SVC,
1939*fb1b10abSAndroid Build Coastguard Worker   // update the golden frame counter, only for base temporal layer.
1940*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && svc->use_gf_temporal_ref_current_layer &&
1941*fb1b10abSAndroid Build Coastguard Worker       svc->temporal_layer_id == 0) {
1942*fb1b10abSAndroid Build Coastguard Worker     int i = 0;
1943*fb1b10abSAndroid Build Coastguard Worker     if (cpi->refresh_golden_frame)
1944*fb1b10abSAndroid Build Coastguard Worker       rc->frames_since_golden = 0;
1945*fb1b10abSAndroid Build Coastguard Worker     else
1946*fb1b10abSAndroid Build Coastguard Worker       rc->frames_since_golden++;
1947*fb1b10abSAndroid Build Coastguard Worker     // Decrement count down till next gf
1948*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_till_gf_update_due > 0) rc->frames_till_gf_update_due--;
1949*fb1b10abSAndroid Build Coastguard Worker     // Update the frames_since_golden for all upper temporal layers.
1950*fb1b10abSAndroid Build Coastguard Worker     for (i = 1; i < svc->number_temporal_layers; ++i) {
1951*fb1b10abSAndroid Build Coastguard Worker       const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i,
1952*fb1b10abSAndroid Build Coastguard Worker                                          svc->number_temporal_layers);
1953*fb1b10abSAndroid Build Coastguard Worker       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
1954*fb1b10abSAndroid Build Coastguard Worker       RATE_CONTROL *const lrc = &lc->rc;
1955*fb1b10abSAndroid Build Coastguard Worker       lrc->frames_since_golden = rc->frames_since_golden;
1956*fb1b10abSAndroid Build Coastguard Worker     }
1957*fb1b10abSAndroid Build Coastguard Worker   }
1958*fb1b10abSAndroid Build Coastguard Worker 
1959*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm)) rc->frames_since_key = 0;
1960*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) {
1961*fb1b10abSAndroid Build Coastguard Worker     rc->frames_since_key++;
1962*fb1b10abSAndroid Build Coastguard Worker     rc->frames_to_key--;
1963*fb1b10abSAndroid Build Coastguard Worker   }
1964*fb1b10abSAndroid Build Coastguard Worker 
1965*fb1b10abSAndroid Build Coastguard Worker   // Trigger the resizing of the next frame if it is scaled.
1966*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass != 0) {
1967*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_pending =
1968*fb1b10abSAndroid Build Coastguard Worker         rc->next_frame_size_selector != rc->frame_size_selector;
1969*fb1b10abSAndroid Build Coastguard Worker     rc->frame_size_selector = rc->next_frame_size_selector;
1970*fb1b10abSAndroid Build Coastguard Worker   }
1971*fb1b10abSAndroid Build Coastguard Worker 
1972*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->pass == 0) {
1973*fb1b10abSAndroid Build Coastguard Worker     if (!frame_is_intra_only(cm))
1974*fb1b10abSAndroid Build Coastguard Worker       if (cpi->sf.use_altref_onepass) update_altref_usage(cpi);
1975*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.last_frame_is_src_altref = cpi->rc.is_src_frame_alt_ref;
1976*fb1b10abSAndroid Build Coastguard Worker   }
1977*fb1b10abSAndroid Build Coastguard Worker 
1978*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_intra_only(cm)) rc->reset_high_source_sad = 0;
1979*fb1b10abSAndroid Build Coastguard Worker 
1980*fb1b10abSAndroid Build Coastguard Worker   rc->last_avg_frame_bandwidth = rc->avg_frame_bandwidth;
1981*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && svc->spatial_layer_id < svc->number_spatial_layers - 1)
1982*fb1b10abSAndroid Build Coastguard Worker     svc->lower_layer_qindex = cm->base_qindex;
1983*fb1b10abSAndroid Build Coastguard Worker   cpi->deadline_mode_previous_frame = cpi->oxcf.mode;
1984*fb1b10abSAndroid Build Coastguard Worker }
1985*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_postencode_update_drop_frame(VP9_COMP * cpi)1986*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) {
1987*fb1b10abSAndroid Build Coastguard Worker   cpi->common.current_video_frame++;
1988*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.frames_since_key++;
1989*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.frames_to_key--;
1990*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.rc_2_frame = 0;
1991*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.rc_1_frame = 0;
1992*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.last_avg_frame_bandwidth = cpi->rc.avg_frame_bandwidth;
1993*fb1b10abSAndroid Build Coastguard Worker   cpi->rc.last_q[INTER_FRAME] = cpi->common.base_qindex;
1994*fb1b10abSAndroid Build Coastguard Worker   // For SVC on dropped frame when framedrop_mode != LAYER_DROP:
1995*fb1b10abSAndroid Build Coastguard Worker   // in this mode the whole superframe may be dropped if only a single layer
1996*fb1b10abSAndroid Build Coastguard Worker   // has buffer underflow (below threshold). Since this can then lead to
1997*fb1b10abSAndroid Build Coastguard Worker   // increasing buffer levels/overflow for certain layers even though whole
1998*fb1b10abSAndroid Build Coastguard Worker   // superframe is dropped, we cap buffer level if its already stable.
1999*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc && cpi->svc.framedrop_mode != LAYER_DROP &&
2000*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.buffer_level > cpi->rc.optimal_buffer_level) {
2001*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.buffer_level = cpi->rc.optimal_buffer_level;
2002*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.bits_off_target = cpi->rc.optimal_buffer_level;
2003*fb1b10abSAndroid Build Coastguard Worker   }
2004*fb1b10abSAndroid Build Coastguard Worker   cpi->deadline_mode_previous_frame = cpi->oxcf.mode;
2005*fb1b10abSAndroid Build Coastguard Worker }
2006*fb1b10abSAndroid Build Coastguard Worker 
vp9_calc_pframe_target_size_one_pass_vbr(const VP9_COMP * cpi)2007*fb1b10abSAndroid Build Coastguard Worker int vp9_calc_pframe_target_size_one_pass_vbr(const VP9_COMP *cpi) {
2008*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *const rc = &cpi->rc;
2009*fb1b10abSAndroid Build Coastguard Worker   const int af_ratio = rc->af_ratio_onepass_vbr;
2010*fb1b10abSAndroid Build Coastguard Worker   int64_t target =
2011*fb1b10abSAndroid Build Coastguard Worker       (!rc->is_src_frame_alt_ref &&
2012*fb1b10abSAndroid Build Coastguard Worker        (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame))
2013*fb1b10abSAndroid Build Coastguard Worker           ? ((int64_t)rc->avg_frame_bandwidth * rc->baseline_gf_interval *
2014*fb1b10abSAndroid Build Coastguard Worker              af_ratio) /
2015*fb1b10abSAndroid Build Coastguard Worker                 (rc->baseline_gf_interval + af_ratio - 1)
2016*fb1b10abSAndroid Build Coastguard Worker           : ((int64_t)rc->avg_frame_bandwidth * rc->baseline_gf_interval) /
2017*fb1b10abSAndroid Build Coastguard Worker                 (rc->baseline_gf_interval + af_ratio - 1);
2018*fb1b10abSAndroid Build Coastguard Worker   // For SVC: refresh flags are used to define the pattern, so we can't
2019*fb1b10abSAndroid Build Coastguard Worker   // use that for boosting the target size here.
2020*fb1b10abSAndroid Build Coastguard Worker   // TODO(marpan): Consider adding internal boost on TL0 for VBR-SVC.
2021*fb1b10abSAndroid Build Coastguard Worker   // For now just use the CBR logic for setting target size.
2022*fb1b10abSAndroid Build Coastguard Worker   if (cpi->use_svc) target = vp9_calc_pframe_target_size_one_pass_cbr(cpi);
2023*fb1b10abSAndroid Build Coastguard Worker   if (target > INT_MAX) target = INT_MAX;
2024*fb1b10abSAndroid Build Coastguard Worker   return vp9_rc_clamp_pframe_target_size(cpi, (int)target);
2025*fb1b10abSAndroid Build Coastguard Worker }
2026*fb1b10abSAndroid Build Coastguard Worker 
vp9_calc_iframe_target_size_one_pass_vbr(const VP9_COMP * cpi)2027*fb1b10abSAndroid Build Coastguard Worker int vp9_calc_iframe_target_size_one_pass_vbr(const VP9_COMP *cpi) {
2028*fb1b10abSAndroid Build Coastguard Worker   static const int kf_ratio = 25;
2029*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
2030*fb1b10abSAndroid Build Coastguard Worker   int target = rc->avg_frame_bandwidth;
2031*fb1b10abSAndroid Build Coastguard Worker   if (target > INT_MAX / kf_ratio)
2032*fb1b10abSAndroid Build Coastguard Worker     target = INT_MAX;
2033*fb1b10abSAndroid Build Coastguard Worker   else
2034*fb1b10abSAndroid Build Coastguard Worker     target = rc->avg_frame_bandwidth * kf_ratio;
2035*fb1b10abSAndroid Build Coastguard Worker   return vp9_rc_clamp_iframe_target_size(cpi, target);
2036*fb1b10abSAndroid Build Coastguard Worker }
2037*fb1b10abSAndroid Build Coastguard Worker 
adjust_gfint_frame_constraint(VP9_COMP * cpi,int frame_constraint)2038*fb1b10abSAndroid Build Coastguard Worker static void adjust_gfint_frame_constraint(VP9_COMP *cpi, int frame_constraint) {
2039*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2040*fb1b10abSAndroid Build Coastguard Worker   rc->constrained_gf_group = 0;
2041*fb1b10abSAndroid Build Coastguard Worker   // Reset gf interval to make more equal spacing for frame_constraint.
2042*fb1b10abSAndroid Build Coastguard Worker   if ((frame_constraint <= 7 * rc->baseline_gf_interval >> 2) &&
2043*fb1b10abSAndroid Build Coastguard Worker       (frame_constraint > rc->baseline_gf_interval)) {
2044*fb1b10abSAndroid Build Coastguard Worker     rc->baseline_gf_interval = frame_constraint >> 1;
2045*fb1b10abSAndroid Build Coastguard Worker     if (rc->baseline_gf_interval < 5)
2046*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval = frame_constraint;
2047*fb1b10abSAndroid Build Coastguard Worker     rc->constrained_gf_group = 1;
2048*fb1b10abSAndroid Build Coastguard Worker   } else {
2049*fb1b10abSAndroid Build Coastguard Worker     // Reset to keep gf_interval <= frame_constraint.
2050*fb1b10abSAndroid Build Coastguard Worker     if (rc->baseline_gf_interval > frame_constraint) {
2051*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval = frame_constraint;
2052*fb1b10abSAndroid Build Coastguard Worker       rc->constrained_gf_group = 1;
2053*fb1b10abSAndroid Build Coastguard Worker     }
2054*fb1b10abSAndroid Build Coastguard Worker   }
2055*fb1b10abSAndroid Build Coastguard Worker }
2056*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_gf_update_one_pass_vbr(VP9_COMP * const cpi)2057*fb1b10abSAndroid Build Coastguard Worker void vp9_set_gf_update_one_pass_vbr(VP9_COMP *const cpi) {
2058*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2059*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2060*fb1b10abSAndroid Build Coastguard Worker   if (rc->frames_till_gf_update_due == 0) {
2061*fb1b10abSAndroid Build Coastguard Worker     double rate_err = 1.0;
2062*fb1b10abSAndroid Build Coastguard Worker     rc->gfu_boost = DEFAULT_GF_BOOST;
2063*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0) {
2064*fb1b10abSAndroid Build Coastguard Worker       vp9_cyclic_refresh_set_golden_update(cpi);
2065*fb1b10abSAndroid Build Coastguard Worker     } else {
2066*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval = VPXMIN(
2067*fb1b10abSAndroid Build Coastguard Worker           20, VPXMAX(10, (rc->min_gf_interval + rc->max_gf_interval) / 2));
2068*fb1b10abSAndroid Build Coastguard Worker     }
2069*fb1b10abSAndroid Build Coastguard Worker     rc->af_ratio_onepass_vbr = 10;
2070*fb1b10abSAndroid Build Coastguard Worker     if (rc->rolling_target_bits > 0)
2071*fb1b10abSAndroid Build Coastguard Worker       rate_err =
2072*fb1b10abSAndroid Build Coastguard Worker           (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits;
2073*fb1b10abSAndroid Build Coastguard Worker     if (cm->current_video_frame > 30) {
2074*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_qindex[INTER_FRAME] > (7 * rc->worst_quality) >> 3 &&
2075*fb1b10abSAndroid Build Coastguard Worker           rate_err > 3.5) {
2076*fb1b10abSAndroid Build Coastguard Worker         rc->baseline_gf_interval =
2077*fb1b10abSAndroid Build Coastguard Worker             VPXMIN(15, (3 * rc->baseline_gf_interval) >> 1);
2078*fb1b10abSAndroid Build Coastguard Worker       } else if (rc->avg_frame_low_motion > 0 &&
2079*fb1b10abSAndroid Build Coastguard Worker                  rc->avg_frame_low_motion < 20) {
2080*fb1b10abSAndroid Build Coastguard Worker         // Decrease gf interval for high motion case.
2081*fb1b10abSAndroid Build Coastguard Worker         rc->baseline_gf_interval = VPXMAX(6, rc->baseline_gf_interval >> 1);
2082*fb1b10abSAndroid Build Coastguard Worker       }
2083*fb1b10abSAndroid Build Coastguard Worker       // Adjust boost and af_ratio based on avg_frame_low_motion, which
2084*fb1b10abSAndroid Build Coastguard Worker       // varies between 0 and 100 (stationary, 100% zero/small motion).
2085*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_low_motion > 0)
2086*fb1b10abSAndroid Build Coastguard Worker         rc->gfu_boost =
2087*fb1b10abSAndroid Build Coastguard Worker             VPXMAX(500, DEFAULT_GF_BOOST * (rc->avg_frame_low_motion << 1) /
2088*fb1b10abSAndroid Build Coastguard Worker                             (rc->avg_frame_low_motion + 100));
2089*fb1b10abSAndroid Build Coastguard Worker       else if (rc->avg_frame_low_motion == 0 && rate_err > 1.0)
2090*fb1b10abSAndroid Build Coastguard Worker         rc->gfu_boost = DEFAULT_GF_BOOST >> 1;
2091*fb1b10abSAndroid Build Coastguard Worker       rc->af_ratio_onepass_vbr = VPXMIN(15, VPXMAX(5, 3 * rc->gfu_boost / 400));
2092*fb1b10abSAndroid Build Coastguard Worker     }
2093*fb1b10abSAndroid Build Coastguard Worker     if (rc->constrain_gf_key_freq_onepass_vbr)
2094*fb1b10abSAndroid Build Coastguard Worker       adjust_gfint_frame_constraint(cpi, rc->frames_to_key);
2095*fb1b10abSAndroid Build Coastguard Worker     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
2096*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_golden_frame = 1;
2097*fb1b10abSAndroid Build Coastguard Worker     rc->source_alt_ref_pending = 0;
2098*fb1b10abSAndroid Build Coastguard Worker     rc->alt_ref_gf_group = 0;
2099*fb1b10abSAndroid Build Coastguard Worker     if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) {
2100*fb1b10abSAndroid Build Coastguard Worker       rc->source_alt_ref_pending = 1;
2101*fb1b10abSAndroid Build Coastguard Worker       rc->alt_ref_gf_group = 1;
2102*fb1b10abSAndroid Build Coastguard Worker     }
2103*fb1b10abSAndroid Build Coastguard Worker   }
2104*fb1b10abSAndroid Build Coastguard Worker }
2105*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_get_one_pass_vbr_params(VP9_COMP * cpi)2106*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
2107*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2108*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2109*fb1b10abSAndroid Build Coastguard Worker   int target;
2110*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->refresh_alt_ref_frame &&
2111*fb1b10abSAndroid Build Coastguard Worker       (cm->current_video_frame == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY) ||
2112*fb1b10abSAndroid Build Coastguard Worker        rc->frames_to_key == 0 ||
2113*fb1b10abSAndroid Build Coastguard Worker        (cpi->oxcf.mode != cpi->deadline_mode_previous_frame))) {
2114*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = KEY_FRAME;
2115*fb1b10abSAndroid Build Coastguard Worker     rc->this_key_frame_forced =
2116*fb1b10abSAndroid Build Coastguard Worker         cm->current_video_frame != 0 && rc->frames_to_key == 0;
2117*fb1b10abSAndroid Build Coastguard Worker     rc->frames_to_key = cpi->oxcf.key_freq;
2118*fb1b10abSAndroid Build Coastguard Worker     rc->kf_boost = DEFAULT_KF_BOOST;
2119*fb1b10abSAndroid Build Coastguard Worker     rc->source_alt_ref_active = 0;
2120*fb1b10abSAndroid Build Coastguard Worker   } else {
2121*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = INTER_FRAME;
2122*fb1b10abSAndroid Build Coastguard Worker   }
2123*fb1b10abSAndroid Build Coastguard Worker   vp9_set_gf_update_one_pass_vbr(cpi);
2124*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME)
2125*fb1b10abSAndroid Build Coastguard Worker     target = vp9_calc_iframe_target_size_one_pass_vbr(cpi);
2126*fb1b10abSAndroid Build Coastguard Worker   else
2127*fb1b10abSAndroid Build Coastguard Worker     target = vp9_calc_pframe_target_size_one_pass_vbr(cpi);
2128*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_set_frame_target(cpi, target);
2129*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cpi->oxcf.pass == 0)
2130*fb1b10abSAndroid Build Coastguard Worker     vp9_cyclic_refresh_update_parameters(cpi);
2131*fb1b10abSAndroid Build Coastguard Worker }
2132*fb1b10abSAndroid Build Coastguard Worker 
vp9_calc_pframe_target_size_one_pass_cbr(const VP9_COMP * cpi)2133*fb1b10abSAndroid Build Coastguard Worker int vp9_calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
2134*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
2135*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
2136*fb1b10abSAndroid Build Coastguard Worker   const SVC *const svc = &cpi->svc;
2137*fb1b10abSAndroid Build Coastguard Worker   const int64_t diff = rc->optimal_buffer_level - rc->buffer_level;
2138*fb1b10abSAndroid Build Coastguard Worker   const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100;
2139*fb1b10abSAndroid Build Coastguard Worker   int min_frame_target =
2140*fb1b10abSAndroid Build Coastguard Worker       VPXMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS);
2141*fb1b10abSAndroid Build Coastguard Worker   int target;
2142*fb1b10abSAndroid Build Coastguard Worker 
2143*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->gf_cbr_boost_pct) {
2144*fb1b10abSAndroid Build Coastguard Worker     const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100;
2145*fb1b10abSAndroid Build Coastguard Worker     target = cpi->refresh_golden_frame
2146*fb1b10abSAndroid Build Coastguard Worker                  ? (rc->avg_frame_bandwidth * rc->baseline_gf_interval *
2147*fb1b10abSAndroid Build Coastguard Worker                     af_ratio_pct) /
2148*fb1b10abSAndroid Build Coastguard Worker                        (rc->baseline_gf_interval * 100 + af_ratio_pct - 100)
2149*fb1b10abSAndroid Build Coastguard Worker                  : (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) /
2150*fb1b10abSAndroid Build Coastguard Worker                        (rc->baseline_gf_interval * 100 + af_ratio_pct - 100);
2151*fb1b10abSAndroid Build Coastguard Worker   } else {
2152*fb1b10abSAndroid Build Coastguard Worker     target = rc->avg_frame_bandwidth;
2153*fb1b10abSAndroid Build Coastguard Worker   }
2154*fb1b10abSAndroid Build Coastguard Worker   if (is_one_pass_svc(cpi)) {
2155*fb1b10abSAndroid Build Coastguard Worker     // Note that for layers, avg_frame_bandwidth is the cumulative
2156*fb1b10abSAndroid Build Coastguard Worker     // per-frame-bandwidth. For the target size of this frame, use the
2157*fb1b10abSAndroid Build Coastguard Worker     // layer average frame size (i.e., non-cumulative per-frame-bw).
2158*fb1b10abSAndroid Build Coastguard Worker     int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
2159*fb1b10abSAndroid Build Coastguard Worker                                  svc->number_temporal_layers);
2160*fb1b10abSAndroid Build Coastguard Worker     const LAYER_CONTEXT *lc = &svc->layer_context[layer];
2161*fb1b10abSAndroid Build Coastguard Worker     target = lc->avg_frame_size;
2162*fb1b10abSAndroid Build Coastguard Worker     min_frame_target = VPXMAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS);
2163*fb1b10abSAndroid Build Coastguard Worker   }
2164*fb1b10abSAndroid Build Coastguard Worker   if (diff > 0) {
2165*fb1b10abSAndroid Build Coastguard Worker     // Lower the target bandwidth for this frame.
2166*fb1b10abSAndroid Build Coastguard Worker     const int pct_low = (int)VPXMIN(diff / one_pct_bits, oxcf->under_shoot_pct);
2167*fb1b10abSAndroid Build Coastguard Worker     target -= (int)(((int64_t)target * pct_low) / 200);
2168*fb1b10abSAndroid Build Coastguard Worker   } else if (diff < 0) {
2169*fb1b10abSAndroid Build Coastguard Worker     // Increase the target bandwidth for this frame.
2170*fb1b10abSAndroid Build Coastguard Worker     const int pct_high =
2171*fb1b10abSAndroid Build Coastguard Worker         (int)VPXMIN(-diff / one_pct_bits, oxcf->over_shoot_pct);
2172*fb1b10abSAndroid Build Coastguard Worker     target += (int)(((int64_t)target * pct_high) / 200);
2173*fb1b10abSAndroid Build Coastguard Worker   }
2174*fb1b10abSAndroid Build Coastguard Worker   if (oxcf->rc_max_inter_bitrate_pct) {
2175*fb1b10abSAndroid Build Coastguard Worker     const int max_rate =
2176*fb1b10abSAndroid Build Coastguard Worker         rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100;
2177*fb1b10abSAndroid Build Coastguard Worker     target = VPXMIN(target, max_rate);
2178*fb1b10abSAndroid Build Coastguard Worker   }
2179*fb1b10abSAndroid Build Coastguard Worker   return VPXMAX(min_frame_target, target);
2180*fb1b10abSAndroid Build Coastguard Worker }
2181*fb1b10abSAndroid Build Coastguard Worker 
vp9_calc_iframe_target_size_one_pass_cbr(const VP9_COMP * cpi)2182*fb1b10abSAndroid Build Coastguard Worker int vp9_calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
2183*fb1b10abSAndroid Build Coastguard Worker   const RATE_CONTROL *rc = &cpi->rc;
2184*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *oxcf = &cpi->oxcf;
2185*fb1b10abSAndroid Build Coastguard Worker   const SVC *const svc = &cpi->svc;
2186*fb1b10abSAndroid Build Coastguard Worker   int64_t target;
2187*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.current_video_frame == 0) {
2188*fb1b10abSAndroid Build Coastguard Worker     target = rc->starting_buffer_level / 2;
2189*fb1b10abSAndroid Build Coastguard Worker   } else {
2190*fb1b10abSAndroid Build Coastguard Worker     int kf_boost = 32;
2191*fb1b10abSAndroid Build Coastguard Worker     double framerate = cpi->framerate;
2192*fb1b10abSAndroid Build Coastguard Worker     if (svc->number_temporal_layers > 1 && oxcf->rc_mode == VPX_CBR) {
2193*fb1b10abSAndroid Build Coastguard Worker       // Use the layer framerate for temporal layers CBR mode.
2194*fb1b10abSAndroid Build Coastguard Worker       const int layer =
2195*fb1b10abSAndroid Build Coastguard Worker           LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
2196*fb1b10abSAndroid Build Coastguard Worker                            svc->number_temporal_layers);
2197*fb1b10abSAndroid Build Coastguard Worker       const LAYER_CONTEXT *lc = &svc->layer_context[layer];
2198*fb1b10abSAndroid Build Coastguard Worker       framerate = lc->framerate;
2199*fb1b10abSAndroid Build Coastguard Worker     }
2200*fb1b10abSAndroid Build Coastguard Worker     kf_boost = VPXMAX(kf_boost, (int)round(2 * framerate - 16));
2201*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_since_key < framerate / 2) {
2202*fb1b10abSAndroid Build Coastguard Worker       kf_boost = (int)round(kf_boost * rc->frames_since_key / (framerate / 2));
2203*fb1b10abSAndroid Build Coastguard Worker     }
2204*fb1b10abSAndroid Build Coastguard Worker 
2205*fb1b10abSAndroid Build Coastguard Worker     target = ((int64_t)(16 + kf_boost) * rc->avg_frame_bandwidth) >> 4;
2206*fb1b10abSAndroid Build Coastguard Worker   }
2207*fb1b10abSAndroid Build Coastguard Worker   target = VPXMIN(INT_MAX, target);
2208*fb1b10abSAndroid Build Coastguard Worker   return vp9_rc_clamp_iframe_target_size(cpi, (int)target);
2209*fb1b10abSAndroid Build Coastguard Worker }
2210*fb1b10abSAndroid Build Coastguard Worker 
set_intra_only_frame(VP9_COMP * cpi)2211*fb1b10abSAndroid Build Coastguard Worker static void set_intra_only_frame(VP9_COMP *cpi) {
2212*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2213*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
2214*fb1b10abSAndroid Build Coastguard Worker   // Don't allow intra_only frame for bypass/flexible SVC mode, or if number
2215*fb1b10abSAndroid Build Coastguard Worker   // of spatial layers is 1 or if number of spatial or temporal layers > 3.
2216*fb1b10abSAndroid Build Coastguard Worker   // Also if intra-only is inserted on very first frame, don't allow if
2217*fb1b10abSAndroid Build Coastguard Worker   // if number of temporal layers > 1. This is because on intra-only frame
2218*fb1b10abSAndroid Build Coastguard Worker   // only 3 reference buffers can be updated, but for temporal layers > 1
2219*fb1b10abSAndroid Build Coastguard Worker   // we generally need to use buffer slots 4 and 5.
2220*fb1b10abSAndroid Build Coastguard Worker   if ((cm->current_video_frame == 0 && svc->number_temporal_layers > 1) ||
2221*fb1b10abSAndroid Build Coastguard Worker       svc->number_spatial_layers > 3 || svc->number_temporal_layers > 3 ||
2222*fb1b10abSAndroid Build Coastguard Worker       svc->number_spatial_layers == 1)
2223*fb1b10abSAndroid Build Coastguard Worker     return;
2224*fb1b10abSAndroid Build Coastguard Worker   cm->show_frame = 0;
2225*fb1b10abSAndroid Build Coastguard Worker   cm->intra_only = 1;
2226*fb1b10abSAndroid Build Coastguard Worker   cm->frame_type = INTER_FRAME;
2227*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_frame_flags_pending = 1;
2228*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_last_frame = 1;
2229*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_golden_frame = 1;
2230*fb1b10abSAndroid Build Coastguard Worker   cpi->ext_refresh_alt_ref_frame = 1;
2231*fb1b10abSAndroid Build Coastguard Worker   if (cm->current_video_frame == 0) {
2232*fb1b10abSAndroid Build Coastguard Worker     cpi->lst_fb_idx = 0;
2233*fb1b10abSAndroid Build Coastguard Worker     cpi->gld_fb_idx = 1;
2234*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx = 2;
2235*fb1b10abSAndroid Build Coastguard Worker   } else {
2236*fb1b10abSAndroid Build Coastguard Worker     int i;
2237*fb1b10abSAndroid Build Coastguard Worker     int count = 0;
2238*fb1b10abSAndroid Build Coastguard Worker     cpi->lst_fb_idx = -1;
2239*fb1b10abSAndroid Build Coastguard Worker     cpi->gld_fb_idx = -1;
2240*fb1b10abSAndroid Build Coastguard Worker     cpi->alt_fb_idx = -1;
2241*fb1b10abSAndroid Build Coastguard Worker     svc->update_buffer_slot[0] = 0;
2242*fb1b10abSAndroid Build Coastguard Worker     // For intra-only frame we need to refresh all slots that were
2243*fb1b10abSAndroid Build Coastguard Worker     // being used for the base layer (fb_idx_base[i] == 1).
2244*fb1b10abSAndroid Build Coastguard Worker     // Start with assigning last first, then golden and then alt.
2245*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < REF_FRAMES; ++i) {
2246*fb1b10abSAndroid Build Coastguard Worker       if (svc->fb_idx_base[i] == 1) {
2247*fb1b10abSAndroid Build Coastguard Worker         svc->update_buffer_slot[0] |= 1 << i;
2248*fb1b10abSAndroid Build Coastguard Worker         count++;
2249*fb1b10abSAndroid Build Coastguard Worker       }
2250*fb1b10abSAndroid Build Coastguard Worker       if (count == 1 && cpi->lst_fb_idx == -1) cpi->lst_fb_idx = i;
2251*fb1b10abSAndroid Build Coastguard Worker       if (count == 2 && cpi->gld_fb_idx == -1) cpi->gld_fb_idx = i;
2252*fb1b10abSAndroid Build Coastguard Worker       if (count == 3 && cpi->alt_fb_idx == -1) cpi->alt_fb_idx = i;
2253*fb1b10abSAndroid Build Coastguard Worker     }
2254*fb1b10abSAndroid Build Coastguard Worker     // If golden or alt is not being used for base layer, then set them
2255*fb1b10abSAndroid Build Coastguard Worker     // to the lst_fb_idx.
2256*fb1b10abSAndroid Build Coastguard Worker     if (cpi->gld_fb_idx == -1) cpi->gld_fb_idx = cpi->lst_fb_idx;
2257*fb1b10abSAndroid Build Coastguard Worker     if (cpi->alt_fb_idx == -1) cpi->alt_fb_idx = cpi->lst_fb_idx;
2258*fb1b10abSAndroid Build Coastguard Worker     if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
2259*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_last_frame = 0;
2260*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_golden_frame = 0;
2261*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_alt_ref_frame = 0;
2262*fb1b10abSAndroid Build Coastguard Worker       cpi->ref_frame_flags = 0;
2263*fb1b10abSAndroid Build Coastguard Worker     }
2264*fb1b10abSAndroid Build Coastguard Worker   }
2265*fb1b10abSAndroid Build Coastguard Worker }
2266*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_get_svc_params(VP9_COMP * cpi)2267*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_get_svc_params(VP9_COMP *cpi) {
2268*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2269*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2270*fb1b10abSAndroid Build Coastguard Worker   SVC *const svc = &cpi->svc;
2271*fb1b10abSAndroid Build Coastguard Worker   int target = rc->avg_frame_bandwidth;
2272*fb1b10abSAndroid Build Coastguard Worker   int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
2273*fb1b10abSAndroid Build Coastguard Worker                                svc->number_temporal_layers);
2274*fb1b10abSAndroid Build Coastguard Worker   if (svc->first_spatial_layer_to_encode)
2275*fb1b10abSAndroid Build Coastguard Worker     svc->layer_context[svc->temporal_layer_id].is_key_frame = 0;
2276*fb1b10abSAndroid Build Coastguard Worker   // Periodic key frames is based on the super-frame counter
2277*fb1b10abSAndroid Build Coastguard Worker   // (svc.current_superframe), also only base spatial layer is key frame.
2278*fb1b10abSAndroid Build Coastguard Worker   // Key frame is set for any of the following: very first frame, frame flags
2279*fb1b10abSAndroid Build Coastguard Worker   // indicates key, superframe counter hits key frequency,(non-intra) sync
2280*fb1b10abSAndroid Build Coastguard Worker   // flag is set for spatial layer 0, or deadline mode changes.
2281*fb1b10abSAndroid Build Coastguard Worker   if ((cm->current_video_frame == 0 && !svc->previous_frame_is_intra_only) ||
2282*fb1b10abSAndroid Build Coastguard Worker       (cpi->frame_flags & FRAMEFLAGS_KEY) ||
2283*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.auto_key &&
2284*fb1b10abSAndroid Build Coastguard Worker        (svc->current_superframe % cpi->oxcf.key_freq == 0) &&
2285*fb1b10abSAndroid Build Coastguard Worker        !svc->previous_frame_is_intra_only && svc->spatial_layer_id == 0) ||
2286*fb1b10abSAndroid Build Coastguard Worker       (svc->spatial_layer_sync[0] == 1 && svc->spatial_layer_id == 0) ||
2287*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.mode != cpi->deadline_mode_previous_frame)) {
2288*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = KEY_FRAME;
2289*fb1b10abSAndroid Build Coastguard Worker     rc->source_alt_ref_active = 0;
2290*fb1b10abSAndroid Build Coastguard Worker     if (is_one_pass_svc(cpi)) {
2291*fb1b10abSAndroid Build Coastguard Worker       if (cm->current_video_frame > 0) vp9_svc_reset_temporal_layers(cpi, 1);
2292*fb1b10abSAndroid Build Coastguard Worker       layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, svc->temporal_layer_id,
2293*fb1b10abSAndroid Build Coastguard Worker                                svc->number_temporal_layers);
2294*fb1b10abSAndroid Build Coastguard Worker       svc->layer_context[layer].is_key_frame = 1;
2295*fb1b10abSAndroid Build Coastguard Worker       cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
2296*fb1b10abSAndroid Build Coastguard Worker       // Assumption here is that LAST_FRAME is being updated for a keyframe.
2297*fb1b10abSAndroid Build Coastguard Worker       // Thus no change in update flags.
2298*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.rc_mode == VPX_CBR)
2299*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_iframe_target_size_one_pass_cbr(cpi);
2300*fb1b10abSAndroid Build Coastguard Worker       else
2301*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_iframe_target_size_one_pass_vbr(cpi);
2302*fb1b10abSAndroid Build Coastguard Worker     }
2303*fb1b10abSAndroid Build Coastguard Worker   } else {
2304*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = INTER_FRAME;
2305*fb1b10abSAndroid Build Coastguard Worker     if (is_one_pass_svc(cpi)) {
2306*fb1b10abSAndroid Build Coastguard Worker       LAYER_CONTEXT *lc = &svc->layer_context[layer];
2307*fb1b10abSAndroid Build Coastguard Worker       // Add condition current_video_frame > 0 for the case where first frame
2308*fb1b10abSAndroid Build Coastguard Worker       // is intra only followed by overlay/copy frame. In this case we don't
2309*fb1b10abSAndroid Build Coastguard Worker       // want to reset is_key_frame to 0 on overlay/copy frame.
2310*fb1b10abSAndroid Build Coastguard Worker       lc->is_key_frame =
2311*fb1b10abSAndroid Build Coastguard Worker           (svc->spatial_layer_id == 0 && cm->current_video_frame > 0)
2312*fb1b10abSAndroid Build Coastguard Worker               ? 0
2313*fb1b10abSAndroid Build Coastguard Worker               : svc->layer_context[svc->temporal_layer_id].is_key_frame;
2314*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.rc_mode == VPX_CBR) {
2315*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_pframe_target_size_one_pass_cbr(cpi);
2316*fb1b10abSAndroid Build Coastguard Worker       } else {
2317*fb1b10abSAndroid Build Coastguard Worker         double rate_err = 0.0;
2318*fb1b10abSAndroid Build Coastguard Worker         rc->fac_active_worst_inter = 140;
2319*fb1b10abSAndroid Build Coastguard Worker         rc->fac_active_worst_gf = 100;
2320*fb1b10abSAndroid Build Coastguard Worker         if (rc->rolling_target_bits > 0) {
2321*fb1b10abSAndroid Build Coastguard Worker           rate_err =
2322*fb1b10abSAndroid Build Coastguard Worker               (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits;
2323*fb1b10abSAndroid Build Coastguard Worker           if (rate_err < 1.0)
2324*fb1b10abSAndroid Build Coastguard Worker             rc->fac_active_worst_inter = 120;
2325*fb1b10abSAndroid Build Coastguard Worker           else if (rate_err > 2.0)
2326*fb1b10abSAndroid Build Coastguard Worker             // Increase active_worst faster if rate fluctuation is high.
2327*fb1b10abSAndroid Build Coastguard Worker             rc->fac_active_worst_inter = 160;
2328*fb1b10abSAndroid Build Coastguard Worker         }
2329*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_pframe_target_size_one_pass_vbr(cpi);
2330*fb1b10abSAndroid Build Coastguard Worker       }
2331*fb1b10abSAndroid Build Coastguard Worker     }
2332*fb1b10abSAndroid Build Coastguard Worker   }
2333*fb1b10abSAndroid Build Coastguard Worker 
2334*fb1b10abSAndroid Build Coastguard Worker   if (svc->simulcast_mode) {
2335*fb1b10abSAndroid Build Coastguard Worker     if (svc->spatial_layer_id > 0 &&
2336*fb1b10abSAndroid Build Coastguard Worker         svc->layer_context[layer].is_key_frame == 1) {
2337*fb1b10abSAndroid Build Coastguard Worker       cm->frame_type = KEY_FRAME;
2338*fb1b10abSAndroid Build Coastguard Worker       cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
2339*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.rc_mode == VPX_CBR)
2340*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_iframe_target_size_one_pass_cbr(cpi);
2341*fb1b10abSAndroid Build Coastguard Worker       else
2342*fb1b10abSAndroid Build Coastguard Worker         target = vp9_calc_iframe_target_size_one_pass_vbr(cpi);
2343*fb1b10abSAndroid Build Coastguard Worker     }
2344*fb1b10abSAndroid Build Coastguard Worker     // Set the buffer idx and refresh flags for key frames in simulcast mode.
2345*fb1b10abSAndroid Build Coastguard Worker     // Note the buffer slot for long-term reference is set below (line 2255),
2346*fb1b10abSAndroid Build Coastguard Worker     // and alt_ref is used for that on key frame. So use last and golden for
2347*fb1b10abSAndroid Build Coastguard Worker     // the other two normal slots.
2348*fb1b10abSAndroid Build Coastguard Worker     if (cm->frame_type == KEY_FRAME) {
2349*fb1b10abSAndroid Build Coastguard Worker       if (svc->number_spatial_layers == 2) {
2350*fb1b10abSAndroid Build Coastguard Worker         if (svc->spatial_layer_id == 0) {
2351*fb1b10abSAndroid Build Coastguard Worker           cpi->lst_fb_idx = 0;
2352*fb1b10abSAndroid Build Coastguard Worker           cpi->gld_fb_idx = 2;
2353*fb1b10abSAndroid Build Coastguard Worker           cpi->alt_fb_idx = 6;
2354*fb1b10abSAndroid Build Coastguard Worker         } else if (svc->spatial_layer_id == 1) {
2355*fb1b10abSAndroid Build Coastguard Worker           cpi->lst_fb_idx = 1;
2356*fb1b10abSAndroid Build Coastguard Worker           cpi->gld_fb_idx = 3;
2357*fb1b10abSAndroid Build Coastguard Worker           cpi->alt_fb_idx = 6;
2358*fb1b10abSAndroid Build Coastguard Worker         }
2359*fb1b10abSAndroid Build Coastguard Worker       } else if (svc->number_spatial_layers == 3) {
2360*fb1b10abSAndroid Build Coastguard Worker         if (svc->spatial_layer_id == 0) {
2361*fb1b10abSAndroid Build Coastguard Worker           cpi->lst_fb_idx = 0;
2362*fb1b10abSAndroid Build Coastguard Worker           cpi->gld_fb_idx = 3;
2363*fb1b10abSAndroid Build Coastguard Worker           cpi->alt_fb_idx = 6;
2364*fb1b10abSAndroid Build Coastguard Worker         } else if (svc->spatial_layer_id == 1) {
2365*fb1b10abSAndroid Build Coastguard Worker           cpi->lst_fb_idx = 1;
2366*fb1b10abSAndroid Build Coastguard Worker           cpi->gld_fb_idx = 4;
2367*fb1b10abSAndroid Build Coastguard Worker           cpi->alt_fb_idx = 6;
2368*fb1b10abSAndroid Build Coastguard Worker         } else if (svc->spatial_layer_id == 2) {
2369*fb1b10abSAndroid Build Coastguard Worker           cpi->lst_fb_idx = 2;
2370*fb1b10abSAndroid Build Coastguard Worker           cpi->gld_fb_idx = 5;
2371*fb1b10abSAndroid Build Coastguard Worker           cpi->alt_fb_idx = 7;
2372*fb1b10abSAndroid Build Coastguard Worker         }
2373*fb1b10abSAndroid Build Coastguard Worker       }
2374*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_last_frame = 1;
2375*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_golden_frame = 1;
2376*fb1b10abSAndroid Build Coastguard Worker       cpi->ext_refresh_alt_ref_frame = 1;
2377*fb1b10abSAndroid Build Coastguard Worker     }
2378*fb1b10abSAndroid Build Coastguard Worker   }
2379*fb1b10abSAndroid Build Coastguard Worker 
2380*fb1b10abSAndroid Build Coastguard Worker   // Check if superframe contains a sync layer request.
2381*fb1b10abSAndroid Build Coastguard Worker   vp9_svc_check_spatial_layer_sync(cpi);
2382*fb1b10abSAndroid Build Coastguard Worker 
2383*fb1b10abSAndroid Build Coastguard Worker   // If long term termporal feature is enabled, set the period of the update.
2384*fb1b10abSAndroid Build Coastguard Worker   // The update/refresh of this reference frame is always on base temporal
2385*fb1b10abSAndroid Build Coastguard Worker   // layer frame.
2386*fb1b10abSAndroid Build Coastguard Worker   if (svc->use_gf_temporal_ref_current_layer) {
2387*fb1b10abSAndroid Build Coastguard Worker     // Only use gf long-term prediction on non-key superframes.
2388*fb1b10abSAndroid Build Coastguard Worker     if (!svc->layer_context[svc->temporal_layer_id].is_key_frame) {
2389*fb1b10abSAndroid Build Coastguard Worker       // Use golden for this reference, which will be used for prediction.
2390*fb1b10abSAndroid Build Coastguard Worker       int index = svc->spatial_layer_id;
2391*fb1b10abSAndroid Build Coastguard Worker       if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
2392*fb1b10abSAndroid Build Coastguard Worker       assert(index >= 0);
2393*fb1b10abSAndroid Build Coastguard Worker       cpi->gld_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
2394*fb1b10abSAndroid Build Coastguard Worker       // Enable prediction off LAST (last reference) and golden (which will
2395*fb1b10abSAndroid Build Coastguard Worker       // generally be further behind/long-term reference).
2396*fb1b10abSAndroid Build Coastguard Worker       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
2397*fb1b10abSAndroid Build Coastguard Worker     }
2398*fb1b10abSAndroid Build Coastguard Worker     // Check for update/refresh of reference: only refresh on base temporal
2399*fb1b10abSAndroid Build Coastguard Worker     // layer.
2400*fb1b10abSAndroid Build Coastguard Worker     if (svc->temporal_layer_id == 0) {
2401*fb1b10abSAndroid Build Coastguard Worker       if (svc->layer_context[svc->temporal_layer_id].is_key_frame) {
2402*fb1b10abSAndroid Build Coastguard Worker         // On key frame we update the buffer index used for long term reference.
2403*fb1b10abSAndroid Build Coastguard Worker         // Use the alt_ref since it is not used or updated on key frames.
2404*fb1b10abSAndroid Build Coastguard Worker         int index = svc->spatial_layer_id;
2405*fb1b10abSAndroid Build Coastguard Worker         if (svc->number_spatial_layers == 3) index = svc->spatial_layer_id - 1;
2406*fb1b10abSAndroid Build Coastguard Worker         assert(index >= 0);
2407*fb1b10abSAndroid Build Coastguard Worker         cpi->alt_fb_idx = svc->buffer_gf_temporal_ref[index].idx;
2408*fb1b10abSAndroid Build Coastguard Worker         cpi->ext_refresh_alt_ref_frame = 1;
2409*fb1b10abSAndroid Build Coastguard Worker       } else if (rc->frames_till_gf_update_due == 0) {
2410*fb1b10abSAndroid Build Coastguard Worker         // Set perdiod of next update. Make it a multiple of 10, as the cyclic
2411*fb1b10abSAndroid Build Coastguard Worker         // refresh is typically ~10%, and we'd like the update to happen after
2412*fb1b10abSAndroid Build Coastguard Worker         // a few cylces of the refresh (so it better quality frame). Note the
2413*fb1b10abSAndroid Build Coastguard Worker         // cyclic refresh for SVC only operates on base temporal layer frames.
2414*fb1b10abSAndroid Build Coastguard Worker         // Choose 20 as perdiod for now (2 cycles).
2415*fb1b10abSAndroid Build Coastguard Worker         rc->baseline_gf_interval = 20;
2416*fb1b10abSAndroid Build Coastguard Worker         rc->frames_till_gf_update_due = rc->baseline_gf_interval;
2417*fb1b10abSAndroid Build Coastguard Worker         cpi->ext_refresh_golden_frame = 1;
2418*fb1b10abSAndroid Build Coastguard Worker         rc->gfu_boost = DEFAULT_GF_BOOST;
2419*fb1b10abSAndroid Build Coastguard Worker       }
2420*fb1b10abSAndroid Build Coastguard Worker     }
2421*fb1b10abSAndroid Build Coastguard Worker   } else if (!svc->use_gf_temporal_ref) {
2422*fb1b10abSAndroid Build Coastguard Worker     rc->frames_till_gf_update_due = INT_MAX;
2423*fb1b10abSAndroid Build Coastguard Worker     rc->baseline_gf_interval = INT_MAX;
2424*fb1b10abSAndroid Build Coastguard Worker   }
2425*fb1b10abSAndroid Build Coastguard Worker   if (svc->set_intra_only_frame) {
2426*fb1b10abSAndroid Build Coastguard Worker     set_intra_only_frame(cpi);
2427*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_CBR)
2428*fb1b10abSAndroid Build Coastguard Worker       target = vp9_calc_iframe_target_size_one_pass_cbr(cpi);
2429*fb1b10abSAndroid Build Coastguard Worker     else
2430*fb1b10abSAndroid Build Coastguard Worker       target = vp9_calc_iframe_target_size_one_pass_vbr(cpi);
2431*fb1b10abSAndroid Build Coastguard Worker   }
2432*fb1b10abSAndroid Build Coastguard Worker   // Overlay frame predicts from LAST (intra-only)
2433*fb1b10abSAndroid Build Coastguard Worker   if (svc->previous_frame_is_intra_only) cpi->ref_frame_flags |= VP9_LAST_FLAG;
2434*fb1b10abSAndroid Build Coastguard Worker 
2435*fb1b10abSAndroid Build Coastguard Worker   // Any update/change of global cyclic refresh parameters (amount/delta-qp)
2436*fb1b10abSAndroid Build Coastguard Worker   // should be done here, before the frame qp is selected.
2437*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2438*fb1b10abSAndroid Build Coastguard Worker     vp9_cyclic_refresh_update_parameters(cpi);
2439*fb1b10abSAndroid Build Coastguard Worker 
2440*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_set_frame_target(cpi, target);
2441*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) vp9_update_buffer_level_svc_preencode(cpi);
2442*fb1b10abSAndroid Build Coastguard Worker 
2443*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC && svc->single_layer_svc == 1 &&
2444*fb1b10abSAndroid Build Coastguard Worker       svc->spatial_layer_id == svc->first_spatial_layer_to_encode &&
2445*fb1b10abSAndroid Build Coastguard Worker       svc->temporal_layer_id == 0) {
2446*fb1b10abSAndroid Build Coastguard Worker     LAYER_CONTEXT *lc = NULL;
2447*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_pending = vp9_resize_one_pass_cbr(cpi);
2448*fb1b10abSAndroid Build Coastguard Worker     if (cpi->resize_pending) {
2449*fb1b10abSAndroid Build Coastguard Worker       int tl, width, height;
2450*fb1b10abSAndroid Build Coastguard Worker       // Apply the same scale to all temporal layers.
2451*fb1b10abSAndroid Build Coastguard Worker       for (tl = 0; tl < svc->number_temporal_layers; tl++) {
2452*fb1b10abSAndroid Build Coastguard Worker         lc = &svc->layer_context[svc->spatial_layer_id *
2453*fb1b10abSAndroid Build Coastguard Worker                                      svc->number_temporal_layers +
2454*fb1b10abSAndroid Build Coastguard Worker                                  tl];
2455*fb1b10abSAndroid Build Coastguard Worker         lc->scaling_factor_num_resize =
2456*fb1b10abSAndroid Build Coastguard Worker             cpi->resize_scale_num * lc->scaling_factor_num;
2457*fb1b10abSAndroid Build Coastguard Worker         lc->scaling_factor_den_resize =
2458*fb1b10abSAndroid Build Coastguard Worker             cpi->resize_scale_den * lc->scaling_factor_den;
2459*fb1b10abSAndroid Build Coastguard Worker         // Reset rate control for all temporal layers.
2460*fb1b10abSAndroid Build Coastguard Worker         lc->rc.buffer_level = lc->rc.optimal_buffer_level;
2461*fb1b10abSAndroid Build Coastguard Worker         lc->rc.bits_off_target = lc->rc.optimal_buffer_level;
2462*fb1b10abSAndroid Build Coastguard Worker         lc->rc.rate_correction_factors[INTER_FRAME] =
2463*fb1b10abSAndroid Build Coastguard Worker             rc->rate_correction_factors[INTER_FRAME];
2464*fb1b10abSAndroid Build Coastguard Worker       }
2465*fb1b10abSAndroid Build Coastguard Worker       // Set the size for this current temporal layer.
2466*fb1b10abSAndroid Build Coastguard Worker       lc = &svc->layer_context[svc->spatial_layer_id *
2467*fb1b10abSAndroid Build Coastguard Worker                                    svc->number_temporal_layers +
2468*fb1b10abSAndroid Build Coastguard Worker                                svc->temporal_layer_id];
2469*fb1b10abSAndroid Build Coastguard Worker       get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
2470*fb1b10abSAndroid Build Coastguard Worker                            lc->scaling_factor_num_resize,
2471*fb1b10abSAndroid Build Coastguard Worker                            lc->scaling_factor_den_resize, &width, &height);
2472*fb1b10abSAndroid Build Coastguard Worker       vp9_set_size_literal(cpi, width, height);
2473*fb1b10abSAndroid Build Coastguard Worker       svc->resize_set = 1;
2474*fb1b10abSAndroid Build Coastguard Worker     }
2475*fb1b10abSAndroid Build Coastguard Worker   } else {
2476*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_pending = 0;
2477*fb1b10abSAndroid Build Coastguard Worker     svc->resize_set = 0;
2478*fb1b10abSAndroid Build Coastguard Worker   }
2479*fb1b10abSAndroid Build Coastguard Worker }
2480*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_get_one_pass_cbr_params(VP9_COMP * cpi)2481*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
2482*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2483*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2484*fb1b10abSAndroid Build Coastguard Worker   int target;
2485*fb1b10abSAndroid Build Coastguard Worker   if ((cm->current_video_frame == 0) || (cpi->frame_flags & FRAMEFLAGS_KEY) ||
2486*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.auto_key && rc->frames_to_key == 0) ||
2487*fb1b10abSAndroid Build Coastguard Worker       (cpi->oxcf.mode != cpi->deadline_mode_previous_frame)) {
2488*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = KEY_FRAME;
2489*fb1b10abSAndroid Build Coastguard Worker     rc->frames_to_key = cpi->oxcf.key_freq;
2490*fb1b10abSAndroid Build Coastguard Worker     rc->kf_boost = DEFAULT_KF_BOOST;
2491*fb1b10abSAndroid Build Coastguard Worker     rc->source_alt_ref_active = 0;
2492*fb1b10abSAndroid Build Coastguard Worker   } else {
2493*fb1b10abSAndroid Build Coastguard Worker     cm->frame_type = INTER_FRAME;
2494*fb1b10abSAndroid Build Coastguard Worker   }
2495*fb1b10abSAndroid Build Coastguard Worker   if (rc->frames_till_gf_update_due == 0) {
2496*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2497*fb1b10abSAndroid Build Coastguard Worker       vp9_cyclic_refresh_set_golden_update(cpi);
2498*fb1b10abSAndroid Build Coastguard Worker     else
2499*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval =
2500*fb1b10abSAndroid Build Coastguard Worker           (rc->min_gf_interval + rc->max_gf_interval) / 2;
2501*fb1b10abSAndroid Build Coastguard Worker     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
2502*fb1b10abSAndroid Build Coastguard Worker     // NOTE: frames_till_gf_update_due must be <= frames_to_key.
2503*fb1b10abSAndroid Build Coastguard Worker     if (rc->frames_till_gf_update_due > rc->frames_to_key)
2504*fb1b10abSAndroid Build Coastguard Worker       rc->frames_till_gf_update_due = rc->frames_to_key;
2505*fb1b10abSAndroid Build Coastguard Worker     cpi->refresh_golden_frame = 1;
2506*fb1b10abSAndroid Build Coastguard Worker     rc->gfu_boost = DEFAULT_GF_BOOST;
2507*fb1b10abSAndroid Build Coastguard Worker   }
2508*fb1b10abSAndroid Build Coastguard Worker 
2509*fb1b10abSAndroid Build Coastguard Worker   // Any update/change of global cyclic refresh parameters (amount/delta-qp)
2510*fb1b10abSAndroid Build Coastguard Worker   // should be done here, before the frame qp is selected.
2511*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
2512*fb1b10abSAndroid Build Coastguard Worker     vp9_cyclic_refresh_update_parameters(cpi);
2513*fb1b10abSAndroid Build Coastguard Worker 
2514*fb1b10abSAndroid Build Coastguard Worker   if (frame_is_intra_only(cm))
2515*fb1b10abSAndroid Build Coastguard Worker     target = vp9_calc_iframe_target_size_one_pass_cbr(cpi);
2516*fb1b10abSAndroid Build Coastguard Worker   else
2517*fb1b10abSAndroid Build Coastguard Worker     target = vp9_calc_pframe_target_size_one_pass_cbr(cpi);
2518*fb1b10abSAndroid Build Coastguard Worker 
2519*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_set_frame_target(cpi, target);
2520*fb1b10abSAndroid Build Coastguard Worker 
2521*fb1b10abSAndroid Build Coastguard Worker   if (cm->show_frame) vp9_update_buffer_level_preencode(cpi);
2522*fb1b10abSAndroid Build Coastguard Worker 
2523*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC)
2524*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_pending = vp9_resize_one_pass_cbr(cpi);
2525*fb1b10abSAndroid Build Coastguard Worker   else
2526*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_pending = 0;
2527*fb1b10abSAndroid Build Coastguard Worker }
2528*fb1b10abSAndroid Build Coastguard Worker 
vp9_compute_qdelta(const RATE_CONTROL * rc,double qstart,double qtarget,vpx_bit_depth_t bit_depth)2529*fb1b10abSAndroid Build Coastguard Worker int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget,
2530*fb1b10abSAndroid Build Coastguard Worker                        vpx_bit_depth_t bit_depth) {
2531*fb1b10abSAndroid Build Coastguard Worker   int start_index = rc->worst_quality;
2532*fb1b10abSAndroid Build Coastguard Worker   int target_index = rc->worst_quality;
2533*fb1b10abSAndroid Build Coastguard Worker   int i;
2534*fb1b10abSAndroid Build Coastguard Worker 
2535*fb1b10abSAndroid Build Coastguard Worker   // Convert the average q value to an index.
2536*fb1b10abSAndroid Build Coastguard Worker   for (i = rc->best_quality; i < rc->worst_quality; ++i) {
2537*fb1b10abSAndroid Build Coastguard Worker     start_index = i;
2538*fb1b10abSAndroid Build Coastguard Worker     if (vp9_convert_qindex_to_q(i, bit_depth) >= qstart) break;
2539*fb1b10abSAndroid Build Coastguard Worker   }
2540*fb1b10abSAndroid Build Coastguard Worker 
2541*fb1b10abSAndroid Build Coastguard Worker   // Convert the q target to an index
2542*fb1b10abSAndroid Build Coastguard Worker   for (i = rc->best_quality; i < rc->worst_quality; ++i) {
2543*fb1b10abSAndroid Build Coastguard Worker     target_index = i;
2544*fb1b10abSAndroid Build Coastguard Worker     if (vp9_convert_qindex_to_q(i, bit_depth) >= qtarget) break;
2545*fb1b10abSAndroid Build Coastguard Worker   }
2546*fb1b10abSAndroid Build Coastguard Worker 
2547*fb1b10abSAndroid Build Coastguard Worker   return target_index - start_index;
2548*fb1b10abSAndroid Build Coastguard Worker }
2549*fb1b10abSAndroid Build Coastguard Worker 
vp9_compute_qdelta_by_rate(const RATE_CONTROL * rc,FRAME_TYPE frame_type,int qindex,double rate_target_ratio,vpx_bit_depth_t bit_depth)2550*fb1b10abSAndroid Build Coastguard Worker int vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
2551*fb1b10abSAndroid Build Coastguard Worker                                int qindex, double rate_target_ratio,
2552*fb1b10abSAndroid Build Coastguard Worker                                vpx_bit_depth_t bit_depth) {
2553*fb1b10abSAndroid Build Coastguard Worker   int target_index = rc->worst_quality;
2554*fb1b10abSAndroid Build Coastguard Worker   int i;
2555*fb1b10abSAndroid Build Coastguard Worker 
2556*fb1b10abSAndroid Build Coastguard Worker   // Look up the current projected bits per block for the base index
2557*fb1b10abSAndroid Build Coastguard Worker   const int base_bits_per_mb =
2558*fb1b10abSAndroid Build Coastguard Worker       vp9_rc_bits_per_mb(frame_type, qindex, 1.0, bit_depth);
2559*fb1b10abSAndroid Build Coastguard Worker 
2560*fb1b10abSAndroid Build Coastguard Worker   // Find the target bits per mb based on the base value and given ratio.
2561*fb1b10abSAndroid Build Coastguard Worker   const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb);
2562*fb1b10abSAndroid Build Coastguard Worker 
2563*fb1b10abSAndroid Build Coastguard Worker   // Convert the q target to an index
2564*fb1b10abSAndroid Build Coastguard Worker   for (i = rc->best_quality; i < rc->worst_quality; ++i) {
2565*fb1b10abSAndroid Build Coastguard Worker     if (vp9_rc_bits_per_mb(frame_type, i, 1.0, bit_depth) <=
2566*fb1b10abSAndroid Build Coastguard Worker         target_bits_per_mb) {
2567*fb1b10abSAndroid Build Coastguard Worker       target_index = i;
2568*fb1b10abSAndroid Build Coastguard Worker       break;
2569*fb1b10abSAndroid Build Coastguard Worker     }
2570*fb1b10abSAndroid Build Coastguard Worker   }
2571*fb1b10abSAndroid Build Coastguard Worker   return target_index - qindex;
2572*fb1b10abSAndroid Build Coastguard Worker }
2573*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_set_gf_interval_range(const VP9_COMP * const cpi,RATE_CONTROL * const rc)2574*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_set_gf_interval_range(const VP9_COMP *const cpi,
2575*fb1b10abSAndroid Build Coastguard Worker                                   RATE_CONTROL *const rc) {
2576*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
2577*fb1b10abSAndroid Build Coastguard Worker 
2578*fb1b10abSAndroid Build Coastguard Worker   // Special case code for 1 pass fixed Q mode tests
2579*fb1b10abSAndroid Build Coastguard Worker   if ((oxcf->pass == 0) && (oxcf->rc_mode == VPX_Q)) {
2580*fb1b10abSAndroid Build Coastguard Worker     rc->max_gf_interval = FIXED_GF_INTERVAL;
2581*fb1b10abSAndroid Build Coastguard Worker     rc->min_gf_interval = FIXED_GF_INTERVAL;
2582*fb1b10abSAndroid Build Coastguard Worker     rc->static_scene_max_gf_interval = FIXED_GF_INTERVAL;
2583*fb1b10abSAndroid Build Coastguard Worker   } else {
2584*fb1b10abSAndroid Build Coastguard Worker     double framerate = cpi->framerate;
2585*fb1b10abSAndroid Build Coastguard Worker     // Set Maximum gf/arf interval
2586*fb1b10abSAndroid Build Coastguard Worker     rc->max_gf_interval = oxcf->max_gf_interval;
2587*fb1b10abSAndroid Build Coastguard Worker     rc->min_gf_interval = oxcf->min_gf_interval;
2588*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_RATE_CTRL
2589*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->use_simple_encode_api) {
2590*fb1b10abSAndroid Build Coastguard Worker       // In this experiment, we avoid framerate being changed dynamically during
2591*fb1b10abSAndroid Build Coastguard Worker       // encoding.
2592*fb1b10abSAndroid Build Coastguard Worker       framerate = oxcf->init_framerate;
2593*fb1b10abSAndroid Build Coastguard Worker     }
2594*fb1b10abSAndroid Build Coastguard Worker #endif  // CONFIG_RATE_CTRL
2595*fb1b10abSAndroid Build Coastguard Worker     if (rc->min_gf_interval == 0) {
2596*fb1b10abSAndroid Build Coastguard Worker       rc->min_gf_interval = vp9_rc_get_default_min_gf_interval(
2597*fb1b10abSAndroid Build Coastguard Worker           oxcf->width, oxcf->height, framerate);
2598*fb1b10abSAndroid Build Coastguard Worker     }
2599*fb1b10abSAndroid Build Coastguard Worker     if (rc->max_gf_interval == 0) {
2600*fb1b10abSAndroid Build Coastguard Worker       rc->max_gf_interval =
2601*fb1b10abSAndroid Build Coastguard Worker           vp9_rc_get_default_max_gf_interval(framerate, rc->min_gf_interval);
2602*fb1b10abSAndroid Build Coastguard Worker     }
2603*fb1b10abSAndroid Build Coastguard Worker 
2604*fb1b10abSAndroid Build Coastguard Worker     // Extended max interval for genuinely static scenes like slide shows.
2605*fb1b10abSAndroid Build Coastguard Worker     rc->static_scene_max_gf_interval = MAX_STATIC_GF_GROUP_LENGTH;
2606*fb1b10abSAndroid Build Coastguard Worker 
2607*fb1b10abSAndroid Build Coastguard Worker     if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
2608*fb1b10abSAndroid Build Coastguard Worker       rc->max_gf_interval = rc->static_scene_max_gf_interval;
2609*fb1b10abSAndroid Build Coastguard Worker 
2610*fb1b10abSAndroid Build Coastguard Worker     // Clamp min to max
2611*fb1b10abSAndroid Build Coastguard Worker     rc->min_gf_interval = VPXMIN(rc->min_gf_interval, rc->max_gf_interval);
2612*fb1b10abSAndroid Build Coastguard Worker 
2613*fb1b10abSAndroid Build Coastguard Worker     if (oxcf->target_level == LEVEL_AUTO) {
2614*fb1b10abSAndroid Build Coastguard Worker       const uint32_t pic_size = cpi->common.width * cpi->common.height;
2615*fb1b10abSAndroid Build Coastguard Worker       const uint32_t pic_breadth =
2616*fb1b10abSAndroid Build Coastguard Worker           VPXMAX(cpi->common.width, cpi->common.height);
2617*fb1b10abSAndroid Build Coastguard Worker       int i;
2618*fb1b10abSAndroid Build Coastguard Worker       for (i = 0; i < VP9_LEVELS; ++i) {
2619*fb1b10abSAndroid Build Coastguard Worker         if (vp9_level_defs[i].max_luma_picture_size >= pic_size &&
2620*fb1b10abSAndroid Build Coastguard Worker             vp9_level_defs[i].max_luma_picture_breadth >= pic_breadth) {
2621*fb1b10abSAndroid Build Coastguard Worker           if (rc->min_gf_interval <=
2622*fb1b10abSAndroid Build Coastguard Worker               (int)vp9_level_defs[i].min_altref_distance) {
2623*fb1b10abSAndroid Build Coastguard Worker             rc->min_gf_interval = (int)vp9_level_defs[i].min_altref_distance;
2624*fb1b10abSAndroid Build Coastguard Worker             rc->max_gf_interval =
2625*fb1b10abSAndroid Build Coastguard Worker                 VPXMAX(rc->max_gf_interval, rc->min_gf_interval);
2626*fb1b10abSAndroid Build Coastguard Worker           }
2627*fb1b10abSAndroid Build Coastguard Worker           break;
2628*fb1b10abSAndroid Build Coastguard Worker         }
2629*fb1b10abSAndroid Build Coastguard Worker       }
2630*fb1b10abSAndroid Build Coastguard Worker     }
2631*fb1b10abSAndroid Build Coastguard Worker   }
2632*fb1b10abSAndroid Build Coastguard Worker }
2633*fb1b10abSAndroid Build Coastguard Worker 
vp9_rc_update_framerate(VP9_COMP * cpi)2634*fb1b10abSAndroid Build Coastguard Worker void vp9_rc_update_framerate(VP9_COMP *cpi) {
2635*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
2636*fb1b10abSAndroid Build Coastguard Worker   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
2637*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2638*fb1b10abSAndroid Build Coastguard Worker 
2639*fb1b10abSAndroid Build Coastguard Worker   rc->avg_frame_bandwidth = saturate_cast_double_to_int(
2640*fb1b10abSAndroid Build Coastguard Worker       round(oxcf->target_bandwidth / cpi->framerate));
2641*fb1b10abSAndroid Build Coastguard Worker 
2642*fb1b10abSAndroid Build Coastguard Worker   int64_t vbr_min_bits =
2643*fb1b10abSAndroid Build Coastguard Worker       (int64_t)rc->avg_frame_bandwidth * oxcf->two_pass_vbrmin_section / 100;
2644*fb1b10abSAndroid Build Coastguard Worker   vbr_min_bits = VPXMIN(vbr_min_bits, INT_MAX);
2645*fb1b10abSAndroid Build Coastguard Worker 
2646*fb1b10abSAndroid Build Coastguard Worker   rc->min_frame_bandwidth = VPXMAX((int)vbr_min_bits, FRAME_OVERHEAD_BITS);
2647*fb1b10abSAndroid Build Coastguard Worker 
2648*fb1b10abSAndroid Build Coastguard Worker   // A maximum bitrate for a frame is defined.
2649*fb1b10abSAndroid Build Coastguard Worker   // However this limit is extended if a very high rate is given on the command
2650*fb1b10abSAndroid Build Coastguard Worker   // line or the rate can not be achieved because of a user specified max q
2651*fb1b10abSAndroid Build Coastguard Worker   // (e.g. when the user specifies lossless encode).
2652*fb1b10abSAndroid Build Coastguard Worker   //
2653*fb1b10abSAndroid Build Coastguard Worker   // If a level is specified that requires a lower maximum rate then the level
2654*fb1b10abSAndroid Build Coastguard Worker   // value take precedence.
2655*fb1b10abSAndroid Build Coastguard Worker   int64_t vbr_max_bits =
2656*fb1b10abSAndroid Build Coastguard Worker       (int64_t)rc->avg_frame_bandwidth * oxcf->two_pass_vbrmax_section / 100;
2657*fb1b10abSAndroid Build Coastguard Worker   vbr_max_bits = VPXMIN(vbr_max_bits, INT_MAX);
2658*fb1b10abSAndroid Build Coastguard Worker 
2659*fb1b10abSAndroid Build Coastguard Worker   rc->max_frame_bandwidth =
2660*fb1b10abSAndroid Build Coastguard Worker       VPXMAX(VPXMAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), (int)vbr_max_bits);
2661*fb1b10abSAndroid Build Coastguard Worker 
2662*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_set_gf_interval_range(cpi, rc);
2663*fb1b10abSAndroid Build Coastguard Worker }
2664*fb1b10abSAndroid Build Coastguard Worker 
2665*fb1b10abSAndroid Build Coastguard Worker #define VBR_PCT_ADJUSTMENT_LIMIT 50
2666*fb1b10abSAndroid Build Coastguard Worker // For VBR...adjustment to the frame target based on error from previous frames
vbr_rate_correction(VP9_COMP * cpi,int * this_frame_target)2667*fb1b10abSAndroid Build Coastguard Worker static void vbr_rate_correction(VP9_COMP *cpi, int *this_frame_target) {
2668*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2669*fb1b10abSAndroid Build Coastguard Worker   int64_t vbr_bits_off_target = rc->vbr_bits_off_target;
2670*fb1b10abSAndroid Build Coastguard Worker   int64_t frame_target = *this_frame_target;
2671*fb1b10abSAndroid Build Coastguard Worker   int frame_window = (int)VPXMIN(
2672*fb1b10abSAndroid Build Coastguard Worker       16, cpi->twopass.total_stats.count - cpi->common.current_video_frame);
2673*fb1b10abSAndroid Build Coastguard Worker 
2674*fb1b10abSAndroid Build Coastguard Worker   // Calcluate the adjustment to rate for this frame.
2675*fb1b10abSAndroid Build Coastguard Worker   if (frame_window > 0) {
2676*fb1b10abSAndroid Build Coastguard Worker     int64_t max_delta = (vbr_bits_off_target > 0)
2677*fb1b10abSAndroid Build Coastguard Worker                             ? (vbr_bits_off_target / frame_window)
2678*fb1b10abSAndroid Build Coastguard Worker                             : (-vbr_bits_off_target / frame_window);
2679*fb1b10abSAndroid Build Coastguard Worker 
2680*fb1b10abSAndroid Build Coastguard Worker     max_delta =
2681*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(max_delta, ((frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100));
2682*fb1b10abSAndroid Build Coastguard Worker 
2683*fb1b10abSAndroid Build Coastguard Worker     // vbr_bits_off_target > 0 means we have extra bits to spend
2684*fb1b10abSAndroid Build Coastguard Worker     if (vbr_bits_off_target > 0) {
2685*fb1b10abSAndroid Build Coastguard Worker       frame_target += VPXMIN(vbr_bits_off_target, max_delta);
2686*fb1b10abSAndroid Build Coastguard Worker     } else {
2687*fb1b10abSAndroid Build Coastguard Worker       frame_target -= VPXMIN(-vbr_bits_off_target, max_delta);
2688*fb1b10abSAndroid Build Coastguard Worker     }
2689*fb1b10abSAndroid Build Coastguard Worker   }
2690*fb1b10abSAndroid Build Coastguard Worker 
2691*fb1b10abSAndroid Build Coastguard Worker   // Fast redistribution of bits arising from massive local undershoot.
2692*fb1b10abSAndroid Build Coastguard Worker   // Don't do it for kf,arf,gf or overlay frames.
2693*fb1b10abSAndroid Build Coastguard Worker   if (!frame_is_kf_gf_arf(cpi) && !rc->is_src_frame_alt_ref &&
2694*fb1b10abSAndroid Build Coastguard Worker       rc->vbr_bits_off_target_fast) {
2695*fb1b10abSAndroid Build Coastguard Worker     int64_t one_frame_bits = VPXMAX(rc->avg_frame_bandwidth, frame_target);
2696*fb1b10abSAndroid Build Coastguard Worker     int64_t fast_extra_bits =
2697*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(rc->vbr_bits_off_target_fast, one_frame_bits);
2698*fb1b10abSAndroid Build Coastguard Worker     fast_extra_bits =
2699*fb1b10abSAndroid Build Coastguard Worker         VPXMIN(fast_extra_bits,
2700*fb1b10abSAndroid Build Coastguard Worker                VPXMAX(one_frame_bits / 8, rc->vbr_bits_off_target_fast / 8));
2701*fb1b10abSAndroid Build Coastguard Worker     frame_target += fast_extra_bits;
2702*fb1b10abSAndroid Build Coastguard Worker     rc->vbr_bits_off_target_fast -= fast_extra_bits;
2703*fb1b10abSAndroid Build Coastguard Worker   }
2704*fb1b10abSAndroid Build Coastguard Worker 
2705*fb1b10abSAndroid Build Coastguard Worker   // Clamp the target for the frame to the maximum allowed for one frame.
2706*fb1b10abSAndroid Build Coastguard Worker   *this_frame_target = (int)VPXMIN(frame_target, INT_MAX);
2707*fb1b10abSAndroid Build Coastguard Worker }
2708*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_target_rate(VP9_COMP * cpi)2709*fb1b10abSAndroid Build Coastguard Worker void vp9_set_target_rate(VP9_COMP *cpi) {
2710*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2711*fb1b10abSAndroid Build Coastguard Worker   int target_rate = rc->base_frame_target;
2712*fb1b10abSAndroid Build Coastguard Worker 
2713*fb1b10abSAndroid Build Coastguard Worker   if (cpi->common.frame_type == KEY_FRAME)
2714*fb1b10abSAndroid Build Coastguard Worker     target_rate = vp9_rc_clamp_iframe_target_size(cpi, target_rate);
2715*fb1b10abSAndroid Build Coastguard Worker   else
2716*fb1b10abSAndroid Build Coastguard Worker     target_rate = vp9_rc_clamp_pframe_target_size(cpi, target_rate);
2717*fb1b10abSAndroid Build Coastguard Worker 
2718*fb1b10abSAndroid Build Coastguard Worker   if (!cpi->oxcf.vbr_corpus_complexity) {
2719*fb1b10abSAndroid Build Coastguard Worker     // Correction to rate target based on prior over or under shoot.
2720*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_VBR || cpi->oxcf.rc_mode == VPX_CQ)
2721*fb1b10abSAndroid Build Coastguard Worker       vbr_rate_correction(cpi, &target_rate);
2722*fb1b10abSAndroid Build Coastguard Worker   }
2723*fb1b10abSAndroid Build Coastguard Worker   vp9_rc_set_frame_target(cpi, target_rate);
2724*fb1b10abSAndroid Build Coastguard Worker }
2725*fb1b10abSAndroid Build Coastguard Worker 
2726*fb1b10abSAndroid Build Coastguard Worker // Check if we should resize, based on average QP from past x frames.
2727*fb1b10abSAndroid Build Coastguard Worker // Only allow for resize at most one scale down for now, scaling factor is 2.
vp9_resize_one_pass_cbr(VP9_COMP * cpi)2728*fb1b10abSAndroid Build Coastguard Worker int vp9_resize_one_pass_cbr(VP9_COMP *cpi) {
2729*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
2730*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2731*fb1b10abSAndroid Build Coastguard Worker   RESIZE_ACTION resize_action = NO_RESIZE;
2732*fb1b10abSAndroid Build Coastguard Worker   int avg_qp_thr1 = 70;
2733*fb1b10abSAndroid Build Coastguard Worker   int avg_qp_thr2 = 50;
2734*fb1b10abSAndroid Build Coastguard Worker   // Don't allow for resized frame to go below 320x180, resize in steps of 3/4.
2735*fb1b10abSAndroid Build Coastguard Worker   int min_width = (320 * 4) / 3;
2736*fb1b10abSAndroid Build Coastguard Worker   int min_height = (180 * 4) / 3;
2737*fb1b10abSAndroid Build Coastguard Worker   int down_size_on = 1;
2738*fb1b10abSAndroid Build Coastguard Worker   int force_downsize_rate = 0;
2739*fb1b10abSAndroid Build Coastguard Worker   cpi->resize_scale_num = 1;
2740*fb1b10abSAndroid Build Coastguard Worker   cpi->resize_scale_den = 1;
2741*fb1b10abSAndroid Build Coastguard Worker   // Don't resize on key frame; reset the counters on key frame.
2742*fb1b10abSAndroid Build Coastguard Worker   if (cm->frame_type == KEY_FRAME) {
2743*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_avg_qp = 0;
2744*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_count = 0;
2745*fb1b10abSAndroid Build Coastguard Worker     return 0;
2746*fb1b10abSAndroid Build Coastguard Worker   }
2747*fb1b10abSAndroid Build Coastguard Worker 
2748*fb1b10abSAndroid Build Coastguard Worker   // No resizing down if frame size is below some limit.
2749*fb1b10abSAndroid Build Coastguard Worker   if ((cm->width * cm->height) < min_width * min_height) down_size_on = 0;
2750*fb1b10abSAndroid Build Coastguard Worker 
2751*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_TEMPORAL_DENOISING
2752*fb1b10abSAndroid Build Coastguard Worker   // If denoiser is on, apply a smaller qp threshold.
2753*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.noise_sensitivity > 0) {
2754*fb1b10abSAndroid Build Coastguard Worker     avg_qp_thr1 = 60;
2755*fb1b10abSAndroid Build Coastguard Worker     avg_qp_thr2 = 40;
2756*fb1b10abSAndroid Build Coastguard Worker   }
2757*fb1b10abSAndroid Build Coastguard Worker #endif
2758*fb1b10abSAndroid Build Coastguard Worker 
2759*fb1b10abSAndroid Build Coastguard Worker   // Force downsize based on per-frame-bandwidth, for extreme case,
2760*fb1b10abSAndroid Build Coastguard Worker   // for HD input.
2761*fb1b10abSAndroid Build Coastguard Worker   if (cpi->resize_state == ORIG && cm->width * cm->height >= 1280 * 720) {
2762*fb1b10abSAndroid Build Coastguard Worker     if (rc->avg_frame_bandwidth < 300000 / 30) {
2763*fb1b10abSAndroid Build Coastguard Worker       resize_action = DOWN_ONEHALF;
2764*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_state = ONE_HALF;
2765*fb1b10abSAndroid Build Coastguard Worker       force_downsize_rate = 1;
2766*fb1b10abSAndroid Build Coastguard Worker     } else if (rc->avg_frame_bandwidth < 400000 / 30) {
2767*fb1b10abSAndroid Build Coastguard Worker       resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR;
2768*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER;
2769*fb1b10abSAndroid Build Coastguard Worker       force_downsize_rate = 1;
2770*fb1b10abSAndroid Build Coastguard Worker     }
2771*fb1b10abSAndroid Build Coastguard Worker   } else if (cpi->resize_state == THREE_QUARTER &&
2772*fb1b10abSAndroid Build Coastguard Worker              cm->width * cm->height >= 960 * 540) {
2773*fb1b10abSAndroid Build Coastguard Worker     if (rc->avg_frame_bandwidth < 300000 / 30) {
2774*fb1b10abSAndroid Build Coastguard Worker       resize_action = DOWN_ONEHALF;
2775*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_state = ONE_HALF;
2776*fb1b10abSAndroid Build Coastguard Worker       force_downsize_rate = 1;
2777*fb1b10abSAndroid Build Coastguard Worker     }
2778*fb1b10abSAndroid Build Coastguard Worker   }
2779*fb1b10abSAndroid Build Coastguard Worker 
2780*fb1b10abSAndroid Build Coastguard Worker   // Resize based on average buffer underflow and QP over some window.
2781*fb1b10abSAndroid Build Coastguard Worker   // Ignore samples close to key frame, since QP is usually high after key.
2782*fb1b10abSAndroid Build Coastguard Worker   if (!force_downsize_rate && cpi->rc.frames_since_key > cpi->framerate) {
2783*fb1b10abSAndroid Build Coastguard Worker     const int window = VPXMIN(30, (int)round(2 * cpi->framerate));
2784*fb1b10abSAndroid Build Coastguard Worker     cpi->resize_avg_qp += rc->last_q[INTER_FRAME];
2785*fb1b10abSAndroid Build Coastguard Worker     if (cpi->rc.buffer_level < (int)(30 * rc->optimal_buffer_level / 100))
2786*fb1b10abSAndroid Build Coastguard Worker       ++cpi->resize_buffer_underflow;
2787*fb1b10abSAndroid Build Coastguard Worker     ++cpi->resize_count;
2788*fb1b10abSAndroid Build Coastguard Worker     // Check for resize action every "window" frames.
2789*fb1b10abSAndroid Build Coastguard Worker     if (cpi->resize_count >= window) {
2790*fb1b10abSAndroid Build Coastguard Worker       int avg_qp = cpi->resize_avg_qp / cpi->resize_count;
2791*fb1b10abSAndroid Build Coastguard Worker       // Resize down if buffer level has underflowed sufficient amount in past
2792*fb1b10abSAndroid Build Coastguard Worker       // window, and we are at original or 3/4 of original resolution.
2793*fb1b10abSAndroid Build Coastguard Worker       // Resize back up if average QP is low, and we are currently in a resized
2794*fb1b10abSAndroid Build Coastguard Worker       // down state, i.e. 1/2 or 3/4 of original resolution.
2795*fb1b10abSAndroid Build Coastguard Worker       // Currently, use a flag to turn 3/4 resizing feature on/off.
2796*fb1b10abSAndroid Build Coastguard Worker       if (cpi->resize_buffer_underflow > (cpi->resize_count >> 2) &&
2797*fb1b10abSAndroid Build Coastguard Worker           down_size_on) {
2798*fb1b10abSAndroid Build Coastguard Worker         if (cpi->resize_state == THREE_QUARTER) {
2799*fb1b10abSAndroid Build Coastguard Worker           resize_action = DOWN_ONEHALF;
2800*fb1b10abSAndroid Build Coastguard Worker           cpi->resize_state = ONE_HALF;
2801*fb1b10abSAndroid Build Coastguard Worker         } else if (cpi->resize_state == ORIG) {
2802*fb1b10abSAndroid Build Coastguard Worker           resize_action = ONEHALFONLY_RESIZE ? DOWN_ONEHALF : DOWN_THREEFOUR;
2803*fb1b10abSAndroid Build Coastguard Worker           cpi->resize_state = ONEHALFONLY_RESIZE ? ONE_HALF : THREE_QUARTER;
2804*fb1b10abSAndroid Build Coastguard Worker         }
2805*fb1b10abSAndroid Build Coastguard Worker       } else if (cpi->resize_state != ORIG &&
2806*fb1b10abSAndroid Build Coastguard Worker                  avg_qp < avg_qp_thr1 * cpi->rc.worst_quality / 100) {
2807*fb1b10abSAndroid Build Coastguard Worker         if (cpi->resize_state == THREE_QUARTER ||
2808*fb1b10abSAndroid Build Coastguard Worker             avg_qp < avg_qp_thr2 * cpi->rc.worst_quality / 100 ||
2809*fb1b10abSAndroid Build Coastguard Worker             ONEHALFONLY_RESIZE) {
2810*fb1b10abSAndroid Build Coastguard Worker           resize_action = UP_ORIG;
2811*fb1b10abSAndroid Build Coastguard Worker           cpi->resize_state = ORIG;
2812*fb1b10abSAndroid Build Coastguard Worker         } else if (cpi->resize_state == ONE_HALF) {
2813*fb1b10abSAndroid Build Coastguard Worker           resize_action = UP_THREEFOUR;
2814*fb1b10abSAndroid Build Coastguard Worker           cpi->resize_state = THREE_QUARTER;
2815*fb1b10abSAndroid Build Coastguard Worker         }
2816*fb1b10abSAndroid Build Coastguard Worker       }
2817*fb1b10abSAndroid Build Coastguard Worker       // Reset for next window measurement.
2818*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_avg_qp = 0;
2819*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_count = 0;
2820*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_buffer_underflow = 0;
2821*fb1b10abSAndroid Build Coastguard Worker     }
2822*fb1b10abSAndroid Build Coastguard Worker   }
2823*fb1b10abSAndroid Build Coastguard Worker   // If decision is to resize, reset some quantities, and check is we should
2824*fb1b10abSAndroid Build Coastguard Worker   // reduce rate correction factor,
2825*fb1b10abSAndroid Build Coastguard Worker   if (resize_action != NO_RESIZE) {
2826*fb1b10abSAndroid Build Coastguard Worker     int target_bits_per_frame;
2827*fb1b10abSAndroid Build Coastguard Worker     int active_worst_quality;
2828*fb1b10abSAndroid Build Coastguard Worker     int qindex;
2829*fb1b10abSAndroid Build Coastguard Worker     int tot_scale_change;
2830*fb1b10abSAndroid Build Coastguard Worker     if (resize_action == DOWN_THREEFOUR || resize_action == UP_THREEFOUR) {
2831*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_num = 3;
2832*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_den = 4;
2833*fb1b10abSAndroid Build Coastguard Worker     } else if (resize_action == DOWN_ONEHALF) {
2834*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_num = 1;
2835*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_den = 2;
2836*fb1b10abSAndroid Build Coastguard Worker     } else {  // UP_ORIG or anything else
2837*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_num = 1;
2838*fb1b10abSAndroid Build Coastguard Worker       cpi->resize_scale_den = 1;
2839*fb1b10abSAndroid Build Coastguard Worker     }
2840*fb1b10abSAndroid Build Coastguard Worker     tot_scale_change = (cpi->resize_scale_den * cpi->resize_scale_den) /
2841*fb1b10abSAndroid Build Coastguard Worker                        (cpi->resize_scale_num * cpi->resize_scale_num);
2842*fb1b10abSAndroid Build Coastguard Worker     // Reset buffer level to optimal, update target size.
2843*fb1b10abSAndroid Build Coastguard Worker     rc->buffer_level = rc->optimal_buffer_level;
2844*fb1b10abSAndroid Build Coastguard Worker     rc->bits_off_target = rc->optimal_buffer_level;
2845*fb1b10abSAndroid Build Coastguard Worker     rc->this_frame_target = vp9_calc_pframe_target_size_one_pass_cbr(cpi);
2846*fb1b10abSAndroid Build Coastguard Worker     // Get the projected qindex, based on the scaled target frame size (scaled
2847*fb1b10abSAndroid Build Coastguard Worker     // so target_bits_per_mb in vp9_rc_regulate_q will be correct target).
2848*fb1b10abSAndroid Build Coastguard Worker     target_bits_per_frame = (resize_action >= 0)
2849*fb1b10abSAndroid Build Coastguard Worker                                 ? rc->this_frame_target * tot_scale_change
2850*fb1b10abSAndroid Build Coastguard Worker                                 : rc->this_frame_target / tot_scale_change;
2851*fb1b10abSAndroid Build Coastguard Worker     active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi);
2852*fb1b10abSAndroid Build Coastguard Worker     qindex = vp9_rc_regulate_q(cpi, target_bits_per_frame, rc->best_quality,
2853*fb1b10abSAndroid Build Coastguard Worker                                active_worst_quality);
2854*fb1b10abSAndroid Build Coastguard Worker     // If resize is down, check if projected q index is close to worst_quality,
2855*fb1b10abSAndroid Build Coastguard Worker     // and if so, reduce the rate correction factor (since likely can afford
2856*fb1b10abSAndroid Build Coastguard Worker     // lower q for resized frame).
2857*fb1b10abSAndroid Build Coastguard Worker     if (resize_action > 0 && qindex > 90 * cpi->rc.worst_quality / 100) {
2858*fb1b10abSAndroid Build Coastguard Worker       rc->rate_correction_factors[INTER_NORMAL] *= 0.85;
2859*fb1b10abSAndroid Build Coastguard Worker     }
2860*fb1b10abSAndroid Build Coastguard Worker     // If resize is back up, check if projected q index is too much above the
2861*fb1b10abSAndroid Build Coastguard Worker     // current base_qindex, and if so, reduce the rate correction factor
2862*fb1b10abSAndroid Build Coastguard Worker     // (since prefer to keep q for resized frame at least close to previous q).
2863*fb1b10abSAndroid Build Coastguard Worker     if (resize_action < 0 && qindex > 130 * cm->base_qindex / 100) {
2864*fb1b10abSAndroid Build Coastguard Worker       rc->rate_correction_factors[INTER_NORMAL] *= 0.9;
2865*fb1b10abSAndroid Build Coastguard Worker     }
2866*fb1b10abSAndroid Build Coastguard Worker   }
2867*fb1b10abSAndroid Build Coastguard Worker   return resize_action;
2868*fb1b10abSAndroid Build Coastguard Worker }
2869*fb1b10abSAndroid Build Coastguard Worker 
adjust_gf_boost_lag_one_pass_vbr(VP9_COMP * cpi,uint64_t avg_sad_current)2870*fb1b10abSAndroid Build Coastguard Worker static void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi,
2871*fb1b10abSAndroid Build Coastguard Worker                                              uint64_t avg_sad_current) {
2872*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
2873*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
2874*fb1b10abSAndroid Build Coastguard Worker   int target;
2875*fb1b10abSAndroid Build Coastguard Worker   int found = 0;
2876*fb1b10abSAndroid Build Coastguard Worker   int found2 = 0;
2877*fb1b10abSAndroid Build Coastguard Worker   int frame;
2878*fb1b10abSAndroid Build Coastguard Worker   int i;
2879*fb1b10abSAndroid Build Coastguard Worker   uint64_t avg_source_sad_lag = avg_sad_current;
2880*fb1b10abSAndroid Build Coastguard Worker   int high_source_sad_lagindex = -1;
2881*fb1b10abSAndroid Build Coastguard Worker   int steady_sad_lagindex = -1;
2882*fb1b10abSAndroid Build Coastguard Worker   uint32_t sad_thresh1 = 70000;
2883*fb1b10abSAndroid Build Coastguard Worker   uint32_t sad_thresh2 = 120000;
2884*fb1b10abSAndroid Build Coastguard Worker   int low_content = 0;
2885*fb1b10abSAndroid Build Coastguard Worker   int high_content = 0;
2886*fb1b10abSAndroid Build Coastguard Worker   double rate_err = 1.0;
2887*fb1b10abSAndroid Build Coastguard Worker   // Get measure of complexity over the future frames, and get the first
2888*fb1b10abSAndroid Build Coastguard Worker   // future frame with high_source_sad/scene-change.
2889*fb1b10abSAndroid Build Coastguard Worker   int tot_frames = (int)vp9_lookahead_depth(cpi->lookahead) - 1;
2890*fb1b10abSAndroid Build Coastguard Worker   for (frame = tot_frames; frame >= 1; --frame) {
2891*fb1b10abSAndroid Build Coastguard Worker     const int lagframe_idx = tot_frames - frame + 1;
2892*fb1b10abSAndroid Build Coastguard Worker     uint64_t reference_sad = rc->avg_source_sad[0];
2893*fb1b10abSAndroid Build Coastguard Worker     for (i = 1; i < lagframe_idx; ++i) {
2894*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_source_sad[i] > 0)
2895*fb1b10abSAndroid Build Coastguard Worker         reference_sad = (3 * reference_sad + rc->avg_source_sad[i]) >> 2;
2896*fb1b10abSAndroid Build Coastguard Worker     }
2897*fb1b10abSAndroid Build Coastguard Worker     // Detect up-coming scene change.
2898*fb1b10abSAndroid Build Coastguard Worker     if (!found &&
2899*fb1b10abSAndroid Build Coastguard Worker         (rc->avg_source_sad[lagframe_idx] >
2900*fb1b10abSAndroid Build Coastguard Worker              VPXMAX(sad_thresh1, (unsigned int)(reference_sad << 1)) ||
2901*fb1b10abSAndroid Build Coastguard Worker          rc->avg_source_sad[lagframe_idx] >
2902*fb1b10abSAndroid Build Coastguard Worker              VPXMAX(3 * sad_thresh1 >> 2,
2903*fb1b10abSAndroid Build Coastguard Worker                     (unsigned int)(reference_sad << 2)))) {
2904*fb1b10abSAndroid Build Coastguard Worker       high_source_sad_lagindex = lagframe_idx;
2905*fb1b10abSAndroid Build Coastguard Worker       found = 1;
2906*fb1b10abSAndroid Build Coastguard Worker     }
2907*fb1b10abSAndroid Build Coastguard Worker     // Detect change from motion to steady.
2908*fb1b10abSAndroid Build Coastguard Worker     if (!found2 && lagframe_idx > 1 && lagframe_idx < tot_frames &&
2909*fb1b10abSAndroid Build Coastguard Worker         rc->avg_source_sad[lagframe_idx - 1] > (sad_thresh1 >> 2)) {
2910*fb1b10abSAndroid Build Coastguard Worker       found2 = 1;
2911*fb1b10abSAndroid Build Coastguard Worker       for (i = lagframe_idx; i < tot_frames; ++i) {
2912*fb1b10abSAndroid Build Coastguard Worker         if (!(rc->avg_source_sad[i] > 0 &&
2913*fb1b10abSAndroid Build Coastguard Worker               rc->avg_source_sad[i] < (sad_thresh1 >> 2) &&
2914*fb1b10abSAndroid Build Coastguard Worker               rc->avg_source_sad[i] <
2915*fb1b10abSAndroid Build Coastguard Worker                   (rc->avg_source_sad[lagframe_idx - 1] >> 1))) {
2916*fb1b10abSAndroid Build Coastguard Worker           found2 = 0;
2917*fb1b10abSAndroid Build Coastguard Worker           i = tot_frames;
2918*fb1b10abSAndroid Build Coastguard Worker         }
2919*fb1b10abSAndroid Build Coastguard Worker       }
2920*fb1b10abSAndroid Build Coastguard Worker       if (found2) steady_sad_lagindex = lagframe_idx;
2921*fb1b10abSAndroid Build Coastguard Worker     }
2922*fb1b10abSAndroid Build Coastguard Worker     avg_source_sad_lag += rc->avg_source_sad[lagframe_idx];
2923*fb1b10abSAndroid Build Coastguard Worker   }
2924*fb1b10abSAndroid Build Coastguard Worker   if (tot_frames > 0) avg_source_sad_lag = avg_source_sad_lag / tot_frames;
2925*fb1b10abSAndroid Build Coastguard Worker   // Constrain distance between detected scene cuts.
2926*fb1b10abSAndroid Build Coastguard Worker   if (high_source_sad_lagindex != -1 &&
2927*fb1b10abSAndroid Build Coastguard Worker       high_source_sad_lagindex != rc->high_source_sad_lagindex - 1 &&
2928*fb1b10abSAndroid Build Coastguard Worker       abs(high_source_sad_lagindex - rc->high_source_sad_lagindex) < 4)
2929*fb1b10abSAndroid Build Coastguard Worker     rc->high_source_sad_lagindex = -1;
2930*fb1b10abSAndroid Build Coastguard Worker   else
2931*fb1b10abSAndroid Build Coastguard Worker     rc->high_source_sad_lagindex = high_source_sad_lagindex;
2932*fb1b10abSAndroid Build Coastguard Worker   // Adjust some factors for the next GF group, ignore initial key frame,
2933*fb1b10abSAndroid Build Coastguard Worker   // and only for lag_in_frames not too small.
2934*fb1b10abSAndroid Build Coastguard Worker   if (cpi->refresh_golden_frame == 1 && cm->current_video_frame > 30 &&
2935*fb1b10abSAndroid Build Coastguard Worker       cpi->oxcf.lag_in_frames > 8) {
2936*fb1b10abSAndroid Build Coastguard Worker     int frame_constraint;
2937*fb1b10abSAndroid Build Coastguard Worker     if (rc->rolling_target_bits > 0)
2938*fb1b10abSAndroid Build Coastguard Worker       rate_err =
2939*fb1b10abSAndroid Build Coastguard Worker           (double)rc->rolling_actual_bits / (double)rc->rolling_target_bits;
2940*fb1b10abSAndroid Build Coastguard Worker     high_content = high_source_sad_lagindex != -1 ||
2941*fb1b10abSAndroid Build Coastguard Worker                    avg_source_sad_lag > (rc->prev_avg_source_sad_lag << 1) ||
2942*fb1b10abSAndroid Build Coastguard Worker                    avg_source_sad_lag > sad_thresh2;
2943*fb1b10abSAndroid Build Coastguard Worker     low_content = high_source_sad_lagindex == -1 &&
2944*fb1b10abSAndroid Build Coastguard Worker                   ((avg_source_sad_lag < (rc->prev_avg_source_sad_lag >> 1)) ||
2945*fb1b10abSAndroid Build Coastguard Worker                    (avg_source_sad_lag < sad_thresh1));
2946*fb1b10abSAndroid Build Coastguard Worker     if (low_content) {
2947*fb1b10abSAndroid Build Coastguard Worker       rc->gfu_boost = DEFAULT_GF_BOOST;
2948*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval =
2949*fb1b10abSAndroid Build Coastguard Worker           VPXMIN(15, (3 * rc->baseline_gf_interval) >> 1);
2950*fb1b10abSAndroid Build Coastguard Worker     } else if (high_content) {
2951*fb1b10abSAndroid Build Coastguard Worker       rc->gfu_boost = DEFAULT_GF_BOOST >> 1;
2952*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval = (rate_err > 3.0)
2953*fb1b10abSAndroid Build Coastguard Worker                                      ? VPXMAX(10, rc->baseline_gf_interval >> 1)
2954*fb1b10abSAndroid Build Coastguard Worker                                      : VPXMAX(6, rc->baseline_gf_interval >> 1);
2955*fb1b10abSAndroid Build Coastguard Worker     }
2956*fb1b10abSAndroid Build Coastguard Worker     if (rc->baseline_gf_interval > cpi->oxcf.lag_in_frames - 1)
2957*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval = cpi->oxcf.lag_in_frames - 1;
2958*fb1b10abSAndroid Build Coastguard Worker     // Check for constraining gf_interval for up-coming scene/content changes,
2959*fb1b10abSAndroid Build Coastguard Worker     // or for up-coming key frame, whichever is closer.
2960*fb1b10abSAndroid Build Coastguard Worker     frame_constraint = rc->frames_to_key;
2961*fb1b10abSAndroid Build Coastguard Worker     if (rc->high_source_sad_lagindex > 0 &&
2962*fb1b10abSAndroid Build Coastguard Worker         frame_constraint > rc->high_source_sad_lagindex)
2963*fb1b10abSAndroid Build Coastguard Worker       frame_constraint = rc->high_source_sad_lagindex;
2964*fb1b10abSAndroid Build Coastguard Worker     if (steady_sad_lagindex > 3 && frame_constraint > steady_sad_lagindex)
2965*fb1b10abSAndroid Build Coastguard Worker       frame_constraint = steady_sad_lagindex;
2966*fb1b10abSAndroid Build Coastguard Worker     adjust_gfint_frame_constraint(cpi, frame_constraint);
2967*fb1b10abSAndroid Build Coastguard Worker     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
2968*fb1b10abSAndroid Build Coastguard Worker     // Adjust factors for active_worst setting & af_ratio for next gf interval.
2969*fb1b10abSAndroid Build Coastguard Worker     rc->fac_active_worst_inter = 150;  // corresponds to 3/2 (= 150 /100).
2970*fb1b10abSAndroid Build Coastguard Worker     rc->fac_active_worst_gf = 100;
2971*fb1b10abSAndroid Build Coastguard Worker     if (rate_err < 2.0 && !high_content) {
2972*fb1b10abSAndroid Build Coastguard Worker       rc->fac_active_worst_inter = 120;
2973*fb1b10abSAndroid Build Coastguard Worker       rc->fac_active_worst_gf = 90;
2974*fb1b10abSAndroid Build Coastguard Worker     } else if (rate_err > 8.0 && rc->avg_frame_qindex[INTER_FRAME] < 16) {
2975*fb1b10abSAndroid Build Coastguard Worker       // Increase active_worst faster at low Q if rate fluctuation is high.
2976*fb1b10abSAndroid Build Coastguard Worker       rc->fac_active_worst_inter = 200;
2977*fb1b10abSAndroid Build Coastguard Worker       if (rc->avg_frame_qindex[INTER_FRAME] < 8)
2978*fb1b10abSAndroid Build Coastguard Worker         rc->fac_active_worst_inter = 400;
2979*fb1b10abSAndroid Build Coastguard Worker     }
2980*fb1b10abSAndroid Build Coastguard Worker     if (low_content && rc->avg_frame_low_motion > 80) {
2981*fb1b10abSAndroid Build Coastguard Worker       rc->af_ratio_onepass_vbr = 15;
2982*fb1b10abSAndroid Build Coastguard Worker     } else if (high_content || rc->avg_frame_low_motion < 30) {
2983*fb1b10abSAndroid Build Coastguard Worker       rc->af_ratio_onepass_vbr = 5;
2984*fb1b10abSAndroid Build Coastguard Worker       rc->gfu_boost = DEFAULT_GF_BOOST >> 2;
2985*fb1b10abSAndroid Build Coastguard Worker     }
2986*fb1b10abSAndroid Build Coastguard Worker     if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf) {
2987*fb1b10abSAndroid Build Coastguard Worker       // Flag to disable usage of ARF based on past usage, only allow this
2988*fb1b10abSAndroid Build Coastguard Worker       // disabling if current frame/group does not start with key frame or
2989*fb1b10abSAndroid Build Coastguard Worker       // scene cut. Note perc_arf_usage is only computed for speed >= 5.
2990*fb1b10abSAndroid Build Coastguard Worker       int arf_usage_low =
2991*fb1b10abSAndroid Build Coastguard Worker           (cm->frame_type != KEY_FRAME && !rc->high_source_sad &&
2992*fb1b10abSAndroid Build Coastguard Worker            cpi->rc.perc_arf_usage < 15 && cpi->oxcf.speed >= 5);
2993*fb1b10abSAndroid Build Coastguard Worker       // Don't use alt-ref for this group under certain conditions.
2994*fb1b10abSAndroid Build Coastguard Worker       if (arf_usage_low ||
2995*fb1b10abSAndroid Build Coastguard Worker           (rc->high_source_sad_lagindex > 0 &&
2996*fb1b10abSAndroid Build Coastguard Worker            rc->high_source_sad_lagindex <= rc->frames_till_gf_update_due) ||
2997*fb1b10abSAndroid Build Coastguard Worker           (avg_source_sad_lag > 3 * sad_thresh1 >> 3)) {
2998*fb1b10abSAndroid Build Coastguard Worker         rc->source_alt_ref_pending = 0;
2999*fb1b10abSAndroid Build Coastguard Worker         rc->alt_ref_gf_group = 0;
3000*fb1b10abSAndroid Build Coastguard Worker       } else {
3001*fb1b10abSAndroid Build Coastguard Worker         rc->source_alt_ref_pending = 1;
3002*fb1b10abSAndroid Build Coastguard Worker         rc->alt_ref_gf_group = 1;
3003*fb1b10abSAndroid Build Coastguard Worker         // If alt-ref is used for this gf group, limit the interval.
3004*fb1b10abSAndroid Build Coastguard Worker         if (rc->baseline_gf_interval > 12) {
3005*fb1b10abSAndroid Build Coastguard Worker           rc->baseline_gf_interval = 12;
3006*fb1b10abSAndroid Build Coastguard Worker           rc->frames_till_gf_update_due = rc->baseline_gf_interval;
3007*fb1b10abSAndroid Build Coastguard Worker         }
3008*fb1b10abSAndroid Build Coastguard Worker       }
3009*fb1b10abSAndroid Build Coastguard Worker     }
3010*fb1b10abSAndroid Build Coastguard Worker     target = vp9_calc_pframe_target_size_one_pass_vbr(cpi);
3011*fb1b10abSAndroid Build Coastguard Worker     vp9_rc_set_frame_target(cpi, target);
3012*fb1b10abSAndroid Build Coastguard Worker   }
3013*fb1b10abSAndroid Build Coastguard Worker   rc->prev_avg_source_sad_lag = avg_source_sad_lag;
3014*fb1b10abSAndroid Build Coastguard Worker }
3015*fb1b10abSAndroid Build Coastguard Worker 
3016*fb1b10abSAndroid Build Coastguard Worker // Compute average source sad (temporal sad: between current source and
3017*fb1b10abSAndroid Build Coastguard Worker // previous source) over a subset of superblocks. Use this is detect big changes
3018*fb1b10abSAndroid Build Coastguard Worker // in content and allow rate control to react.
3019*fb1b10abSAndroid Build Coastguard Worker // This function also handles special case of lag_in_frames, to measure content
3020*fb1b10abSAndroid Build Coastguard Worker // level in #future frames set by the lag_in_frames.
vp9_scene_detection_onepass(VP9_COMP * cpi)3021*fb1b10abSAndroid Build Coastguard Worker void vp9_scene_detection_onepass(VP9_COMP *cpi) {
3022*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3023*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
3024*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG const *unscaled_src = cpi->un_scaled_source;
3025*fb1b10abSAndroid Build Coastguard Worker   YV12_BUFFER_CONFIG const *unscaled_last_src = cpi->unscaled_last_source;
3026*fb1b10abSAndroid Build Coastguard Worker   uint8_t *src_y;
3027*fb1b10abSAndroid Build Coastguard Worker   int src_ystride;
3028*fb1b10abSAndroid Build Coastguard Worker   int src_width;
3029*fb1b10abSAndroid Build Coastguard Worker   int src_height;
3030*fb1b10abSAndroid Build Coastguard Worker   uint8_t *last_src_y;
3031*fb1b10abSAndroid Build Coastguard Worker   int last_src_ystride;
3032*fb1b10abSAndroid Build Coastguard Worker   int last_src_width;
3033*fb1b10abSAndroid Build Coastguard Worker   int last_src_height;
3034*fb1b10abSAndroid Build Coastguard Worker   if (cpi->un_scaled_source == NULL || cpi->unscaled_last_source == NULL ||
3035*fb1b10abSAndroid Build Coastguard Worker       (cpi->use_svc && cpi->svc.current_superframe == 0))
3036*fb1b10abSAndroid Build Coastguard Worker     return;
3037*fb1b10abSAndroid Build Coastguard Worker   src_y = unscaled_src->y_buffer;
3038*fb1b10abSAndroid Build Coastguard Worker   src_ystride = unscaled_src->y_stride;
3039*fb1b10abSAndroid Build Coastguard Worker   src_width = unscaled_src->y_width;
3040*fb1b10abSAndroid Build Coastguard Worker   src_height = unscaled_src->y_height;
3041*fb1b10abSAndroid Build Coastguard Worker   last_src_y = unscaled_last_src->y_buffer;
3042*fb1b10abSAndroid Build Coastguard Worker   last_src_ystride = unscaled_last_src->y_stride;
3043*fb1b10abSAndroid Build Coastguard Worker   last_src_width = unscaled_last_src->y_width;
3044*fb1b10abSAndroid Build Coastguard Worker   last_src_height = unscaled_last_src->y_height;
3045*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
3046*fb1b10abSAndroid Build Coastguard Worker   if (cm->use_highbitdepth) return;
3047*fb1b10abSAndroid Build Coastguard Worker #endif
3048*fb1b10abSAndroid Build Coastguard Worker   rc->high_source_sad = 0;
3049*fb1b10abSAndroid Build Coastguard Worker   rc->high_num_blocks_with_motion = 0;
3050*fb1b10abSAndroid Build Coastguard Worker   // For SVC: scene detection is only checked on first spatial layer of
3051*fb1b10abSAndroid Build Coastguard Worker   // the superframe using the original/unscaled resolutions.
3052*fb1b10abSAndroid Build Coastguard Worker   if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode &&
3053*fb1b10abSAndroid Build Coastguard Worker       src_width == last_src_width && src_height == last_src_height) {
3054*fb1b10abSAndroid Build Coastguard Worker     YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
3055*fb1b10abSAndroid Build Coastguard Worker     int num_mi_cols = cm->mi_cols;
3056*fb1b10abSAndroid Build Coastguard Worker     int num_mi_rows = cm->mi_rows;
3057*fb1b10abSAndroid Build Coastguard Worker     int start_frame = 0;
3058*fb1b10abSAndroid Build Coastguard Worker     int frames_to_buffer = 1;
3059*fb1b10abSAndroid Build Coastguard Worker     int frame = 0;
3060*fb1b10abSAndroid Build Coastguard Worker     int scene_cut_force_key_frame = 0;
3061*fb1b10abSAndroid Build Coastguard Worker     int num_zero_temp_sad = 0;
3062*fb1b10abSAndroid Build Coastguard Worker     uint64_t avg_sad_current = 0;
3063*fb1b10abSAndroid Build Coastguard Worker     uint32_t min_thresh = 20000;  // ~5 * 64 * 64
3064*fb1b10abSAndroid Build Coastguard Worker     float thresh = 8.0f;
3065*fb1b10abSAndroid Build Coastguard Worker     uint32_t thresh_key = 140000;
3066*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.speed <= 5) thresh_key = 240000;
3067*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.content != VP9E_CONTENT_SCREEN) min_thresh = 65000;
3068*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_VBR) thresh = 2.1f;
3069*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc && cpi->svc.number_spatial_layers > 1) {
3070*fb1b10abSAndroid Build Coastguard Worker       const int aligned_width = ALIGN_POWER_OF_TWO(src_width, MI_SIZE_LOG2);
3071*fb1b10abSAndroid Build Coastguard Worker       const int aligned_height = ALIGN_POWER_OF_TWO(src_height, MI_SIZE_LOG2);
3072*fb1b10abSAndroid Build Coastguard Worker       num_mi_cols = aligned_width >> MI_SIZE_LOG2;
3073*fb1b10abSAndroid Build Coastguard Worker       num_mi_rows = aligned_height >> MI_SIZE_LOG2;
3074*fb1b10abSAndroid Build Coastguard Worker     }
3075*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.lag_in_frames > 0) {
3076*fb1b10abSAndroid Build Coastguard Worker       frames_to_buffer = (cm->current_video_frame == 1)
3077*fb1b10abSAndroid Build Coastguard Worker                              ? (int)vp9_lookahead_depth(cpi->lookahead) - 1
3078*fb1b10abSAndroid Build Coastguard Worker                              : 2;
3079*fb1b10abSAndroid Build Coastguard Worker       start_frame = (int)vp9_lookahead_depth(cpi->lookahead) - 1;
3080*fb1b10abSAndroid Build Coastguard Worker       for (frame = 0; frame < frames_to_buffer; ++frame) {
3081*fb1b10abSAndroid Build Coastguard Worker         const int lagframe_idx = start_frame - frame;
3082*fb1b10abSAndroid Build Coastguard Worker         if (lagframe_idx >= 0) {
3083*fb1b10abSAndroid Build Coastguard Worker           struct lookahead_entry *buf =
3084*fb1b10abSAndroid Build Coastguard Worker               vp9_lookahead_peek(cpi->lookahead, lagframe_idx);
3085*fb1b10abSAndroid Build Coastguard Worker           frames[frame] = &buf->img;
3086*fb1b10abSAndroid Build Coastguard Worker         }
3087*fb1b10abSAndroid Build Coastguard Worker       }
3088*fb1b10abSAndroid Build Coastguard Worker       // The avg_sad for this current frame is the value of frame#1
3089*fb1b10abSAndroid Build Coastguard Worker       // (first future frame) from previous frame.
3090*fb1b10abSAndroid Build Coastguard Worker       avg_sad_current = rc->avg_source_sad[1];
3091*fb1b10abSAndroid Build Coastguard Worker       if (avg_sad_current >
3092*fb1b10abSAndroid Build Coastguard Worker               VPXMAX(min_thresh,
3093*fb1b10abSAndroid Build Coastguard Worker                      (unsigned int)(rc->avg_source_sad[0] * thresh)) &&
3094*fb1b10abSAndroid Build Coastguard Worker           cm->current_video_frame > (unsigned int)cpi->oxcf.lag_in_frames)
3095*fb1b10abSAndroid Build Coastguard Worker         rc->high_source_sad = 1;
3096*fb1b10abSAndroid Build Coastguard Worker       else
3097*fb1b10abSAndroid Build Coastguard Worker         rc->high_source_sad = 0;
3098*fb1b10abSAndroid Build Coastguard Worker       if (rc->high_source_sad && avg_sad_current > thresh_key)
3099*fb1b10abSAndroid Build Coastguard Worker         scene_cut_force_key_frame = 1;
3100*fb1b10abSAndroid Build Coastguard Worker       // Update recursive average for current frame.
3101*fb1b10abSAndroid Build Coastguard Worker       if (avg_sad_current > 0)
3102*fb1b10abSAndroid Build Coastguard Worker         rc->avg_source_sad[0] =
3103*fb1b10abSAndroid Build Coastguard Worker             (3 * rc->avg_source_sad[0] + avg_sad_current) >> 2;
3104*fb1b10abSAndroid Build Coastguard Worker       // Shift back data, starting at frame#1.
3105*fb1b10abSAndroid Build Coastguard Worker       for (frame = 1; frame < cpi->oxcf.lag_in_frames - 1; ++frame)
3106*fb1b10abSAndroid Build Coastguard Worker         rc->avg_source_sad[frame] = rc->avg_source_sad[frame + 1];
3107*fb1b10abSAndroid Build Coastguard Worker     }
3108*fb1b10abSAndroid Build Coastguard Worker     for (frame = 0; frame < frames_to_buffer; ++frame) {
3109*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.lag_in_frames == 0 ||
3110*fb1b10abSAndroid Build Coastguard Worker           (frames[frame] != NULL && frames[frame + 1] != NULL &&
3111*fb1b10abSAndroid Build Coastguard Worker            frames[frame]->y_width == frames[frame + 1]->y_width &&
3112*fb1b10abSAndroid Build Coastguard Worker            frames[frame]->y_height == frames[frame + 1]->y_height)) {
3113*fb1b10abSAndroid Build Coastguard Worker         int sbi_row, sbi_col;
3114*fb1b10abSAndroid Build Coastguard Worker         const int lagframe_idx =
3115*fb1b10abSAndroid Build Coastguard Worker             (cpi->oxcf.lag_in_frames == 0) ? 0 : start_frame - frame + 1;
3116*fb1b10abSAndroid Build Coastguard Worker         const BLOCK_SIZE bsize = BLOCK_64X64;
3117*fb1b10abSAndroid Build Coastguard Worker         // Loop over sub-sample of frame, compute average sad over 64x64 blocks.
3118*fb1b10abSAndroid Build Coastguard Worker         uint64_t avg_sad = 0;
3119*fb1b10abSAndroid Build Coastguard Worker         uint64_t tmp_sad = 0;
3120*fb1b10abSAndroid Build Coastguard Worker         int num_samples = 0;
3121*fb1b10abSAndroid Build Coastguard Worker         int sb_cols = (num_mi_cols + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
3122*fb1b10abSAndroid Build Coastguard Worker         int sb_rows = (num_mi_rows + MI_BLOCK_SIZE - 1) / MI_BLOCK_SIZE;
3123*fb1b10abSAndroid Build Coastguard Worker         if (cpi->oxcf.lag_in_frames > 0) {
3124*fb1b10abSAndroid Build Coastguard Worker           src_y = frames[frame]->y_buffer;
3125*fb1b10abSAndroid Build Coastguard Worker           src_ystride = frames[frame]->y_stride;
3126*fb1b10abSAndroid Build Coastguard Worker           last_src_y = frames[frame + 1]->y_buffer;
3127*fb1b10abSAndroid Build Coastguard Worker           last_src_ystride = frames[frame + 1]->y_stride;
3128*fb1b10abSAndroid Build Coastguard Worker         }
3129*fb1b10abSAndroid Build Coastguard Worker         num_zero_temp_sad = 0;
3130*fb1b10abSAndroid Build Coastguard Worker         for (sbi_row = 0; sbi_row < sb_rows; ++sbi_row) {
3131*fb1b10abSAndroid Build Coastguard Worker           for (sbi_col = 0; sbi_col < sb_cols; ++sbi_col) {
3132*fb1b10abSAndroid Build Coastguard Worker             // Checker-board pattern, ignore boundary.
3133*fb1b10abSAndroid Build Coastguard Worker             if (((sbi_row > 0 && sbi_col > 0) &&
3134*fb1b10abSAndroid Build Coastguard Worker                  (sbi_row < sb_rows - 1 && sbi_col < sb_cols - 1) &&
3135*fb1b10abSAndroid Build Coastguard Worker                  ((sbi_row % 2 == 0 && sbi_col % 2 == 0) ||
3136*fb1b10abSAndroid Build Coastguard Worker                   (sbi_row % 2 != 0 && sbi_col % 2 != 0)))) {
3137*fb1b10abSAndroid Build Coastguard Worker               tmp_sad = cpi->fn_ptr[bsize].sdf(src_y, src_ystride, last_src_y,
3138*fb1b10abSAndroid Build Coastguard Worker                                                last_src_ystride);
3139*fb1b10abSAndroid Build Coastguard Worker               avg_sad += tmp_sad;
3140*fb1b10abSAndroid Build Coastguard Worker               num_samples++;
3141*fb1b10abSAndroid Build Coastguard Worker               if (tmp_sad == 0) num_zero_temp_sad++;
3142*fb1b10abSAndroid Build Coastguard Worker             }
3143*fb1b10abSAndroid Build Coastguard Worker             src_y += 64;
3144*fb1b10abSAndroid Build Coastguard Worker             last_src_y += 64;
3145*fb1b10abSAndroid Build Coastguard Worker           }
3146*fb1b10abSAndroid Build Coastguard Worker           src_y += (src_ystride << 6) - (sb_cols << 6);
3147*fb1b10abSAndroid Build Coastguard Worker           last_src_y += (last_src_ystride << 6) - (sb_cols << 6);
3148*fb1b10abSAndroid Build Coastguard Worker         }
3149*fb1b10abSAndroid Build Coastguard Worker         if (num_samples > 0) avg_sad = avg_sad / num_samples;
3150*fb1b10abSAndroid Build Coastguard Worker         // Set high_source_sad flag if we detect very high increase in avg_sad
3151*fb1b10abSAndroid Build Coastguard Worker         // between current and previous frame value(s). Use minimum threshold
3152*fb1b10abSAndroid Build Coastguard Worker         // for cases where there is small change from content that is completely
3153*fb1b10abSAndroid Build Coastguard Worker         // static.
3154*fb1b10abSAndroid Build Coastguard Worker         if (lagframe_idx == 0) {
3155*fb1b10abSAndroid Build Coastguard Worker           if (avg_sad >
3156*fb1b10abSAndroid Build Coastguard Worker                   VPXMAX(min_thresh,
3157*fb1b10abSAndroid Build Coastguard Worker                          (unsigned int)(rc->avg_source_sad[0] * thresh)) &&
3158*fb1b10abSAndroid Build Coastguard Worker               rc->frames_since_key > 1 + cpi->svc.number_spatial_layers &&
3159*fb1b10abSAndroid Build Coastguard Worker               num_zero_temp_sad < 3 * (num_samples >> 2))
3160*fb1b10abSAndroid Build Coastguard Worker             rc->high_source_sad = 1;
3161*fb1b10abSAndroid Build Coastguard Worker           else
3162*fb1b10abSAndroid Build Coastguard Worker             rc->high_source_sad = 0;
3163*fb1b10abSAndroid Build Coastguard Worker           if (rc->high_source_sad && avg_sad > thresh_key)
3164*fb1b10abSAndroid Build Coastguard Worker             scene_cut_force_key_frame = 1;
3165*fb1b10abSAndroid Build Coastguard Worker           if (avg_sad > 0 || cpi->oxcf.rc_mode == VPX_CBR)
3166*fb1b10abSAndroid Build Coastguard Worker             rc->avg_source_sad[0] = (3 * rc->avg_source_sad[0] + avg_sad) >> 2;
3167*fb1b10abSAndroid Build Coastguard Worker         } else {
3168*fb1b10abSAndroid Build Coastguard Worker           rc->avg_source_sad[lagframe_idx] = avg_sad;
3169*fb1b10abSAndroid Build Coastguard Worker         }
3170*fb1b10abSAndroid Build Coastguard Worker         if (num_zero_temp_sad < (3 * num_samples >> 2))
3171*fb1b10abSAndroid Build Coastguard Worker           rc->high_num_blocks_with_motion = 1;
3172*fb1b10abSAndroid Build Coastguard Worker       }
3173*fb1b10abSAndroid Build Coastguard Worker     }
3174*fb1b10abSAndroid Build Coastguard Worker     // For CBR non-screen content mode, check if we should reset the rate
3175*fb1b10abSAndroid Build Coastguard Worker     // control. Reset is done if high_source_sad is detected and the rate
3176*fb1b10abSAndroid Build Coastguard Worker     // control is at very low QP with rate correction factor at min level.
3177*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_CBR &&
3178*fb1b10abSAndroid Build Coastguard Worker         cpi->oxcf.content != VP9E_CONTENT_SCREEN && !cpi->use_svc) {
3179*fb1b10abSAndroid Build Coastguard Worker       if (rc->high_source_sad && rc->last_q[INTER_FRAME] == rc->best_quality &&
3180*fb1b10abSAndroid Build Coastguard Worker           rc->avg_frame_qindex[INTER_FRAME] < (rc->best_quality << 1) &&
3181*fb1b10abSAndroid Build Coastguard Worker           rc->rate_correction_factors[INTER_NORMAL] == MIN_BPB_FACTOR) {
3182*fb1b10abSAndroid Build Coastguard Worker         rc->rate_correction_factors[INTER_NORMAL] = 0.5;
3183*fb1b10abSAndroid Build Coastguard Worker         rc->avg_frame_qindex[INTER_FRAME] = rc->worst_quality;
3184*fb1b10abSAndroid Build Coastguard Worker         rc->buffer_level = rc->optimal_buffer_level;
3185*fb1b10abSAndroid Build Coastguard Worker         rc->bits_off_target = rc->optimal_buffer_level;
3186*fb1b10abSAndroid Build Coastguard Worker         rc->reset_high_source_sad = 1;
3187*fb1b10abSAndroid Build Coastguard Worker       }
3188*fb1b10abSAndroid Build Coastguard Worker       if (cm->frame_type != KEY_FRAME && rc->reset_high_source_sad)
3189*fb1b10abSAndroid Build Coastguard Worker         rc->this_frame_target = rc->avg_frame_bandwidth;
3190*fb1b10abSAndroid Build Coastguard Worker     }
3191*fb1b10abSAndroid Build Coastguard Worker     // For SVC the new (updated) avg_source_sad[0] for the current superframe
3192*fb1b10abSAndroid Build Coastguard Worker     // updates the setting for all layers.
3193*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
3194*fb1b10abSAndroid Build Coastguard Worker       int sl, tl;
3195*fb1b10abSAndroid Build Coastguard Worker       SVC *const svc = &cpi->svc;
3196*fb1b10abSAndroid Build Coastguard Worker       for (sl = 0; sl < svc->number_spatial_layers; ++sl)
3197*fb1b10abSAndroid Build Coastguard Worker         for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
3198*fb1b10abSAndroid Build Coastguard Worker           int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
3199*fb1b10abSAndroid Build Coastguard Worker           LAYER_CONTEXT *const lc = &svc->layer_context[layer];
3200*fb1b10abSAndroid Build Coastguard Worker           RATE_CONTROL *const lrc = &lc->rc;
3201*fb1b10abSAndroid Build Coastguard Worker           lrc->avg_source_sad[0] = rc->avg_source_sad[0];
3202*fb1b10abSAndroid Build Coastguard Worker         }
3203*fb1b10abSAndroid Build Coastguard Worker     }
3204*fb1b10abSAndroid Build Coastguard Worker     // For VBR, under scene change/high content change, force golden refresh.
3205*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.rc_mode == VPX_VBR && cm->frame_type != KEY_FRAME &&
3206*fb1b10abSAndroid Build Coastguard Worker         rc->high_source_sad && rc->frames_to_key > 3 &&
3207*fb1b10abSAndroid Build Coastguard Worker         rc->count_last_scene_change > 4 &&
3208*fb1b10abSAndroid Build Coastguard Worker         cpi->ext_refresh_frame_flags_pending == 0) {
3209*fb1b10abSAndroid Build Coastguard Worker       int target;
3210*fb1b10abSAndroid Build Coastguard Worker       cpi->refresh_golden_frame = 1;
3211*fb1b10abSAndroid Build Coastguard Worker       if (scene_cut_force_key_frame) cm->frame_type = KEY_FRAME;
3212*fb1b10abSAndroid Build Coastguard Worker       rc->source_alt_ref_pending = 0;
3213*fb1b10abSAndroid Build Coastguard Worker       if (cpi->sf.use_altref_onepass && cpi->oxcf.enable_auto_arf)
3214*fb1b10abSAndroid Build Coastguard Worker         rc->source_alt_ref_pending = 1;
3215*fb1b10abSAndroid Build Coastguard Worker       rc->gfu_boost = DEFAULT_GF_BOOST >> 1;
3216*fb1b10abSAndroid Build Coastguard Worker       rc->baseline_gf_interval =
3217*fb1b10abSAndroid Build Coastguard Worker           VPXMIN(20, VPXMAX(10, rc->baseline_gf_interval));
3218*fb1b10abSAndroid Build Coastguard Worker       adjust_gfint_frame_constraint(cpi, rc->frames_to_key);
3219*fb1b10abSAndroid Build Coastguard Worker       rc->frames_till_gf_update_due = rc->baseline_gf_interval;
3220*fb1b10abSAndroid Build Coastguard Worker       target = vp9_calc_pframe_target_size_one_pass_vbr(cpi);
3221*fb1b10abSAndroid Build Coastguard Worker       vp9_rc_set_frame_target(cpi, target);
3222*fb1b10abSAndroid Build Coastguard Worker       rc->count_last_scene_change = 0;
3223*fb1b10abSAndroid Build Coastguard Worker     } else {
3224*fb1b10abSAndroid Build Coastguard Worker       rc->count_last_scene_change++;
3225*fb1b10abSAndroid Build Coastguard Worker     }
3226*fb1b10abSAndroid Build Coastguard Worker     // If lag_in_frame is used, set the gf boost and interval.
3227*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.lag_in_frames > 0)
3228*fb1b10abSAndroid Build Coastguard Worker       adjust_gf_boost_lag_one_pass_vbr(cpi, avg_sad_current);
3229*fb1b10abSAndroid Build Coastguard Worker   }
3230*fb1b10abSAndroid Build Coastguard Worker }
3231*fb1b10abSAndroid Build Coastguard Worker 
3232*fb1b10abSAndroid Build Coastguard Worker // Test if encoded frame will significantly overshoot the target bitrate, and
3233*fb1b10abSAndroid Build Coastguard Worker // if so, set the QP, reset/adjust some rate control parameters, and return 1.
3234*fb1b10abSAndroid Build Coastguard Worker // frame_size = -1 means frame has not been encoded.
vp9_encodedframe_overshoot(VP9_COMP * cpi,int frame_size,int * q)3235*fb1b10abSAndroid Build Coastguard Worker int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) {
3236*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
3237*fb1b10abSAndroid Build Coastguard Worker   RATE_CONTROL *const rc = &cpi->rc;
3238*fb1b10abSAndroid Build Coastguard Worker   SPEED_FEATURES *const sf = &cpi->sf;
3239*fb1b10abSAndroid Build Coastguard Worker   int thresh_qp = 7 * (rc->worst_quality >> 3);
3240*fb1b10abSAndroid Build Coastguard Worker   int thresh_rate = rc->avg_frame_bandwidth << 3;
3241*fb1b10abSAndroid Build Coastguard Worker   // Lower thresh_qp for video (more overshoot at lower Q) to be
3242*fb1b10abSAndroid Build Coastguard Worker   // more conservative for video.
3243*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.content != VP9E_CONTENT_SCREEN)
3244*fb1b10abSAndroid Build Coastguard Worker     thresh_qp = 3 * (rc->worst_quality >> 2);
3245*fb1b10abSAndroid Build Coastguard Worker   // If this decision is not based on an encoded frame size but just on
3246*fb1b10abSAndroid Build Coastguard Worker   // scene/slide change detection (i.e., re_encode_overshoot_cbr_rt ==
3247*fb1b10abSAndroid Build Coastguard Worker   // FAST_DETECTION_MAXQ), for now skip the (frame_size > thresh_rate)
3248*fb1b10abSAndroid Build Coastguard Worker   // condition in this case.
3249*fb1b10abSAndroid Build Coastguard Worker   // TODO(marpan): Use a better size/rate condition for this case and
3250*fb1b10abSAndroid Build Coastguard Worker   // adjust thresholds.
3251*fb1b10abSAndroid Build Coastguard Worker   if ((sf->overshoot_detection_cbr_rt == FAST_DETECTION_MAXQ ||
3252*fb1b10abSAndroid Build Coastguard Worker        frame_size > thresh_rate) &&
3253*fb1b10abSAndroid Build Coastguard Worker       cm->base_qindex < thresh_qp) {
3254*fb1b10abSAndroid Build Coastguard Worker     double rate_correction_factor =
3255*fb1b10abSAndroid Build Coastguard Worker         cpi->rc.rate_correction_factors[INTER_NORMAL];
3256*fb1b10abSAndroid Build Coastguard Worker     const int target_size = cpi->rc.avg_frame_bandwidth;
3257*fb1b10abSAndroid Build Coastguard Worker     double new_correction_factor;
3258*fb1b10abSAndroid Build Coastguard Worker     int target_bits_per_mb;
3259*fb1b10abSAndroid Build Coastguard Worker     double q2;
3260*fb1b10abSAndroid Build Coastguard Worker     int enumerator;
3261*fb1b10abSAndroid Build Coastguard Worker     // Force a re-encode, and for now use max-QP.
3262*fb1b10abSAndroid Build Coastguard Worker     *q = cpi->rc.worst_quality;
3263*fb1b10abSAndroid Build Coastguard Worker     cpi->cyclic_refresh->counter_encode_maxq_scene_change = 0;
3264*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.re_encode_maxq_scene_change = 1;
3265*fb1b10abSAndroid Build Coastguard Worker     // If the frame_size is much larger than the threshold (big content change)
3266*fb1b10abSAndroid Build Coastguard Worker     // and the encoded frame used alot of Intra modes, then force hybrid_intra
3267*fb1b10abSAndroid Build Coastguard Worker     // encoding for the re-encode on this scene change. hybrid_intra will
3268*fb1b10abSAndroid Build Coastguard Worker     // use rd-based intra mode selection for small blocks.
3269*fb1b10abSAndroid Build Coastguard Worker     if (sf->overshoot_detection_cbr_rt == RE_ENCODE_MAXQ &&
3270*fb1b10abSAndroid Build Coastguard Worker         frame_size > (thresh_rate << 1) && cpi->svc.spatial_layer_id == 0) {
3271*fb1b10abSAndroid Build Coastguard Worker       MODE_INFO **mi = cm->mi_grid_visible;
3272*fb1b10abSAndroid Build Coastguard Worker       int sum_intra_usage = 0;
3273*fb1b10abSAndroid Build Coastguard Worker       int mi_row, mi_col;
3274*fb1b10abSAndroid Build Coastguard Worker       for (mi_row = 0; mi_row < cm->mi_rows; mi_row++) {
3275*fb1b10abSAndroid Build Coastguard Worker         for (mi_col = 0; mi_col < cm->mi_cols; mi_col++) {
3276*fb1b10abSAndroid Build Coastguard Worker           if (mi[0]->ref_frame[0] == INTRA_FRAME) sum_intra_usage++;
3277*fb1b10abSAndroid Build Coastguard Worker           mi++;
3278*fb1b10abSAndroid Build Coastguard Worker         }
3279*fb1b10abSAndroid Build Coastguard Worker         mi += 8;
3280*fb1b10abSAndroid Build Coastguard Worker       }
3281*fb1b10abSAndroid Build Coastguard Worker       sum_intra_usage = 100 * sum_intra_usage / (cm->mi_rows * cm->mi_cols);
3282*fb1b10abSAndroid Build Coastguard Worker       if (sum_intra_usage > 60) cpi->rc.hybrid_intra_scene_change = 1;
3283*fb1b10abSAndroid Build Coastguard Worker     }
3284*fb1b10abSAndroid Build Coastguard Worker     // Adjust avg_frame_qindex, buffer_level, and rate correction factors, as
3285*fb1b10abSAndroid Build Coastguard Worker     // these parameters will affect QP selection for subsequent frames. If they
3286*fb1b10abSAndroid Build Coastguard Worker     // have settled down to a very different (low QP) state, then not adjusting
3287*fb1b10abSAndroid Build Coastguard Worker     // them may cause next frame to select low QP and overshoot again.
3288*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.avg_frame_qindex[INTER_FRAME] = *q;
3289*fb1b10abSAndroid Build Coastguard Worker     rc->buffer_level = rc->optimal_buffer_level;
3290*fb1b10abSAndroid Build Coastguard Worker     rc->bits_off_target = rc->optimal_buffer_level;
3291*fb1b10abSAndroid Build Coastguard Worker     // Reset rate under/over-shoot flags.
3292*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_1_frame = 0;
3293*fb1b10abSAndroid Build Coastguard Worker     cpi->rc.rc_2_frame = 0;
3294*fb1b10abSAndroid Build Coastguard Worker     // Adjust rate correction factor.
3295*fb1b10abSAndroid Build Coastguard Worker     target_bits_per_mb =
3296*fb1b10abSAndroid Build Coastguard Worker         (int)(((uint64_t)target_size << BPER_MB_NORMBITS) / cm->MBs);
3297*fb1b10abSAndroid Build Coastguard Worker     // Rate correction factor based on target_bits_per_mb and qp (==max_QP).
3298*fb1b10abSAndroid Build Coastguard Worker     // This comes from the inverse computation of vp9_rc_bits_per_mb().
3299*fb1b10abSAndroid Build Coastguard Worker     q2 = vp9_convert_qindex_to_q(*q, cm->bit_depth);
3300*fb1b10abSAndroid Build Coastguard Worker     enumerator = 1800000;  // Factor for inter frame.
3301*fb1b10abSAndroid Build Coastguard Worker     enumerator += (int)(enumerator * q2) >> 12;
3302*fb1b10abSAndroid Build Coastguard Worker     new_correction_factor = (double)target_bits_per_mb * q2 / enumerator;
3303*fb1b10abSAndroid Build Coastguard Worker     if (new_correction_factor > rate_correction_factor) {
3304*fb1b10abSAndroid Build Coastguard Worker       rate_correction_factor =
3305*fb1b10abSAndroid Build Coastguard Worker           VPXMIN(2.0 * rate_correction_factor, new_correction_factor);
3306*fb1b10abSAndroid Build Coastguard Worker       if (rate_correction_factor > MAX_BPB_FACTOR)
3307*fb1b10abSAndroid Build Coastguard Worker         rate_correction_factor = MAX_BPB_FACTOR;
3308*fb1b10abSAndroid Build Coastguard Worker       cpi->rc.rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
3309*fb1b10abSAndroid Build Coastguard Worker     }
3310*fb1b10abSAndroid Build Coastguard Worker     // For temporal layers, reset the rate control parametes across all
3311*fb1b10abSAndroid Build Coastguard Worker     // temporal layers.
3312*fb1b10abSAndroid Build Coastguard Worker     // If the first_spatial_layer_to_encode > 0, then this superframe has
3313*fb1b10abSAndroid Build Coastguard Worker     // skipped lower base layers. So in this case we should also reset and
3314*fb1b10abSAndroid Build Coastguard Worker     // force max-q for spatial layers < first_spatial_layer_to_encode.
3315*fb1b10abSAndroid Build Coastguard Worker     // For the case of no inter-layer prediction on delta frames: reset and
3316*fb1b10abSAndroid Build Coastguard Worker     // force max-q for all spatial layers, to avoid excessive frame drops.
3317*fb1b10abSAndroid Build Coastguard Worker     if (cpi->use_svc) {
3318*fb1b10abSAndroid Build Coastguard Worker       int tl = 0;
3319*fb1b10abSAndroid Build Coastguard Worker       int sl = 0;
3320*fb1b10abSAndroid Build Coastguard Worker       SVC *svc = &cpi->svc;
3321*fb1b10abSAndroid Build Coastguard Worker       int num_spatial_layers = VPXMAX(1, svc->first_spatial_layer_to_encode);
3322*fb1b10abSAndroid Build Coastguard Worker       if (svc->disable_inter_layer_pred != INTER_LAYER_PRED_ON)
3323*fb1b10abSAndroid Build Coastguard Worker         num_spatial_layers = svc->number_spatial_layers;
3324*fb1b10abSAndroid Build Coastguard Worker       for (sl = 0; sl < num_spatial_layers; ++sl) {
3325*fb1b10abSAndroid Build Coastguard Worker         for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
3326*fb1b10abSAndroid Build Coastguard Worker           const int layer =
3327*fb1b10abSAndroid Build Coastguard Worker               LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
3328*fb1b10abSAndroid Build Coastguard Worker           LAYER_CONTEXT *lc = &svc->layer_context[layer];
3329*fb1b10abSAndroid Build Coastguard Worker           RATE_CONTROL *lrc = &lc->rc;
3330*fb1b10abSAndroid Build Coastguard Worker           lrc->avg_frame_qindex[INTER_FRAME] = *q;
3331*fb1b10abSAndroid Build Coastguard Worker           lrc->buffer_level = lrc->optimal_buffer_level;
3332*fb1b10abSAndroid Build Coastguard Worker           lrc->bits_off_target = lrc->optimal_buffer_level;
3333*fb1b10abSAndroid Build Coastguard Worker           lrc->rc_1_frame = 0;
3334*fb1b10abSAndroid Build Coastguard Worker           lrc->rc_2_frame = 0;
3335*fb1b10abSAndroid Build Coastguard Worker           lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
3336*fb1b10abSAndroid Build Coastguard Worker           lrc->force_max_q = 1;
3337*fb1b10abSAndroid Build Coastguard Worker         }
3338*fb1b10abSAndroid Build Coastguard Worker       }
3339*fb1b10abSAndroid Build Coastguard Worker     }
3340*fb1b10abSAndroid Build Coastguard Worker     return 1;
3341*fb1b10abSAndroid Build Coastguard Worker   } else {
3342*fb1b10abSAndroid Build Coastguard Worker     return 0;
3343*fb1b10abSAndroid Build Coastguard Worker   }
3344*fb1b10abSAndroid Build Coastguard Worker }
3345