/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <math.h>
#include <limits.h>
#include <stdio.h>

#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
#include "block.h"
#include "onyx_int.h"
#include "vpx_dsp/variance.h"
#include "encodeintra.h"
#include "vp8/common/common.h"
#include "vp8/common/setupintrarecon.h"
#include "vp8/common/systemdependent.h"
#include "mcomp.h"
#include "firstpass.h"
#include "vpx_scale/vpx_scale.h"
#include "encodemb.h"
#include "vp8/common/extend.h"
#include "vpx_ports/system_state.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/swapyv12buffer.h"
#include "rdopt.h"
#include "vp8/common/quant_common.h"
#include "encodemv.h"
#include "encodeframe.h"

#define OUTPUT_FPF 0

extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);

#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q]
extern int vp8_kf_boost_qadjustment[QINDEX_RANGE];

extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];

#define IIFACTOR 1.5
#define IIKFACTOR1 1.40
#define IIKFACTOR2 1.5
#define RMAX 14.0
#define GF_RMAX 48.0

#define KF_MB_INTRA_MIN 300
#define GF_MB_INTRA_MIN 200

#define DOUBLE_DIVIDE_CHECK(X) ((X) < 0 ? (X)-.000001 : (X) + .000001)

#define POW1 (double)cpi->oxcf.two_pass_vbrbias / 100.0
#define POW2 (double)cpi->oxcf.two_pass_vbrbias / 100.0

#define NEW_BOOST 1

static int vscale_lookup[7] = { 0, 1, 1, 2, 2, 3, 3 };
static int hscale_lookup[7] = { 0, 0, 1, 1, 2, 2, 3 };

static const int cq_level[QINDEX_RANGE] = {
  0,  0,  1,  1,  2,  3,  3,  4,  4,  5,  6,  6,  7,  8,  8,  9,  9,  10, 11,
  11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24,
  24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38,
  39, 39, 40, 41, 42, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 50, 51, 52, 53,
  54, 55, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 67, 68, 69,
  70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 86,
  87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
};

static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);

/* Resets the first pass file to the given position using a relative seek
 * from the current position
 */
static void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position) {
  cpi->twopass.stats_in = Position;
}

static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame) {
  if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) return EOF;

  *next_frame = *cpi->twopass.stats_in;
  return 1;
}

/* Read frame stats at an offset from the current position */
static int read_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *frame_stats,
                            int offset) {
  FIRSTPASS_STATS *fps_ptr = cpi->twopass.stats_in;

  /* Check legality of offset */
  if (offset >= 0) {
    if (&fps_ptr[offset] >= cpi->twopass.stats_in_end) return EOF;
  } else if (offset < 0) {
    if (&fps_ptr[offset] < cpi->twopass.stats_in_start) return EOF;
  }

  *frame_stats = fps_ptr[offset];
  return 1;
}

static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps) {
  if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) return EOF;

  *fps = *cpi->twopass.stats_in;
  cpi->twopass.stats_in =
      (void *)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
  return 1;
}

static void output_stats(const VP8_COMP *cpi,
                         struct vpx_codec_pkt_list *pktlist,
                         FIRSTPASS_STATS *stats) {
  struct vpx_codec_cx_pkt pkt;
  (void)cpi;
  pkt.kind = VPX_CODEC_STATS_PKT;
  pkt.data.twopass_stats.buf = stats;
  pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
  vpx_codec_pkt_list_add(pktlist, &pkt);

/* TEMP debug code */
#if OUTPUT_FPF

  {
    FILE *fpfile;
    fpfile = fopen("firstpass.stt", "a");

    fprintf(fpfile,
            "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
            " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
            " %12.0f %12.0f %12.4f\n",
            stats->frame, stats->intra_error, stats->coded_error,
            stats->ssim_weighted_pred_err, stats->pcnt_inter,
            stats->pcnt_motion, stats->pcnt_second_ref, stats->pcnt_neutral,
            stats->MVr, stats->mvr_abs, stats->MVc, stats->mvc_abs, stats->MVrv,
            stats->MVcv, stats->mv_in_out_count, stats->new_mv_count,
            stats->count, stats->duration);
    fclose(fpfile);
  }
#endif
}

static void zero_stats(FIRSTPASS_STATS *section) {
  section->frame = 0.0;
  section->intra_error = 0.0;
  section->coded_error = 0.0;
  section->ssim_weighted_pred_err = 0.0;
  section->pcnt_inter = 0.0;
  section->pcnt_motion = 0.0;
  section->pcnt_second_ref = 0.0;
  section->pcnt_neutral = 0.0;
  section->MVr = 0.0;
  section->mvr_abs = 0.0;
  section->MVc = 0.0;
  section->mvc_abs = 0.0;
  section->MVrv = 0.0;
  section->MVcv = 0.0;
  section->mv_in_out_count = 0.0;
  section->new_mv_count = 0.0;
  section->count = 0.0;
  section->duration = 1.0;
}

static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) {
  section->frame += frame->frame;
  section->intra_error += frame->intra_error;
  section->coded_error += frame->coded_error;
  section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
  section->pcnt_inter += frame->pcnt_inter;
  section->pcnt_motion += frame->pcnt_motion;
  section->pcnt_second_ref += frame->pcnt_second_ref;
  section->pcnt_neutral += frame->pcnt_neutral;
  section->MVr += frame->MVr;
  section->mvr_abs += frame->mvr_abs;
  section->MVc += frame->MVc;
  section->mvc_abs += frame->mvc_abs;
  section->MVrv += frame->MVrv;
  section->MVcv += frame->MVcv;
  section->mv_in_out_count += frame->mv_in_out_count;
  section->new_mv_count += frame->new_mv_count;
  section->count += frame->count;
  section->duration += frame->duration;
}

static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) {
  section->frame -= frame->frame;
  section->intra_error -= frame->intra_error;
  section->coded_error -= frame->coded_error;
  section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
  section->pcnt_inter -= frame->pcnt_inter;
  section->pcnt_motion -= frame->pcnt_motion;
  section->pcnt_second_ref -= frame->pcnt_second_ref;
  section->pcnt_neutral -= frame->pcnt_neutral;
  section->MVr -= frame->MVr;
  section->mvr_abs -= frame->mvr_abs;
  section->MVc -= frame->MVc;
  section->mvc_abs -= frame->mvc_abs;
  section->MVrv -= frame->MVrv;
  section->MVcv -= frame->MVcv;
  section->mv_in_out_count -= frame->mv_in_out_count;
  section->new_mv_count -= frame->new_mv_count;
  section->count -= frame->count;
  section->duration -= frame->duration;
}

static void avg_stats(FIRSTPASS_STATS *section) {
  if (section->count < 1.0) return;

  section->intra_error /= section->count;
  section->coded_error /= section->count;
  section->ssim_weighted_pred_err /= section->count;
  section->pcnt_inter /= section->count;
  section->pcnt_second_ref /= section->count;
  section->pcnt_neutral /= section->count;
  section->pcnt_motion /= section->count;
  section->MVr /= section->count;
  section->mvr_abs /= section->count;
  section->MVc /= section->count;
  section->mvc_abs /= section->count;
  section->MVrv /= section->count;
  section->MVcv /= section->count;
  section->mv_in_out_count /= section->count;
  section->duration /= section->count;
}

/* Calculate a modified Error used in distributing bits between easier
 * and harder frames
 */
static double calculate_modified_err(VP8_COMP *cpi,
                                     FIRSTPASS_STATS *this_frame) {
  double av_err = (cpi->twopass.total_stats.ssim_weighted_pred_err /
                   cpi->twopass.total_stats.count);
  double this_err = this_frame->ssim_weighted_pred_err;
  double modified_err;

  if (this_err > av_err) {
    modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
  } else {
    modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);
  }

  return modified_err;
}

static const double weight_table[256] = {
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.031250, 0.062500,
  0.093750, 0.125000, 0.156250, 0.187500, 0.218750, 0.250000, 0.281250,
  0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750, 0.500000,
  0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750,
  0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500,
  0.968750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000
};

static double simple_weight(YV12_BUFFER_CONFIG *source) {
  int i, j;

  unsigned char *src = source->y_buffer;
  double sum_weights = 0.0;

  /* Loop throught the Y plane raw examining levels and creating a weight
   * for the image
   */
  i = source->y_height;
  do {
    j = source->y_width;
    do {
      sum_weights += weight_table[*src];
      src++;
    } while (--j);
    src -= source->y_width;
    src += source->y_stride;
  } while (--i);

  sum_weights /= (source->y_height * source->y_width);

  return sum_weights;
}

/* This function returns the current per frame maximum bitrate target */
static int frame_max_bits(VP8_COMP *cpi) {
  /* Max allocation for a single frame based on the max section guidelines
   * passed in and how many bits are left
   */
  int max_bits;

  /* For CBR we need to also consider buffer fullness.
   * If we are running below the optimal level then we need to gradually
   * tighten up on max_bits.
   */
  if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
    double buffer_fullness_ratio =
        (double)cpi->buffer_level /
        DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);

    /* For CBR base this on the target average bits per frame plus the
     * maximum sedction rate passed in by the user
     */
    max_bits = (int)(cpi->av_per_frame_bandwidth *
                     ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));

    /* If our buffer is below the optimum level */
    if (buffer_fullness_ratio < 1.0) {
      /* The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4. */
      int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2))
                             ? cpi->av_per_frame_bandwidth >> 2
                             : max_bits >> 2;

      max_bits = (int)(max_bits * buffer_fullness_ratio);

      /* Lowest value we will set ... which should allow the buffer to
       * refill.
       */
      if (max_bits < min_max_bits) max_bits = min_max_bits;
    }
  }
  /* VBR */
  else {
    /* For VBR base this on the bits and frames left plus the
     * two_pass_vbrmax_section rate passed in by the user
     */
    max_bits = (int)(((double)cpi->twopass.bits_left /
                      (cpi->twopass.total_stats.count -
                       (double)cpi->common.current_video_frame)) *
                     ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
  }

  /* Trap case where we are out of bits */
  if (max_bits < 0) max_bits = 0;

  return max_bits;
}

void vp8_init_first_pass(VP8_COMP *cpi) {
  zero_stats(&cpi->twopass.total_stats);
}

void vp8_end_first_pass(VP8_COMP *cpi) {
  output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.total_stats);
}

static void zz_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
                             YV12_BUFFER_CONFIG *raw_buffer,
                             int *raw_motion_err,
                             YV12_BUFFER_CONFIG *recon_buffer,
                             int *best_motion_err, int recon_yoffset) {
  MACROBLOCKD *const xd = &x->e_mbd;
  BLOCK *b = &x->block[0];
  BLOCKD *d = &x->e_mbd.block[0];

  unsigned char *src_ptr = (*(b->base_src) + b->src);
  int src_stride = b->src_stride;
  unsigned char *raw_ptr;
  int raw_stride = raw_buffer->y_stride;
  unsigned char *ref_ptr;
  int ref_stride = x->e_mbd.pre.y_stride;
  (void)cpi;

  /* Set up pointers for this macro block raw buffer */
  raw_ptr = (unsigned char *)(raw_buffer->y_buffer + recon_yoffset + d->offset);
  vpx_mse16x16(src_ptr, src_stride, raw_ptr, raw_stride,
               (unsigned int *)(raw_motion_err));

  /* Set up pointers for this macro block recon buffer */
  xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
  ref_ptr = (unsigned char *)(xd->pre.y_buffer + d->offset);
  vpx_mse16x16(src_ptr, src_stride, ref_ptr, ref_stride,
               (unsigned int *)(best_motion_err));
}

static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
                                     int_mv *ref_mv, MV *best_mv,
                                     YV12_BUFFER_CONFIG *recon_buffer,
                                     int *best_motion_err, int recon_yoffset) {
  MACROBLOCKD *const xd = &x->e_mbd;
  BLOCK *b = &x->block[0];
  BLOCKD *d = &x->e_mbd.block[0];
  int num00;

  int_mv tmp_mv;
  int_mv ref_mv_full;

  int tmp_err;
  int step_param = 3; /* Dont search over full range for first pass */
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
  int n;
  vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16];
  int new_mv_mode_penalty = 256;

  /* override the default variance function to use MSE */
  v_fn_ptr.vf = vpx_mse16x16;

  /* Set up pointers for this macro block recon buffer */
  xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;

  /* Initial step/diamond search centred on best mv */
  tmp_mv.as_int = 0;
  ref_mv_full.as_mv.col = ref_mv->as_mv.col >> 3;
  ref_mv_full.as_mv.row = ref_mv->as_mv.row >> 3;
  tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param,
                                    x->sadperbit16, &num00, &v_fn_ptr,
                                    x->mvcost, ref_mv);
  if (tmp_err < INT_MAX - new_mv_mode_penalty) tmp_err += new_mv_mode_penalty;

  if (tmp_err < *best_motion_err) {
    *best_motion_err = tmp_err;
    best_mv->row = tmp_mv.as_mv.row;
    best_mv->col = tmp_mv.as_mv.col;
  }

  /* Further step/diamond searches as necessary */
  n = num00;
  num00 = 0;

  while (n < further_steps) {
    n++;

    if (num00) {
      num00--;
    } else {
      tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv,
                                        step_param + n, x->sadperbit16, &num00,
                                        &v_fn_ptr, x->mvcost, ref_mv);
      if (tmp_err < INT_MAX - new_mv_mode_penalty) {
        tmp_err += new_mv_mode_penalty;
      }

      if (tmp_err < *best_motion_err) {
        *best_motion_err = tmp_err;
        best_mv->row = tmp_mv.as_mv.row;
        best_mv->col = tmp_mv.as_mv.col;
      }
    }
  }
}

