/*
 *  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 "block.h"
#include "onyx_int.h"
#include "variance.h"
#include "encodeintra.h"
#include "vp8/common/setupintrarecon.h"
#include "mcomp.h"
#include "vpx_scale/vpxscale.h"
#include "encodemb.h"
#include "vp8/common/extend.h"
#include "vp8/common/systemdependent.h"
#include "vpx_scale/yv12extend.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/swapyv12buffer.h"
#include <stdio.h>
#include "rdopt.h"
#include "vp8/common/quant_common.h"
#include "encodemv.h"

//#define OUTPUT_FPF 1

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif

extern void vp8_build_block_offsets(MACROBLOCK *x);
extern void vp8_setup_block_ptrs(MACROBLOCK *x);
extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, MV *mv);
extern void vp8_alloc_compressor_data(VP8_COMP *cpi);

//#define GFQ_ADJUSTMENT (40 + ((15*Q)/10))
//#define GFQ_ADJUSTMENT (80 + ((15*Q)/10))
#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.4
#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

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


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

void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);
int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps);

int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_dc_pred)
{

    int i;
    int intra_pred_var = 0;
    (void) cpi;

    if (use_dc_pred)
    {
        x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
        x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;

        vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
    }
    else
    {
        for (i = 0; i < 16; i++)
        {
            BLOCKD *b = &x->e_mbd.block[i];
            BLOCK  *be = &x->block[i];

            vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, be, b, B_DC_PRED);
        }
    }

    intra_pred_var = VARIANCE_INVOKE(&cpi->rtcd.variance, getmbss)(x->src_diff);

    return intra_pred_var;
}

// 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->stats_in = Position;
}

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

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

// 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->total_stats->ssim_weighted_pred_err;
    double this_err = this_frame->ssim_weighted_pred_err;
    double modified_err;

    //double relative_next_iiratio;
    //double next_iiratio;
    //double sum_iiratio;
    //int i;

    //FIRSTPASS_STATS next_frame;
    //FIRSTPASS_STATS *start_pos;

    /*start_pos = cpi->stats_in;
    sum_iiratio = 0.0;
    i = 0;
    while ( (i < 1) && vp8_input_stats(cpi,&next_frame) != EOF )
    {

        next_iiratio = next_frame.intra_error / DOUBLE_DIVIDE_CHECK(next_frame.coded_error);
        next_iiratio = ( next_iiratio < 1.0 ) ? 1.0 : (next_iiratio > 20.0) ? 20.0 : next_iiratio;
        sum_iiratio += next_iiratio;
        i++;
    }
    if ( i > 0 )
    {
        relative_next_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK(cpi->avg_iiratio * (double)i);
    }
    else
    {
        relative_next_iiratio = 1.0;
    }
    reset_fpf_position(cpi, start_pos);*/

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

    /*
    relative_next_iiratio = pow(relative_next_iiratio,0.25);
    modified_err = modified_err * relative_next_iiratio;
    */

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

double vp8_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
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);

            if (max_bits < min_max_bits)
                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
        }
    }
    // 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->bits_left / (cpi->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;
}


extern size_t vp8_firstpass_stats_sz(unsigned int mb_count)
{
    /* Calculate the size of a stats packet, which is dependent on the frame
     * resolution. The FIRSTPASS_STATS struct has a single element array,
     * motion_map, which is virtually expanded to have one element per
     * macroblock.
     */
    size_t stats_sz;

    stats_sz = sizeof(FIRSTPASS_STATS) + mb_count;
    stats_sz = (stats_sz + 7) & ~7;
    return stats_sz;
}


void vp8_output_stats(const VP8_COMP            *cpi,
                      struct vpx_codec_pkt_list *pktlist,
                      FIRSTPASS_STATS            *stats)
{
    struct vpx_codec_cx_pkt pkt;
    pkt.kind = VPX_CODEC_STATS_PKT;
    pkt.data.twopass_stats.buf = stats;
    pkt.data.twopass_stats.sz = vp8_firstpass_stats_sz(cpi->common.MBs);
    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.0f\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->MVr,
                stats->mvr_abs,
                stats->MVc,
                stats->mvc_abs,
                stats->MVrv,
                stats->MVcv,
                stats->mv_in_out_count,
                stats->count);
        fclose(fpfile);


        fpfile = fopen("fpmotionmap.stt", "a");
        if(fwrite(cpi->fp_motion_map, 1, cpi->common.MBs, fpfile));
        fclose(fpfile);
    }
#endif
}

int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
{
    size_t stats_sz = vp8_firstpass_stats_sz(cpi->common.MBs);

    if (cpi->stats_in >= cpi->stats_in_end)
        return EOF;

    *fps = *cpi->stats_in;
    cpi->stats_in = (void*)((char *)cpi->stats_in + stats_sz);
    return 1;
}

void vp8_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->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->count      = 0.0;
    section->duration   = 1.0;
}
void vp8_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->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->count      += frame->count;
    section->duration   += frame->duration;
}
void vp8_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_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;
}

unsigned char *vp8_fpmm_get_pos(VP8_COMP *cpi)
{
    return cpi->fp_motion_map_stats;
}
void vp8_fpmm_reset_pos(VP8_COMP *cpi, unsigned char *target_pos)
{
    cpi->fp_motion_map_stats = target_pos;
}

