/*
 *  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/vpxscale.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;
    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;

    /* 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, 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 <<= 3;
                    d->bmi.mv.as_mv.col <<= 3;
                    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 / 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 )
{
    return -(log( prob ) / log( 2.0 ));
}
static int64_t estimate_modemvcost(VP8_COMP *cpi,
                                     FIRSTPASS_STATS * fpstats)
{
    int mv_cost;
    int 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 =
        (int)( ( ((av_pct_inter - av_pct_motion) * zz_cost) +
                 (av_pct_motion * motion_cost) +
                 (av_intra * intra_cost) ) * cpi->common.MBs ) << 9;

    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_frame_rate(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_frame_rate(cpi, 10000000.0 * cpi->twopass.total_stats.count / cpi->twopass.total_stats.duration);

    cpi->output_frame_rate = cpi->frame_rate;
    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)
{
}

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

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

    /* 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 =
            (int)((double)cpi->twopass.kf_group_bits *
                  (gf_group_err / (double)cpi->twopass.kf_group_error_left));
    }
    else
        cpi->twopass.gf_group_bits = 0;

    cpi->twopass.gf_group_bits = (int)(
        (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 > max_bits * cpi->baseline_gf_interval)
        cpi->twopass.gf_group_bits = 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 =
                    (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 = 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->common.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 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->twopass.gf_group_bits = (int)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_frame_rate);
    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 a 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;
    loop_decay_rate = 1.00;       /* Starting decay rate */

    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_frame_rate);
    }

    /* 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)cpi->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->frame_rate);

        /* 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->frame_rate));
            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);
        }
    }
}