void vp8_first_pass(VP8_COMP *cpi) {
  int mb_row, mb_col;
  MACROBLOCK *const x = &cpi->mb;
  VP8_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;

  int recon_yoffset, recon_uvoffset;
  YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx];
  YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
  YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx];
  int recon_y_stride = lst_yv12->y_stride;
  int recon_uv_stride = lst_yv12->uv_stride;
  int64_t intra_error = 0;
  int64_t coded_error = 0;

  int sum_mvr = 0, sum_mvc = 0;
  int sum_mvr_abs = 0, sum_mvc_abs = 0;
  int sum_mvrs = 0, sum_mvcs = 0;
  int mvcount = 0;
  int intercount = 0;
  int second_ref_count = 0;
  int intrapenalty = 256;
  int neutral_count = 0;
  int new_mv_count = 0;
  int sum_in_vectors = 0;
  uint32_t lastmv_as_int = 0;

  int_mv zero_ref_mv;

  zero_ref_mv.as_int = 0;

  vpx_clear_system_state();

  x->src = *cpi->Source;
  xd->pre = *lst_yv12;
  xd->dst = *new_yv12;

  x->partition_info = x->pi;

  xd->mode_info_context = cm->mi;

  if (!cm->use_bilinear_mc_filter) {
    xd->subpixel_predict = vp8_sixtap_predict4x4;
    xd->subpixel_predict8x4 = vp8_sixtap_predict8x4;
    xd->subpixel_predict8x8 = vp8_sixtap_predict8x8;
    xd->subpixel_predict16x16 = vp8_sixtap_predict16x16;
  } else {
    xd->subpixel_predict = vp8_bilinear_predict4x4;
    xd->subpixel_predict8x4 = vp8_bilinear_predict8x4;
    xd->subpixel_predict8x8 = vp8_bilinear_predict8x8;
    xd->subpixel_predict16x16 = vp8_bilinear_predict16x16;
  }

  vp8_build_block_offsets(x);

  /* set up frame new frame for intra coded blocks */
  vp8_setup_intra_recon(new_yv12);
  vp8cx_frame_init_quantizer(cpi);

  /* Initialise the MV cost table to the defaults */
  {
    int flag[2] = { 1, 1 };
    vp8_initialize_rd_consts(cpi, x,
                             vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
    memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
    vp8_build_component_cost_table(cpi->mb.mvcost,
                                   (const MV_CONTEXT *)cm->fc.mvc, flag);
  }

  /* for each macroblock row in image */
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
    int_mv best_ref_mv;

    best_ref_mv.as_int = 0;

    /* reset above block coeffs */
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
    recon_uvoffset = (mb_row * recon_uv_stride * 8);

    /* Set up limit values for motion vectors to prevent them extending
     * outside the UMV borders
     */
    x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
    x->mv_row_max =
        ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);

    /* for each macroblock col in image */
    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
      int this_error;
      int gf_motion_error = INT_MAX;
      int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);

      xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
      xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset;
      xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset;
      xd->left_available = (mb_col != 0);

      /* Copy current mb to a buffer */
      vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);

      /* do intra 16x16 prediction */
      this_error = vp8_encode_intra(cpi, x, use_dc_pred);

      /* "intrapenalty" below deals with situations where the intra
       * and inter error scores are very low (eg a plain black frame)
       * We do not have special cases in first pass for 0,0 and
       * nearest etc so all inter modes carry an overhead cost
       * estimate fot the mv. When the error score is very low this
       * causes us to pick all or lots of INTRA modes and throw lots
       * of key frames. This penalty adds a cost matching that of a
       * 0,0 mv to the intra case.
       */
      this_error += intrapenalty;

      /* Cumulative intra error total */
      intra_error += (int64_t)this_error;

      /* Set up limit values for motion vectors to prevent them
       * extending outside the UMV borders
       */
      x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
      x->mv_col_max =
          ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);

      /* Other than for the first frame do a motion search */
      if (cm->current_video_frame > 0) {
        BLOCKD *d = &x->e_mbd.block[0];
        MV tmp_mv = { 0, 0 };
        int tmp_err;
        int motion_error = INT_MAX;
        int raw_motion_error = INT_MAX;

        /* Simple 0,0 motion with no mv overhead */
        zz_motion_search(cpi, x, cpi->last_frame_unscaled_source,
                         &raw_motion_error, lst_yv12, &motion_error,
                         recon_yoffset);
        d->bmi.mv.as_mv.row = 0;
        d->bmi.mv.as_mv.col = 0;

        if (raw_motion_error < cpi->oxcf.encode_breakout) {
          goto skip_motion_search;
        }

        /* Test last reference frame using the previous best mv as the
         * starting point (best reference) for the search
         */
        first_pass_motion_search(cpi, x, &best_ref_mv, &d->bmi.mv.as_mv,
                                 lst_yv12, &motion_error, recon_yoffset);

        /* If the current best reference mv is not centred on 0,0
         * then do a 0,0 based search as well
         */
        if (best_ref_mv.as_int) {
          tmp_err = INT_MAX;
          first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, lst_yv12,
                                   &tmp_err, recon_yoffset);

          if (tmp_err < motion_error) {
            motion_error = tmp_err;
            d->bmi.mv.as_mv.row = tmp_mv.row;
            d->bmi.mv.as_mv.col = tmp_mv.col;
          }
        }

        /* Experimental search in a second reference frame ((0,0)
         * based only)
         */
        if (cm->current_video_frame > 1) {
          first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, gld_yv12,
                                   &gf_motion_error, recon_yoffset);

          if ((gf_motion_error < motion_error) &&
              (gf_motion_error < this_error)) {
            second_ref_count++;
          }

          /* Reset to last frame as reference buffer */
          xd->pre.y_buffer = lst_yv12->y_buffer + recon_yoffset;
          xd->pre.u_buffer = lst_yv12->u_buffer + recon_uvoffset;
          xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset;
        }

      skip_motion_search:
        /* Intra assumed best */
        best_ref_mv.as_int = 0;

        if (motion_error <= this_error) {
          /* Keep a count of cases where the inter and intra were
           * very close and very low. This helps with scene cut
           * detection for example in cropped clips with black bars
           * at the sides or top and bottom.
           */
          if ((((this_error - intrapenalty) * 9) <= (motion_error * 10)) &&
              (this_error < (2 * intrapenalty))) {
            neutral_count++;
          }

          d->bmi.mv.as_mv.row *= 8;
          d->bmi.mv.as_mv.col *= 8;
          this_error = motion_error;
          vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv);
          vp8_encode_inter16x16y(x);
          sum_mvr += d->bmi.mv.as_mv.row;
          sum_mvr_abs += abs(d->bmi.mv.as_mv.row);
          sum_mvc += d->bmi.mv.as_mv.col;
          sum_mvc_abs += abs(d->bmi.mv.as_mv.col);
          sum_mvrs += d->bmi.mv.as_mv.row * d->bmi.mv.as_mv.row;
          sum_mvcs += d->bmi.mv.as_mv.col * d->bmi.mv.as_mv.col;
          intercount++;

          best_ref_mv.as_int = d->bmi.mv.as_int;

          /* Was the vector non-zero */
          if (d->bmi.mv.as_int) {
            mvcount++;

            /* Was it different from the last non zero vector */
            if (d->bmi.mv.as_int != lastmv_as_int) new_mv_count++;
            lastmv_as_int = d->bmi.mv.as_int;

            /* Does the Row vector point inwards or outwards */
            if (mb_row < cm->mb_rows / 2) {
              if (d->bmi.mv.as_mv.row > 0) {
                sum_in_vectors--;
              } else if (d->bmi.mv.as_mv.row < 0) {
                sum_in_vectors++;
              }
            } else if (mb_row > cm->mb_rows / 2) {
              if (d->bmi.mv.as_mv.row > 0) {
                sum_in_vectors++;
              } else if (d->bmi.mv.as_mv.row < 0) {
                sum_in_vectors--;
              }
            }

            /* Does the Row vector point inwards or outwards */
            if (mb_col < cm->mb_cols / 2) {
              if (d->bmi.mv.as_mv.col > 0) {
                sum_in_vectors--;
              } else if (d->bmi.mv.as_mv.col < 0) {
                sum_in_vectors++;
              }
            } else if (mb_col > cm->mb_cols / 2) {
              if (d->bmi.mv.as_mv.col > 0) {
                sum_in_vectors++;
              } else if (d->bmi.mv.as_mv.col < 0) {
                sum_in_vectors--;
              }
            }
          }
        }
      }

      coded_error += (int64_t)this_error;

      /* adjust to the next column of macroblocks */
      x->src.y_buffer += 16;
      x->src.u_buffer += 8;
      x->src.v_buffer += 8;

      recon_yoffset += 16;
      recon_uvoffset += 8;
    }

    /* adjust to the next row of mbs */
    x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
    x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
    x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;

    /* extend the recon for intra prediction */
    vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8,
                      xd->dst.v_buffer + 8);
    vpx_clear_system_state();
  }

  vpx_clear_system_state();
  {
    double weight = 0.0;

    FIRSTPASS_STATS fps;

    fps.frame = cm->current_video_frame;
    fps.intra_error = (double)(intra_error >> 8);
    fps.coded_error = (double)(coded_error >> 8);
    weight = simple_weight(cpi->Source);

    if (weight < 0.1) weight = 0.1;

    fps.ssim_weighted_pred_err = fps.coded_error * weight;

    fps.pcnt_inter = 0.0;
    fps.pcnt_motion = 0.0;
    fps.MVr = 0.0;
    fps.mvr_abs = 0.0;
    fps.MVc = 0.0;
    fps.mvc_abs = 0.0;
    fps.MVrv = 0.0;
    fps.MVcv = 0.0;
    fps.mv_in_out_count = 0.0;
    fps.new_mv_count = 0.0;
    fps.count = 1.0;

    fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs;
    fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs;
    fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs;

    if (mvcount > 0) {
      fps.MVr = (double)sum_mvr / (double)mvcount;
      fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount;
      fps.MVc = (double)sum_mvc / (double)mvcount;
      fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount;
      fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) /
                 (double)mvcount;
      fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) /
                 (double)mvcount;
      fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
      fps.new_mv_count = new_mv_count;

      fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
    }

    /* TODO:  handle the case when duration is set to 0, or something less
     * than the full time between subsequent cpi->source_time_stamps
     */
    fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start);

    /* don't want to do output stats with a stack variable! */
    memcpy(&cpi->twopass.this_frame_stats, &fps, sizeof(FIRSTPASS_STATS));
    output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.this_frame_stats);
    accumulate_stats(&cpi->twopass.total_stats, &fps);
  }

  /* Copy the previous Last Frame into the GF buffer if specific
   * conditions for doing so are met
   */
  if ((cm->current_video_frame > 0) &&
      (cpi->twopass.this_frame_stats.pcnt_inter > 0.20) &&
      ((cpi->twopass.this_frame_stats.intra_error /
        DOUBLE_DIVIDE_CHECK(cpi->twopass.this_frame_stats.coded_error)) >
       2.0)) {
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
  }

  /* swap frame pointers so last frame refers to the frame we just
   * compressed
   */
  vp8_swap_yv12_buffer(lst_yv12, new_yv12);
  vp8_yv12_extend_frame_borders(lst_yv12);

  /* Special case for the first frame. Copy into the GF buffer as a
   * second reference.
   */
  if (cm->current_video_frame == 0) {
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
  }

  /* use this to see what the first pass reconstruction looks like */
  if (0) {
    char filename[512];
    FILE *recon_file;
    sprintf(filename, "enc%04d.yuv", (int)cm->current_video_frame);

    if (cm->current_video_frame == 0) {
      recon_file = fopen(filename, "wb");
    } else {
      recon_file = fopen(filename, "ab");
    }

    (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file);
    fclose(recon_file);
  }

  cm->current_video_frame++;
}
extern const int vp8_bits_per_mb[2][QINDEX_RANGE];

