16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <assert.h>
12411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <limits.h>
1390c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org#include <math.h>
14411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <stdio.h>
15411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <stdlib.h>
16411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include <string.h>
17411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
18411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vpx_mem/vpx_mem.h"
196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_alloccommon.h"
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_common.h"
226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_entropymode.h"
236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_quant_common.h"
2490c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org#include "vp9/common/vp9_seg_common.h"
25411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vp9/common/vp9_systemdependent.h"
26411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
27411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vp9/encoder/vp9_encodemv.h"
28411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#include "vp9/encoder/vp9_ratectrl.h"
296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
30693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// Max rate target for 1080P and below encodes under normal circumstances
31693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com// (1920 * 1080 / (16 * 16)) * MAX_MB_RATE bits per MB
32693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#define MAX_MB_RATE 250
33693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#define MAXRATE_1080P 2025000
34693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
3593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#define DEFAULT_KF_BOOST 2000
3693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#define DEFAULT_GF_BOOST 2000
3793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
38d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1
39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
4090c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org#define MIN_BPB_FACTOR 0.005
4190c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org#define MAX_BPB_FACTOR 50
426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
439a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org#define FRAME_OVERHEAD_BITS 200
449a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org
4587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
4687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#define ASSIGN_MINQ_TABLE(bit_depth, name) \
4787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  do { \
4887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    switch (bit_depth) { \
4987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      case VPX_BITS_8: \
5087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        name = name##_8; \
5187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        break; \
5287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      case VPX_BITS_10: \
5387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        name = name##_10; \
5487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        break; \
5587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      case VPX_BITS_12: \
5687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        name = name##_12; \
5787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        break; \
5887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      default: \
5987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10" \
6087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                    " or VPX_BITS_12"); \
6187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        name = NULL; \
6287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    } \
6387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  } while (0)
6487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else
6587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#define ASSIGN_MINQ_TABLE(bit_depth, name) \
6687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  do { \
6787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    (void) bit_depth; \
6887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    name = name##_8; \
6987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  } while (0)
7087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
7187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
72d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// Tables relating active max Q to active min Q
7387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_low_motion_minq_8[QINDEX_RANGE];
7487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_high_motion_minq_8[QINDEX_RANGE];
7587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_low_motion_minq_8[QINDEX_RANGE];
7687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_high_motion_minq_8[QINDEX_RANGE];
7787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int inter_minq_8[QINDEX_RANGE];
7887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int rtc_minq_8[QINDEX_RANGE];
7987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
8087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
8187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_low_motion_minq_10[QINDEX_RANGE];
8287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_high_motion_minq_10[QINDEX_RANGE];
8387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_low_motion_minq_10[QINDEX_RANGE];
8487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_high_motion_minq_10[QINDEX_RANGE];
8587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int inter_minq_10[QINDEX_RANGE];
8687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int rtc_minq_10[QINDEX_RANGE];
8787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_low_motion_minq_12[QINDEX_RANGE];
8887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int kf_high_motion_minq_12[QINDEX_RANGE];
8987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_low_motion_minq_12[QINDEX_RANGE];
9087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int arfgf_high_motion_minq_12[QINDEX_RANGE];
9187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int inter_minq_12[QINDEX_RANGE];
9287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int rtc_minq_12[QINDEX_RANGE];
9387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
9487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
95d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic int gf_high = 2000;
96d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic int gf_low = 400;
97d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic int kf_high = 5000;
98d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgstatic int kf_low = 400;
99d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
100d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// Functions to compute the active minq lookup table entries based on a
101d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// formulaic approach to facilitate easier adjustment of the Q tables.
102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// The formulae were derived from computing a 3rd order polynomial best
103d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org// fit to the original data (after plotting real maxq vs minq (not q index))
10487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int get_minq_index(double maxq, double x3, double x2, double x1,
10587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                          vpx_bit_depth_t bit_depth) {
106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int i;
10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const double minqtarget = MIN(((x3 * maxq + x2) * maxq + x1) * maxq,
108d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                                maxq);
109d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
110d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Special case handling to deal with the step from q2.0
111d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // down to lossless mode represented by q 1.0.
112d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (minqtarget <= 2.0)
113d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    return 0;
114d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
11587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  for (i = 0; i < QINDEX_RANGE; i++) {
11687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (minqtarget <= vp9_convert_qindex_to_q(i, bit_depth))
117d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      return i;
11887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
119d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
120d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return QINDEX_RANGE - 1;
121d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
122d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
12387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic void init_minq_luts(int *kf_low_m, int *kf_high_m,
12487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           int *arfgf_low, int *arfgf_high,
12587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                           int *inter, int *rtc, vpx_bit_depth_t bit_depth) {
126d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int i;
127d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  for (i = 0; i < QINDEX_RANGE; i++) {
12887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    const double maxq = vp9_convert_qindex_to_q(i, bit_depth);
12987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    kf_low_m[i] = get_minq_index(maxq, 0.000001, -0.0004, 0.150, bit_depth);
13087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    kf_high_m[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
13187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    arfgf_low[i] = get_minq_index(maxq, 0.0000015, -0.0009, 0.30, bit_depth);
13287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    arfgf_high[i] = get_minq_index(maxq, 0.0000021, -0.00125, 0.55, bit_depth);
13387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    inter[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.90, bit_depth);
13487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    rtc[i] = get_minq_index(maxq, 0.00000271, -0.00113, 0.70, bit_depth);
135d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
136d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
137d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
13887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid vp9_rc_init_minq_luts() {
13987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  init_minq_luts(kf_low_motion_minq_8, kf_high_motion_minq_8,
14087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 arfgf_low_motion_minq_8, arfgf_high_motion_minq_8,
14187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 inter_minq_8, rtc_minq_8, VPX_BITS_8);
14287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
14387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  init_minq_luts(kf_low_motion_minq_10, kf_high_motion_minq_10,
14487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 arfgf_low_motion_minq_10, arfgf_high_motion_minq_10,
14587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 inter_minq_10, rtc_minq_10, VPX_BITS_10);
14687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  init_minq_luts(kf_low_motion_minq_12, kf_high_motion_minq_12,
14787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 arfgf_low_motion_minq_12, arfgf_high_motion_minq_12,
14887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                 inter_minq_12, rtc_minq_12, VPX_BITS_12);
14987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
15087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org}
15187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
1526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// These functions use formulaic calculations to make playing with the
1536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// quantizer tables easier. If necessary they can be replaced by lookup
1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// tables if and when things settle down in the experimental bitstream
15587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgdouble vp9_convert_qindex_to_q(int qindex, vpx_bit_depth_t bit_depth) {
1566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // Convert the index to a real Q value (scaled down to match old Q values)
15787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH
15887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  switch (bit_depth) {
15987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_8:
16087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return vp9_ac_quant(qindex, 0, bit_depth) / 4.0;
16187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_10:
16287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return vp9_ac_quant(qindex, 0, bit_depth) / 16.0;
16387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    case VPX_BITS_12:
16487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return vp9_ac_quant(qindex, 0, bit_depth) / 64.0;
16587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    default:
16687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 or VPX_BITS_12");
16787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      return -1.0;
16887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  }
16987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else
17087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  return vp9_ac_quant(qindex, 0, bit_depth) / 4.0;
17187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif
1726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
1736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
174d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint vp9_rc_bits_per_mb(FRAME_TYPE frame_type, int qindex,
17587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                       double correction_factor,
17687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                       vpx_bit_depth_t bit_depth) {
17787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const double q = vp9_convert_qindex_to_q(qindex, bit_depth);
17887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int enumerator = frame_type == KEY_FRAME ? 2700000 : 1800000;
17990c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org
18010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // q based adjustment to baseline enumerator
18190c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  enumerator += (int)(enumerator * q) >> 12;
18241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  return (int)(enumerator * correction_factor / q);
18390c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org}
1846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
18593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic int estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs,
18687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                              double correction_factor,
18787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                              vpx_bit_depth_t bit_depth) {
18887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int bpm = (int)(vp9_rc_bits_per_mb(frame_type, q, correction_factor,
18987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                           bit_depth));
19093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  return ((uint64_t)bpm * mbs) >> BPER_MB_NORMBITS;
1916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
1926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
19376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
19476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
19576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const int min_frame_target = MAX(rc->min_frame_bandwidth,
196693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                   rc->avg_frame_bandwidth >> 5);
19776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (target < min_frame_target)
19876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = min_frame_target;
19976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
20076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // If there is an active ARF at this location use the minimum
20176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // bits on this frame even if it is a constructed arf.
20276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // The active maximum quantizer insures that an appropriate
20376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // number of bits will be spent if needed for constructed ARFs.
20476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = min_frame_target;
2050e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  }
20676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Clip the frame target to the maximum allowed value.
20776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (target > rc->max_frame_bandwidth)
20876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = rc->max_frame_bandwidth;
20976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return target;
21076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
2110e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org
21276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vp9_rc_clamp_iframe_target_size(const VP9_COMP *const cpi, int target) {
21376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
214693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *oxcf = &cpi->oxcf;
215dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (oxcf->rc_max_intra_bitrate_pct) {
216693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    const int max_rate = rc->avg_frame_bandwidth *
217693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                             oxcf->rc_max_intra_bitrate_pct / 100;
218dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    target = MIN(target, max_rate);
2196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
22076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (target > rc->max_frame_bandwidth)
22176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = rc->max_frame_bandwidth;
22276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return target;
22376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
22476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
22576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
22676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Update the buffer level for higher layers, given the encoded current layer.
22793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic void update_layer_buffer_level(SVC *svc, int encoded_frame_size) {
22876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int temporal_layer = 0;
22993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int current_temporal_layer = svc->temporal_layer_id;
23076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  for (temporal_layer = current_temporal_layer + 1;
23193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      temporal_layer < svc->number_temporal_layers; ++temporal_layer) {
23293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    LAYER_CONTEXT *lc = &svc->layer_context[temporal_layer];
23376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    RATE_CONTROL *lrc = &lc->rc;
23476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int bits_off_for_this_layer = (int)(lc->target_bandwidth / lc->framerate -
23576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        encoded_frame_size);
23676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    lrc->bits_off_target += bits_off_for_this_layer;
23776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
23876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Clip buffer level to maximum buffer size for the layer.
23988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    lrc->bits_off_target = MIN(lrc->bits_off_target, lrc->maximum_buffer_size);
24076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    lrc->buffer_level = lrc->bits_off_target;
24176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
2436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2440e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org// Update the buffer level: leaky bucket model.
24576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic void update_buffer_level(VP9_COMP *cpi, int encoded_frame_size) {
246dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
247dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
248dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
2490e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  // Non-viewable frames are a special case and are treated as pure overhead.
2500e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  if (!cm->show_frame) {
251dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->bits_off_target -= encoded_frame_size;
2520e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  } else {
253693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    rc->bits_off_target += rc->avg_frame_bandwidth - encoded_frame_size;
2540e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  }
255dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
2560e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  // Clip the buffer level to the maximum specified buffer size.
25788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->bits_off_target = MIN(rc->bits_off_target, rc->maximum_buffer_size);
25876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  rc->buffer_level = rc->bits_off_target;
25976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
26088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR) {
26193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    update_layer_buffer_level(&cpi->svc, encoded_frame_size);
26276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
2630e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org}
2640e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org
265693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comvoid vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
266e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  int i;
267e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
26888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (pass == 0 && oxcf->rc_mode == VPX_CBR) {
26988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    rc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
27088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    rc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
27193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  } else {
27288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    rc->avg_frame_qindex[KEY_FRAME] = (oxcf->worst_allowed_q +
27388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                                           oxcf->best_allowed_q) / 2;
27488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    rc->avg_frame_qindex[INTER_FRAME] = (oxcf->worst_allowed_q +
27588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                                           oxcf->best_allowed_q) / 2;
27693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
27793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
27888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->last_q[KEY_FRAME] = oxcf->best_allowed_q;
27988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->last_q[INTER_FRAME] = oxcf->best_allowed_q;
28093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
28188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->buffer_level =    rc->starting_buffer_level;
28288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->bits_off_target = rc->starting_buffer_level;
28393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
284693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->rolling_target_bits      = rc->avg_frame_bandwidth;
285693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->rolling_actual_bits      = rc->avg_frame_bandwidth;
286693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->long_rolling_target_bits = rc->avg_frame_bandwidth;
287693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->long_rolling_actual_bits = rc->avg_frame_bandwidth;
28893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
28993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->total_actual_bits = 0;
29088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->total_target_bits = 0;
29193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->total_target_vs_actual = 0;
29293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
29393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
29493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->frames_since_key = 8;  // Sensible default for first frame.
29593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->this_key_frame_forced = 0;
29693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->next_key_frame_forced = 0;
29793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->source_alt_ref_pending = 0;
29893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->source_alt_ref_active = 0;
29993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
30093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->frames_till_gf_update_due = 0;
30193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
30293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->ni_av_qi = oxcf->worst_allowed_q;
30393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->ni_tot_qi = 0;
30493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->ni_frames = 0;
30593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
30693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->tot_q = 0.0;
30787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  rc->avg_q = vp9_convert_qindex_to_q(oxcf->worst_allowed_q, oxcf->bit_depth);
30893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
309e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
310e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    rc->rate_correction_factors[i] = 1.0;
311e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  }
31293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
31393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
31476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vp9_rc_drop_frame(VP9_COMP *cpi) {
315693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *oxcf = &cpi->oxcf;
316dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
317dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
318dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (!oxcf->drop_frames_water_mark) {
3190e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org    return 0;
3200e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  } else {
321dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (rc->buffer_level < 0) {
3220e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      // Always drop if buffer is below 0.
3230e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      return 1;
3240e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org    } else {
3250e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      // If buffer is below drop_mark, for now just drop every other frame
3260e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      // (starting with the next frame) until it increases back over drop_mark.
327dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      int drop_mark = (int)(oxcf->drop_frames_water_mark *
32888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org          rc->optimal_buffer_level / 100);
329dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      if ((rc->buffer_level > drop_mark) &&
330dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          (rc->decimation_factor > 0)) {
331dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        --rc->decimation_factor;
332dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      } else if (rc->buffer_level <= drop_mark &&
333dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          rc->decimation_factor == 0) {
334dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->decimation_factor = 1;
3350e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      }
336dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      if (rc->decimation_factor > 0) {
337dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        if (rc->decimation_count > 0) {
338dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          --rc->decimation_count;
3390e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org          return 1;
3400e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org        } else {
341dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org          rc->decimation_count = rc->decimation_factor;
3420e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org          return 0;
3430e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org        }
3440e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      } else {
345dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->decimation_count = 0;
3460e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org        return 0;
3470e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org      }
3480e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org    }
3490e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org  }
3500e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org}
3510e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org
352dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic double get_rate_correction_factor(const VP9_COMP *cpi) {
353e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
354e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
355dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (cpi->common.frame_type == KEY_FRAME) {
356e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    return rc->rate_correction_factors[KF_STD];
35741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  } else if (cpi->oxcf.pass == 2) {
358e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    RATE_FACTOR_LEVEL rf_lvl =
359e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
360e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    return rc->rate_correction_factors[rf_lvl];
361dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else {
36276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
363e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org        !rc->is_src_frame_alt_ref &&
36488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        !(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR))
365e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      return rc->rate_correction_factors[GF_ARF_STD];
366dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    else
367e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      return rc->rate_correction_factors[INTER_NORMAL];
368dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
369dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
370dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
371dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void set_rate_correction_factor(VP9_COMP *cpi, double factor) {
372e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
373e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
374dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (cpi->common.frame_type == KEY_FRAME) {
375e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    rc->rate_correction_factors[KF_STD] = factor;
37641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  } else if (cpi->oxcf.pass == 2) {
377e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    RATE_FACTOR_LEVEL rf_lvl =
378e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index];
379e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    rc->rate_correction_factors[rf_lvl] = factor;
380dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else {
38176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) &&
382e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org        !rc->is_src_frame_alt_ref &&
38388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        !(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR))
384e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      rc->rate_correction_factors[GF_ARF_STD] = factor;
385dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    else
386e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      rc->rate_correction_factors[INTER_NORMAL] = factor;
387dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
388dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
389dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
390d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
39193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
39290c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  int correction_factor = 100;
393dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  double rate_correction_factor = get_rate_correction_factor(cpi);
3946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  double adjustment_limit;
3956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
39690c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  int projected_size_based_on_q = 0;
3976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
398693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // Do not update the rate factors for arf overlay frames.
399693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (cpi->rc.is_src_frame_alt_ref)
400693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    return;
401693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
4026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // Clear down mmx registers to allow floating point in what follows
403411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  vp9_clear_system_state();
4046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
40590c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  // Work out how big we would have expected the frame to be at this Q given
40690c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  // the current correction factor.
4076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // Stay in double to avoid int overflow when values are large
40893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  projected_size_based_on_q = estimate_bits_at_q(cm->frame_type,
40993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                                 cm->base_qindex, cm->MBs,
41087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                 rate_correction_factor,
41187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                 cm->bit_depth);
4126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  // Work out a size correction factor.
4136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (projected_size_based_on_q > 0)
414dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    correction_factor = (100 * cpi->rc.projected_frame_size) /
415dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                            projected_size_based_on_q;
4166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
417ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  // More heavily damped adjustment used if we have been oscillating either side
418ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  // of target.
4196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (damp_var) {
4206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case 0:
4216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      adjustment_limit = 0.75;
4226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
4236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case 1:
4246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      adjustment_limit = 0.375;
4256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
4266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    case 2:
4276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    default:
4286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      adjustment_limit = 0.25;
4296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
4306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
4316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (correction_factor > 102) {
4336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // We are not already at the worst allowable quality
43493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    correction_factor = (int)(100 + ((correction_factor - 100) *
43593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                  adjustment_limit));
43693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
4376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // Keep rate_correction_factor within limits
4396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (rate_correction_factor > MAX_BPB_FACTOR)
4406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      rate_correction_factor = MAX_BPB_FACTOR;
441ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  } else if (correction_factor < 99) {
4426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // We are not already at the best allowable quality
44393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    correction_factor = (int)(100 - ((100 - correction_factor) *
44493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                  adjustment_limit));
44593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    rate_correction_factor = (rate_correction_factor * correction_factor) / 100;
4466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // Keep rate_correction_factor within limits
4486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (rate_correction_factor < MIN_BPB_FACTOR)
4496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      rate_correction_factor = MIN_BPB_FACTOR;
4506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
4516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
452dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  set_rate_correction_factor(cpi, rate_correction_factor);
4536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
456d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgint vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
457d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                      int active_best_quality, int active_worst_quality) {
458dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
459d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int q = active_worst_quality;
4606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int last_error = INT_MAX;
461dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  int i, target_bits_per_mb;
462dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const double correction_factor = get_rate_correction_factor(cpi);
4636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
464ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  // Calculate required scaling factor based on target frame size and size of
465ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org  // frame produced using previous Q.
466693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  target_bits_per_mb =
467693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      ((uint64_t)target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs;
4686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
469d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  i = active_best_quality;
4706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  do {
472dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const int bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(cm->frame_type, i,
47387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                              correction_factor,
47487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                              cm->bit_depth);
4756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (bits_per_mb_at_this_q <= target_bits_per_mb) {
4776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error)
47890c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org        q = i;
4796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      else
48090c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org        q = i - 1;
4816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
48390c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org    } else {
4846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      last_error = bits_per_mb_at_this_q - target_bits_per_mb;
4856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
486d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } while (++i <= active_worst_quality);
4876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
48890c5310de3dfbd1b1624502616cbc8aaf9ad25f0johannkoenig@chromium.org  return q;
4896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
491dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic int get_active_quality(int q, int gfu_boost, int low, int high,
492dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                              int *low_motion_minq, int *high_motion_minq) {
493d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (gfu_boost > high) {
494dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return low_motion_minq[q];
495d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } else if (gfu_boost < low) {
496dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return high_motion_minq[q];
497d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } else {
498d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int gap = high - low;
499d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int offset = high - gfu_boost;
500d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int qdiff = high_motion_minq[q] - low_motion_minq[q];
501d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap;
502dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    return low_motion_minq[q] + adjustment;
503d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
504d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
505d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
50687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int get_kf_active_quality(const RATE_CONTROL *const rc, int q,
50787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 vpx_bit_depth_t bit_depth) {
50887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *kf_low_motion_minq;
50987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *kf_high_motion_minq;
51087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(bit_depth, kf_low_motion_minq);
51187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(bit_depth, kf_high_motion_minq);
512ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  return get_active_quality(q, rc->kf_boost, kf_low, kf_high,
513ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org                            kf_low_motion_minq, kf_high_motion_minq);
514ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org}
515ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org
51687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic int get_gf_active_quality(const RATE_CONTROL *const rc, int q,
51787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                 vpx_bit_depth_t bit_depth) {
51887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *arfgf_low_motion_minq;
51987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *arfgf_high_motion_minq;
52087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(bit_depth, arfgf_low_motion_minq);
52187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(bit_depth, arfgf_high_motion_minq);
522ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  return get_active_quality(q, rc->gfu_boost, gf_low, gf_high,
523ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org                            arfgf_low_motion_minq, arfgf_high_motion_minq);
524ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org}
525ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org
52676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) {
52793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
52893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const unsigned int curr_frame = cpi->common.current_video_frame;
52976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_worst_quality;
53093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
53176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cpi->common.frame_type == KEY_FRAME) {
53293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    active_worst_quality = curr_frame == 0 ? rc->worst_quality
53393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                           : rc->last_q[KEY_FRAME] * 2;
53476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
53593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (!rc->is_src_frame_alt_ref &&
53693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
53793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      active_worst_quality =  curr_frame == 1 ? rc->last_q[KEY_FRAME] * 5 / 4
53893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                              : rc->last_q[INTER_FRAME];
53976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
54093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      active_worst_quality = curr_frame == 1 ? rc->last_q[KEY_FRAME] * 2
54193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                             : rc->last_q[INTER_FRAME] * 2;
54276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
54376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
54493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  return MIN(active_worst_quality, rc->worst_quality);
54576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
54676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
54776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Adjust active_worst_quality level based on buffer level.
54876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
54976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Adjust active_worst_quality: If buffer is above the optimal/target level,
55076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // bring active_worst_quality down depending on fullness of buffer.
55176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // If buffer is below the optimal level, let the active_worst_quality go from
55276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // ambient Q (at buffer = optimal level) to worst_quality level
55376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // (at buffer = critical level).
55493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
55576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
55676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Buffer level below which we push active_worst to worst_quality.
55788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  int64_t critical_level = rc->optimal_buffer_level >> 2;
558411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  int64_t buff_lvl_step = 0;
55976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int adjustment = 0;
56076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_worst_quality;
56193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME)
56276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    return rc->worst_quality;
56393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cm->current_video_frame > 1)
56476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    active_worst_quality = MIN(rc->worst_quality,
56576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                               rc->avg_frame_qindex[INTER_FRAME] * 5 / 4);
56676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
56776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    active_worst_quality = MIN(rc->worst_quality,
56876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                               rc->avg_frame_qindex[KEY_FRAME] * 3 / 2);
56988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (rc->buffer_level > rc->optimal_buffer_level) {
57076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Adjust down.
57176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Maximum limit for down adjustment, ~30%.
57276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    int max_adjustment_down = active_worst_quality / 3;
57376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (max_adjustment_down) {
57488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      buff_lvl_step = ((rc->maximum_buffer_size -
57588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                        rc->optimal_buffer_level) / max_adjustment_down);
57676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (buff_lvl_step)
57788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        adjustment = (int)((rc->buffer_level - rc->optimal_buffer_level) /
57876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                            buff_lvl_step);
57976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      active_worst_quality -= adjustment;
58076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
58176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if (rc->buffer_level > critical_level) {
58276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Adjust up from ambient Q.
58376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (critical_level) {
58488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      buff_lvl_step = (rc->optimal_buffer_level - critical_level);
58576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (buff_lvl_step) {
586411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        adjustment =
587411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org            (int)((rc->worst_quality - rc->avg_frame_qindex[INTER_FRAME]) *
58888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                  (rc->optimal_buffer_level - rc->buffer_level) /
589411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org                  buff_lvl_step);
59076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      }
59176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      active_worst_quality = rc->avg_frame_qindex[INTER_FRAME] + adjustment;
59276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
59376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
59476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Set to worst_quality if buffer is below critical level.
59576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    active_worst_quality = rc->worst_quality;
59676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
59776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return active_worst_quality;
59876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
59976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
60076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int rc_pick_q_and_bounds_one_pass_cbr(const VP9_COMP *cpi,
60176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             int *bottom_index,
60276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             int *top_index) {
60376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
60476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
60576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_best_quality;
60676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi);
60776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int q;
60887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *rtc_minq;
60987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(cm->bit_depth, rtc_minq);
61076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
61176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (frame_is_intra_only(cm)) {
61276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    active_best_quality = rc->best_quality;
61387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Handle the special case for key frames forced when we have reached
61476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // the maximum key frame interval. Here force the Q to a range
61576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // based on the ambient Q to reduce the risk of popping.
61676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (rc->this_key_frame_forced) {
61776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      int qindex = rc->last_boosted_qindex;
61887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
61993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
62087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            (last_boosted_q * 0.75),
62187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            cm->bit_depth);
62276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
62376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else if (cm->current_video_frame > 0) {
62476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // not first frame of one pass and kf_boost is set
62576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      double q_adj_factor = 1.0;
62676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      double q_val;
62776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
628ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org      active_best_quality =
62987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME],
63087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                cm->bit_depth);
63176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
63276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Allow somewhat lower kf minq with small image formats.
63376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if ((cm->width * cm->height) <= (352 * 288)) {
63476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        q_adj_factor -= 0.25;
63576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      }
63676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
63776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Convert the adjustment factor to a qindex delta
63876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // on active_best_quality.
63987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
64093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      active_best_quality += vp9_compute_qdelta(rc, q_val,
64187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                q_val * q_adj_factor,
64287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                cm->bit_depth);
64376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
64476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if (!rc->is_src_frame_alt_ref &&
64593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org             !cpi->use_svc &&
64676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
64776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Use the lower of active_worst_quality and recent
64876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // average Q as basis for GF/ARF best Q limit unless last frame was
64976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // a key frame.
65076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (rc->frames_since_key > 1 &&
65176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
65276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = rc->avg_frame_qindex[INTER_FRAME];
65376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
65476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = active_worst_quality;
65576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
65687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
65776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
65876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Use the lower of active_worst_quality and recent/average Q.
65976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (cm->current_video_frame > 1) {
66076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality)
6617765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        active_best_quality = rtc_minq[rc->avg_frame_qindex[INTER_FRAME]];
66276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      else
6637765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        active_best_quality = rtc_minq[active_worst_quality];
66476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
66576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (rc->avg_frame_qindex[KEY_FRAME] < active_worst_quality)
6667765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        active_best_quality = rtc_minq[rc->avg_frame_qindex[KEY_FRAME]];
66776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      else
6687765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        active_best_quality = rtc_minq[active_worst_quality];
66976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
67076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
67176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
67276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Clip the active best and worst quality values to limits
67376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  active_best_quality = clamp(active_best_quality,
67476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                              rc->best_quality, rc->worst_quality);
67576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  active_worst_quality = clamp(active_worst_quality,
67676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                               active_best_quality, rc->worst_quality);
67776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
67876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  *top_index = active_worst_quality;
67976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  *bottom_index = active_best_quality;
68076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
68176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
68276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Limit Q range for the adaptive loop.
683693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if (cm->frame_type == KEY_FRAME &&
684693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      !rc->this_key_frame_forced  &&
685693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      !(cm->current_video_frame == 0)) {
686693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int qdelta = 0;
687693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    vp9_clear_system_state();
688693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
68987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                        active_worst_quality, 2.0,
69087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                        cm->bit_depth);
691693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *top_index = active_worst_quality + qdelta;
692693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index;
69376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
69476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
695693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
69676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Special case code to try and match quality with forced key frames
69776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME && rc->this_key_frame_forced) {
69876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = rc->last_boosted_qindex;
69976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
70076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = vp9_rc_regulate_q(cpi, rc->this_frame_target,
70176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                          active_best_quality, active_worst_quality);
70276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (q > *top_index) {
70376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Special case when we are targeting the max allowed rate
70493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (rc->this_frame_target >= rc->max_frame_bandwidth)
70576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        *top_index = q;
70676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      else
70776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        q = *top_index;
70876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
70976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
71076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(*top_index <= rc->worst_quality &&
71176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org         *top_index >= rc->best_quality);
71276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(*bottom_index <= rc->worst_quality &&
71376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org         *bottom_index >= rc->best_quality);
71476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(q <= rc->worst_quality && q >= rc->best_quality);
71576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return q;
71676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
71776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
71888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgstatic int get_active_cq_level(const RATE_CONTROL *rc,
71988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                               const VP9EncoderConfig *const oxcf) {
72088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  static const double cq_adjust_threshold = 0.5;
72188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  int active_cq_level = oxcf->cq_level;
72288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (oxcf->rc_mode == VPX_CQ &&
72388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->total_target_bits > 0) {
72488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    const double x = (double)rc->total_actual_bits / rc->total_target_bits;
72588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (x < cq_adjust_threshold) {
72688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      active_cq_level = (int)(active_cq_level * x / cq_adjust_threshold);
72788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    }
72888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
72988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  return active_cq_level;
73088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
73188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
73276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int rc_pick_q_and_bounds_one_pass_vbr(const VP9_COMP *cpi,
73376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             int *bottom_index,
73476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                             int *top_index) {
735d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
736dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
737693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
73888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int cq_level = get_active_cq_level(rc, oxcf);
739d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int active_best_quality;
74076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi);
741d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  int q;
74287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *inter_minq;
74387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
744d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
745d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (frame_is_intra_only(cm)) {
746e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
747e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    // Handle the special case for key frames forced when we have reached
748d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // the maximum key frame interval. Here force the Q to a range
749d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // based on the ambient Q to reduce the risk of popping.
750dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (rc->this_key_frame_forced) {
751dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      int qindex = rc->last_boosted_qindex;
75287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      double last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
75393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      int delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
75487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            last_boosted_q * 0.75,
75587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            cm->bit_depth);
756dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
75788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    } else {
758dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      // not first frame of one pass and kf_boost is set
759d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      double q_adj_factor = 1.0;
760d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      double q_val;
761d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
762ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org      active_best_quality =
76387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org          get_kf_active_quality(rc, rc->avg_frame_qindex[KEY_FRAME],
76487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                cm->bit_depth);
76576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
76676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Allow somewhat lower kf minq with small image formats.
76776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if ((cm->width * cm->height) <= (352 * 288)) {
76876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        q_adj_factor -= 0.25;
76976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      }
77076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
77176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Convert the adjustment factor to a qindex delta
77276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // on active_best_quality.
77387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
77493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      active_best_quality += vp9_compute_qdelta(rc, q_val,
77587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                q_val * q_adj_factor,
77687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                cm->bit_depth);
77776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
77876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if (!rc->is_src_frame_alt_ref &&
77976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
78076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Use the lower of active_worst_quality and recent
78176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // average Q as basis for GF/ARF best Q limit unless last frame was
78276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // a key frame.
78376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (rc->frames_since_key > 1 &&
78476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
78576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = rc->avg_frame_qindex[INTER_FRAME];
78676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
78776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = rc->avg_frame_qindex[KEY_FRAME];
78876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
78976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // For constrained quality dont allow Q less than the cq level
79088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (oxcf->rc_mode == VPX_CQ) {
791693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      if (q < cq_level)
792693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        q = cq_level;
793810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
79487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
795810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
79676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Constrained quality use slightly lower active best.
79776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      active_best_quality = active_best_quality * 15 / 16;
79876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
79988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    } else if (oxcf->rc_mode == VPX_Q) {
80076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (!cpi->refresh_alt_ref_frame) {
801693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        active_best_quality = cq_level;
80276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      } else {
80387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
80476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      }
80576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
80687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
80776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
80876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
80988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (oxcf->rc_mode == VPX_Q) {
810693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      active_best_quality = cq_level;
81176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
81276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Use the lower of active_worst_quality and recent/average Q.
81376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      if (cm->current_video_frame > 1)
81476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]];
81576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      else
81676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]];
81776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // For the constrained quality mode we don't want
81876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // q to fall below the cq level.
81988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      if ((oxcf->rc_mode == VPX_CQ) &&
820693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com          (active_best_quality < cq_level)) {
821693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        active_best_quality = cq_level;
82276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      }
82376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
82476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
82576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
82676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Clip the active best and worst quality values to limits
82776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  active_best_quality = clamp(active_best_quality,
82876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                              rc->best_quality, rc->worst_quality);
82976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  active_worst_quality = clamp(active_worst_quality,
83076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                               active_best_quality, rc->worst_quality);
83176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
83276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  *top_index = active_worst_quality;
83376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  *bottom_index = active_best_quality;
83476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
83576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
836693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  {
837693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int qdelta = 0;
838693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    vp9_clear_system_state();
839693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
840693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    // Limit Q range for the adaptive loop.
841693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (cm->frame_type == KEY_FRAME &&
842693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        !rc->this_key_frame_forced &&
843693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        !(cm->current_video_frame == 0)) {
844693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
84587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                          active_worst_quality, 2.0,
84687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                          cm->bit_depth);
847693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    } else if (!rc->is_src_frame_alt_ref &&
848693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com               (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
849693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
85087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                          active_worst_quality, 1.75,
85187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                          cm->bit_depth);
852693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    }
853693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *top_index = active_worst_quality + qdelta;
854693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *top_index = (*top_index > *bottom_index) ? *top_index : *bottom_index;
85576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
85676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
857693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
85888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (oxcf->rc_mode == VPX_Q) {
85976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = active_best_quality;
86076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Special case code to try and match quality with forced key frames
86176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced) {
86276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = rc->last_boosted_qindex;
86376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
86476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = vp9_rc_regulate_q(cpi, rc->this_frame_target,
86576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                          active_best_quality, active_worst_quality);
86676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (q > *top_index) {
86776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Special case when we are targeting the max allowed rate
86893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (rc->this_frame_target >= rc->max_frame_bandwidth)
86976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        *top_index = q;
87076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      else
87176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        q = *top_index;
87276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
87376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
874e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
87576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(*top_index <= rc->worst_quality &&
87676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org         *top_index >= rc->best_quality);
87776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(*bottom_index <= rc->worst_quality &&
87876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org         *bottom_index >= rc->best_quality);
87976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  assert(q <= rc->worst_quality && q >= rc->best_quality);
88076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return q;
88176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
88276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
88387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#define STATIC_MOTION_THRESH 95
88476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi,
88576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                         int *bottom_index,
88676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                         int *top_index) {
88776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
88876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
889693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
89088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int cq_level = get_active_cq_level(rc, oxcf);
89176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_best_quality;
89276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int active_worst_quality = cpi->twopass.active_worst_quality;
89376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int q;
89487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  int *inter_minq;
89587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  ASSIGN_MINQ_TABLE(cm->bit_depth, inter_minq);
89676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
8979a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  if (frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) {
89887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // Handle the special case for key frames forced when we have reached
89976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // the maximum key frame interval. Here force the Q to a range
90076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // based on the ambient Q to reduce the risk of popping.
90176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (rc->this_key_frame_forced) {
90287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      double last_boosted_q;
90387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      int delta_qindex;
90487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      int qindex;
90587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
90687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) {
90787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        qindex = MIN(rc->last_kf_qindex, rc->last_boosted_qindex);
90887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_best_quality = qindex;
90987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
91087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
91187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                              last_boosted_q * 1.25,
91287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                              cm->bit_depth);
91387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_worst_quality = MIN(qindex + delta_qindex, active_worst_quality);
91487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
91587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      } else {
91687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        qindex = rc->last_boosted_qindex;
91787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        last_boosted_q = vp9_convert_qindex_to_q(qindex, cm->bit_depth);
91887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        delta_qindex = vp9_compute_qdelta(rc, last_boosted_q,
91987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                              last_boosted_q * 0.75,
92087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                              cm->bit_depth);
92187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_best_quality = MAX(qindex + delta_qindex, rc->best_quality);
92287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      }
92376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    } else {
92476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Not forced keyframe.
92576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      double q_adj_factor = 1.0;
92676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      double q_val;
92776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Baseline value derived from cpi->active_worst_quality and kf boost.
92887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      active_best_quality = get_kf_active_quality(rc, active_worst_quality,
92987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                  cm->bit_depth);
930d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
931d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // Allow somewhat lower kf minq with small image formats.
932d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if ((cm->width * cm->height) <= (352 * 288)) {
933d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org        q_adj_factor -= 0.25;
934d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
935d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
936d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // Make a further adjustment based on the kf zero motion measure.
9378b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      q_adj_factor += 0.05 - (0.001 * (double)cpi->twopass.kf_zeromotion_pct);
938d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
939d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // Convert the adjustment factor to a qindex delta
940d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // on active_best_quality.
94187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      q_val = vp9_convert_qindex_to_q(active_best_quality, cm->bit_depth);
94293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      active_best_quality += vp9_compute_qdelta(rc, q_val,
94387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                q_val * q_adj_factor,
94487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                cm->bit_depth);
945d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
946dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else if (!rc->is_src_frame_alt_ref &&
947d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org             (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
948d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // Use the lower of active_worst_quality and recent
949d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // average Q as basis for GF/ARF best Q limit unless last frame was
950d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // a key frame.
951dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (rc->frames_since_key > 1 &&
952dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
953dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      q = rc->avg_frame_qindex[INTER_FRAME];
954d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    } else {
955d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      q = active_worst_quality;
956d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
957d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    // For constrained quality dont allow Q less than the cq level
95888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (oxcf->rc_mode == VPX_CQ) {
959693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      if (q < cq_level)
960693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        q = cq_level;
961810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
96287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
963810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
964d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // Constrained quality use slightly lower active best.
965d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      active_best_quality = active_best_quality * 15 / 16;
966d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
96788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    } else if (oxcf->rc_mode == VPX_Q) {
968d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      if (!cpi->refresh_alt_ref_frame) {
969693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        active_best_quality = cq_level;
970d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      } else {
97187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
972d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
973d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    } else {
97487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth);
975d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
976d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } else {
97788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (oxcf->rc_mode == VPX_Q) {
978693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      active_best_quality = cq_level;
979d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    } else {
98076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      active_best_quality = inter_minq[active_worst_quality];
981d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
982d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // For the constrained quality mode we don't want
983d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      // q to fall below the cq level.
98488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      if ((oxcf->rc_mode == VPX_CQ) &&
985693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com          (active_best_quality < cq_level)) {
986693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        active_best_quality = cq_level;
987d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      }
988d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    }
989d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
990d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
991d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
992e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  vp9_clear_system_state();
99387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // Static forced key frames Q restrictions dealt with elsewhere.
99487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (!((frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi))) ||
99587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      !rc->this_key_frame_forced ||
99687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      (cpi->twopass.last_kfgroup_zeromotion_pct < STATIC_MOTION_THRESH)) {
997e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
998e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    const double rate_factor_deltas[RATE_FACTOR_LEVELS] = {
999e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      1.00,  // INTER_NORMAL
1000e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      1.00,  // INTER_HIGH
1001e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      1.50,  // GF_ARF_LOW
1002e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      1.75,  // GF_ARF_STD
1003e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      2.00,  // KF_STD
1004e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    };
1005e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    const double rate_factor =
1006e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      rate_factor_deltas[gf_group->rf_level[gf_group->index]];
1007e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    int qdelta = vp9_compute_qdelta_by_rate(&cpi->rc, cm->frame_type,
100887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            active_worst_quality, rate_factor,
100987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                            cm->bit_depth);
101087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    active_worst_quality = active_worst_quality + qdelta;
101187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    active_worst_quality = MAX(active_worst_quality, active_best_quality);
1012d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
1013d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#endif
1014d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
101587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  // Clip the active best and worst quality values to limits.
101687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  active_best_quality = clamp(active_best_quality,
101787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                              rc->best_quality, rc->worst_quality);
101887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  active_worst_quality = clamp(active_worst_quality,
101987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                               active_best_quality, rc->worst_quality);
102087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
102188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (oxcf->rc_mode == VPX_Q) {
1022d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    q = active_best_quality;
102376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Special case code to try and match quality with forced key frames.
102487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  } else if ((frame_is_intra_only(cm) || vp9_is_upper_layer_key_frame(cpi)) &&
102587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org             rc->this_key_frame_forced) {
102687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    // If static since last kf use better of last boosted and last kf q.
102787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (cpi->twopass.last_kfgroup_zeromotion_pct >= STATIC_MOTION_THRESH) {
102887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      q = MIN(rc->last_kf_qindex, rc->last_boosted_qindex);
102987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    } else {
103087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      q = rc->last_boosted_qindex;
103187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    }
1032d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  } else {
1033dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    q = vp9_rc_regulate_q(cpi, rc->this_frame_target,
10340e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org                          active_best_quality, active_worst_quality);
103587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (q > active_worst_quality) {
103676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      // Special case when we are targeting the max allowed rate.
103793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      if (rc->this_frame_target >= rc->max_frame_bandwidth)
103887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        active_worst_quality = q;
1039dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      else
104087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org        q = active_worst_quality;
1041dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    }
1042d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
104387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  clamp(q, active_best_quality, active_worst_quality);
104487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org
104587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *top_index = active_worst_quality;
104687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  *bottom_index = active_best_quality;
1047e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org
1048dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  assert(*top_index <= rc->worst_quality &&
1049dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org         *top_index >= rc->best_quality);
1050dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  assert(*bottom_index <= rc->worst_quality &&
1051dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org         *bottom_index >= rc->best_quality);
1052dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  assert(q <= rc->worst_quality && q >= rc->best_quality);
1053d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  return q;
1054d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
10556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
105676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgint vp9_rc_pick_q_and_bounds(const VP9_COMP *cpi,
105793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                             int *bottom_index, int *top_index) {
105876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int q;
105941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  if (cpi->oxcf.pass == 0) {
106088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (cpi->oxcf.rc_mode == VPX_CBR)
106176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = rc_pick_q_and_bounds_one_pass_cbr(cpi, bottom_index, top_index);
106276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    else
106376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      q = rc_pick_q_and_bounds_one_pass_vbr(cpi, bottom_index, top_index);
106476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
106576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    q = rc_pick_q_and_bounds_two_pass(cpi, bottom_index, top_index);
106676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
1067411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  if (cpi->sf.use_nonrd_pick_mode) {
106893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (cpi->sf.force_frame_boost == 1)
106993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      q -= cpi->sf.max_delta_qindex;
107093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
107176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (q < *bottom_index)
107276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      *bottom_index = q;
107376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    else if (q > *top_index)
107476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      *top_index = q;
107576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
107676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return q;
107776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
107876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
1079d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
1080693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                      int frame_target,
1081d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                                      int *frame_under_shoot_limit,
1082d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org                                      int *frame_over_shoot_limit) {
108388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (cpi->oxcf.rc_mode == VPX_Q) {
10846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    *frame_under_shoot_limit = 0;
10856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    *frame_over_shoot_limit  = INT_MAX;
10866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  } else {
10876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // For very small rate targets where the fractional adjustment
108893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // may be tiny make sure there is at least a minimum range.
1089693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    const int tolerance = (cpi->sf.recode_tolerance * frame_target) / 100;
1090693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *frame_under_shoot_limit = MAX(frame_target - tolerance - 200, 0);
1091693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    *frame_over_shoot_limit = MIN(frame_target + tolerance + 200,
1092693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                  cpi->rc.max_frame_bandwidth);
10936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
10946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
10956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
109676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid vp9_rc_set_frame_target(VP9_COMP *cpi, int target) {
1097dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  const VP9_COMMON *const cm = &cpi->common;
1098dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
10996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
110076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  rc->this_frame_target = target;
1101693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
1102d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Target rate per SB64 (including partial SB64s.
1103dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  rc->sb64_target_rate = ((int64_t)rc->this_frame_target * 64 * 64) /
1104dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org                             (cm->width * cm->height);
11056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
1106d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1107dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void update_alt_ref_frame_stats(VP9_COMP *cpi) {
1108dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  // this frame refreshes means next frames don't unless specified by user
110993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
111093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->frames_since_golden = 0;
1111dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1112e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  // Mark the alt ref as done (setting to 0 means no further alt refs pending).
1113e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  rc->source_alt_ref_pending = 0;
1114dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1115dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  // Set the alternate reference frame active flag
111693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->source_alt_ref_active = 1;
1117dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
1118dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1119dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgstatic void update_golden_frame_stats(VP9_COMP *cpi) {
1120dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
1121dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1122dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  // Update the Golden frame usage counts.
1123dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (cpi->refresh_golden_frame) {
1124dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    // this frame refreshes means next frames don't unless specified by user
1125dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->frames_since_golden = 0;
1126dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
112741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    if (cpi->oxcf.pass == 2) {
1128e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      if (!rc->source_alt_ref_pending &&
1129e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org          cpi->twopass.gf_group.rf_level[0] == GF_ARF_STD)
1130dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      rc->source_alt_ref_active = 0;
1131e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    } else if (!rc->source_alt_ref_pending) {
1132e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      rc->source_alt_ref_active = 0;
1133e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    }
1134dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1135dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    // Decrement count down till next gf
1136dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (rc->frames_till_gf_update_due > 0)
1137dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      rc->frames_till_gf_update_due--;
1138dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1139dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  } else if (!cpi->refresh_alt_ref_frame) {
1140dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    // Decrement count down till next gf
1141dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (rc->frames_till_gf_update_due > 0)
1142dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      rc->frames_till_gf_update_due--;
1143dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1144dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->frames_since_golden++;
1145dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
1146dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
1147dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
11488b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.orgvoid vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
1149693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9_COMMON *const cm = &cpi->common;
1150693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1151dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
1152693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const int qindex = cm->base_qindex;
115376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
1154d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Update rate control heuristics
1155411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  rc->projected_frame_size = (int)(bytes_used << 3);
1156d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1157d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Post encode loop adjustment of Q prediction.
115876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_rc_update_rate_correction_factors(
115976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF ||
116088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org            oxcf->rc_mode == VPX_CBR) ? 2 : 0);
1161d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
11628b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  // Keep a record of last Q and ambient average Q.
11638b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME) {
1164693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    rc->last_q[KEY_FRAME] = qindex;
1165693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    rc->avg_frame_qindex[KEY_FRAME] =
1166693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[KEY_FRAME] + qindex, 2);
11678b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  } else {
116888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (rc->is_src_frame_alt_ref ||
116988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        !(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) ||
117088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        (cpi->use_svc && oxcf->rc_mode == VPX_CBR)) {
117188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->last_q[INTER_FRAME] = qindex;
117288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->avg_frame_qindex[INTER_FRAME] =
1173693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com        ROUND_POWER_OF_TWO(3 * rc->avg_frame_qindex[INTER_FRAME] + qindex, 2);
117488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->ni_frames++;
117587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      rc->tot_q += vp9_convert_qindex_to_q(qindex, cm->bit_depth);
117688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->avg_q = rc->tot_q / rc->ni_frames;
117788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      // Calculate the average Q for normal inter frames (not key or GFU
117888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      // frames).
117988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->ni_tot_qi += qindex;
118088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->ni_av_qi = rc->ni_tot_qi / rc->ni_frames;
118188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    }
11828b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  }
1183d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1184d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Keep record of last boosted (KF/KF/ARF) Q value.
1185d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // If the current frame is coded at a lower Q then we also update it.
1186d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // If all mbs in this group are skipped only update if the Q value is
1187d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // better than that already stored.
1188d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // This is used to help set quality in forced key frames to reduce popping
1189693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  if ((qindex < rc->last_boosted_qindex) ||
119087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org      (((cm->frame_type == KEY_FRAME) || cpi->refresh_alt_ref_frame ||
1191dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        (cpi->refresh_golden_frame && !rc->is_src_frame_alt_ref)))) {
1192693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    rc->last_boosted_qindex = qindex;
1193d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
119487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME)
119587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    rc->last_kf_qindex = qindex;
1196d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
119776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  update_buffer_level(cpi, rc->projected_frame_size);
1198d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1199d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Rolling monitors of whether we are over or underspending used to help
1200d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // regulate min and Max Q in two pass.
1201d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  if (cm->frame_type != KEY_FRAME) {
1202dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->rolling_target_bits = ROUND_POWER_OF_TWO(
1203dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->rolling_target_bits * 3 + rc->this_frame_target, 2);
1204dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->rolling_actual_bits = ROUND_POWER_OF_TWO(
1205dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->rolling_actual_bits * 3 + rc->projected_frame_size, 2);
1206dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->long_rolling_target_bits = ROUND_POWER_OF_TWO(
1207dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->long_rolling_target_bits * 31 + rc->this_frame_target, 5);
1208dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->long_rolling_actual_bits = ROUND_POWER_OF_TWO(
1209dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        rc->long_rolling_actual_bits * 31 + rc->projected_frame_size, 5);
1210d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  }
1211d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1212d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org  // Actual bits spent
1213dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  rc->total_actual_bits += rc->projected_frame_size;
1214693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->total_target_bits += cm->show_frame ? rc->avg_frame_bandwidth : 0;
1215d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
121693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->total_target_vs_actual = rc->total_actual_bits - rc->total_target_bits;
1217d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
1218ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  if (is_altref_enabled(cpi) && cpi->refresh_alt_ref_frame &&
1219dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org      (cm->frame_type != KEY_FRAME))
1220dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    // Update the alternate reference frame stats as appropriate.
1221dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    update_alt_ref_frame_stats(cpi);
1222dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  else
1223dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    // Update the Golden frame stats as appropriate.
1224dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    update_golden_frame_stats(cpi);
1225dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1226dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME)
1227dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->frames_since_key = 0;
1228dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  if (cm->show_frame) {
1229dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->frames_since_key++;
1230dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    rc->frames_to_key--;
1231dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  }
1232dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org}
1233dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
1234dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgvoid vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) {
123576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Update buffer level with zero size, update frame counters, and return.
123676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  update_buffer_level(cpi, 0);
123776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  cpi->common.last_frame_type = cpi->common.frame_type;
1238dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  cpi->rc.frames_since_key++;
1239dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org  cpi->rc.frames_to_key--;
1240d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org}
124176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
124276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// Use this macro to turn on/off use of alt-refs in one-pass mode.
124376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#define USE_ALTREF_FOR_ONE_PASS   1
124476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
124576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
124676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  static const int af_ratio = 10;
124793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
124876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int target;
124976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#if USE_ALTREF_FOR_ONE_PASS
125076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  target = (!rc->is_src_frame_alt_ref &&
125176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) ?
1252693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio) /
125393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      (rc->baseline_gf_interval + af_ratio - 1) :
1254693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      (rc->avg_frame_bandwidth * rc->baseline_gf_interval) /
125593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      (rc->baseline_gf_interval + af_ratio - 1);
125676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#else
1257693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  target = rc->avg_frame_bandwidth;
125876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#endif
125976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return vp9_rc_clamp_pframe_target_size(cpi, target);
126076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
126176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
126276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_iframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
126376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  static const int kf_ratio = 25;
126476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
1265693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const int target = rc->avg_frame_bandwidth * kf_ratio;
126676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return vp9_rc_clamp_iframe_target_size(cpi, target);
126776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
126876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
126976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
127076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  VP9_COMMON *const cm = &cpi->common;
127176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
127276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int target;
12737765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  // TODO(yaowu): replace the "auto_key && 0" below with proper decision logic.
127476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (!cpi->refresh_alt_ref_frame &&
127576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      (cm->current_video_frame == 0 ||
1276693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com       (cpi->frame_flags & FRAMEFLAGS_KEY) ||
127776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org       rc->frames_to_key == 0 ||
12787765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org       (cpi->oxcf.auto_key && 0))) {
127976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = KEY_FRAME;
128076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->this_key_frame_forced = cm->current_video_frame != 0 &&
128176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                rc->frames_to_key == 0;
128277496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rc->frames_to_key = cpi->oxcf.key_freq;
128376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->kf_boost = DEFAULT_KF_BOOST;
128476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->source_alt_ref_active = 0;
128576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
128676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = INTER_FRAME;
128776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
128876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (rc->frames_till_gf_update_due == 0) {
128976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
129076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->frames_till_gf_update_due = rc->baseline_gf_interval;
129176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // NOTE: frames_till_gf_update_due must be <= frames_to_key.
129276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    if (rc->frames_till_gf_update_due > rc->frames_to_key)
129376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      rc->frames_till_gf_update_due = rc->frames_to_key;
129476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cpi->refresh_golden_frame = 1;
129576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
129676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->gfu_boost = DEFAULT_GF_BOOST;
129776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
129876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cm->frame_type == KEY_FRAME)
129976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = calc_iframe_target_size_one_pass_vbr(cpi);
130076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  else
130176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = calc_pframe_target_size_one_pass_vbr(cpi);
130276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_rc_set_frame_target(cpi, target);
130376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
130476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
130576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
1306693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *oxcf = &cpi->oxcf;
130776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
130893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const SVC *const svc = &cpi->svc;
130988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int64_t diff = rc->optimal_buffer_level - rc->buffer_level;
131088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100;
1311693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  int min_frame_target = MAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS);
1312693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  int target = rc->avg_frame_bandwidth;
131393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (svc->number_temporal_layers > 1 &&
131488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      oxcf->rc_mode == VPX_CBR) {
1315693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    // Note that for layers, avg_frame_bandwidth is the cumulative
131676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // per-frame-bandwidth. For the target size of this frame, use the
131776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // layer average frame size (i.e., non-cumulative per-frame-bw).
131893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    int current_temporal_layer = svc->temporal_layer_id;
131993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const LAYER_CONTEXT *lc = &svc->layer_context[current_temporal_layer];
132076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = lc->avg_frame_size;
132176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS);
132276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
132376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (diff > 0) {
132476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Lower the target bandwidth for this frame.
1325411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    const int pct_low = (int)MIN(diff / one_pct_bits, oxcf->under_shoot_pct);
132676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target -= (target * pct_low) / 200;
132776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else if (diff < 0) {
132876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    // Increase the target bandwidth for this frame.
1329411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    const int pct_high = (int)MIN(-diff / one_pct_bits, oxcf->over_shoot_pct);
133076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target += (target * pct_high) / 200;
133176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
133276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  return MAX(min_frame_target, target);
133376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
133476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
133576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic int calc_iframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
133676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  const RATE_CONTROL *rc = &cpi->rc;
1337693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *oxcf = &cpi->oxcf;
1338693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const SVC *const svc = &cpi->svc;
1339411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  int target;
134076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if (cpi->common.current_video_frame == 0) {
134188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    target = ((rc->starting_buffer_level / 2) > INT_MAX)
134288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      ? INT_MAX : (int)(rc->starting_buffer_level / 2);
134376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
1344693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    int kf_boost = 32;
134541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    double framerate = cpi->framerate;
1346693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (svc->number_temporal_layers > 1 &&
134788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org        oxcf->rc_mode == VPX_CBR) {
1348693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      // Use the layer framerate for temporal layers CBR mode.
1349693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      const LAYER_CONTEXT *lc = &svc->layer_context[svc->temporal_layer_id];
1350693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      framerate = lc->framerate;
1351693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    }
1352693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    kf_boost = MAX(kf_boost, (int)(2 * framerate - 16));
1353693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    if (rc->frames_since_key <  framerate / 2) {
135476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      kf_boost = (int)(kf_boost * rc->frames_since_key /
1355693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                       (framerate / 2));
135676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
1357693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    target = ((16 + kf_boost) * rc->avg_frame_bandwidth) >> 4;
135876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
1359411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org  return vp9_rc_clamp_iframe_target_size(cpi, target);
136076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
136176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
136276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid vp9_rc_get_svc_params(VP9_COMP *cpi) {
136376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  VP9_COMMON *const cm = &cpi->common;
136493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
1365693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  int target = rc->avg_frame_bandwidth;
136676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if ((cm->current_video_frame == 0) ||
1367693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      (cpi->frame_flags & FRAMEFLAGS_KEY) ||
136893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      (cpi->oxcf.auto_key && (rc->frames_since_key %
136977496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org          cpi->oxcf.key_freq == 0))) {
137076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = KEY_FRAME;
137193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    rc->source_alt_ref_active = 0;
1372810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
1373d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org    if (is_two_pass_svc(cpi)) {
1374810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org      cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame = 1;
137541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      cpi->ref_frame_flags &=
137641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org          (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
1377810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org    }
1378810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
137941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR) {
138076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      target = calc_iframe_target_size_one_pass_cbr(cpi);
138176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
138276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
138376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = INTER_FRAME;
1384810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
1385d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org    if (is_two_pass_svc(cpi)) {
1386810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org      LAYER_CONTEXT *lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
1387810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org      if (cpi->svc.spatial_layer_id == 0) {
1388810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org        lc->is_key_frame = 0;
1389810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org      } else {
1390810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org        lc->is_key_frame = cpi->svc.layer_context[0].is_key_frame;
139141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org        if (lc->is_key_frame)
139241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org          cpi->ref_frame_flags &= (~VP9_LAST_FLAG);
1393810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org      }
139441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org      cpi->ref_frame_flags &= (~VP9_ALT_FLAG);
1395810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org    }
1396810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org
139741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org    if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR) {
139876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      target = calc_pframe_target_size_one_pass_cbr(cpi);
139976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    }
140076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
140176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_rc_set_frame_target(cpi, target);
140293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->frames_till_gf_update_due = INT_MAX;
140393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  rc->baseline_gf_interval = INT_MAX;
140476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
140576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org
140676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
140776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  VP9_COMMON *const cm = &cpi->common;
140876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  RATE_CONTROL *const rc = &cpi->rc;
140976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  int target;
14107765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  // TODO(yaowu): replace the "auto_key && 0" below with proper decision logic.
141176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  if ((cm->current_video_frame == 0 ||
1412693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      (cpi->frame_flags & FRAMEFLAGS_KEY) ||
141376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org      rc->frames_to_key == 0 ||
14147765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org      (cpi->oxcf.auto_key && 0))) {
141576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = KEY_FRAME;
141676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->this_key_frame_forced = cm->current_video_frame != 0 &&
141776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                                rc->frames_to_key == 0;
141877496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org    rc->frames_to_key = cpi->oxcf.key_freq;
141976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->kf_boost = DEFAULT_KF_BOOST;
142076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    rc->source_alt_ref_active = 0;
142176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = calc_iframe_target_size_one_pass_cbr(cpi);
142276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  } else {
142376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    cm->frame_type = INTER_FRAME;
142476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    target = calc_pframe_target_size_one_pass_cbr(cpi);
142576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  }
142676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_rc_set_frame_target(cpi, target);
142776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  // Don't use gf_update by default in CBR mode.
142876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  rc->frames_till_gf_update_due = INT_MAX;
142976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  rc->baseline_gf_interval = INT_MAX;
143076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org}
143193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
143287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgint vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget,
143387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                       vpx_bit_depth_t bit_depth) {
143493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int start_index = rc->worst_quality;
143593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int target_index = rc->worst_quality;
143693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int i;
143793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
143893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Convert the average q value to an index.
143993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (i = rc->best_quality; i < rc->worst_quality; ++i) {
144093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    start_index = i;
144187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (vp9_convert_qindex_to_q(i, bit_depth) >= qstart)
144293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      break;
144393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
144493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
144593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Convert the q target to an index
144693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (i = rc->best_quality; i < rc->worst_quality; ++i) {
144793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    target_index = i;
144887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (vp9_convert_qindex_to_q(i, bit_depth) >= qtarget)
144993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      break;
145093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
145193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
145293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  return target_index - start_index;
145393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
145493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
145593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgint vp9_compute_qdelta_by_rate(const RATE_CONTROL *rc, FRAME_TYPE frame_type,
145687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                               int qindex, double rate_target_ratio,
145787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                               vpx_bit_depth_t bit_depth) {
145893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int target_index = rc->worst_quality;
145993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int i;
146093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
146193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Look up the current projected bits per block for the base index
146287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org  const int base_bits_per_mb = vp9_rc_bits_per_mb(frame_type, qindex, 1.0,
146387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org                                                  bit_depth);
146493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
146593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Find the target bits per mb based on the base value and given ratio.
146693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb);
146793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
146893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Convert the q target to an index
146993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (i = rc->best_quality; i < rc->worst_quality; ++i) {
147093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    target_index = i;
147187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org    if (vp9_rc_bits_per_mb(frame_type, i, 1.0, bit_depth) <= target_bits_per_mb)
147293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      break;
147393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
147493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
147593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  return target_index - qindex;
147693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
1477693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
1478ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.orgvoid vp9_rc_set_gf_max_interval(const VP9_COMP *const cpi,
147988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                                RATE_CONTROL *const rc) {
1480ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
148188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // Set Maximum gf/arf interval
148288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->max_gf_interval = 16;
148388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
148488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  // Extended interval for genuinely static scenes
148588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  rc->static_scene_max_gf_interval = oxcf->key_freq >> 1;
1486e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org  if (rc->static_scene_max_gf_interval > (MAX_LAG_BUFFERS * 2))
1487e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
148888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1489ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  if (is_altref_enabled(cpi)) {
149088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)
149188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org      rc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1;
149288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  }
149388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
149488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org  if (rc->max_gf_interval > rc->static_scene_max_gf_interval)
149588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org    rc->max_gf_interval = rc->static_scene_max_gf_interval;
149688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org}
149788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org
1498693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comvoid vp9_rc_update_framerate(VP9_COMP *cpi) {
1499693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9_COMMON *const cm = &cpi->common;
1500693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1501693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  RATE_CONTROL *const rc = &cpi->rc;
1502693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  int vbr_max_bits;
1503693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
150441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org  rc->avg_frame_bandwidth = (int)(oxcf->target_bandwidth / cpi->framerate);
1505693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->min_frame_bandwidth = (int)(rc->avg_frame_bandwidth *
1506693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                oxcf->two_pass_vbrmin_section / 100);
1507693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
1508693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->min_frame_bandwidth = MAX(rc->min_frame_bandwidth, FRAME_OVERHEAD_BITS);
1509693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
1510693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // A maximum bitrate for a frame is defined.
1511693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // The baseline for this aligns with HW implementations that
1512693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // can support decode of 1080P content up to a bitrate of MAX_MB_RATE bits
1513693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // per 16x16 MB (averaged over a frame). However this limit is extended if
1514693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // a very high rate is given on the command line or the the rate cannnot
1515693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // be acheived because of a user specificed max q (e.g. when the user
1516693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  // specifies lossless encode.
1517693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  vbr_max_bits = (int)(((int64_t)rc->avg_frame_bandwidth *
1518693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                     oxcf->two_pass_vbrmax_section) / 100);
1519693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  rc->max_frame_bandwidth = MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P),
1520693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                    vbr_max_bits);
1521693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
1522ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org  vp9_rc_set_gf_max_interval(cpi, rc);
1523693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com}
1524