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

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

#include "./vpx_dsp_rtcd.h"
#include "./vpx_scale_rtcd.h"
#include "block.h"
#include "onyx_int.h"
#include "vpx_dsp/variance.h"
#include "encodeintra.h"
#include "vp8/common/common.h"
#include "vp8/common/setupintrarecon.h"
#include "vp8/common/systemdependent.h"
#include "mcomp.h"
#include "firstpass.h"
#include "vpx_scale/vpx_scale.h"
#include "encodemb.h"
#include "vp8/common/extend.h"
#include "vpx_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);

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

extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];

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

#define KF_MB_INTRA_MIN 300
#define GF_MB_INTRA_MIN 200

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

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

#define NEW_BOOST 1

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


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

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

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

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

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

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

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

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

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

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

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

/* TEMP debug code */
#if OUTPUT_FPF

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

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

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

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

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

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

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

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

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

    return modified_err;
}

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

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

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

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

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

    return sum_weights;
}


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

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

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

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

            max_bits = (int)(max_bits * buffer_fullness_ratio);

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

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

    return max_bits;
}

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

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

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

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

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

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

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

    int_mv tmp_mv;
    int_mv ref_mv_full;

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

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

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

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

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

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

    while (n < further_steps)
    {
        n++;

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

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

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

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

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

    int_mv zero_ref_mv;

    zero_ref_mv.as_int = 0;

    vp8_clear_system_state();

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

    x->partition_info = x->pi;

    xd->mode_info_context = cm->mi;

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

    vp8_build_block_offsets(x);

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

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

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

        best_ref_mv.as_int = 0;

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            coded_error += (int64_t)this_error;

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

            recon_yoffset += 16;
            recon_uvoffset += 8;
        }

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

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

    vp8_clear_system_state();
    {
        double weight = 0.0;

        FIRSTPASS_STATS fps;

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


        if (weight < 0.1)
            weight = 0.1;

        fps.ssim_weighted_pred_err = fps.coded_error * weight;

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

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

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

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

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

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

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

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

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


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

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

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

    cm->current_video_frame++;

}
extern const int vp8_bits_per_mb[2][QINDEX_RANGE];

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

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

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

    double zz_cost;
    double motion_cost;
    double intra_cost;

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

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

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

    return mv_cost + mode_cost;
}

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

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

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

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

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

    return correction_factor;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

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

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

    return Q;
}

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

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

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

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

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

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

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

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

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

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

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

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

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

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

    return Q;
}

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

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

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

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

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

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

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

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

    return Q;
}

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

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

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

    double iiratio_correction_factor = 1.0;

    double combined_correction_factor;

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

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

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

    if (iiratio_correction_factor < 0.5)
        iiratio_correction_factor = 0.5;

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

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

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

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

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

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

        bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
        Q++;
    }

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

    return Q;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    }
}

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

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

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

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

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

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

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

    return prediction_decay_rate;
}

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

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

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

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

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

    return trans_to_still;
}

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

    int flash_detected = 0;

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

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

    return flash_detected;
}

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

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

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

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

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

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

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

    }
}

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

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

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

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

    return frame_boost;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        boost_score += (decay_accumulator * r);

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

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

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

    double mv_ratio_accumulator = 0.0;
    double decay_accumulator = 1.0;

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

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

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

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

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

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

    vp8_clear_system_state();

    start_pos = cpi->twopass.stats_in;

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

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

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

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

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

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

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

        gf_group_err += mod_frame_err;

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

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

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

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

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

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

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

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

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

        old_boost_score = boost_score;
    }

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

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

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

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

        if (boost_score > max_boost)
            boost_score = max_boost;
    }

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

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

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

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

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

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

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

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

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

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

        allocation_chunks = (i * 100) + Boost;

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

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

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

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

            cpi->source_alt_ref_pending = 1;

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

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

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

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

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

                frames_bwd = frames_fwd;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        avg_stats(&sectionstats);

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

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

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

        reset_fpf_position(cpi, start_pos);
    }
}

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

    double modified_err;
    double err_fraction;

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

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

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

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

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

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

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

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

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

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

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

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

    FIRSTPASS_STATS this_frame;
    FIRSTPASS_STATS this_frame_copy;

    double this_frame_intra_error;
    double this_frame_coded_error;

    int overhead_bits;

    vp8_zero(this_frame);

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

    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 */
        memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
        find_next_key_frame(cpi, &this_frame_copy);

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

    }

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

    cpi->twopass.frames_to_key --;

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


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

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

        FIRSTPASS_STATS local_next_frame;

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

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

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

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

            if (next_iiratio > RMAX)
                next_iiratio = RMAX;

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

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

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

            old_boost_score = boost_score;

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

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

            is_viable_kf = 0;
        }
    }

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

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

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

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

    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 */
    memcpy(&first_frame, this_frame, sizeof(*this_frame));

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

    kf_mod_err = calculate_modified_err(cpi, this_frame);

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

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

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

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

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

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

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


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

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

        i++;
    }

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

        cpi->twopass.frames_to_key /= 2;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                int64_t av_group_bits;

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

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

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

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

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

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

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

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

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

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

        if (r > RMAX)
            r = RMAX;

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

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

        boost_score += (decay_accumulator * r);

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

        old_boost_score = boost_score;
    }

    if (1)
    {
        FIRSTPASS_STATS sectionstats;
        double Ratio;

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

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

        avg_stats(&sectionstats);

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

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

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

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

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

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

        if (boost_score > max_boost)
            boost_score = max_boost;
    }

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

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

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

#endif

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

            if (kf_boost > 48) kf_boost = 48;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        int projected_buffer_level;
        int tmp_q;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        }

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

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

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

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

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

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

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

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