/* Estimate a cost per mb attributable to overheads such as the coding of
 * modes and motion vectors.
 * Currently simplistic in its assumptions for testing.
 */

static double bitcost(double prob) {
  if (prob > 0.000122) {
    return -log(prob) / log(2.0);
  } else {
    return 13.0;
  }
}
static int64_t estimate_modemvcost(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats) {
  int mv_cost;
  int64_t mode_cost;

  double av_pct_inter = fpstats->pcnt_inter / fpstats->count;
  double av_pct_motion = fpstats->pcnt_motion / fpstats->count;
  double av_intra = (1.0 - av_pct_inter);

  double zz_cost;
  double motion_cost;
  double intra_cost;

  zz_cost = bitcost(av_pct_inter - av_pct_motion);
  motion_cost = bitcost(av_pct_motion);
  intra_cost = bitcost(av_intra);

  /* Estimate of extra bits per mv overhead for mbs
   * << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb
   */
  mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9;

  /* Crude estimate of overhead cost from modes
   * << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb
   */
  mode_cost =
      (int64_t)((((av_pct_inter - av_pct_motion) * zz_cost) +
                 (av_pct_motion * motion_cost) + (av_intra * intra_cost)) *
                cpi->common.MBs) *
      512;

  return mv_cost + mode_cost;
}

static double calc_correction_factor(double err_per_mb, double err_devisor,
                                     double pt_low, double pt_high, int Q) {
  double power_term;
  double error_term = err_per_mb / err_devisor;
  double correction_factor;

  /* Adjustment based on Q to power term. */
  power_term = pt_low + (Q * 0.01);
  power_term = (power_term > pt_high) ? pt_high : power_term;

  /* Adjustments to error term */
  /* TBD */

  /* Calculate correction factor */
  correction_factor = pow(error_term, power_term);

  /* Clip range */
  correction_factor = (correction_factor < 0.05)
                          ? 0.05
                          : (correction_factor > 5.0) ? 5.0 : correction_factor;

  return correction_factor;
}

static int estimate_max_q(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats,
                          int section_target_bandwitdh, int overhead_bits) {
  int Q;
  int num_mbs = cpi->common.MBs;
  int target_norm_bits_per_mb;

  double section_err = (fpstats->coded_error / fpstats->count);
  double err_per_mb = section_err / num_mbs;
  double err_correction_factor;
  double speed_correction = 1.0;
  int overhead_bits_per_mb;

  if (section_target_bandwitdh <= 0) {
    return cpi->twopass.maxq_max_limit; /* Highest value allowed */
  }

  target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
                                ? (512 * section_target_bandwitdh) / num_mbs
                                : 512 * (section_target_bandwitdh / num_mbs);

  /* Calculate a corrective factor based on a rolling ratio of bits spent
   * vs target bits
   */
  if ((cpi->rolling_target_bits > 0) &&
      (cpi->active_worst_quality < cpi->worst_quality)) {
    double rolling_ratio;

    rolling_ratio =
        (double)cpi->rolling_actual_bits / (double)cpi->rolling_target_bits;

    if (rolling_ratio < 0.95) {
      cpi->twopass.est_max_qcorrection_factor -= 0.005;
    } else if (rolling_ratio > 1.05) {
      cpi->twopass.est_max_qcorrection_factor += 0.005;
    }

    cpi->twopass.est_max_qcorrection_factor =
        (cpi->twopass.est_max_qcorrection_factor < 0.1)
            ? 0.1
            : (cpi->twopass.est_max_qcorrection_factor > 10.0)
                  ? 10.0
                  : cpi->twopass.est_max_qcorrection_factor;
  }

  /* Corrections for higher compression speed settings
   * (reduced compression expected)
   */
  if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) {
    if (cpi->oxcf.cpu_used <= 5) {
      speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
    } else {
      speed_correction = 1.25;
    }
  }

  /* Estimate of overhead bits per mb */
  /* Correction to overhead bits for min allowed Q. */
  overhead_bits_per_mb = overhead_bits / num_mbs;
  overhead_bits_per_mb = (int)(overhead_bits_per_mb *
                               pow(0.98, (double)cpi->twopass.maxq_min_limit));

  /* Try and pick a max Q that will be high enough to encode the
   * content at the given rate.
   */
  for (Q = cpi->twopass.maxq_min_limit; Q < cpi->twopass.maxq_max_limit; ++Q) {
    int bits_per_mb_at_this_q;

    /* Error per MB based correction factor */
    err_correction_factor =
        calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);

    bits_per_mb_at_this_q =
        vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;

    bits_per_mb_at_this_q = (int)(.5 +
                                  err_correction_factor * speed_correction *
                                      cpi->twopass.est_max_qcorrection_factor *
                                      cpi->twopass.section_max_qfactor *
                                      (double)bits_per_mb_at_this_q);

    /* Mode and motion overhead */
    /* As Q rises in real encode loop rd code will force overhead down
     * We make a crude adjustment for this here as *.98 per Q step.
     */
    overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);

    if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break;
  }

  /* Restriction on active max q for constrained quality mode. */
  if ((cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
      (Q < cpi->cq_target_quality)) {
    Q = cpi->cq_target_quality;
  }

  /* Adjust maxq_min_limit and maxq_max_limit limits based on
   * average q observed in clip for non kf/gf.arf frames
   * Give average a chance to settle though.
   */
  if ((cpi->ni_frames > ((int)cpi->twopass.total_stats.count >> 8)) &&
      (cpi->ni_frames > 150)) {
    cpi->twopass.maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality)
                                      ? (cpi->ni_av_qi + 32)
                                      : cpi->worst_quality;
    cpi->twopass.maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality)
                                      ? (cpi->ni_av_qi - 32)
                                      : cpi->best_quality;
  }

  return Q;
}

/* For cq mode estimate a cq level that matches the observed
 * complexity and data rate.
 */
static int estimate_cq(VP8_COMP *cpi, FIRSTPASS_STATS *fpstats,
                       int section_target_bandwitdh, int overhead_bits) {
  int Q;
  int num_mbs = cpi->common.MBs;
  int target_norm_bits_per_mb;

  double section_err = (fpstats->coded_error / fpstats->count);
  double err_per_mb = section_err / num_mbs;
  double err_correction_factor;
  double speed_correction = 1.0;
  double clip_iiratio;
  double clip_iifactor;
  int overhead_bits_per_mb;

  if (0) {
    FILE *f = fopen("epmp.stt", "a");
    fprintf(f, "%10.2f\n", err_per_mb);
    fclose(f);
  }

  target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
                                ? (512 * section_target_bandwitdh) / num_mbs
                                : 512 * (section_target_bandwitdh / num_mbs);

  /* Estimate of overhead bits per mb */
  overhead_bits_per_mb = overhead_bits / num_mbs;

  /* Corrections for higher compression speed settings
   * (reduced compression expected)
   */
  if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) {
    if (cpi->oxcf.cpu_used <= 5) {
      speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
    } else {
      speed_correction = 1.25;
    }
  }

  /* II ratio correction factor for clip as a whole */
  clip_iiratio = cpi->twopass.total_stats.intra_error /
                 DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.coded_error);
  clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
  if (clip_iifactor < 0.80) clip_iifactor = 0.80;

  /* Try and pick a Q that can encode the content at the given rate. */
  for (Q = 0; Q < MAXQ; ++Q) {
    int bits_per_mb_at_this_q;

    /* Error per MB based correction factor */
    err_correction_factor =
        calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q);

    bits_per_mb_at_this_q =
        vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;

    bits_per_mb_at_this_q =
        (int)(.5 +
              err_correction_factor * speed_correction * clip_iifactor *
                  (double)bits_per_mb_at_this_q);

    /* Mode and motion overhead */
    /* As Q rises in real encode loop rd code will force overhead down
     * We make a crude adjustment for this here as *.98 per Q step.
     */
    overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);

    if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break;
  }

  /* Clip value to range "best allowed to (worst allowed - 1)" */
  Q = cq_level[Q];
  if (Q >= cpi->worst_quality) Q = cpi->worst_quality - 1;
  if (Q < cpi->best_quality) Q = cpi->best_quality;

  return Q;
}

static int estimate_q(VP8_COMP *cpi, double section_err,
                      int section_target_bandwitdh) {
  int Q;
  int num_mbs = cpi->common.MBs;
  int target_norm_bits_per_mb;

  double err_per_mb = section_err / num_mbs;
  double err_correction_factor;
  double speed_correction = 1.0;

  target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
                                ? (512 * section_target_bandwitdh) / num_mbs
                                : 512 * (section_target_bandwitdh / num_mbs);

  /* Corrections for higher compression speed settings
   * (reduced compression expected)
   */
  if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) {
    if (cpi->oxcf.cpu_used <= 5) {
      speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
    } else {
      speed_correction = 1.25;
    }
  }

  /* Try and pick a Q that can encode the content at the given rate. */
  for (Q = 0; Q < MAXQ; ++Q) {
    int bits_per_mb_at_this_q;

    /* Error per MB based correction factor */
    err_correction_factor =
        calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);

    bits_per_mb_at_this_q =
        (int)(.5 + (err_correction_factor * speed_correction *
                    cpi->twopass.est_max_qcorrection_factor *
                    (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0));

    if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break;
  }

  return Q;
}

/* Estimate a worst case Q for a KF group */
static int estimate_kf_group_q(VP8_COMP *cpi, double section_err,
                               int section_target_bandwitdh,
                               double group_iiratio) {
  int Q;
  int num_mbs = cpi->common.MBs;
  int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs;
  int bits_per_mb_at_this_q;

  double err_per_mb = section_err / num_mbs;
  double err_correction_factor;
  double speed_correction = 1.0;
  double current_spend_ratio = 1.0;

  double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90;
  double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80;

  double iiratio_correction_factor = 1.0;

  double combined_correction_factor;

  /* Trap special case where the target is <= 0 */
  if (target_norm_bits_per_mb <= 0) return MAXQ * 2;

  /* Calculate a corrective factor based on a rolling ratio of bits spent
   *  vs target bits
   * This is clamped to the range 0.1 to 10.0
   */
  if (cpi->long_rolling_target_bits <= 0) {
    current_spend_ratio = 10.0;
  } else {
    current_spend_ratio = (double)cpi->long_rolling_actual_bits /
                          (double)cpi->long_rolling_target_bits;
    current_spend_ratio =
        (current_spend_ratio > 10.0)
            ? 10.0
            : (current_spend_ratio < 0.1) ? 0.1 : current_spend_ratio;
  }

  /* Calculate a correction factor based on the quality of prediction in
   * the sequence as indicated by intra_inter error score ratio (IIRatio)
   * The idea here is to favour subsampling in the hardest sections vs
   * the easyest.
   */
  iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1);

  if (iiratio_correction_factor < 0.5) iiratio_correction_factor = 0.5;

  /* Corrections for higher compression speed settings
   * (reduced compression expected)
   */
  if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1)) {
    if (cpi->oxcf.cpu_used <= 5) {
      speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
    } else {
      speed_correction = 1.25;
    }
  }

  /* Combine the various factors calculated above */
  combined_correction_factor =
      speed_correction * iiratio_correction_factor * current_spend_ratio;

  /* Try and pick a Q that should be high enough to encode the content at
   * the given rate.
   */
  for (Q = 0; Q < MAXQ; ++Q) {
    /* Error per MB based correction factor */
    err_correction_factor =
        calc_correction_factor(err_per_mb, 150.0, pow_lowq, pow_highq, Q);

    bits_per_mb_at_this_q =
        (int)(.5 + (err_correction_factor * combined_correction_factor *
                    (double)vp8_bits_per_mb[INTER_FRAME][Q]));

    if (bits_per_mb_at_this_q <= target_norm_bits_per_mb) break;
  }

  /* If we could not hit the target even at Max Q then estimate what Q
   * would have been required
   */
  while ((bits_per_mb_at_this_q > target_norm_bits_per_mb) &&
         (Q < (MAXQ * 2))) {
    bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
    Q++;
  }

  if (0) {
    FILE *f = fopen("estkf_q.stt", "a");
    fprintf(f, "%8d %8d %8d %8.2f %8.3f %8.2f %8.3f %8.3f %8.3f %8d\n",
            cpi->common.current_video_frame, bits_per_mb_at_this_q,
            target_norm_bits_per_mb, err_per_mb, err_correction_factor,
            current_spend_ratio, group_iiratio, iiratio_correction_factor,
            (double)cpi->buffer_level / (double)cpi->oxcf.optimal_buffer_level,
            Q);
    fclose(f);
  }

  return Q;
}