void vp8_advance_fpmm(VP8_COMP *cpi, int count)
{
    cpi->fp_motion_map_stats = (void*)((char*)cpi->fp_motion_map_stats +
        count * vp8_firstpass_stats_sz(cpi->common.MBs));
}

void vp8_input_fpmm(VP8_COMP *cpi)
{
    unsigned char *fpmm = cpi->fp_motion_map;
    int MBs = cpi->common.MBs;
    int max_frames = cpi->active_arnr_frames;
    int i;

    for (i=0; i<max_frames; i++)
    {
        char *motion_map = (char*)cpi->fp_motion_map_stats
                           + sizeof(FIRSTPASS_STATS);

        memcpy(fpmm, motion_map, MBs);
        fpmm += MBs;
        vp8_advance_fpmm(cpi, 1);
    }

    // Flag the use of weights in the temporal filter
    cpi->use_weighted_temporal_filter = 1;
}

void vp8_init_first_pass(VP8_COMP *cpi)
{
    vp8_zero_stats(cpi->total_stats);

// TEMP debug code
#ifdef OUTPUT_FPF
    {
        FILE *fpfile;
        fpfile = fopen("firstpass.stt", "w");
        fclose(fpfile);
        fpfile = fopen("fpmotionmap.stt", "wb");
        fclose(fpfile);
    }
#endif

}

void vp8_end_first_pass(VP8_COMP *cpi)
{
    vp8_output_stats(cpi, cpi->output_pkt_list, cpi->total_stats);
}

void vp8_zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, 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 *ref_ptr;
    int ref_stride=d->pre_stride;

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

    ref_ptr = (unsigned char *)(*(d->base_pre) + d->pre );

    VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), mse16x16) ( src_ptr, src_stride, ref_ptr, ref_stride, (unsigned int *)(best_motion_err));
}

