/*
 *  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_scale_rtcd.h"
#include "block.h"
#include "onyx_int.h"
#include "vp8/common/variance.h"
#include "encodeintra.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_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 1 */

extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
extern void vp8_alloc_compressor_data(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);
    vp8_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 );
    vp8_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    = vp8_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;

    vp8_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));
        vpx_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);
        vp8_clear_system_state();
    }

    vp8_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;
}

extern void vp8_new_framerate(VP8_COMP *cpi, double framerate);

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;

    vp8_clear_system_state();

    start_pos = cpi->twopass.stats_in;

    vpx_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;
        }

        vpx_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 = {0};
    FIRSTPASS_STATS this_frame_copy;

    double this_frame_intra_error;
    double this_frame_coded_error;

    int overhead_bits;

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

    vp8_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 */
        vpx_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 */
        vpx_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;
            vpx_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 */
                vpx_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 */
            vpx_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;

        vpx_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};

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

    vp8_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 */
    vpx_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. */
        vpx_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,
                                             (cpi->key_frame_frequency-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 */
        vpx_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);
        }
    }
}