void vp8_init_second_pass(VP8_COMP *cpi) {
  FIRSTPASS_STATS this_frame;
  FIRSTPASS_STATS *start_pos;

  double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth *
                                      cpi->oxcf.two_pass_vbrmin_section / 100);

  zero_stats(&cpi->twopass.total_stats);
  zero_stats(&cpi->twopass.total_left_stats);

  if (!cpi->twopass.stats_in_end) return;

  cpi->twopass.total_stats = *cpi->twopass.stats_in_end;
  cpi->twopass.total_left_stats = cpi->twopass.total_stats;

  /* each frame can have a different duration, as the frame rate in the
   * source isn't guaranteed to be constant.   The frame rate prior to
   * the first frame encoded in the second pass is a guess.  However the
   * sum duration is not. Its calculated based on the actual durations of
   * all frames from the first pass.
   */
  vp8_new_framerate(cpi, 10000000.0 * cpi->twopass.total_stats.count /
                             cpi->twopass.total_stats.duration);

  cpi->output_framerate = cpi->framerate;
  cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats.duration *
                                     cpi->oxcf.target_bandwidth / 10000000.0);
  cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats.duration *
                                      two_pass_min_rate / 10000000.0);

  /* Calculate a minimum intra value to be used in determining the IIratio
   * scores used in the second pass. We have this minimum to make sure
   * that clips that are static but "low complexity" in the intra domain
   * are still boosted appropriately for KF/GF/ARF
   */
  cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
  cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;

  /* Scan the first pass file and calculate an average Intra / Inter error
   * score ratio for the sequence
   */
  {
    double sum_iiratio = 0.0;
    double IIRatio;

    start_pos = cpi->twopass.stats_in; /* Note starting "file" position */

    while (input_stats(cpi, &this_frame) != EOF) {
      IIRatio =
          this_frame.intra_error / DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
      IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio;
      sum_iiratio += IIRatio;
    }

    cpi->twopass.avg_iiratio =
        sum_iiratio /
        DOUBLE_DIVIDE_CHECK((double)cpi->twopass.total_stats.count);

    /* Reset file position */
    reset_fpf_position(cpi, start_pos);
  }

  /* Scan the first pass file and calculate a modified total error based
   * upon the bias/power function used to allocate bits
   */
  {
    start_pos = cpi->twopass.stats_in; /* Note starting "file" position */

    cpi->twopass.modified_error_total = 0.0;
    cpi->twopass.modified_error_used = 0.0;

    while (input_stats(cpi, &this_frame) != EOF) {
      cpi->twopass.modified_error_total +=
          calculate_modified_err(cpi, &this_frame);
    }
    cpi->twopass.modified_error_left = cpi->twopass.modified_error_total;

    reset_fpf_position(cpi, start_pos); /* Reset file position */
  }
}

void vp8_end_second_pass(VP8_COMP *cpi) { (void)cpi; }

/* This function gives and estimate of how badly we believe the prediction
 * quality is decaying from frame to frame.
 */
static double get_prediction_decay_rate(VP8_COMP *cpi,
                                        FIRSTPASS_STATS *next_frame) {
  double prediction_decay_rate;
  double motion_decay;
  double motion_pct = next_frame->pcnt_motion;
  (void)cpi;

  /* Initial basis is the % mbs inter coded */
  prediction_decay_rate = next_frame->pcnt_inter;

  /* High % motion -> somewhat higher decay rate */
  motion_decay = (1.0 - (motion_pct / 20.0));
  if (motion_decay < prediction_decay_rate) {
    prediction_decay_rate = motion_decay;
  }

  /* Adjustment to decay rate based on speed of motion */
  {
    double this_mv_rabs;
    double this_mv_cabs;
    double distance_factor;

    this_mv_rabs = fabs(next_frame->mvr_abs * motion_pct);
    this_mv_cabs = fabs(next_frame->mvc_abs * motion_pct);

    distance_factor =
        sqrt((this_mv_rabs * this_mv_rabs) + (this_mv_cabs * this_mv_cabs)) /
        250.0;
    distance_factor = ((distance_factor > 1.0) ? 0.0 : (1.0 - distance_factor));
    if (distance_factor < prediction_decay_rate) {
      prediction_decay_rate = distance_factor;
    }
  }

  return prediction_decay_rate;
}

/* Function to test for a condition where a complex transition is followed
 * by a static section. For example in slide shows where there is a fade
 * between slides. This is to help with more optimal kf and gf positioning.
 */
static int detect_transition_to_still(VP8_COMP *cpi, int frame_interval,
                                      int still_interval,
                                      double loop_decay_rate,
                                      double decay_accumulator) {
  int trans_to_still = 0;

  /* Break clause to detect very still sections after motion
   * For example a static image after a fade or other transition
   * instead of a clean scene cut.
   */
  if ((frame_interval > MIN_GF_INTERVAL) && (loop_decay_rate >= 0.999) &&
      (decay_accumulator < 0.9)) {
    int j;
    FIRSTPASS_STATS *position = cpi->twopass.stats_in;
    FIRSTPASS_STATS tmp_next_frame;
    double decay_rate;

    /* Look ahead a few frames to see if static condition persists... */
    for (j = 0; j < still_interval; ++j) {
      if (EOF == input_stats(cpi, &tmp_next_frame)) break;

      decay_rate = get_prediction_decay_rate(cpi, &tmp_next_frame);
      if (decay_rate < 0.999) break;
    }
    /* Reset file position */
    reset_fpf_position(cpi, position);

    /* Only if it does do we signal a transition to still */
    if (j == still_interval) trans_to_still = 1;
  }

  return trans_to_still;
}

/* This function detects a flash through the high relative pcnt_second_ref
 * score in the frame following a flash frame. The offset passed in should
 * reflect this
 */
static int detect_flash(VP8_COMP *cpi, int offset) {
  FIRSTPASS_STATS next_frame;

  int flash_detected = 0;

  /* Read the frame data. */
  /* The return is 0 (no flash detected) if not a valid frame */
  if (read_frame_stats(cpi, &next_frame, offset) != EOF) {
    /* What we are looking for here is a situation where there is a
     * brief break in prediction (such as a flash) but subsequent frames
     * are reasonably well predicted by an earlier (pre flash) frame.
     * The recovery after a flash is indicated by a high pcnt_second_ref
     * comapred to pcnt_inter.
     */
    if ((next_frame.pcnt_second_ref > next_frame.pcnt_inter) &&
        (next_frame.pcnt_second_ref >= 0.5)) {
      flash_detected = 1;

      /*if (1)
      {
          FILE *f = fopen("flash.stt", "a");
          fprintf(f, "%8.0f %6.2f %6.2f\n",
              next_frame.frame,
              next_frame.pcnt_inter,
              next_frame.pcnt_second_ref);
          fclose(f);
      }*/
    }
  }

  return flash_detected;
}

/* Update the motion related elements to the GF arf boost calculation */
static void accumulate_frame_motion_stats(VP8_COMP *cpi,
                                          FIRSTPASS_STATS *this_frame,
                                          double *this_frame_mv_in_out,
                                          double *mv_in_out_accumulator,
                                          double *abs_mv_in_out_accumulator,
                                          double *mv_ratio_accumulator) {
  double this_frame_mvr_ratio;
  double this_frame_mvc_ratio;
  double motion_pct;
  (void)cpi;

  /* Accumulate motion stats. */
  motion_pct = this_frame->pcnt_motion;

  /* Accumulate Motion In/Out of frame stats */
  *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct;
  *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct;
  *abs_mv_in_out_accumulator += fabs(this_frame->mv_in_out_count * motion_pct);

  /* Accumulate a measure of how uniform (or conversely how random)
   * the motion field is. (A ratio of absmv / mv)
   */
  if (motion_pct > 0.05) {
    this_frame_mvr_ratio =
        fabs(this_frame->mvr_abs) / DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));

    this_frame_mvc_ratio =
        fabs(this_frame->mvc_abs) / DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));

    *mv_ratio_accumulator += (this_frame_mvr_ratio < this_frame->mvr_abs)
                                 ? (this_frame_mvr_ratio * motion_pct)
                                 : this_frame->mvr_abs * motion_pct;

    *mv_ratio_accumulator += (this_frame_mvc_ratio < this_frame->mvc_abs)
                                 ? (this_frame_mvc_ratio * motion_pct)
                                 : this_frame->mvc_abs * motion_pct;
  }
}

/* Calculate a baseline boost number for the current frame. */
static double calc_frame_boost(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame,
                               double this_frame_mv_in_out) {
  double frame_boost;

  /* Underlying boost factor is based on inter intra error ratio */
  if (this_frame->intra_error > cpi->twopass.gf_intra_err_min) {
    frame_boost = (IIFACTOR * this_frame->intra_error /
                   DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
  } else {
    frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min /
                   DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
  }

  /* Increase boost for frames where new data coming into frame
   * (eg zoom out). Slightly reduce boost if there is a net balance
   * of motion out of the frame (zoom in).
   * The range for this_frame_mv_in_out is -1.0 to +1.0
   */
  if (this_frame_mv_in_out > 0.0) {
    frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
    /* In extreme case boost is halved */
  } else {
    frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
  }

  /* Clip to maximum */
  if (frame_boost > GF_RMAX) frame_boost = GF_RMAX;

  return frame_boost;
}

#if NEW_BOOST
static int calc_arf_boost(VP8_COMP *cpi, int offset, int f_frames, int b_frames,
                          int *f_boost, int *b_boost) {
  FIRSTPASS_STATS this_frame;

  int i;
  double boost_score = 0.0;
  double mv_ratio_accumulator = 0.0;
  double decay_accumulator = 1.0;
  double this_frame_mv_in_out = 0.0;
  double mv_in_out_accumulator = 0.0;
  double abs_mv_in_out_accumulator = 0.0;
  double r;
  int flash_detected = 0;

  /* Search forward from the proposed arf/next gf position */
  for (i = 0; i < f_frames; ++i) {
    if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) break;

    /* Update the motion related elements to the boost calculation */
    accumulate_frame_motion_stats(
        cpi, &this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
        &abs_mv_in_out_accumulator, &mv_ratio_accumulator);

    /* Calculate the baseline boost number for this frame */
    r = calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out);

    /* We want to discount the the flash frame itself and the recovery
     * frame that follows as both will have poor scores.
     */
    flash_detected =
        detect_flash(cpi, (i + offset)) || detect_flash(cpi, (i + offset + 1));

    /* Cumulative effect of prediction quality decay */
    if (!flash_detected) {
      decay_accumulator =
          decay_accumulator * get_prediction_decay_rate(cpi, &this_frame);
      decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
    }
    boost_score += (decay_accumulator * r);

    /* Break out conditions. */
    if ((!flash_detected) &&
        ((mv_ratio_accumulator > 100.0) || (abs_mv_in_out_accumulator > 3.0) ||
         (mv_in_out_accumulator < -2.0))) {
      break;
    }
  }

  *f_boost = (int)(boost_score * 100.0) >> 4;

  /* Reset for backward looking loop */
  boost_score = 0.0;
  mv_ratio_accumulator = 0.0;
  decay_accumulator = 1.0;
  this_frame_mv_in_out = 0.0;
  mv_in_out_accumulator = 0.0;
  abs_mv_in_out_accumulator = 0.0;

  /* Search forward from the proposed arf/next gf position */
  for (i = -1; i >= -b_frames; i--) {
    if (read_frame_stats(cpi, &this_frame, (i + offset)) == EOF) break;

    /* Update the motion related elements to the boost calculation */
    accumulate_frame_motion_stats(
        cpi, &this_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
        &abs_mv_in_out_accumulator, &mv_ratio_accumulator);

    /* Calculate the baseline boost number for this frame */
    r = calc_frame_boost(cpi, &this_frame, this_frame_mv_in_out);

    /* We want to discount the the flash frame itself and the recovery
     * frame that follows as both will have poor scores.
     */
    flash_detected =
        detect_flash(cpi, (i + offset)) || detect_flash(cpi, (i + offset + 1));

    /* Cumulative effect of prediction quality decay */
    if (!flash_detected) {
      decay_accumulator =
          decay_accumulator * get_prediction_decay_rate(cpi, &this_frame);
      decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
    }

    boost_score += (decay_accumulator * r);

    /* Break out conditions. */
    if ((!flash_detected) &&
        ((mv_ratio_accumulator > 100.0) || (abs_mv_in_out_accumulator > 3.0) ||
         (mv_in_out_accumulator < -2.0))) {
      break;
    }
  }
  *b_boost = (int)(boost_score * 100.0) >> 4;

  return (*f_boost + *b_boost);
}
#endif