void vp8_first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x, 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;

    MV tmp_mv = {0, 0};

    int tmp_err;
    int step_param = 3;                                       //3;          // Dont search over full range for first pass
    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; //3;
    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    = VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), 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_err = cpi->diamond_search_sad(x, b, d, ref_mv, &tmp_mv, step_param, x->errorperbit, &num00, &v_fn_ptr, x->mvsadcost, 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.row;
        best_mv->col = tmp_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, &tmp_mv, step_param + n, x->errorperbit, &num00, &v_fn_ptr, x->mvsadcost, 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.row;
                best_mv->col = tmp_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 col_blocks = 4 * cm->mb_cols;
    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;
    long long intra_error = 0;
    long long 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 sum_in_vectors = 0;

    MV zero_ref_mv = {0, 0};

    unsigned char *fp_motion_map_ptr = cpi->fp_motion_map;

    vp8_clear_system_state();  //__asm emms;

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

    x->partition_info = x->pi;

    xd->mode_info_context = cm->mi;

    vp8_build_block_offsets(x);

    vp8_setup_block_dptrs(&x->e_mbd);

    vp8_setup_block_ptrs(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
    //if( cm->current_video_frame == 0)
    //if ( 0 )
    {
        int flag[2] = {1, 1};
        vp8_initialize_rd_consts(cpi, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
        vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
        vp8_build_component_cost_table(cpi->mb.mvcost, cpi->mb.mvsadcost, (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 zero_error;
            int zz_to_best_ratio;
            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);

            // 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 += (long long)this_error;

            // Indicate default assumption of intra in the motion map
            *fp_motion_map_ptr = 0;

            // 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)
            {
                BLOCK *b = &x->block[0];
                BLOCKD *d = &x->e_mbd.block[0];
                MV tmp_mv = {0, 0};
                int tmp_err;
                int motion_error = INT_MAX;

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

                // Save (0,0) error for later use
                zero_error = motion_error;

                // Test last reference frame using the previous best mv as the
                // starting point (best reference) for the search
                vp8_first_pass_motion_search(cpi, x, &best_ref_mv.as_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;
                   vp8_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)
                {
                    vp8_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++;
                        //motion_error = gf_motion_error;
                        //d->bmi.mv.as_mv.row = tmp_mv.row;
                        //d->bmi.mv.as_mv.col = tmp_mv.col;
                    }
                    /*else
                    {
                        xd->pre.y_buffer = cm->last_frame.y_buffer + recon_yoffset;
                        xd->pre.u_buffer = cm->last_frame.u_buffer + recon_uvoffset;
                        xd->pre.v_buffer = cm->last_frame.v_buffer + recon_uvoffset;
                    }*/


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

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

                if (motion_error <= this_error)
                {
                    d->bmi.mv.as_mv.row <<= 3;
                    d->bmi.mv.as_mv.col <<= 3;
                    this_error = motion_error;
                    vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv.as_mv);
                    vp8_encode_inter16x16y(IF_RTCD(&cpi->rtcd), 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++;

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

                        // Compute how close (0,0) predictor is to best
                        // predictor in terms of their prediction error
                        zz_to_best_ratio = (10*zero_error + this_error/2)
                                            / (this_error+!this_error);

                        if ((zero_error < 50000) &&
                            (zz_to_best_ratio <= 11) )
                            *fp_motion_map_ptr = 1;
                        else
                            *fp_motion_map_ptr = 0;
                    }
                    else
                    {
                        // 0,0 mv was best
                        if( zero_error<50000 )
                            *fp_motion_map_ptr = 2;
                        else
                            *fp_motion_map_ptr = 1;
                    }
                }
            }

            coded_error += (long long)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;

            // Update the motion map
            fp_motion_map_ptr++;
        }

        // 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();  //__asm emms;
    }

    vp8_clear_system_state();  //__asm emms;
    {
        double weight = 0.0;

        FIRSTPASS_STATS fps;

        fps.frame      = cm->current_video_frame ;
        fps.intra_error = intra_error >> 8;
        fps.coded_error = coded_error >> 8;
        weight = vp8_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.count      = 1.0;

        fps.pcnt_inter   = 1.0 * (double)intercount / cm->MBs;
        fps.pcnt_second_ref = 1.0 * (double)second_ref_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.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_stamp s  .
        fps.duration = cpi->source_end_time_stamp - cpi->source_time_stamp;

        // don't want to do outputstats with a stack variable!
        memcpy(cpi->this_frame_stats,
               &fps,
               sizeof(FIRSTPASS_STATS));
        memcpy((char*)cpi->this_frame_stats + sizeof(FIRSTPASS_STATS),
               cpi->fp_motion_map,
               sizeof(cpi->fp_motion_map[0]) * cpi->common.MBs);
        vp8_output_stats(cpi, cpi->output_pkt_list, cpi->this_frame_stats);
        vp8_accumulate_stats(cpi->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->this_frame_stats->pcnt_inter > 0.20) &&
        ((cpi->this_frame_stats->intra_error / cpi->this_frame_stats->coded_error) > 2.0))
    {
        vp8_yv12_copy_frame_ptr(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_ptr(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");

        if(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];

#define BASE_ERRPERMB   150
static int estimate_max_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
{
    int Q;
    int num_mbs = ((Height * Width) / (16 * 16));
    int target_norm_bits_per_mb;

    double err_per_mb = section_err / num_mbs;
    double correction_factor;
    double corr_high;
    double speed_correction = 1.0;
    double rolling_ratio;

    double pow_highq = 0.90;
    double pow_lowq = 0.40;

    if (section_target_bandwitdh <= 0)
        return cpi->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.0) && (cpi->active_worst_quality < cpi->worst_quality))
    {
        //double adjustment_rate = 0.985 + (0.00005 * cpi->active_worst_quality);
        double adjustment_rate = 0.99;

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

        //if ( cpi->est_max_qcorrection_factor > rolling_ratio )
        if (rolling_ratio < 0.95)
            //cpi->est_max_qcorrection_factor *= adjustment_rate;
            cpi->est_max_qcorrection_factor -= 0.005;
        //else if ( cpi->est_max_qcorrection_factor < rolling_ratio )
        else if (rolling_ratio > 1.05)
            cpi->est_max_qcorrection_factor += 0.005;

        //cpi->est_max_qcorrection_factor /= adjustment_rate;

        cpi->est_max_qcorrection_factor = (cpi->est_max_qcorrection_factor < 0.1) ? 0.1 : (cpi->est_max_qcorrection_factor > 10.0) ? 10.0 : cpi->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;
    }

    // Correction factor used for Q values >= 20
    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
    corr_high = (corr_high < 0.05)
                    ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;

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

        if (Q < 50)
        {
            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
        }
        else
            correction_factor = corr_high;

        bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->est_max_qcorrection_factor * cpi->section_max_qfactor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
        //bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->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;
    }

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

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

    return Q;
}
static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, int Height, int Width)
{
    int Q;
    int num_mbs = ((Height * Width) / (16 * 16));
    int target_norm_bits_per_mb;

    double err_per_mb = section_err / num_mbs;
    double correction_factor;
    double corr_high;
    double speed_correction = 1.0;
    double pow_highq = 0.90;
    double pow_lowq = 0.40;

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

    // Correction factor used for Q values >= 20
    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;

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

        if (Q < 50)
        {
            correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
            correction_factor = (correction_factor < 0.05) ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
        }
        else
            correction_factor = corr_high;

        bits_per_mb_at_this_q = (int)(.5 + correction_factor * speed_correction * cpi->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, int Height, int Width, double group_iiratio)
{
    int Q;
    int num_mbs = ((Height * Width) / (16 * 16));
    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 corr_high;
    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;

    // Correction factor used for Q values >= 20
    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;

    // Try and pick a Q that should be high enough to encode the content at the given rate.
    for (Q = 0; Q < MAXQ; Q++)
    {
        // Q values < 20 treated as a special case
        if (Q < 20)
        {
            err_correction_factor = pow(err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));
            err_correction_factor = (err_correction_factor < 0.05) ? 0.05 : (err_correction_factor > 5.0) ? 5.0 : err_correction_factor;
        }
        else
            err_correction_factor = corr_high;

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

// For cq mode estimate a cq level that matches the observed
// complexity and data rate.
static int estimate_cq(VP8_COMP *cpi, double section_err,
                       int section_target_bandwitdh, int Height, int Width)
{
    int Q;
    int num_mbs = ((Height * Width) / (16 * 16));
    int target_norm_bits_per_mb;

    double err_per_mb = section_err / num_mbs;
    double correction_factor;
    double corr_high;
    double speed_correction = 1.0;
    double pow_highq = 0.90;
    double pow_lowq = 0.40;
    double clip_iiratio;
    double clip_iifactor;

    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;
    }
    // II ratio correction factor for clip as a whole
    clip_iiratio = cpi->total_stats->intra_error /
                   DOUBLE_DIVIDE_CHECK(cpi->total_stats->coded_error);
    clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
    if (clip_iifactor < 0.80)
        clip_iifactor = 0.80;

    // Correction factor used for Q values >= 20
    corr_high = pow(err_per_mb / BASE_ERRPERMB, pow_highq);
    corr_high = (corr_high < 0.05) ? 0.05 : (corr_high > 5.0) ? 5.0 : corr_high;

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

        if (Q < 50)
        {
            correction_factor =
                pow( err_per_mb / BASE_ERRPERMB, (pow_lowq + Q * 0.01));

            correction_factor = (correction_factor < 0.05) ? 0.05
                                    : (correction_factor > 5.0) ? 5.0
                                        : correction_factor;
        }
        else
            correction_factor = corr_high;

        bits_per_mb_at_this_q =
            (int)( .5 + correction_factor *
                        speed_correction *
                        clip_iifactor *
                        (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

    return cq_level[Q];
}

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

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

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

    vp8_zero_stats(cpi->total_stats);

    if (!cpi->stats_in_end)
        return;

    *cpi->total_stats = *cpi->stats_in_end;

    cpi->total_error_left = cpi->total_stats->ssim_weighted_pred_err;
    cpi->total_intra_error_left = cpi->total_stats->intra_error;
    cpi->total_coded_error_left = cpi->total_stats->coded_error;
    cpi->start_tot_err_left = cpi->total_error_left;

    //cpi->bits_left = (long long)(cpi->total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
    //cpi->bits_left -= (long long)(cpi->total_stats->count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));

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

    cpi->output_frame_rate = cpi->oxcf.frame_rate;
    cpi->bits_left = (long long)(cpi->total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
    cpi->bits_left -= (long long)(cpi->total_stats->duration * two_pass_min_rate / 10000000.0);
    cpi->clip_bits_total = cpi->bits_left;

    // 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->kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
    cpi->gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;

    vp8_avg_stats(cpi->total_stats);

    // 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->stats_in;               // Note starting "file" position

        while (vp8_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->avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->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->stats_in;               // Note starting "file" position

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

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

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

    }

    // Calculate the clip target modified bits per error
    // The observed bpe starts as the same number.
    cpi->clip_bpe =  cpi->bits_left /
                     DOUBLE_DIVIDE_CHECK(cpi->modified_error_total);
    cpi->observed_bpe = cpi->clip_bpe;

    cpi->fp_motion_map_stats = (unsigned char *)cpi->stats_in;
}

void vp8_end_second_pass(VP8_COMP *cpi)
{
}

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


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

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

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

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

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

    return prediction_decay_rate;
}

// 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;
    int y_width  = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_width;
    int y_height = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_height;
    int image_size = y_width  * y_height;
    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_accumulator_rabs  = 0.0;
    double mv_accumulator_cabs  = 0.0;
    double mv_ratio_accumulator = 0.0;
    double decay_accumulator = 1.0;

    double boost_factor = IIFACTOR;
    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 char *fpmm_pos;

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

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

    vp8_clear_system_state();  //__asm emms;

    fpmm_pos = vp8_fpmm_get_pos(cpi);

    start_pos = cpi->stats_in;

    vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean

    // Preload the stats for the next 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->static_scene_max_gf_interval) ||
            ((cpi->frames_to_key - i) < MIN_GF_INTERVAL)) &&
           (i < cpi->frames_to_key))
    {
        double r;
        double this_frame_mvr_ratio;
        double this_frame_mvc_ratio;
        double motion_decay;
        //double motion_pct = next_frame.pcnt_motion;
        double motion_pct;

        i++;    // Increment the loop counter

        // 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 == vp8_input_stats(cpi, &next_frame))
            break;

        // Accumulate motion stats.
        motion_pct = next_frame.pcnt_motion;
        mv_accumulator_rabs += fabs(next_frame.mvr_abs * motion_pct);
        mv_accumulator_cabs += fabs(next_frame.mvc_abs * motion_pct);

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

        // If there is a significant amount of motion
        if (motion_pct > 0.05)
        {
            this_frame_mvr_ratio = fabs(next_frame.mvr_abs) /
                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVr));

            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) /
                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));

            mv_ratio_accumulator +=
                (this_frame_mvr_ratio < next_frame.mvr_abs)
                    ? (this_frame_mvr_ratio * motion_pct)
                    : next_frame.mvr_abs * motion_pct;

            mv_ratio_accumulator +=
                (this_frame_mvc_ratio < next_frame.mvc_abs)
                    ? (this_frame_mvc_ratio * motion_pct)
                    : next_frame.mvc_abs * motion_pct;
        }
        else
        {
            mv_ratio_accumulator += 0.0;
            this_frame_mvr_ratio = 1.0;
            this_frame_mvc_ratio = 1.0;
        }

        // Underlying boost factor is based on inter intra error ratio
        r = ( boost_factor *
              ( next_frame.intra_error /
                DOUBLE_DIVIDE_CHECK(next_frame.coded_error)));

        if (next_frame.intra_error > cpi->gf_intra_err_min)
            r = (IIKFACTOR2 * next_frame.intra_error /
                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
        else
            r = (IIKFACTOR2 * cpi->gf_intra_err_min /
                     DOUBLE_DIVIDE_CHECK(next_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)
            r += r * (this_frame_mv_in_out * 2.0);
        // In extreme case boost is halved
        else
            r += r * (this_frame_mv_in_out / 2.0);

        if (r > GF_RMAX)
            r = GF_RMAX;

        loop_decay_rate = gf_prediction_decay_rate(cpi, &next_frame);

        // Cumulative effect of decay
        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
        // instead of a clean key frame.
        if ( (i > MIN_GF_INTERVAL) &&
             (loop_decay_rate >= 0.999) &&
             (decay_accumulator < 0.9) )
        {
            int j;
            FIRSTPASS_STATS * position = cpi->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 < 4; j++ )
            {
                if (EOF == vp8_input_stats(cpi, &tmp_next_frame))
                    break;

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

            // Force GF not alt ref
            if ( j == 4 )
            {
                if (0)
                {
                    FILE *f = fopen("fadegf.stt", "a");
                    fprintf(f, " %8d %8d %10.4f %10.4f %10.4f\n",
                         cpi->common.current_video_frame+i, i,
                         loop_decay_rate, decay_accumulator,
                         boost_score );
                    fclose(f);
                }

                allow_alt_ref = FALSE;

                boost_score = old_boost_score;
                break;
            }
        }

        // Break out conditions.
        if  (   /* i>4 || */
            // 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->frames_to_key - i) >= MIN_GF_INTERVAL) &&
                ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
                ((mv_ratio_accumulator > 100.0) ||
                 (abs_mv_in_out_accumulator > 3.0) ||
                 (mv_in_out_accumulator < -2.0) ||
                 ((boost_score - old_boost_score) < 2.0))
            ) )
        {
            boost_score = old_boost_score;
            break;
        }

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

        old_boost_score = boost_score;
    }

    cpi->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)
        {
            int 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;
    }

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

    // Should we use the alternate refernce frame
    if (allow_alt_ref &&
        (i >= MIN_GF_INTERVAL) &&
        // dont use ARF very near next kf
        (i <= (cpi->frames_to_key - MIN_GF_INTERVAL)) &&
        (((next_frame.pcnt_inter > 0.75) &&
          ((mv_in_out_accumulator / (double)i > -0.2) || (mv_in_out_accumulator > -2.0)) &&
          //(cpi->gfu_boost>150) &&
          (cpi->gfu_boost > 100) &&
          //(cpi->gfu_boost>AF_THRESH2) &&
          //((cpi->gfu_boost/i)>AF_THRESH) &&
          //(decay_accumulator > 0.5) &&
          (cpi->gf_decay_rate <= (ARF_DECAY_THRESH + (cpi->gfu_boost / 200)))
         )
        )
       )
    {
        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;

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

        // Boost for arf frame
        Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
        Boost += (i * 50);
        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, cpi->common.Height, cpi->common.Width);

        // 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 = TRUE;

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

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

            // 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 = cpi->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;

            {
                // Advance to & read in the motion map for those frames
                // to be considered for filtering based on the position
                // of the ARF
                vp8_fpmm_reset_pos(cpi, cpi->fp_motion_map_stats_save);

                // Position at the 'earliest' frame to be filtered
                vp8_advance_fpmm(cpi,
                    cpi->baseline_gf_interval - frames_bwd);

                // Read / create a motion map for the region of interest
                vp8_input_fpmm(cpi);
            }
        }
        else
        {
            cpi->source_alt_ref_pending = FALSE;
            cpi->baseline_gf_interval = i;
        }
    }
    else
    {
        cpi->source_alt_ref_pending = FALSE;
        cpi->baseline_gf_interval = i;
    }

    // Conventional GF
    if (!cpi->source_alt_ref_pending)
    {
        // Dont allow conventional gf too near the next kf
        if ((cpi->frames_to_key - cpi->baseline_gf_interval) < MIN_GF_INTERVAL)
        {
            while (cpi->baseline_gf_interval < cpi->frames_to_key)
            {
                if (EOF == vp8_input_stats(cpi, this_frame))
                    break;

                cpi->baseline_gf_interval++;

                if (cpi->baseline_gf_interval < cpi->frames_to_key)
                    gf_group_err += calculate_modified_err(cpi, this_frame);
            }
        }
    }

    // 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->kf_group_bits is tied to cpi->bits_left.
    // This is also important for short clips where there may only be one key frame.
    if (cpi->frames_to_key >= (int)(cpi->total_stats->count - cpi->common.current_video_frame))
    {
        cpi->kf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;
    }

    // Calculate the bits to be allocated to the group as a whole
    if ((cpi->kf_group_bits > 0) && (cpi->kf_group_error_left > 0))
        cpi->gf_group_bits = (int)((double)cpi->kf_group_bits * (gf_group_err / (double)cpi->kf_group_error_left));
    else
        cpi->gf_group_bits = 0;

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

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

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

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

    // Assign  bits to the arf or gf.
    {
        int Boost;
        int frames_in_section;
        int allocation_chunks;
        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;

        // For ARF frames
        if (cpi->source_alt_ref_pending)
        {
            Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
            //Boost += (cpi->baseline_gf_interval * 25);
            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;

            frames_in_section = cpi->baseline_gf_interval + 1;
            allocation_chunks = (frames_in_section * 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;

            frames_in_section = cpi->baseline_gf_interval;
            allocation_chunks = (frames_in_section * 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
        cpi->gf_bits = (int)((double)Boost * (cpi->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->kf_group_bits  *
                (mod_frame_err * (double)cpi->baseline_gf_interval) /
                DOUBLE_DIVIDE_CHECK((double)cpi->kf_group_error_left);

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

            if (cpi->gf_bits > alt_gf_bits)
            {
                cpi->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->kf_group_bits *
                      mod_frame_err /
                      DOUBLE_DIVIDE_CHECK((double)cpi->kf_group_error_left));

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

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

        // Dont allow a negative value for gf_bits
        if (cpi->gf_bits < 0)
            cpi->gf_bits = 0;

        // Adjust KF group bits and error remainin
        cpi->kf_group_error_left -= gf_group_err;
        cpi->kf_group_bits -= cpi->gf_group_bits;

        if (cpi->kf_group_bits < 0)
            cpi->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->gf_group_error_left = gf_group_err - gf_first_frame_err;
        else
            cpi->gf_group_error_left = gf_group_err;

        cpi->gf_group_bits -= cpi->gf_bits;

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

        // Set aside some bits for a mid gf sequence boost
        if ((cpi->gfu_boost > 150) && (cpi->baseline_gf_interval > 5))
        {
            int pct_extra = (cpi->gfu_boost - 100) / 50;
            pct_extra = (pct_extra > 10) ? 10 : pct_extra;

            cpi->mid_gf_extra_bits = (cpi->gf_group_bits * pct_extra) / 100;
            cpi->gf_group_bits -= cpi->mid_gf_extra_bits;
        }
        else
            cpi->mid_gf_extra_bits = 0;

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

    if (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))                  // Normal GF and not a KF
    {
        cpi->per_frame_bandwidth = cpi->gf_bits;                                               // Per frame bit target for this frame
    }

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

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

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

        vp8_avg_stats(&sectionstats);

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

        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
        //if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
        //{
        cpi->section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);

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

        //}
        //else
        //    cpi->section_max_qfactor = 1.0;

        reset_fpf_position(cpi, start_pos);
    }

    // Reset the First pass motion map file position
    vp8_fpmm_reset_pos(cpi, fpmm_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;                                                             // gf_group_error_left

    double modified_err;
    double err_fraction;                                                                 // What portion of the remaining GF group error is used by this frame

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

    // The final few frames have special treatment
    if (cpi->frames_till_gf_update_due >= (int)(cpi->total_stats->count - cpi->common.current_video_frame))
    {
        cpi->gf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;;
    }

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

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

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

    // Clip to target size to 0 - max_bits (or cpi->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->gf_group_bits)
            target_frame_size = cpi->gf_group_bits;
    }

    cpi->gf_group_error_left -= modified_err;                                               // Adjust error remaining
    cpi->gf_group_bits -= target_frame_size;                                                // Adjust bits remaining

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

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

    // Special case for the frame that lies half way between two gfs
    if (cpi->common.frames_since_golden == cpi->baseline_gf_interval / 2)
        target_frame_size += cpi->mid_gf_extra_bits;

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

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

    FIRSTPASS_STATS this_frame;
    FIRSTPASS_STATS this_frame_copy;

    VP8_COMMON *cm = &cpi->common;

    double this_frame_error;
    double this_frame_intra_error;
    double this_frame_coded_error;

    FIRSTPASS_STATS *start_pos;

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

    vp8_clear_system_state();

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

    vpx_memset(cpi->fp_motion_map, 0,
                cpi->oxcf.arnr_max_frames*cpi->common.MBs);
    cpi->fp_motion_map_stats_save = vp8_fpmm_get_pos(cpi);

    // Step over this frame's first pass motion map
    vp8_advance_fpmm(cpi, 1);

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

    // Store information regarding level of motion etc for use mode decisions.
    cpi->motion_speed = (int)(fabs(this_frame.MVr) + fabs(this_frame.MVc));
    cpi->motion_var = (int)(fabs(this_frame.MVrv) + fabs(this_frame.MVcv));
    cpi->inter_lvl = (int)(this_frame.pcnt_inter * 100);
    cpi->intra_lvl = (int)((1.0 - this_frame.pcnt_inter) * 100);
    cpi->motion_lvl = (int)(this_frame.pcnt_motion * 100);

    start_pos = cpi->stats_in;

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

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

    }

    // Is this a GF / ARF (Note that a KF is always also a GF)
    if (cpi->frames_till_gf_update_due == 0)
    {
        // Update monitor of the bits per error observed so far.
        // Done once per gf group based on what has gone before
        // so do nothing if this is the first frame.
        if (cpi->common.current_video_frame > 0)
        {
            cpi->observed_bpe =
                (double)(cpi->clip_bits_total - cpi->bits_left) /
                cpi->modified_error_used;
        }

        // Define next gf group and assign bits to it
        vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
        define_gf_group(cpi, &this_frame_copy);

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

            // If appropriate (we are switching into ARF active but it was not previously active) apply a boost for the gf at the start of the group.
            //if ( !cpi->source_alt_ref_active && (cpi->gfu_boost > 150) )
            if (FALSE)
            {
                int extra_bits;
                int pct_extra = (cpi->gfu_boost - 100) / 50;

                pct_extra = (pct_extra > 20) ? 20 : pct_extra;

                extra_bits = (cpi->gf_group_bits * pct_extra) / 100;
                cpi->gf_group_bits -= extra_bits;
                cpi->per_frame_bandwidth += extra_bits;
            }
        }
    }

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

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

    // Keep a globally available copy of this and the next frame's iiratio.
    cpi->this_iiratio = 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->next_iiratio = next_frame.intra_error /
                                DOUBLE_DIVIDE_CHECK(next_frame.coded_error);
        }
    }

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

    if (cpi->common.current_video_frame == 0)
    {
        cpi->est_max_qcorrection_factor = 1.0;

        // Experimental code to try and 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->total_coded_error_left / frames_left),
                             (int)(cpi->bits_left / frames_left),
                             cpi->common.Height, cpi->common.Width);

            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->maxq_max_limit = cpi->worst_quality;
        cpi->maxq_min_limit = cpi->best_quality;
        tmp_q = estimate_max_q( cpi,
                                (cpi->total_coded_error_left / frames_left),
                                (int)(cpi->bits_left / frames_left),
                                cpi->common.Height,
                                cpi->common.Width);

        // 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->maxq_max_limit = ((tmp_q + 32) < cpi->worst_quality)
                                  ? (tmp_q + 32) : cpi->worst_quality;
        cpi->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->total_stats->count * 255)>>8)) &&
              ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
                  (unsigned int)cpi->total_stats->count) )
    {
        if (frames_left < 1)
            frames_left = 1;

        tmp_q = estimate_max_q(cpi, (cpi->total_coded_error_left / frames_left), (int)(cpi->bits_left / frames_left), cpi->common.Height, cpi->common.Width);

        // 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->frames_to_key --;
    cpi->total_error_left      -= this_frame_error;
    cpi->total_intra_error_left -= this_frame_intra_error;
    cpi->total_coded_error_left -= this_frame_coded_error;
}


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

    // 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 < .25) &&
             ((this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
             ((fabs(last_frame->coded_error - this_frame->coded_error) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > .40) ||
              (fabs(last_frame->intra_error - this_frame->intra_error) / DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > .40) ||
              ((next_frame->intra_error / DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5)
             )
         )
        )
       )
    {
        int i;
        FIRSTPASS_STATS *start_pos;

        FIRSTPASS_STATS local_next_frame;

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

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

        // Note the starting file position so we can reset to it
        start_pos = cpi->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);

            //decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter;

            // 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 < 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 == vp8_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 = TRUE;
        else
        {
            // Reset the file position
            reset_fpf_position(cpi, start_pos);

            is_viable_kf = FALSE;
        }
    }

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

    double decay_accumulator = 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 two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);

    vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean

    vp8_clear_system_state();  //__asm emms;
    start_position = cpi->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 = FALSE;

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

    cpi->frames_to_key = 1;

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

    cpi->kf_group_bits = 0;        // Total bits avaialable to kf group
    cpi->kf_group_error_left = 0;  // Group modified error score.

    kf_mod_err = calculate_modified_err(cpi, this_frame);

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

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

        // load a the next frame's stats
        vpx_memcpy(&last_frame, this_frame, sizeof(*this_frame));
        vp8_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)
        {
            if (test_candidate_kf(cpi, &last_frame, this_frame, &next_frame))
                break;

            // Step on to the next frame
            cpi->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->frames_to_key >= 2 *(int)cpi->key_frame_frequency)
                break;
        } else
            cpi->frames_to_key ++;
    }

    // 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->frames_to_key > (int)cpi->key_frame_frequency )
    {
        FIRSTPASS_STATS *current_pos = cpi->stats_in;
        FIRSTPASS_STATS tmp_frame;

        cpi->frames_to_key /= 2;

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

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

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

        // Rescan to get the correct error data for the forced kf group
        for( i = 0; i < cpi->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
            vp8_input_stats(cpi, &tmp_frame);
        }

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

        cpi->next_key_frame_forced = TRUE;
    }
    else
        cpi->next_key_frame_forced = FALSE;

    // Special case for the last frame of the file
    if (cpi->stats_in >= cpi->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->bits_left > 0) && ((int)cpi->modified_error_left > 0))
    {
        // Max for a single normal frame (not key frame)
        int max_bits = frame_max_bits(cpi);

        // Maximum bits for the kf group
        long long max_grp_bits;

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

        // Clip based on maximum per frame rate defined by the user.
        max_grp_bits = (long long)max_bits * (long long)cpi->frames_to_key;
        if (cpi->kf_group_bits > max_grp_bits)
            cpi->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)
        {
            int opt_buffer_lvl = cpi->oxcf.optimal_buffer_level;
            int 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)
            {
                int high_water_mark = (opt_buffer_lvl +
                                       cpi->oxcf.maximum_buffer_size) >> 1;

                long long av_group_bits;

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

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

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

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

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

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

    // determine how big to make this keyframe based on how well the subsequent frames use inter blocks
    decay_accumulator = 1.0;
    boost_score = 0.0;
    loop_decay_rate = 1.00;       // Starting decay rate

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

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

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

        if (r > RMAX)
            r = RMAX;

        // Adjust loop decay rate
        //if ( next_frame.pcnt_inter < loop_decay_rate )
        loop_decay_rate = next_frame.pcnt_inter;

        // High % motion -> somewhat higher decay rate
        motion_pct = next_frame.pcnt_motion;
        motion_decay = (1.0 - (motion_pct / 20.0));
        if (motion_decay < loop_decay_rate)
            loop_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 < loop_decay_rate)
                loop_decay_rate = distance_factor;
        }

        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;

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

        for (i = 0 ; i < cpi->frames_to_key ; i++)
        {
            vp8_input_stats(cpi, &next_frame);
            vp8_accumulate_stats(&sectionstats, &next_frame);
        }

        vp8_avg_stats(&sectionstats);

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

        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
        // if( (Ratio > 11) ) //&& (sectionstats.pcnt_second_ref < .20) )
        //{
        cpi->section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);

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

        //}
        //else
        //    cpi->section_max_qfactor = 1.0;
    }

    // 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 = 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 = boost_score;
        int allocation_chunks;
        int Counter = cpi->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);

        kf_boost = (int)((double)kf_boost * 100.0) >> 4;                          // Scale 16 to 100

        // Adjustment to boost based on recent average q
        //kf_boost = kf_boost * vp8_kf_boost_qadjustment[cpi->ni_av_qi] / 100;

        if (kf_boost < 250)                                                      // Min KF boost
            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

        allocation_chunks = ((cpi->frames_to_key - 1) * 100) + kf_boost;           // cpi->frames_to_key-1 because key frame itself is taken care of by kf_boost

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

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

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

        // Apply an additional limit for CBR
        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
        {
            if (cpi->kf_bits > ((3 * cpi->buffer_level) >> 2))
                cpi->kf_bits = (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->frames_to_key)
        {
            double  alt_kf_grp_bits =
                        ((double)cpi->bits_left *
                         (kf_mod_err * (double)cpi->frames_to_key) /
                         DOUBLE_DIVIDE_CHECK(cpi->modified_error_left));

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

            if (cpi->kf_bits > alt_kf_bits)
            {
                cpi->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->bits_left *
                      (kf_mod_err /
                       DOUBLE_DIVIDE_CHECK(cpi->modified_error_left)));

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

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

        cpi->per_frame_bandwidth = cpi->kf_bits;                                           // Peer frame bit target for this frame
        cpi->target_bandwidth = cpi->kf_bits * cpi->output_frame_rate;                      // Convert to a per second bitrate
    }

    // Note the total error score of the kf group minus the key frame itself
    cpi->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->modified_error_left -= kf_group_err;

    if (cpi->oxcf.allow_spatial_resampling)
    {
        int resample_trigger = FALSE;
        int last_kf_resampled = FALSE;
        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 = cpi->buffer_level;
        int tmp_q;

        double projected_bits_perframe;
        double group_iiratio = (kf_group_intra_err - first_frame.intra_error) / (kf_group_coded_err - first_frame.coded_error);
        double err_per_frame = kf_group_err / cpi->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 = TRUE;

        // 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->bits_left/(double)(cpi->total_stats->count - cpi->common.current_video_frame);
        av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate);
        //if ( av_bits_per_frame < 0.0 )
        //  av_bits_per_frame = 0.0

        // 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 sectoion or average bitrate for sequence
        else
        {
            bits_per_frame = cpi->kf_group_bits / cpi->frames_to_key;     // This accounts for how hard the section is...

            if (bits_per_frame < av_bits_per_frame)                      // Dont turn to resampling in easy sections just because they have been assigned a small number of bits
                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, bits_per_frame, new_height, new_width, 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 = cpi->buffer_level - (int)((projected_bits_perframe - av_bits_per_frame) * cpi->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->frames_to_key, (int)(cpi->kf_group_bits / cpi->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))))
                //( ((cpi->buffer_level < (cpi->oxcf.resample_down_water_mark * cpi->oxcf.optimal_buffer_level / 100))) &&
                //  ((projected_buffer_level < (cpi->oxcf.resample_up_water_mark * cpi->oxcf.optimal_buffer_level / 100))) ))
                resample_trigger = TRUE;
            else
                resample_trigger = FALSE;
        }
        else
        {
            long long clip_bits = (long long)(cpi->total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
            long long over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level;
            long long over_spend2 = cpi->oxcf.starting_buffer_level - projected_buffer_level;

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

        }

        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, bits_per_frame, new_height, new_width, 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->frames_to_key, (int)(cpi->kf_group_bits / cpi->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);
        }
    }
}