/* Analyse and define a gf/arf group . */
static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) {
  FIRSTPASS_STATS next_frame;
  FIRSTPASS_STATS *start_pos;
  int i;
  double r;
  double boost_score = 0.0;
  double old_boost_score = 0.0;
  double gf_group_err = 0.0;
  double gf_first_frame_err = 0.0;
  double mod_frame_err = 0.0;

  double mv_ratio_accumulator = 0.0;
  double decay_accumulator = 1.0;

  double loop_decay_rate = 1.00; /* Starting decay rate */

  double this_frame_mv_in_out = 0.0;
  double mv_in_out_accumulator = 0.0;
  double abs_mv_in_out_accumulator = 0.0;
  double mod_err_per_mb_accumulator = 0.0;

  int max_bits = frame_max_bits(cpi); /* Max for a single frame */

  unsigned int allow_alt_ref =
      cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;

  int alt_boost = 0;
  int f_boost = 0;
  int b_boost = 0;
  int flash_detected;

  cpi->twopass.gf_group_bits = 0;
  cpi->twopass.gf_decay_rate = 0;

  vpx_clear_system_state();

  start_pos = cpi->twopass.stats_in;

  memset(&next_frame, 0, sizeof(next_frame)); /* assure clean */

  /* Load stats for the current frame. */
  mod_frame_err = calculate_modified_err(cpi, this_frame);

  /* Note the error of the frame at the start of the group (this will be
   * the GF frame error if we code a normal gf
   */
  gf_first_frame_err = mod_frame_err;

  /* Special treatment if the current frame is a key frame (which is also
   * a gf). If it is then its error score (and hence bit allocation) need
   * to be subtracted out from the calculation for the GF group
   */
  if (cpi->common.frame_type == KEY_FRAME) gf_group_err -= gf_first_frame_err;

  /* Scan forward to try and work out how many frames the next gf group
   * should contain and what level of boost is appropriate for the GF
   * or ARF that will be coded with the group
   */
  i = 0;

  while (((i < cpi->twopass.static_scene_max_gf_interval) ||
          ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) &&
         (i < cpi->twopass.frames_to_key)) {
    i++;

    /* Accumulate error score of frames in this gf group */
    mod_frame_err = calculate_modified_err(cpi, this_frame);

    gf_group_err += mod_frame_err;

    mod_err_per_mb_accumulator +=
        mod_frame_err / DOUBLE_DIVIDE_CHECK((double)cpi->common.MBs);

    if (EOF == input_stats(cpi, &next_frame)) break;

    /* Test for the case where there is a brief flash but the prediction
     * quality back to an earlier frame is then restored.
     */
    flash_detected = detect_flash(cpi, 0);

    /* Update the motion related elements to the boost calculation */
    accumulate_frame_motion_stats(
        cpi, &next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
        &abs_mv_in_out_accumulator, &mv_ratio_accumulator);

    /* Calculate a baseline boost number for this frame */
    r = calc_frame_boost(cpi, &next_frame, this_frame_mv_in_out);

    /* Cumulative effect of prediction quality decay */
    if (!flash_detected) {
      loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
      decay_accumulator = decay_accumulator * loop_decay_rate;
      decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
    }
    boost_score += (decay_accumulator * r);

    /* Break clause to detect very still sections after motion
     * For example a staic image after a fade or other transition.
     */
    if (detect_transition_to_still(cpi, i, 5, loop_decay_rate,
                                   decay_accumulator)) {
      allow_alt_ref = 0;
      boost_score = old_boost_score;
      break;
    }

    /* Break out conditions. */
    if (
        /* Break at cpi->max_gf_interval unless almost totally static */
        (i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) ||
        (
            /* Dont break out with a very short interval */
            (i > MIN_GF_INTERVAL) &&
            /* Dont break out very close to a key frame */
            ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) &&
            ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
            (!flash_detected) && ((mv_ratio_accumulator > 100.0) ||
                                  (abs_mv_in_out_accumulator > 3.0) ||
                                  (mv_in_out_accumulator < -2.0) ||
                                  ((boost_score - old_boost_score) < 2.0)))) {
      boost_score = old_boost_score;
      break;
    }

    memcpy(this_frame, &next_frame, sizeof(*this_frame));

    old_boost_score = boost_score;
  }

  cpi->twopass.gf_decay_rate =
      (i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0;

  /* When using CBR apply additional buffer related upper limits */
  if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
    double max_boost;

    /* For cbr apply buffer related limits */
    if (cpi->drop_frames_allowed) {
      int64_t df_buffer_level = cpi->oxcf.drop_frames_water_mark *
                                (cpi->oxcf.optimal_buffer_level / 100);

      if (cpi->buffer_level > df_buffer_level) {
        max_boost =
            ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) /
            DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
      } else {
        max_boost = 0.0;
      }
    } else if (cpi->buffer_level > 0) {
      max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) /
                  DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
    } else {
      max_boost = 0.0;
    }

    if (boost_score > max_boost) boost_score = max_boost;
  }

  /* Dont allow conventional gf too near the next kf */
  if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL) {
    while (i < cpi->twopass.frames_to_key) {
      i++;

      if (EOF == input_stats(cpi, this_frame)) break;

      if (i < cpi->twopass.frames_to_key) {
        mod_frame_err = calculate_modified_err(cpi, this_frame);
        gf_group_err += mod_frame_err;
      }
    }
  }

  cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;

#if NEW_BOOST
  /* Alterrnative boost calculation for alt ref */
  alt_boost = calc_arf_boost(cpi, 0, (i - 1), (i - 1), &f_boost, &b_boost);
#endif

  /* Should we use the alternate refernce frame */
  if (allow_alt_ref && (i >= MIN_GF_INTERVAL) &&
      /* dont use ARF very near next kf */
      (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
#if NEW_BOOST
      ((next_frame.pcnt_inter > 0.75) || (next_frame.pcnt_second_ref > 0.5)) &&
      ((mv_in_out_accumulator / (double)i > -0.2) ||
       (mv_in_out_accumulator > -2.0)) &&
      (b_boost > 100) && (f_boost > 100))
#else
      (next_frame.pcnt_inter > 0.75) &&
      ((mv_in_out_accumulator / (double)i > -0.2) ||
       (mv_in_out_accumulator > -2.0)) &&
      (cpi->gfu_boost > 100) && (cpi->twopass.gf_decay_rate <=
                                 (ARF_DECAY_THRESH + (cpi->gfu_boost / 200))))
#endif
  {
    int Boost;
    int allocation_chunks;
    int Q =
        (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
    int tmp_q;
    int arf_frame_bits = 0;
    int group_bits;

#if NEW_BOOST
    cpi->gfu_boost = alt_boost;
#endif

    /* Estimate the bits to be allocated to the group as a whole */
    if ((cpi->twopass.kf_group_bits > 0) &&
        (cpi->twopass.kf_group_error_left > 0)) {
      group_bits =
          (int)((double)cpi->twopass.kf_group_bits *
                (gf_group_err / (double)cpi->twopass.kf_group_error_left));
    } else {
      group_bits = 0;
    }

/* Boost for arf frame */
#if NEW_BOOST
    Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
#else
    Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
#endif
    Boost += (i * 50);

    /* Set max and minimum boost and hence minimum allocation */
    if (Boost > ((cpi->baseline_gf_interval + 1) * 200)) {
      Boost = ((cpi->baseline_gf_interval + 1) * 200);
    } else if (Boost < 125) {
      Boost = 125;
    }

    allocation_chunks = (i * 100) + Boost;

    /* Normalize Altboost and allocations chunck down to prevent overflow */
    while (Boost > 1000) {
      Boost /= 2;
      allocation_chunks /= 2;
    }

    /* Calculate the number of bits to be spent on the arf based on the
     * boost number
     */
    arf_frame_bits =
        (int)((double)Boost * (group_bits / (double)allocation_chunks));

    /* Estimate if there are enough bits available to make worthwhile use
     * of an arf.
     */
    tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits);

    /* Only use an arf if it is likely we will be able to code
     * it at a lower Q than the surrounding frames.
     */
    if (tmp_q < cpi->worst_quality) {
      int half_gf_int;
      int frames_after_arf;
      int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
      int frames_fwd = cpi->oxcf.arnr_max_frames - 1;

      cpi->source_alt_ref_pending = 1;

      /*
       * For alt ref frames the error score for the end frame of the
       * group (the alt ref frame) should not contribute to the group
       * total and hence the number of bit allocated to the group.
       * Rather it forms part of the next group (it is the GF at the
       * start of the next group)
       * gf_group_err -= mod_frame_err;
       *
       * For alt ref frames alt ref frame is technically part of the
       * GF frame for the next group but we always base the error
       * calculation and bit allocation on the current group of frames.
       *
       * Set the interval till the next gf or arf.
       * For ARFs this is the number of frames to be coded before the
       * future frame that is coded as an ARF.
       * The future frame itself is part of the next group
       */
      cpi->baseline_gf_interval = i;

      /*
       * Define the arnr filter width for this group of frames:
       * We only filter frames that lie within a distance of half
       * the GF interval from the ARF frame. We also have to trap
       * cases where the filter extends beyond the end of clip.
       * Note: this_frame->frame has been updated in the loop
       * so it now points at the ARF frame.
       */
      half_gf_int = cpi->baseline_gf_interval >> 1;
      frames_after_arf =
          (int)(cpi->twopass.total_stats.count - this_frame->frame - 1);

      switch (cpi->oxcf.arnr_type) {
        case 1: /* Backward filter */
          frames_fwd = 0;
          if (frames_bwd > half_gf_int) frames_bwd = half_gf_int;
          break;

        case 2: /* Forward filter */
          if (frames_fwd > half_gf_int) frames_fwd = half_gf_int;
          if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf;
          frames_bwd = 0;
          break;

        case 3: /* Centered filter */
        default:
          frames_fwd >>= 1;
          if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf;
          if (frames_fwd > half_gf_int) frames_fwd = half_gf_int;

          frames_bwd = frames_fwd;

          /* For even length filter there is one more frame backward
           * than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
           */
          if (frames_bwd < half_gf_int) {
            frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
          }
          break;
      }

      cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
    } else {
      cpi->source_alt_ref_pending = 0;
      cpi->baseline_gf_interval = i;
    }
  } else {
    cpi->source_alt_ref_pending = 0;
    cpi->baseline_gf_interval = i;
  }

  /*
   * Now decide how many bits should be allocated to the GF group as  a
   * proportion of those remaining in the kf group.
   * The final key frame group in the clip is treated as a special case
   * where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
   * This is also important for short clips where there may only be one
   * key frame.
   */
  if (cpi->twopass.frames_to_key >=
      (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame)) {
    cpi->twopass.kf_group_bits =
        (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
  }

  /* Calculate the bits to be allocated to the group as a whole */
  if ((cpi->twopass.kf_group_bits > 0) &&
      (cpi->twopass.kf_group_error_left > 0)) {
    cpi->twopass.gf_group_bits =
        (int64_t)(cpi->twopass.kf_group_bits *
                  (gf_group_err / cpi->twopass.kf_group_error_left));
  } else {
    cpi->twopass.gf_group_bits = 0;
  }

  cpi->twopass.gf_group_bits =
      (cpi->twopass.gf_group_bits < 0)
          ? 0
          : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits)
                ? cpi->twopass.kf_group_bits
                : cpi->twopass.gf_group_bits;

  /* Clip cpi->twopass.gf_group_bits based on user supplied data rate
   * variability limit (cpi->oxcf.two_pass_vbrmax_section)
   */
  if (cpi->twopass.gf_group_bits >
      (int64_t)max_bits * cpi->baseline_gf_interval) {
    cpi->twopass.gf_group_bits = (int64_t)max_bits * cpi->baseline_gf_interval;
  }

  /* Reset the file position */
  reset_fpf_position(cpi, start_pos);

  /* Update the record of error used so far (only done once per gf group) */
  cpi->twopass.modified_error_used += gf_group_err;

  /* Assign  bits to the arf or gf. */
  for (i = 0; i <= (cpi->source_alt_ref_pending &&
                    cpi->common.frame_type != KEY_FRAME);
       i++) {
    int Boost;
    int allocation_chunks;
    int Q =
        (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
    int gf_bits;

    /* For ARF frames */
    if (cpi->source_alt_ref_pending && i == 0) {
#if NEW_BOOST
      Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
#else
      Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
#endif
      Boost += (cpi->baseline_gf_interval * 50);

      /* Set max and minimum boost and hence minimum allocation */
      if (Boost > ((cpi->baseline_gf_interval + 1) * 200)) {
        Boost = ((cpi->baseline_gf_interval + 1) * 200);
      } else if (Boost < 125) {
        Boost = 125;
      }

      allocation_chunks = ((cpi->baseline_gf_interval + 1) * 100) + Boost;
    }
    /* Else for standard golden frames */
    else {
      /* boost based on inter / intra ratio of subsequent frames */
      Boost = (cpi->gfu_boost * GFQ_ADJUSTMENT) / 100;

      /* Set max and minimum boost and hence minimum allocation */
      if (Boost > (cpi->baseline_gf_interval * 150)) {
        Boost = (cpi->baseline_gf_interval * 150);
      } else if (Boost < 125) {
        Boost = 125;
      }

      allocation_chunks = (cpi->baseline_gf_interval * 100) + (Boost - 100);
    }

    /* Normalize Altboost and allocations chunck down to prevent overflow */
    while (Boost > 1000) {
      Boost /= 2;
      allocation_chunks /= 2;
    }

    /* Calculate the number of bits to be spent on the gf or arf based on
     * the boost number
     */
    gf_bits = (int)((double)Boost *
                    (cpi->twopass.gf_group_bits / (double)allocation_chunks));

    /* If the frame that is to be boosted is simpler than the average for
     * the gf/arf group then use an alternative calculation
     * based on the error score of the frame itself
     */
    if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval) {
      double alt_gf_grp_bits;
      int alt_gf_bits;

      alt_gf_grp_bits =
          (double)cpi->twopass.kf_group_bits *
          (mod_frame_err * (double)cpi->baseline_gf_interval) /
          DOUBLE_DIVIDE_CHECK((double)cpi->twopass.kf_group_error_left);

      alt_gf_bits =
          (int)((double)Boost * (alt_gf_grp_bits / (double)allocation_chunks));

      if (gf_bits > alt_gf_bits) {
        gf_bits = alt_gf_bits;
      }
    }
    /* Else if it is harder than other frames in the group make sure it at
     * least receives an allocation in keeping with its relative error
     * score, otherwise it may be worse off than an "un-boosted" frame
     */
    else {
      int alt_gf_bits =
          (int)((double)cpi->twopass.kf_group_bits * mod_frame_err /
                DOUBLE_DIVIDE_CHECK((double)cpi->twopass.kf_group_error_left));

      if (alt_gf_bits > gf_bits) {
        gf_bits = alt_gf_bits;
      }
    }

    /* Apply an additional limit for CBR */
    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
      if (cpi->twopass.gf_bits > (int)(cpi->buffer_level >> 1)) {
        cpi->twopass.gf_bits = (int)(cpi->buffer_level >> 1);
      }
    }

    /* Dont allow a negative value for gf_bits */
    if (gf_bits < 0) gf_bits = 0;

    /* Add in minimum for a frame */
    gf_bits += cpi->min_frame_bandwidth;

    if (i == 0) {
      cpi->twopass.gf_bits = gf_bits;
    }
    if (i == 1 || (!cpi->source_alt_ref_pending &&
                   (cpi->common.frame_type != KEY_FRAME))) {
      /* Per frame bit target for this frame */
      cpi->per_frame_bandwidth = gf_bits;
    }
  }

  {
    /* Adjust KF group bits and error remainin */
    cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err;
    cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits;

    if (cpi->twopass.kf_group_bits < 0) cpi->twopass.kf_group_bits = 0;

    /* Note the error score left in the remaining frames of the group.
     * For normal GFs we want to remove the error score for the first
     * frame of the group (except in Key frame case where this has
     * already happened)
     */
    if (!cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME) {
      cpi->twopass.gf_group_error_left =
          (int)(gf_group_err - gf_first_frame_err);
    } else {
      cpi->twopass.gf_group_error_left = (int)gf_group_err;
    }

    cpi->twopass.gf_group_bits -=
        cpi->twopass.gf_bits - cpi->min_frame_bandwidth;

    if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0;

    /* This condition could fail if there are two kfs very close together
     * despite (MIN_GF_INTERVAL) and would cause a devide by 0 in the
     * calculation of cpi->twopass.alt_extra_bits.
     */
    if (cpi->baseline_gf_interval >= 3) {
#if NEW_BOOST
      int boost = (cpi->source_alt_ref_pending) ? b_boost : cpi->gfu_boost;
#else
      int boost = cpi->gfu_boost;
#endif
      if (boost >= 150) {
        int pct_extra;

        pct_extra = (boost - 100) / 50;
        pct_extra = (pct_extra > 20) ? 20 : pct_extra;

        cpi->twopass.alt_extra_bits =
            (int)(cpi->twopass.gf_group_bits * pct_extra) / 100;
        cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits;
        cpi->twopass.alt_extra_bits /= ((cpi->baseline_gf_interval - 1) >> 1);
      } else {
        cpi->twopass.alt_extra_bits = 0;
      }
    } else {
      cpi->twopass.alt_extra_bits = 0;
    }
  }

  /* Adjustments based on a measure of complexity of the section */
  if (cpi->common.frame_type != KEY_FRAME) {
    FIRSTPASS_STATS sectionstats;
    double Ratio;

    zero_stats(&sectionstats);
    reset_fpf_position(cpi, start_pos);

    for (i = 0; i < cpi->baseline_gf_interval; ++i) {
      input_stats(cpi, &next_frame);
      accumulate_stats(&sectionstats, &next_frame);
    }

    avg_stats(&sectionstats);

    cpi->twopass.section_intra_rating =
        (unsigned int)(sectionstats.intra_error /
                       DOUBLE_DIVIDE_CHECK(sectionstats.coded_error));

    Ratio = sectionstats.intra_error /
            DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
    cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);

    if (cpi->twopass.section_max_qfactor < 0.80) {
      cpi->twopass.section_max_qfactor = 0.80;
    }

    reset_fpf_position(cpi, start_pos);
  }
}

/* Allocate bits to a normal frame that is neither a gf an arf or a key frame.
 */
static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) {
  int target_frame_size;

  double modified_err;
  double err_fraction;

  int max_bits = frame_max_bits(cpi); /* Max for a single frame */

  /* Calculate modified prediction error used in bit allocation */
  modified_err = calculate_modified_err(cpi, this_frame);

  /* What portion of the remaining GF group error is used by this frame */
  if (cpi->twopass.gf_group_error_left > 0) {
    err_fraction = modified_err / cpi->twopass.gf_group_error_left;
  } else {
    err_fraction = 0.0;
  }

  /* How many of those bits available for allocation should we give it? */
  target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction);

  /* Clip to target size to 0 - max_bits (or cpi->twopass.gf_group_bits)
   * at the top end.
   */
  if (target_frame_size < 0) {
    target_frame_size = 0;
  } else {
    if (target_frame_size > max_bits) target_frame_size = max_bits;

    if (target_frame_size > cpi->twopass.gf_group_bits) {
      target_frame_size = (int)cpi->twopass.gf_group_bits;
    }
  }

  /* Adjust error and bits remaining */
  cpi->twopass.gf_group_error_left -= (int)modified_err;
  cpi->twopass.gf_group_bits -= target_frame_size;

  if (cpi->twopass.gf_group_bits < 0) cpi->twopass.gf_group_bits = 0;

  /* Add in the minimum number of bits that is set aside for every frame. */
  target_frame_size += cpi->min_frame_bandwidth;

  /* Every other frame gets a few extra bits */
  if ((cpi->frames_since_golden & 0x01) &&
      (cpi->frames_till_gf_update_due > 0)) {
    target_frame_size += cpi->twopass.alt_extra_bits;
  }

  /* Per frame bit target for this frame */
  cpi->per_frame_bandwidth = target_frame_size;
}

void vp8_second_pass(VP8_COMP *cpi) {
  int tmp_q;
  int frames_left =
      (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame);

  FIRSTPASS_STATS this_frame;
  FIRSTPASS_STATS this_frame_copy;

  double this_frame_intra_error;
  double this_frame_coded_error;

  int overhead_bits;

  vp8_zero(this_frame);

  if (!cpi->twopass.stats_in) {
    return;
  }

  vpx_clear_system_state();

  if (EOF == input_stats(cpi, &this_frame)) return;

  this_frame_intra_error = this_frame.intra_error;
  this_frame_coded_error = this_frame.coded_error;

  /* keyframe and section processing ! */
  if (cpi->twopass.frames_to_key == 0) {
    /* Define next KF group and assign bits to it */
    memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
    find_next_key_frame(cpi, &this_frame_copy);

    /* Special case: Error error_resilient_mode mode does not make much
     * sense for two pass but with its current meaning this code is
     * designed to stop outlandish behaviour if someone does set it when
     * using two pass. It effectively disables GF groups. This is
     * temporary code until we decide what should really happen in this
     * case.
     */
    if (cpi->oxcf.error_resilient_mode) {
      cpi->twopass.gf_group_bits = cpi->twopass.kf_group_bits;
      cpi->twopass.gf_group_error_left = (int)cpi->twopass.kf_group_error_left;
      cpi->baseline_gf_interval = cpi->twopass.frames_to_key;
      cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
      cpi->source_alt_ref_pending = 0;
    }
  }

  /* Is this a GF / ARF (Note that a KF is always also a GF) */
  if (cpi->frames_till_gf_update_due == 0) {
    /* Define next gf group and assign bits to it */
    memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
    define_gf_group(cpi, &this_frame_copy);

    /* If we are going to code an altref frame at the end of the group
     * and the current frame is not a key frame.... If the previous
     * group used an arf this frame has already benefited from that arf
     * boost and it should not be given extra bits If the previous
     * group was NOT coded using arf we may want to apply some boost to
     * this GF as well
     */
    if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)) {
      /* Assign a standard frames worth of bits from those allocated
       * to the GF group
       */
      int bak = cpi->per_frame_bandwidth;
      memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
      assign_std_frame_bits(cpi, &this_frame_copy);
      cpi->per_frame_bandwidth = bak;
    }
  }

  /* Otherwise this is an ordinary frame */
  else {
    /* Special case: Error error_resilient_mode mode does not make much
     * sense for two pass but with its current meaning but this code is
     * designed to stop outlandish behaviour if someone does set it
     * when using two pass. It effectively disables GF groups. This is
     * temporary code till we decide what should really happen in this
     * case.
     */
    if (cpi->oxcf.error_resilient_mode) {
      cpi->frames_till_gf_update_due = cpi->twopass.frames_to_key;

      if (cpi->common.frame_type != KEY_FRAME) {
        /* Assign bits from those allocated to the GF group */
        memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
        assign_std_frame_bits(cpi, &this_frame_copy);
      }
    } else {
      /* Assign bits from those allocated to the GF group */
      memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
      assign_std_frame_bits(cpi, &this_frame_copy);
    }
  }

  /* Keep a globally available copy of this and the next frame's iiratio. */
  cpi->twopass.this_iiratio =
      (unsigned int)(this_frame_intra_error /
                     DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
  {
    FIRSTPASS_STATS next_frame;
    if (lookup_next_frame_stats(cpi, &next_frame) != EOF) {
      cpi->twopass.next_iiratio =
          (unsigned int)(next_frame.intra_error /
                         DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
    }
  }

  /* Set nominal per second bandwidth for this frame */
  cpi->target_bandwidth =
      (int)(cpi->per_frame_bandwidth * cpi->output_framerate);
  if (cpi->target_bandwidth < 0) cpi->target_bandwidth = 0;

  /* Account for mv, mode and other overheads. */
  overhead_bits = (int)estimate_modemvcost(cpi, &cpi->twopass.total_left_stats);

  /* Special case code for first frame. */
  if (cpi->common.current_video_frame == 0) {
    cpi->twopass.est_max_qcorrection_factor = 1.0;

    /* Set a cq_level in constrained quality mode. */
    if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) {
      int est_cq;

      est_cq = estimate_cq(cpi, &cpi->twopass.total_left_stats,
                           (int)(cpi->twopass.bits_left / frames_left),
                           overhead_bits);

      cpi->cq_target_quality = cpi->oxcf.cq_level;
      if (est_cq > cpi->cq_target_quality) cpi->cq_target_quality = est_cq;
    }

    /* guess at maxq needed in 2nd pass */
    cpi->twopass.maxq_max_limit = cpi->worst_quality;
    cpi->twopass.maxq_min_limit = cpi->best_quality;

    tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
                           (int)(cpi->twopass.bits_left / frames_left),
                           overhead_bits);

    /* Limit the maxq value returned subsequently.
     * This increases the risk of overspend or underspend if the initial
     * estimate for the clip is bad, but helps prevent excessive
     * variation in Q, especially near the end of a clip
     * where for example a small overspend may cause Q to crash
     */
    cpi->twopass.maxq_max_limit =
        ((tmp_q + 32) < cpi->worst_quality) ? (tmp_q + 32) : cpi->worst_quality;
    cpi->twopass.maxq_min_limit =
        ((tmp_q - 32) > cpi->best_quality) ? (tmp_q - 32) : cpi->best_quality;

    cpi->active_worst_quality = tmp_q;
    cpi->ni_av_qi = tmp_q;
  }

  /* The last few frames of a clip almost always have to few or too many
   * bits and for the sake of over exact rate control we dont want to make
   * radical adjustments to the allowed quantizer range just to use up a
   * few surplus bits or get beneath the target rate.
   */
  else if ((cpi->common.current_video_frame <
            (((unsigned int)cpi->twopass.total_stats.count * 255) >> 8)) &&
           ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
            (unsigned int)cpi->twopass.total_stats.count)) {
    if (frames_left < 1) frames_left = 1;

    tmp_q = estimate_max_q(cpi, &cpi->twopass.total_left_stats,
                           (int)(cpi->twopass.bits_left / frames_left),
                           overhead_bits);

    /* Move active_worst_quality but in a damped way */
    if (tmp_q > cpi->active_worst_quality) {
      cpi->active_worst_quality++;
    } else if (tmp_q < cpi->active_worst_quality) {
      cpi->active_worst_quality--;
    }

    cpi->active_worst_quality =
        ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
  }

  cpi->twopass.frames_to_key--;

  /* Update the total stats remaining sturcture */
  subtract_stats(&cpi->twopass.total_left_stats, &this_frame);
}

static int test_candidate_kf(VP8_COMP *cpi, FIRSTPASS_STATS *last_frame,
                             FIRSTPASS_STATS *this_frame,
                             FIRSTPASS_STATS *next_frame) {
  int is_viable_kf = 0;

  /* Does the frame satisfy the primary criteria of a key frame
   *      If so, then examine how well it predicts subsequent frames
   */
  if ((this_frame->pcnt_second_ref < 0.10) &&
      (next_frame->pcnt_second_ref < 0.10) &&
      ((this_frame->pcnt_inter < 0.05) ||
       (((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .25) &&
        ((this_frame->intra_error /
          DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
        ((fabs(last_frame->coded_error - this_frame->coded_error) /
              DOUBLE_DIVIDE_CHECK(this_frame->coded_error) >
          .40) ||
         (fabs(last_frame->intra_error - this_frame->intra_error) /
              DOUBLE_DIVIDE_CHECK(this_frame->intra_error) >
          .40) ||
         ((next_frame->intra_error /
           DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) {
    int i;
    FIRSTPASS_STATS *start_pos;

    FIRSTPASS_STATS local_next_frame;

    double boost_score = 0.0;
    double old_boost_score = 0.0;
    double decay_accumulator = 1.0;
    double next_iiratio;

    memcpy(&local_next_frame, next_frame, sizeof(*next_frame));

    /* Note the starting file position so we can reset to it */
    start_pos = cpi->twopass.stats_in;

    /* Examine how well the key frame predicts subsequent frames */
    for (i = 0; i < 16; ++i) {
      next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error /
                      DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error));

      if (next_iiratio > RMAX) next_iiratio = RMAX;

      /* Cumulative effect of decay in prediction quality */
      if (local_next_frame.pcnt_inter > 0.85) {
        decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter;
      } else {
        decay_accumulator =
            decay_accumulator * ((0.85 + local_next_frame.pcnt_inter) / 2.0);
      }

      /* Keep a running total */
      boost_score += (decay_accumulator * next_iiratio);

      /* Test various breakout clauses */
      if ((local_next_frame.pcnt_inter < 0.05) || (next_iiratio < 1.5) ||
          (((local_next_frame.pcnt_inter - local_next_frame.pcnt_neutral) <
            0.20) &&
           (next_iiratio < 3.0)) ||
          ((boost_score - old_boost_score) < 0.5) ||
          (local_next_frame.intra_error < 200)) {
        break;
      }

      old_boost_score = boost_score;

      /* Get the next frame details */
      if (EOF == input_stats(cpi, &local_next_frame)) break;
    }

    /* If there is tolerable prediction for at least the next 3 frames
     * then break out else discard this pottential key frame and move on
     */
    if (boost_score > 5.0 && (i > 3)) {
      is_viable_kf = 1;
    } else {
      /* Reset the file position */
      reset_fpf_position(cpi, start_pos);

      is_viable_kf = 0;
    }
  }

  return is_viable_kf;
}
static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame) {
  int i, j;
  FIRSTPASS_STATS last_frame;
  FIRSTPASS_STATS first_frame;
  FIRSTPASS_STATS next_frame;
  FIRSTPASS_STATS *start_position;

  double decay_accumulator = 1.0;
  double boost_score = 0;
  double old_boost_score = 0.0;
  double loop_decay_rate;

  double kf_mod_err = 0.0;
  double kf_group_err = 0.0;
  double kf_group_intra_err = 0.0;
  double kf_group_coded_err = 0.0;
  double recent_loop_decay[8] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };

  memset(&next_frame, 0, sizeof(next_frame));

  vpx_clear_system_state();
  start_position = cpi->twopass.stats_in;

  cpi->common.frame_type = KEY_FRAME;

  /* is this a forced key frame by interval */
  cpi->this_key_frame_forced = cpi->next_key_frame_forced;

  /* Clear the alt ref active flag as this can never be active on a key
   * frame
   */
  cpi->source_alt_ref_active = 0;

  /* Kf is always a gf so clear frames till next gf counter */
  cpi->frames_till_gf_update_due = 0;

  cpi->twopass.frames_to_key = 1;

  /* Take a copy of the initial frame details */
  memcpy(&first_frame, this_frame, sizeof(*this_frame));

  cpi->twopass.kf_group_bits = 0;
  cpi->twopass.kf_group_error_left = 0;

  kf_mod_err = calculate_modified_err(cpi, this_frame);

  /* find the next keyframe */
  i = 0;
  while (cpi->twopass.stats_in < cpi->twopass.stats_in_end) {
    /* Accumulate kf group error */
    kf_group_err += calculate_modified_err(cpi, this_frame);

    /* These figures keep intra and coded error counts for all frames
     * including key frames in the group. The effect of the key frame
     * itself can be subtracted out using the first_frame data
     * collected above
     */
    kf_group_intra_err += this_frame->intra_error;
    kf_group_coded_err += this_frame->coded_error;

    /* Load the next frame's stats. */
    memcpy(&last_frame, this_frame, sizeof(*this_frame));
    input_stats(cpi, this_frame);

    /* Provided that we are not at the end of the file... */
    if (cpi->oxcf.auto_key &&
        lookup_next_frame_stats(cpi, &next_frame) != EOF) {
      /* Normal scene cut check */
      if ((i >= MIN_GF_INTERVAL) &&
          test_candidate_kf(cpi, &last_frame, this_frame, &next_frame)) {
        break;
      }

      /* How fast is prediction quality decaying */
      loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);

      /* We want to know something about the recent past... rather than
       * as used elsewhere where we are concened with decay in prediction
       * quality since the last GF or KF.
       */
      recent_loop_decay[i % 8] = loop_decay_rate;
      decay_accumulator = 1.0;
      for (j = 0; j < 8; ++j) {
        decay_accumulator = decay_accumulator * recent_loop_decay[j];
      }

      /* Special check for transition or high motion followed by a
       * static scene.
       */
      if (detect_transition_to_still(cpi, i,
                                     ((int)(cpi->key_frame_frequency) - (int)i),
                                     loop_decay_rate, decay_accumulator)) {
        break;
      }

      /* Step on to the next frame */
      cpi->twopass.frames_to_key++;

      /* If we don't have a real key frame within the next two
       * forcekeyframeevery intervals then break out of the loop.
       */
      if (cpi->twopass.frames_to_key >= 2 * (int)cpi->key_frame_frequency) {
        break;
      }
    } else {
      cpi->twopass.frames_to_key++;
    }

    i++;
  }

  /* If there is a max kf interval set by the user we must obey it.
   * We already breakout of the loop above at 2x max.
   * This code centers the extra kf if the actual natural
   * interval is between 1x and 2x
   */
  if (cpi->oxcf.auto_key &&
      cpi->twopass.frames_to_key > (int)cpi->key_frame_frequency) {
    FIRSTPASS_STATS *current_pos = cpi->twopass.stats_in;
    FIRSTPASS_STATS tmp_frame;

    cpi->twopass.frames_to_key /= 2;

    /* Copy first frame details */
    memcpy(&tmp_frame, &first_frame, sizeof(first_frame));

    /* Reset to the start of the group */
    reset_fpf_position(cpi, start_position);

    kf_group_err = 0;
    kf_group_intra_err = 0;
    kf_group_coded_err = 0;

    /* Rescan to get the correct error data for the forced kf group */
    for (i = 0; i < cpi->twopass.frames_to_key; ++i) {
      /* Accumulate kf group errors */
      kf_group_err += calculate_modified_err(cpi, &tmp_frame);
      kf_group_intra_err += tmp_frame.intra_error;
      kf_group_coded_err += tmp_frame.coded_error;

      /* Load a the next frame's stats */
      input_stats(cpi, &tmp_frame);
    }

    /* Reset to the start of the group */
    reset_fpf_position(cpi, current_pos);

    cpi->next_key_frame_forced = 1;
  } else {
    cpi->next_key_frame_forced = 0;
  }

  /* Special case for the last frame of the file */
  if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end) {
    /* Accumulate kf group error */
    kf_group_err += calculate_modified_err(cpi, this_frame);

    /* These figures keep intra and coded error counts for all frames
     * including key frames in the group. The effect of the key frame
     * itself can be subtracted out using the first_frame data
     * collected above
     */
    kf_group_intra_err += this_frame->intra_error;
    kf_group_coded_err += this_frame->coded_error;
  }

  /* Calculate the number of bits that should be assigned to the kf group. */
  if ((cpi->twopass.bits_left > 0) &&
      (cpi->twopass.modified_error_left > 0.0)) {
    /* Max for a single normal frame (not key frame) */
    int max_bits = frame_max_bits(cpi);

    /* Maximum bits for the kf group */
    int64_t max_grp_bits;

    /* Default allocation based on bits left and relative
     * complexity of the section
     */
    cpi->twopass.kf_group_bits =
        (int64_t)(cpi->twopass.bits_left *
                  (kf_group_err / cpi->twopass.modified_error_left));

    /* Clip based on maximum per frame rate defined by the user. */
    max_grp_bits = (int64_t)max_bits * (int64_t)cpi->twopass.frames_to_key;
    if (cpi->twopass.kf_group_bits > max_grp_bits) {
      cpi->twopass.kf_group_bits = max_grp_bits;
    }

    /* Additional special case for CBR if buffer is getting full. */
    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
      int64_t opt_buffer_lvl = cpi->oxcf.optimal_buffer_level;
      int64_t buffer_lvl = cpi->buffer_level;

      /* If the buffer is near or above the optimal and this kf group is
       * not being allocated much then increase the allocation a bit.
       */
      if (buffer_lvl >= opt_buffer_lvl) {
        int64_t high_water_mark =
            (opt_buffer_lvl + cpi->oxcf.maximum_buffer_size) >> 1;

        int64_t av_group_bits;

        /* Av bits per frame * number of frames */
        av_group_bits = (int64_t)cpi->av_per_frame_bandwidth *
                        (int64_t)cpi->twopass.frames_to_key;

        /* We are at or above the maximum. */
        if (cpi->buffer_level >= high_water_mark) {
          int64_t min_group_bits;

          min_group_bits =
              av_group_bits + (int64_t)(buffer_lvl - high_water_mark);

          if (cpi->twopass.kf_group_bits < min_group_bits) {
            cpi->twopass.kf_group_bits = min_group_bits;
          }
        }
        /* We are above optimal but below the maximum */
        else if (cpi->twopass.kf_group_bits < av_group_bits) {
          int64_t bits_below_av = av_group_bits - cpi->twopass.kf_group_bits;

          cpi->twopass.kf_group_bits += (int64_t)(
              (double)bits_below_av * (double)(buffer_lvl - opt_buffer_lvl) /
              (double)(high_water_mark - opt_buffer_lvl));
        }
      }
    }
  } else {
    cpi->twopass.kf_group_bits = 0;
  }

  /* Reset the first pass file position */
  reset_fpf_position(cpi, start_position);

  /* determine how big to make this keyframe based on how well the
   * subsequent frames use inter blocks
   */
  decay_accumulator = 1.0;
  boost_score = 0.0;

  for (i = 0; i < cpi->twopass.frames_to_key; ++i) {
    double r;

    if (EOF == input_stats(cpi, &next_frame)) break;

    if (next_frame.intra_error > cpi->twopass.kf_intra_err_min) {
      r = (IIKFACTOR2 * next_frame.intra_error /
           DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
    } else {
      r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min /
           DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
    }

    if (r > RMAX) r = RMAX;

    /* How fast is prediction quality decaying */
    loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);

    decay_accumulator = decay_accumulator * loop_decay_rate;
    decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;

    boost_score += (decay_accumulator * r);

    if ((i > MIN_GF_INTERVAL) && ((boost_score - old_boost_score) < 1.0)) {
      break;
    }

    old_boost_score = boost_score;
  }

  if (1) {
    FIRSTPASS_STATS sectionstats;
    double Ratio;

    zero_stats(&sectionstats);
    reset_fpf_position(cpi, start_position);

    for (i = 0; i < cpi->twopass.frames_to_key; ++i) {
      input_stats(cpi, &next_frame);
      accumulate_stats(&sectionstats, &next_frame);
    }

    avg_stats(&sectionstats);

    cpi->twopass.section_intra_rating =
        (unsigned int)(sectionstats.intra_error /
                       DOUBLE_DIVIDE_CHECK(sectionstats.coded_error));

    Ratio = sectionstats.intra_error /
            DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
    cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);

    if (cpi->twopass.section_max_qfactor < 0.80) {
      cpi->twopass.section_max_qfactor = 0.80;
    }
  }

  /* When using CBR apply additional buffer fullness related upper limits */
  if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
    double max_boost;

    if (cpi->drop_frames_allowed) {
      int df_buffer_level = (int)(cpi->oxcf.drop_frames_water_mark *
                                  (cpi->oxcf.optimal_buffer_level / 100));

      if (cpi->buffer_level > df_buffer_level) {
        max_boost =
            ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) /
            DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
      } else {
        max_boost = 0.0;
      }
    } else if (cpi->buffer_level > 0) {
      max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) /
                  DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
    } else {
      max_boost = 0.0;
    }

    if (boost_score > max_boost) boost_score = max_boost;
  }

  /* Reset the first pass file position */
  reset_fpf_position(cpi, start_position);

  /* Work out how many bits to allocate for the key frame itself */
  if (1) {
    int kf_boost = (int)boost_score;
    int allocation_chunks;
    int Counter = cpi->twopass.frames_to_key;
    int alt_kf_bits;
    YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];
/* Min boost based on kf interval */
#if 0

        while ((kf_boost < 48) && (Counter > 0))
        {
            Counter -= 2;
            kf_boost ++;
        }

#endif

    if (kf_boost < 48) {
      kf_boost += ((Counter + 1) >> 1);

      if (kf_boost > 48) kf_boost = 48;
    }

    /* bigger frame sizes need larger kf boosts, smaller frames smaller
     * boosts...
     */
    if ((lst_yv12->y_width * lst_yv12->y_height) > (320 * 240)) {
      kf_boost += 2 * (lst_yv12->y_width * lst_yv12->y_height) / (320 * 240);
    } else if ((lst_yv12->y_width * lst_yv12->y_height) < (320 * 240)) {
      kf_boost -= 4 * (320 * 240) / (lst_yv12->y_width * lst_yv12->y_height);
    }

    /* Min KF boost */
    kf_boost = (int)((double)kf_boost * 100.0) >> 4; /* Scale 16 to 100 */
    if (kf_boost < 250) kf_boost = 250;

    /*
     * We do three calculations for kf size.
     * The first is based on the error score for the whole kf group.
     * The second (optionaly) on the key frames own error if this is
     * smaller than the average for the group.
     * The final one insures that the frame receives at least the
     * allocation it would have received based on its own error score vs
     * the error score remaining
     * Special case if the sequence appears almost totaly static
     * as measured by the decay accumulator. In this case we want to
     * spend almost all of the bits on the key frame.
     * cpi->twopass.frames_to_key-1 because key frame itself is taken
     * care of by kf_boost.
     */
    if (decay_accumulator >= 0.99) {
      allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost;
    } else {
      allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost;
    }

    /* Normalize Altboost and allocations chunck down to prevent overflow */
    while (kf_boost > 1000) {
      kf_boost /= 2;
      allocation_chunks /= 2;
    }

    cpi->twopass.kf_group_bits =
        (cpi->twopass.kf_group_bits < 0) ? 0 : cpi->twopass.kf_group_bits;

    /* Calculate the number of bits to be spent on the key frame */
    cpi->twopass.kf_bits =
        (int)((double)kf_boost *
              ((double)cpi->twopass.kf_group_bits / (double)allocation_chunks));

    /* Apply an additional limit for CBR */
    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
      if (cpi->twopass.kf_bits > (int)((3 * cpi->buffer_level) >> 2)) {
        cpi->twopass.kf_bits = (int)((3 * cpi->buffer_level) >> 2);
      }
    }

    /* If the key frame is actually easier than the average for the
     * kf group (which does sometimes happen... eg a blank intro frame)
     * Then use an alternate calculation based on the kf error score
     * which should give a smaller key frame.
     */
    if (kf_mod_err < kf_group_err / cpi->twopass.frames_to_key) {
      double alt_kf_grp_bits =
          ((double)cpi->twopass.bits_left *
           (kf_mod_err * (double)cpi->twopass.frames_to_key) /
           DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left));

      alt_kf_bits = (int)((double)kf_boost *
                          (alt_kf_grp_bits / (double)allocation_chunks));

      if (cpi->twopass.kf_bits > alt_kf_bits) {
        cpi->twopass.kf_bits = alt_kf_bits;
      }
    }
    /* Else if it is much harder than other frames in the group make sure
     * it at least receives an allocation in keeping with its relative
     * error score
     */
    else {
      alt_kf_bits = (int)((double)cpi->twopass.bits_left *
                          (kf_mod_err / DOUBLE_DIVIDE_CHECK(
                                            cpi->twopass.modified_error_left)));

      if (alt_kf_bits > cpi->twopass.kf_bits) {
        cpi->twopass.kf_bits = alt_kf_bits;
      }
    }

    cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits;
    /* Add in the minimum frame allowance */
    cpi->twopass.kf_bits += cpi->min_frame_bandwidth;

    /* Peer frame bit target for this frame */
    cpi->per_frame_bandwidth = cpi->twopass.kf_bits;

    /* Convert to a per second bitrate */
    cpi->target_bandwidth = (int)(cpi->twopass.kf_bits * cpi->output_framerate);
  }

  /* Note the total error score of the kf group minus the key frame itself */
  cpi->twopass.kf_group_error_left = (int)(kf_group_err - kf_mod_err);

  /* Adjust the count of total modified error left. The count of bits left
   * is adjusted elsewhere based on real coded frame sizes
   */
  cpi->twopass.modified_error_left -= kf_group_err;

  if (cpi->oxcf.allow_spatial_resampling) {
    int resample_trigger = 0;
    int last_kf_resampled = 0;
    int kf_q;
    int scale_val = 0;
    int hr, hs, vr, vs;
    int new_width = cpi->oxcf.Width;
    int new_height = cpi->oxcf.Height;

    int projected_buffer_level;
    int tmp_q;

    double projected_bits_perframe;
    double group_iiratio = (kf_group_intra_err - first_frame.intra_error) /
                           (kf_group_coded_err - first_frame.coded_error);
    double err_per_frame = kf_group_err / cpi->twopass.frames_to_key;
    double bits_per_frame;
    double av_bits_per_frame;
    double effective_size_ratio;

    if ((cpi->common.Width != cpi->oxcf.Width) ||
        (cpi->common.Height != cpi->oxcf.Height)) {
      last_kf_resampled = 1;
    }

    /* Set back to unscaled by defaults */
    cpi->common.horiz_scale = NORMAL;
    cpi->common.vert_scale = NORMAL;

    /* Calculate Average bits per frame. */
    av_bits_per_frame = cpi->oxcf.target_bandwidth /
                        DOUBLE_DIVIDE_CHECK((double)cpi->framerate);

    /* CBR... Use the clip average as the target for deciding resample */
    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
      bits_per_frame = av_bits_per_frame;
    }

    /* In VBR we want to avoid downsampling in easy section unless we
     * are under extreme pressure So use the larger of target bitrate
     * for this section or average bitrate for sequence
     */
    else {
      /* This accounts for how hard the section is... */
      bits_per_frame =
          (double)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key);

      /* Dont turn to resampling in easy sections just because they
       * have been assigned a small number of bits
       */
      if (bits_per_frame < av_bits_per_frame) {
        bits_per_frame = av_bits_per_frame;
      }
    }

    /* bits_per_frame should comply with our minimum */
    if (bits_per_frame < (cpi->oxcf.target_bandwidth *
                          cpi->oxcf.two_pass_vbrmin_section / 100)) {
      bits_per_frame = (cpi->oxcf.target_bandwidth *
                        cpi->oxcf.two_pass_vbrmin_section / 100);
    }

    /* Work out if spatial resampling is necessary */
    kf_q = estimate_kf_group_q(cpi, err_per_frame, (int)bits_per_frame,
                               group_iiratio);

    /* If we project a required Q higher than the maximum allowed Q then
     * make a guess at the actual size of frames in this section
     */
    projected_bits_perframe = bits_per_frame;
    tmp_q = kf_q;

    while (tmp_q > cpi->worst_quality) {
      projected_bits_perframe *= 1.04;
      tmp_q--;
    }

    /* Guess at buffer level at the end of the section */
    projected_buffer_level =
        (int)(cpi->buffer_level -
              (int)((projected_bits_perframe - av_bits_per_frame) *
                    cpi->twopass.frames_to_key));

    if (0) {
      FILE *f = fopen("Subsamle.stt", "a");
      fprintf(f, " %8d %8d %8d %8d %12.0f %8d %8d %8d\n",
              cpi->common.current_video_frame, kf_q, cpi->common.horiz_scale,
              cpi->common.vert_scale, kf_group_err / cpi->twopass.frames_to_key,
              (int)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key),
              new_height, new_width);
      fclose(f);
    }

    /* The trigger for spatial resampling depends on the various
     * parameters such as whether we are streaming (CBR) or VBR.
     */
    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
      /* Trigger resample if we are projected to fall below down
       * sample level or resampled last time and are projected to
       * remain below the up sample level
       */
      if ((projected_buffer_level < (cpi->oxcf.resample_down_water_mark *
                                     cpi->oxcf.optimal_buffer_level / 100)) ||
          (last_kf_resampled &&
           (projected_buffer_level < (cpi->oxcf.resample_up_water_mark *
                                      cpi->oxcf.optimal_buffer_level / 100)))) {
        resample_trigger = 1;
      } else {
        resample_trigger = 0;
      }
    } else {
      int64_t clip_bits = (int64_t)(
          cpi->twopass.total_stats.count * cpi->oxcf.target_bandwidth /
          DOUBLE_DIVIDE_CHECK((double)cpi->framerate));
      int64_t over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level;

      /* If triggered last time the threshold for triggering again is
       * reduced:
       *
       * Projected Q higher than allowed and Overspend > 5% of total
       * bits
       */
      if ((last_kf_resampled && (kf_q > cpi->worst_quality)) ||
          ((kf_q > cpi->worst_quality) && (over_spend > clip_bits / 20))) {
        resample_trigger = 1;
      } else {
        resample_trigger = 0;
      }
    }

    if (resample_trigger) {
      while ((kf_q >= cpi->worst_quality) && (scale_val < 6)) {
        scale_val++;

        cpi->common.vert_scale = vscale_lookup[scale_val];
        cpi->common.horiz_scale = hscale_lookup[scale_val];

        Scale2Ratio(cpi->common.horiz_scale, &hr, &hs);
        Scale2Ratio(cpi->common.vert_scale, &vr, &vs);

        new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs;
        new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs;

        /* Reducing the area to 1/4 does not reduce the complexity
         * (err_per_frame) to 1/4... effective_sizeratio attempts
         * to provide a crude correction for this
         */
        effective_size_ratio = (double)(new_width * new_height) /
                               (double)(cpi->oxcf.Width * cpi->oxcf.Height);
        effective_size_ratio = (1.0 + (3.0 * effective_size_ratio)) / 4.0;

        /* Now try again and see what Q we get with the smaller
         * image size
         */
        kf_q = estimate_kf_group_q(cpi, err_per_frame * effective_size_ratio,
                                   (int)bits_per_frame, group_iiratio);

        if (0) {
          FILE *f = fopen("Subsamle.stt", "a");
          fprintf(
              f, "******** %8d %8d %8d %12.0f %8d %8d %8d\n", kf_q,
              cpi->common.horiz_scale, cpi->common.vert_scale,
              kf_group_err / cpi->twopass.frames_to_key,
              (int)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key),
              new_height, new_width);
          fclose(f);
        }
      }
    }

    if ((cpi->common.Width != new_width) ||
        (cpi->common.Height != new_height)) {
      cpi->common.Width = new_width;
      cpi->common.Height = new_height;
      vp8_alloc_compressor_data(cpi);
    }
  }
}
