/*
 *  Copyright (c) 2010 The VP8 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 <stdio.h>
#include <math.h>
#include <limits.h>
#include <assert.h>
#include "pragmas.h"

#include "tokenize.h"
#include "treewriter.h"
#include "onyx_int.h"
#include "modecosts.h"
#include "encodeintra.h"
#include "entropymode.h"
#include "reconinter.h"
#include "reconintra.h"
#include "reconintra4x4.h"
#include "findnearmv.h"
#include "encodemb.h"
#include "quantize.h"
#include "idct.h"
#include "g_common.h"
#include "variance.h"
#include "mcomp.h"

#include "vpx_mem/vpx_mem.h"
#include "dct.h"
#include "systemdependent.h"

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


void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x);


#define RDFUNC(RM,DM,R,D,target_rd) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )
/*int  RDFUNC( int RM,int DM, int R, int D, int target_r )
{
    int rd_value;

    rd_value =  ( ((128+(R)*(RM)) >> 8) + (DM)*(D) );

    return rd_value;
}*/

#define UVRDFUNC(RM,DM,R,D,target_r)  RDFUNC(RM,DM,R,D,target_r)

#define RDCOST(RM,DM,R,D) ( ((128+(R)*(RM)) >> 8) + (DM)*(D) )

#define MAXF(a,b)            (((a) > (b)) ? (a) : (b))


extern const TOKENEXTRA vp8_dct_value_tokens[DCT_MAX_VALUE*2];
extern const TOKENEXTRA *vp8_dct_value_tokens_ptr;
extern int vp8_dct_value_cost[DCT_MAX_VALUE*2];
extern int *vp8_dct_value_cost_ptr;


const int vp8_auto_speed_thresh[17] =
{
    1000,
    200,
    150,
    130,
    150,
    125,
    120,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    115,
    105
};

const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] =
{
    ZEROMV,
    DC_PRED,

    NEARESTMV,
    NEARMV,

    ZEROMV,
    NEARESTMV,

    ZEROMV,
    NEARESTMV,

    NEARMV,
    NEARMV,

    V_PRED,
    H_PRED,
    TM_PRED,

    NEWMV,
    NEWMV,
    NEWMV,

    SPLITMV,
    SPLITMV,
    SPLITMV,

    B_PRED,
};

const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] =
{
    LAST_FRAME,
    INTRA_FRAME,

    LAST_FRAME,
    LAST_FRAME,

    GOLDEN_FRAME,
    GOLDEN_FRAME,

    ALTREF_FRAME,
    ALTREF_FRAME,

    GOLDEN_FRAME,
    ALTREF_FRAME,

    INTRA_FRAME,
    INTRA_FRAME,
    INTRA_FRAME,

    LAST_FRAME,
    GOLDEN_FRAME,
    ALTREF_FRAME,

    LAST_FRAME,
    GOLDEN_FRAME,
    ALTREF_FRAME,

    INTRA_FRAME,
};

static void fill_token_costs(
    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens],
    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens-1]
)
{
    int i, j, k;


    for (i = 0; i < BLOCK_TYPES; i++)
        for (j = 0; j < COEF_BANDS; j++)
            for (k = 0; k < PREV_COEF_CONTEXTS; k++)

                vp8_cost_tokens((int *)(c [i][j][k]), p [i][j][k], vp8_coef_tree);

}

static int rd_iifactor [ 32 ] =  {    16,  16,  16,  12,   8,   4,   2,   0,
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                      0,   0,   0,   0,   0,   0,   0,   0,
                                 };




// The values in this table should be reviewed
static int sad_per_bit16lut[128] =
{
    4,  4, 4, 4,  4, 4, 4, 4,   // 4
    4,  4, 4, 4,  4, 4, 4, 4,   // 1
    4,  4, 4, 4,  4, 4, 4, 4,   // 2
    4,  4, 4, 4,  4, 4, 4, 4,   // 3
    4,  4, 4, 4,  4, 4, 4, 4,   // 4
    4,  4, 12, 12, 13, 13, 14, 14, // 5
    14, 14, 14, 15, 15, 15, 15, 15, // 6
    15, 15, 15, 15, 15, 15, 15, 15, // 7
    15, 15, 15, 15, 15, 16, 16, 16, // 8
    16, 16, 18, 18, 18, 18, 19, 19, // 9
    19, 19, 19, 19, 19, 19, 19, 19, // 10
    20, 20, 22, 22, 22, 22, 21, 21, // 11
    22, 22, 22, 22, 22, 22, 22, 22, // 12
    22, 22, 22, 22, 22, 22, 22, 22, // 13
    22, 22, 22, 22, 22, 22, 22, 22, // 14
    22, 22, 22, 22, 22, 22, 22, 22, // 15
};

static int sad_per_bit4lut[128] =
{
    4,  4, 4, 4,  4, 4, 4, 4,   // 4
    4,  4, 4, 4,  4, 4, 4, 4,   // 1
    4,  4, 4, 4,  4, 4, 4, 4,   // 2
    4,  4, 4, 4,  4, 4, 4, 4,   // 3
    4,  4, 4, 4,  4, 4, 4, 4,   // 4
    4,  4, 15, 15, 15, 15, 16, 16, // 5
    16, 17, 17, 17, 17, 17, 17, 17, // 6
    17, 17, 19, 19, 22, 22, 21, 21, // 7
    23, 23, 23, 23, 23, 24, 24, 24, // 8
    25, 25, 27, 27, 27, 27, 28, 28, // 9
    28, 28, 29, 29, 29, 29, 29, 29, // 10
    30, 30, 31, 31, 31, 31, 32, 32, // 11
    34, 34, 34, 34, 34, 34, 34, 34, // 12
    34, 34, 34, 34, 34, 34, 34, 34, // 13
    34, 34, 34, 34, 34, 34, 34, 34, // 14
    34, 34, 34, 34, 34, 34, 34, 34, // 15
};

void vp8cx_initialize_me_consts(VP8_COMP *cpi, int QIndex)
{
    cpi->mb.sadperbit16 =  sad_per_bit16lut[QIndex];
    cpi->mb.sadperbit4  =  sad_per_bit4lut[QIndex];
}

void vp8_initialize_rd_consts(VP8_COMP *cpi, int Qvalue)
{
    int q;
    int i;
    int *thresh;
    int threshmult;

    int capped_q = (Qvalue < 160) ? Qvalue : 160;

    vp8_clear_system_state();  //__asm emms;

    cpi->RDMULT = (int)((0.00007 * (capped_q * capped_q * capped_q * capped_q)) - (0.0125 * (capped_q * capped_q * capped_q)) +
                        (2.25 * (capped_q * capped_q)) - (12.5 * capped_q) + 25.0);

    if (cpi->RDMULT < 25)
        cpi->RDMULT = 25;

    if (cpi->pass == 2)
    {
        if (cpi->common.frame_type == KEY_FRAME)
            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[0]) / 16;
        else if (cpi->next_iiratio > 31)
            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[31]) / 16;
        else
            cpi->RDMULT += (cpi->RDMULT * rd_iifactor[cpi->next_iiratio]) / 16;
    }


    // Extend rate multiplier along side quantizer zbin increases
    if (cpi->zbin_over_quant  > 0)
    {
        // Extend rate multiplier along side quantizer zbin increases
        if (cpi->zbin_over_quant  > 0)
        {
            double oq_factor = pow(1.006,  cpi->zbin_over_quant);

            if (oq_factor > (1.0 + ((double)cpi->zbin_over_quant / 64.0)))
                oq_factor = (1.0 + (double)cpi->zbin_over_quant / 64.0);

            cpi->RDMULT = (int)(oq_factor * cpi->RDMULT);
        }
    }

    cpi->mb.errorperbit = (cpi->RDMULT / 100);

    if (cpi->mb.errorperbit < 1)
        cpi->mb.errorperbit = 1;

    vp8_set_speed_features(cpi);

    if (cpi->common.simpler_lpf)
        cpi->common.filter_type = SIMPLE_LOOPFILTER;

    q = (int)pow(Qvalue, 1.25);

    if (q < 8)
        q = 8;

    if (cpi->ref_frame_flags == VP8_ALT_FLAG)
    {
        thresh      = &cpi->rd_threshes[THR_NEWA];
        threshmult  = cpi->sf.thresh_mult[THR_NEWA];
    }
    else if (cpi->ref_frame_flags == VP8_GOLD_FLAG)
    {
        thresh      = &cpi->rd_threshes[THR_NEWG];
        threshmult  = cpi->sf.thresh_mult[THR_NEWG];
    }
    else
    {
        thresh      = &cpi->rd_threshes[THR_NEWMV];
        threshmult  = cpi->sf.thresh_mult[THR_NEWMV];
    }

    if (cpi->RDMULT > 1000)
    {
        cpi->RDDIV = 1;
        cpi->RDMULT /= 100;

        for (i = 0; i < MAX_MODES; i++)
        {
            if (cpi->sf.thresh_mult[i] < INT_MAX)
            {
                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q / 100;
            }
            else
            {
                cpi->rd_threshes[i] = INT_MAX;
            }

            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
        }
    }
    else
    {
        cpi->RDDIV = 100;

        for (i = 0; i < MAX_MODES; i++)
        {
            if (cpi->sf.thresh_mult[i] < (INT_MAX / q))
            {
                cpi->rd_threshes[i] = cpi->sf.thresh_mult[i] * q;
            }
            else
            {
                cpi->rd_threshes[i] = INT_MAX;
            }

            cpi->rd_baseline_thresh[i] = cpi->rd_threshes[i];
        }
    }

    fill_token_costs(
        cpi->mb.token_costs,
        (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs
    );

    vp8_init_mode_costs(cpi);

}

void vp8_auto_select_speed(VP8_COMP *cpi)
{
    int used = cpi->oxcf.cpu_used;

    int milliseconds_for_compress = (int)(1000000 / cpi->oxcf.frame_rate);

    milliseconds_for_compress = milliseconds_for_compress * (16 - cpi->oxcf.cpu_used) / 16;

#if 0

    if (0)
    {
        FILE *f;

        f = fopen("speed.stt", "a");
        fprintf(f, " %8ld %10ld %10ld %10ld\n",
                cpi->common.current_video_frame, cpi->Speed, milliseconds_for_compress, cpi->avg_pick_mode_time);
        fclose(f);
    }

#endif

    /*
    // this is done during parameter valid check
    if( used > 16)
        used = 16;
    if( used < -16)
        used = -16;
    */

    if (cpi->avg_pick_mode_time < milliseconds_for_compress && (cpi->avg_encode_time - cpi->avg_pick_mode_time) < milliseconds_for_compress)
    {
        if (cpi->avg_pick_mode_time == 0)
        {
            cpi->Speed = 4;
        }
        else
        {
            if (milliseconds_for_compress * 100 < cpi->avg_encode_time * 95)
            {
                cpi->Speed          += 2;
                cpi->avg_pick_mode_time = 0;
                cpi->avg_encode_time = 0;

                if (cpi->Speed > 16)
                {
                    cpi->Speed = 16;
                }
            }

            if (milliseconds_for_compress * 100 > cpi->avg_encode_time * vp8_auto_speed_thresh[cpi->Speed])
            {
                cpi->Speed          -= 1;
                cpi->avg_pick_mode_time = 0;
                cpi->avg_encode_time = 0;

                // In real-time mode, cpi->speed is in [4, 16].
                if (cpi->Speed < 4)        //if ( cpi->Speed < 0 )
                {
                    cpi->Speed = 4;        //cpi->Speed = 0;
                }
            }
        }
    }
    else
    {
        cpi->Speed += 4;

        if (cpi->Speed > 16)
            cpi->Speed = 16;


        cpi->avg_pick_mode_time = 0;
        cpi->avg_encode_time = 0;
    }
}

int vp8_block_error_c(short *coeff, short *dqcoeff)
{
    int i;
    int error = 0;

    for (i = 0; i < 16; i++)
    {
        int this_diff = coeff[i] - dqcoeff[i];
        error += this_diff * this_diff;
    }

    return error;
}

int vp8_mbblock_error_c(MACROBLOCK *mb, int dc)
{
    BLOCK  *be;
    BLOCKD *bd;
    int i, j;
    int berror, error = 0;

    for (i = 0; i < 16; i++)
    {
        be = &mb->block[i];
        bd = &mb->e_mbd.block[i];

        berror = 0;

        for (j = dc; j < 16; j++)
        {
            int this_diff = be->coeff[j] - bd->dqcoeff[j];
            berror += this_diff * this_diff;
        }

        error += berror;
    }

    return error;
}

int vp8_mbuverror_c(MACROBLOCK *mb)
{

    BLOCK  *be;
    BLOCKD *bd;


    int i;
    int error = 0;

    for (i = 16; i < 24; i++)
    {
        be = &mb->block[i];
        bd = &mb->e_mbd.block[i];

        error += vp8_block_error_c(be->coeff, bd->dqcoeff);
    }

    return error;
}

#if !(CONFIG_REALTIME_ONLY)
static int macro_block_max_error(MACROBLOCK *mb)
{
    int error = 0;
    int dc = 0;
    BLOCK  *be;
    int i, j;
    int berror;

    dc = !(mb->e_mbd.mbmi.mode == B_PRED || mb->e_mbd.mbmi.mode == SPLITMV);

    for (i = 0; i < 16; i++)
    {
        be = &mb->block[i];

        berror = 0;

        for (j = dc; j < 16; j++)
        {
            int this_diff = be->coeff[j];
            berror += this_diff * this_diff;
        }

        error += berror;
    }

    for (i = 16; i < 24; i++)
    {
        be = &mb->block[i];
        berror = 0;

        for (j = 0; j < 16; j++)
        {
            int this_diff = be->coeff[j];
            berror += this_diff * this_diff;
        }

        error += berror;
    }

    error <<= 2;

    if (dc)
    {
        be = &mb->block[24];
        berror = 0;

        for (j = 0; j < 16; j++)
        {
            int this_diff = be->coeff[j];
            berror += this_diff * this_diff;
        }

        error += berror;
    }

    error >>= 4;
    return error;
}
#endif

int VP8_UVSSE(MACROBLOCK *x, const vp8_variance_rtcd_vtable_t *rtcd)
{
    unsigned char *uptr, *vptr;
    unsigned char *upred_ptr = (*(x->block[16].base_src) + x->block[16].src);
    unsigned char *vpred_ptr = (*(x->block[20].base_src) + x->block[20].src);
    int uv_stride = x->block[16].src_stride;

    unsigned int sse1 = 0;
    unsigned int sse2 = 0;
    int mv_row;
    int mv_col;
    int offset;
    int pre_stride = x->e_mbd.block[16].pre_stride;

    vp8_build_uvmvs(&x->e_mbd, 0);
    mv_row = x->e_mbd.block[16].bmi.mv.as_mv.row;
    mv_col = x->e_mbd.block[16].bmi.mv.as_mv.col;

    offset = (mv_row >> 3) * pre_stride + (mv_col >> 3);
    uptr = x->e_mbd.pre.u_buffer + offset;
    vptr = x->e_mbd.pre.v_buffer + offset;

    if ((mv_row | mv_col) & 7)
    {
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
        sse2 += sse1;
    }
    else
    {
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(uptr, pre_stride, mv_col & 7, mv_row & 7, upred_ptr, uv_stride, &sse2);
        VARIANCE_INVOKE(rtcd, subpixvar8x8)(vptr, pre_stride, mv_col & 7, mv_row & 7, vpred_ptr, uv_stride, &sse1);
        sse2 += sse1;
    }

    return sse2;

}

#if !(CONFIG_REALTIME_ONLY)
static int cost_coeffs(MACROBLOCK *mb, BLOCKD *b, int type, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
{
    int c = !type;              /* start at coef 0, unless Y with Y2 */
    int eob = b->eob;
    int pt ;    /* surrounding block/prev coef predictor */
    int cost = 0;
    short *qcoeff_ptr = b->qcoeff;

    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);

# define QC( I)  ( qcoeff_ptr [vp8_default_zig_zag1d[I]] )

    for (; c < eob; c++)
    {
        int v = QC(c);
        int t = vp8_dct_value_tokens_ptr[v].Token;
        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [t];
        cost += vp8_dct_value_cost_ptr[v];
        pt = vp8_prev_token_class[t];
    }

# undef QC

    if (c < 16)
        cost += mb->token_costs [type] [vp8_coef_bands[c]] [pt] [DCT_EOB_TOKEN];

    pt = (c != !type); // is eob first coefficient;
    *a = *l = pt;

    return cost;
}

int vp8_rdcost_mby(MACROBLOCK *mb)
{
    int cost = 0;
    int b;
    TEMP_CONTEXT t, t2;
    int type = 0;

    MACROBLOCKD *x = &mb->e_mbd;

    vp8_setup_temp_context(&t, x->above_context[Y1CONTEXT], x->left_context[Y1CONTEXT], 4);
    vp8_setup_temp_context(&t2, x->above_context[Y2CONTEXT], x->left_context[Y2CONTEXT], 1);

    if (x->mbmi.mode == SPLITMV)
        type = 3;

    for (b = 0; b < 16; b++)
        cost += cost_coeffs(mb, x->block + b, type,
                            t.a + vp8_block2above[b], t.l + vp8_block2left[b]);

    if (x->mbmi.mode != SPLITMV)
        cost += cost_coeffs(mb, x->block + 24, 1,
                            t2.a + vp8_block2above[24], t2.l + vp8_block2left[24]);

    return cost;
}


static void rd_pick_intra4x4block(
    VP8_COMP *cpi,
    MACROBLOCK *x,
    BLOCK *be,
    BLOCKD *b,
    B_PREDICTION_MODE *best_mode,
    B_PREDICTION_MODE above,
    B_PREDICTION_MODE left,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,

    int *bestrate,
    int *bestratey,
    int *bestdistortion)
{
    B_PREDICTION_MODE mode;
    int best_rd = INT_MAX;       // 1<<30
    int rate = 0;
    int distortion;
    unsigned int *mode_costs;

    ENTROPY_CONTEXT ta = *a, tempa = *a;
    ENTROPY_CONTEXT tl = *l, templ = *l;


    if (x->e_mbd.frame_type == KEY_FRAME)
    {
        mode_costs  = x->bmode_costs[above][left];
    }
    else
    {
        mode_costs = x->inter_bmode_costs;
    }

    for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++)
    {
        int this_rd;
        int ratey;

        rate = mode_costs[mode];
        vp8_encode_intra4x4block_rd(IF_RTCD(&cpi->rtcd), x, be, b, mode);

        tempa = ta;
        templ = tl;

        ratey = cost_coeffs(x, b, 3, &tempa, &templ);
        rate += ratey;
        distortion = ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)(be->coeff, b->dqcoeff) >> 2;

        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);

        if (this_rd < best_rd)
        {
            *bestrate = rate;
            *bestratey = ratey;
            *bestdistortion = distortion;
            best_rd = this_rd;
            *best_mode = mode;
            *a = tempa;
            *l = templ;
        }
    }

    b->bmi.mode = (B_PREDICTION_MODE)(*best_mode);
    vp8_encode_intra4x4block_rd(IF_RTCD(&cpi->rtcd), x, be, b, b->bmi.mode);

}


int vp8_rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate, int *rate_y, int *Distortion)
{
    MACROBLOCKD *const xd = &mb->e_mbd;
    int i;
    TEMP_CONTEXT t;
    int cost = mb->mbmode_cost [xd->frame_type] [B_PRED];
    int distortion = 0;
    int tot_rate_y = 0;

    vp8_intra_prediction_down_copy(xd);
    vp8_setup_temp_context(&t, xd->above_context[Y1CONTEXT], xd->left_context[Y1CONTEXT], 4);

    for (i = 0; i < 16; i++)
    {
        MODE_INFO *const mic = xd->mode_info_context;
        const int mis = xd->mode_info_stride;
        const B_PREDICTION_MODE A = vp8_above_bmi(mic, i, mis)->mode;
        const B_PREDICTION_MODE L = vp8_left_bmi(mic, i)->mode;
        B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
        int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d);

        rd_pick_intra4x4block(
            cpi, mb, mb->block + i, xd->block + i, &best_mode, A, L,
            t.a + vp8_block2above[i],
            t.l + vp8_block2left[i], &r, &ry, &d);

        cost += r;
        distortion += d;
        tot_rate_y += ry;
        mic->bmi[i].mode = xd->block[i].bmi.mode = best_mode;
    }

    *Rate = cost;
    *rate_y += tot_rate_y;
    *Distortion = distortion;

    return RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
}

int vp8_rd_pick_intra16x16mby_mode(VP8_COMP *cpi, MACROBLOCK *x, int *Rate, int *rate_y, int *Distortion)
{

    MB_PREDICTION_MODE mode;
    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
    int rate, ratey;
    unsigned int distortion;
    int best_rd = INT_MAX;

    //Y Search for 16x16 intra prediction mode
    for (mode = DC_PRED; mode <= TM_PRED; mode++)
    {
        int this_rd;
        int dummy;
        rate = 0;

        x->e_mbd.mbmi.mode = mode;

        rate += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.mode];

        vp8_encode_intra16x16mbyrd(IF_RTCD(&cpi->rtcd), x);

        ratey = vp8_rdcost_mby(x);

        rate += ratey;

        VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer, x->src.y_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride, &distortion, &dummy);

        this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);

        if (this_rd < best_rd)
        {
            mode_selected = mode;
            best_rd = this_rd;
            *Rate = rate;
            *rate_y = ratey;
            *Distortion = (int)distortion;
        }
    }

    x->e_mbd.mbmi.mode = mode_selected;
    return best_rd;
}


static int rd_cost_mbuv(MACROBLOCK *mb)
{
    TEMP_CONTEXT t, t2;
    int b;
    int cost = 0;
    MACROBLOCKD *x = &mb->e_mbd;

    vp8_setup_temp_context(&t, x->above_context[UCONTEXT], x->left_context[UCONTEXT], 2);
    vp8_setup_temp_context(&t2, x->above_context[VCONTEXT], x->left_context[VCONTEXT], 2);

    for (b = 16; b < 20; b++)
        cost += cost_coeffs(mb, x->block + b, vp8_block2type[b],
                            t.a + vp8_block2above[b], t.l + vp8_block2left[b]);

    for (b = 20; b < 24; b++)
        cost += cost_coeffs(mb, x->block + b, vp8_block2type[b],
                            t2.a + vp8_block2above[b], t2.l + vp8_block2left[b]);

    return cost;
}


unsigned int vp8_get_mbuvrecon_error(const vp8_variance_rtcd_vtable_t *rtcd, const MACROBLOCK *x) // sum of squares
{
    unsigned int sse0, sse1;
    int sum0, sum1;
    VARIANCE_INVOKE(rtcd, get8x8var)(x->src.u_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer, x->e_mbd.dst.uv_stride, &sse0, &sum0);
    VARIANCE_INVOKE(rtcd, get8x8var)(x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride, &sse1, &sum1);
    return (sse0 + sse1);
}

static int vp8_rd_inter_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *distortion, int fullpixel)
{
    vp8_build_uvmvs(&x->e_mbd, fullpixel);
    vp8_encode_inter16x16uvrd(IF_RTCD(&cpi->rtcd), x);


    *rate       = rd_cost_mbuv(x);
    *distortion = ENCODEMB_INVOKE(&cpi->rtcd.encodemb, mbuverr)(x) / 4;

    return UVRDFUNC(x->rdmult, x->rddiv, *rate, *distortion, cpi->target_bits_per_mb);
}

int vp8_rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int *distortion)
{
    MB_PREDICTION_MODE mode;
    MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
    int best_rd = INT_MAX;
    int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r);
    int rate_to;

    for (mode = DC_PRED; mode <= TM_PRED; mode++)
    {
        int rate;
        int distortion;
        int this_rd;

        x->e_mbd.mbmi.uv_mode = mode;
        vp8_encode_intra16x16mbuvrd(IF_RTCD(&cpi->rtcd), x);

        rate_to = rd_cost_mbuv(x);
        rate = rate_to + x->intra_uv_mode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.uv_mode];

        distortion = vp8_get_mbuvrecon_error(IF_RTCD(&cpi->rtcd.variance), x);

        this_rd = UVRDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);

        if (this_rd < best_rd)
        {
            best_rd = this_rd;
            d = distortion;
            r = rate;
            *rate_tokenonly = rate_to;
            mode_selected = mode;
        }
    }

    *rate = r;
    *distortion = d;

    x->e_mbd.mbmi.uv_mode = mode_selected;
    return best_rd;
}
#endif

int vp8_cost_mv_ref(MB_PREDICTION_MODE m, const int near_mv_ref_ct[4])
{
    vp8_prob p [VP8_MVREFS-1];
    assert(NEARESTMV <= m  &&  m <= SPLITMV);
    vp8_mv_ref_probs(p, near_mv_ref_ct);
    return vp8_cost_token(vp8_mv_ref_tree, p, VP8_MVREFENCODINGS + m);
}

void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, MV *mv)
{
    int i;

    x->e_mbd.mbmi.mode = mb;
    x->e_mbd.mbmi.mv.as_mv.row = mv->row;
    x->e_mbd.mbmi.mv.as_mv.col = mv->col;

    for (i = 0; i < 16; i++)
    {
        B_MODE_INFO *bmi = &x->e_mbd.block[i].bmi;
        bmi->mode = (B_PREDICTION_MODE) mb;
        bmi->mv.as_mv.row = mv->row;
        bmi->mv.as_mv.col = mv->col;
    }
}

#if !(CONFIG_REALTIME_ONLY)
int vp8_count_labels(int const *labelings)
{
    int i;
    int count = 0;

    for (i = 0; i < 16; i++)
    {
        if (labelings[i] > count)
            count = labelings[i];
    }

    return count + 1;
}


static int labels2mode(
    MACROBLOCK *x,
    int const *labelings, int which_label,
    B_PREDICTION_MODE this_mode,
    MV *this_mv, MV *best_ref_mv,
    int *mvcost[2]
)
{
    MACROBLOCKD *const xd = & x->e_mbd;
    MODE_INFO *const mic = xd->mode_info_context;
    const int mis = xd->mode_info_stride;

    int cost = 0;
    int thismvcost = 0;

    /* We have to be careful retrieving previously-encoded motion vectors.
       Ones from this macroblock have to be pulled from the BLOCKD array
       as they have not yet made it to the bmi array in our MB_MODE_INFO. */

    int i = 0;

    do
    {
        BLOCKD *const d = xd->block + i;
        const int row = i >> 2,  col = i & 3;

        B_PREDICTION_MODE m;

        if (labelings[i] != which_label)
            continue;

        if (col  &&  labelings[i] == labelings[i-1])
            m = LEFT4X4;
        else if (row  &&  labelings[i] == labelings[i-4])
            m = ABOVE4X4;
        else
        {
            // the only time we should do costing for new motion vector or mode
            // is when we are on a new label  (jbb May 08, 2007)
            switch (m = this_mode)
            {
            case NEW4X4 :
                thismvcost  = vp8_mv_bit_cost(this_mv, best_ref_mv, mvcost, 102);
                break;
            case LEFT4X4:
                *this_mv = col ? d[-1].bmi.mv.as_mv : vp8_left_bmi(mic, i)->mv.as_mv;
                break;
            case ABOVE4X4:
                *this_mv = row ? d[-4].bmi.mv.as_mv : vp8_above_bmi(mic, i, mis)->mv.as_mv;
                break;
            case ZERO4X4:
                this_mv->row = this_mv->col = 0;
                break;
            default:
                break;
            }

            if (m == ABOVE4X4)  // replace above with left if same
            {
                const MV mv = col ? d[-1].bmi.mv.as_mv : vp8_left_bmi(mic, i)->mv.as_mv;

                if (mv.row == this_mv->row  &&  mv.col == this_mv->col)
                    m = LEFT4X4;
            }

            cost = x->inter_bmode_costs[ m];
        }

        d->bmi.mode = m;
        d->bmi.mv.as_mv = *this_mv;

    }
    while (++i < 16);

    cost += thismvcost ;
    return cost;
}

static int rdcost_mbsegment_y(MACROBLOCK *mb, const int *labels, int which_label, TEMP_CONTEXT *t)
{
    int cost = 0;
    int b;
    MACROBLOCKD *x = &mb->e_mbd;


    for (b = 0; b < 16; b++)
        if (labels[ b] == which_label)
            cost += cost_coeffs(mb, x->block + b, 3,
                                t->a + vp8_block2above[b],
                                t->l + vp8_block2left[b]);

    return cost;

}
static unsigned int vp8_encode_inter_mb_segment(MACROBLOCK *x, int const *labels, int which_label, const vp8_encodemb_rtcd_vtable_t *rtcd)
{
    int i;
    unsigned int distortion = 0;

    for (i = 0; i < 16; i++)
    {
        if (labels[i] == which_label)
        {
            BLOCKD *bd = &x->e_mbd.block[i];
            BLOCK *be = &x->block[i];


            vp8_build_inter_predictors_b(bd, 16, x->e_mbd.subpixel_predict);
            ENCODEMB_INVOKE(rtcd, subb)(be, bd, 16);
            x->short_fdct4x4rd(be->src_diff, be->coeff, 32);

            // set to 0 no way to account for 2nd order DC so discount
            //be->coeff[0] = 0;
            x->quantize_brd(be, bd);

            distortion += ENCODEMB_INVOKE(rtcd, berr)(be->coeff, bd->dqcoeff);
        }
    }

    return distortion;
}

static void macro_block_yrd(MACROBLOCK *mb, int *Rate, int *Distortion, const vp8_encodemb_rtcd_vtable_t *rtcd)
{
    int b;
    MACROBLOCKD *const x = &mb->e_mbd;
    BLOCK   *const mb_y2 = mb->block + 24;
    BLOCKD *const x_y2  = x->block + 24;
    short *Y2DCPtr = mb_y2->src_diff;
    BLOCK *beptr;
    int d;

    ENCODEMB_INVOKE(rtcd, submby)(mb->src_diff, mb->src.y_buffer, mb->e_mbd.predictor, mb->src.y_stride);

    // Fdct and building the 2nd order block
    for (beptr = mb->block; beptr < mb->block + 16; beptr += 2)
    {
        mb->short_fdct8x4rd(beptr->src_diff, beptr->coeff, 32);
        *Y2DCPtr++ = beptr->coeff[0];
        *Y2DCPtr++ = beptr->coeff[16];
    }

    // 2nd order fdct
    if (x->mbmi.mode != SPLITMV)
    {
        mb->short_walsh4x4(mb_y2->src_diff, mb_y2->coeff, 8);
    }

    // Quantization
    for (b = 0; b < 16; b++)
    {
        mb->quantize_brd(&mb->block[b], &mb->e_mbd.block[b]);
    }

    // DC predication and Quantization of 2nd Order block
    if (x->mbmi.mode != SPLITMV)
    {

        {
            mb->quantize_brd(mb_y2, x_y2);
        }
    }

    // Distortion
    if (x->mbmi.mode == SPLITMV)
        d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 0) << 2;
    else
    {
        d = ENCODEMB_INVOKE(rtcd, mberr)(mb, 1) << 2;
        d += ENCODEMB_INVOKE(rtcd, berr)(mb_y2->coeff, x_y2->dqcoeff);
    }

    *Distortion = (d >> 4);

    // rate
    *Rate = vp8_rdcost_mby(mb);
}

static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, MV *best_ref_mv, int best_rd, int *mdcounts, int *returntotrate, int *returnyrate, int *returndistortion, int compressor_speed, int *mvcost[2], int mvthresh, int fullpixel)
{
    int i, segmentation;
    B_PREDICTION_MODE this_mode;
    MACROBLOCKD *xc = &x->e_mbd;
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    BLOCK *c = &x->block[0];
    BLOCKD *e = &x->e_mbd.block[0];
    int const *labels;
    int best_segment_rd = INT_MAX;
    int best_seg = 0;
    int br = 0;
    int bd = 0;
    int bsr = 0;
    int bsd = 0;
    int bestsegmentyrate = 0;

    // FIX TO Rd error outrange bug PGW 9 june 2004
    B_PREDICTION_MODE bmodes[16] = {ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4,
                                    ZERO4X4, ZERO4X4, ZERO4X4, ZERO4X4
                                   };

    MV bmvs[16];
    int beobs[16];

    for (segmentation = 0; segmentation < VP8_NUMMBSPLITS; segmentation++)
    {
        int label_count;
        int this_segment_rd = 0;
        int label_mv_thresh;
        int rate = 0;
        int sbr = 0;
        int sbd = 0;
        int UNINITIALIZED_IS_SAFE(sseshift);
        int segmentyrate = 0;

        vp8_variance_fn_ptr_t v_fn_ptr;

        TEMP_CONTEXT t;
        TEMP_CONTEXT tb;
        vp8_setup_temp_context(&t, xc->above_context[Y1CONTEXT], xc->left_context[Y1CONTEXT], 4);

        br = 0;
        bd = 0;

        switch (segmentation)
        {
        case 0:
            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x8);
            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar16x8);
            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8);
            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8x3);
            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x8x4d);
            sseshift = 3;
            break;
        case 1:
            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var8x16);
            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar8x16);
            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16);
            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16x3);
            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x16x4d);
            sseshift = 3;
            break;
        case 2:
            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var8x8);
            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar8x8);
            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8);
            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8x3);
            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad8x8x4d);
            sseshift = 2;
            break;
        case 3:
            v_fn_ptr.vf    = VARIANCE_INVOKE(&cpi->rtcd.variance, var4x4);
            v_fn_ptr.svf   = VARIANCE_INVOKE(&cpi->rtcd.variance, subpixvar4x4);
            v_fn_ptr.sdf   = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4);
            v_fn_ptr.sdx3f = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4x3);
            v_fn_ptr.sdx4df = VARIANCE_INVOKE(&cpi->rtcd.variance, sad4x4x4d);
            sseshift = 0;
            break;
        }

        labels = vp8_mbsplits[segmentation];
        label_count = vp8_count_labels(labels);

        // 64 makes this threshold really big effectively
        // making it so that we very rarely check mvs on
        // segments.   setting this to 1 would make mv thresh
        // roughly equal to what it is for macroblocks
        label_mv_thresh = 1 * mvthresh / label_count ;

        // Segmentation method overheads
        rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation);

        rate += vp8_cost_mv_ref(SPLITMV, mdcounts);

        this_segment_rd += RDFUNC(x->rdmult, x->rddiv, rate, 0, cpi->target_bits_per_mb);
        br += rate;

        for (i = 0; i < label_count; i++)
        {
            MV mode_mv[B_MODE_COUNT];
            int best_label_rd = INT_MAX;
            B_PREDICTION_MODE mode_selected = ZERO4X4;
            int j;
            int bestlabelyrate = 0;

            b = &x->block[0];
            d = &x->e_mbd.block[0];


            // find first label
            for (j = 0; j < 16; j++)
                if (labels[j] == i)
                    break;

            c = &x->block[j];
            e = &x->e_mbd.block[j];

            // search for the best motion vector on this segment
            for (this_mode = LEFT4X4; this_mode <= NEW4X4 ; this_mode ++)
            {
                int distortion;
                int this_rd;
                int num00;
                int labelyrate;

                TEMP_CONTEXT ts;
                vp8_setup_temp_context(&ts, &t.a[0], &t.l[0], 4);

                if (this_mode == NEW4X4)
                {
                    int step_param = 0;
                    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
                    int n;
                    int thissme;
                    int bestsme = INT_MAX;
                    MV  temp_mv;

                    // Is the best so far sufficiently good that we cant justify doing and new motion search.
                    if (best_label_rd < label_mv_thresh)
                        break;

                    {
                        int sadpb = x->sadperbit4;

                        if (cpi->sf.search_method == HEX)
                            bestsme = vp8_hex_search(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb/*x->errorperbit*/, &num00, v_fn_ptr.vf, v_fn_ptr.sdf, x->mvsadcost, mvcost);
                        else
                        {
                            bestsme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &mode_mv[NEW4X4], step_param, sadpb / 2/*x->errorperbit*/, &num00, &v_fn_ptr, x->mvsadcost, mvcost);

                            n = num00;
                            num00 = 0;

                            while (n < further_steps)
                            {
                                n++;

                                if (num00)
                                    num00--;
                                else
                                {
                                    thissme = cpi->diamond_search_sad(x, c, e, best_ref_mv, &temp_mv, step_param + n, sadpb / 2/*x->errorperbit*/, &num00, &v_fn_ptr, x->mvsadcost, mvcost);

                                    if (thissme < bestsme)
                                    {
                                        bestsme = thissme;
                                        mode_mv[NEW4X4].row = temp_mv.row;
                                        mode_mv[NEW4X4].col = temp_mv.col;
                                    }
                                }
                            }
                        }

                        // Should we do a full search (best quality only)
                        if ((compressor_speed == 0) && (bestsme >> sseshift) > 4000)
                        {
                            thissme = cpi->full_search_sad(x, c, e, best_ref_mv, sadpb / 4, 16, &v_fn_ptr, x->mvcost, x->mvsadcost);

                            if (thissme < bestsme)
                            {
                                bestsme = thissme;
                                mode_mv[NEW4X4] = e->bmi.mv.as_mv;
                            }
                            else
                            {
                                // The full search result is actually worse so re-instate the previous best vector
                                e->bmi.mv.as_mv = mode_mv[NEW4X4];
                            }
                        }
                    }

                    if (bestsme < INT_MAX)
                    {
                        if (!fullpixel)
                            cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit / 2, v_fn_ptr.svf, v_fn_ptr.vf, mvcost);
                        else
                            vp8_skip_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], best_ref_mv, x->errorperbit, v_fn_ptr.svf, v_fn_ptr.vf, mvcost);
                    }
                }

                rate = labels2mode(x, labels, i, this_mode, &mode_mv[this_mode], best_ref_mv, mvcost);

                // Trap vectors that reach beyond the UMV borders
                if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
                    ((mode_mv[this_mode].col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].col >> 3) > x->mv_col_max))
                {
                    continue;
                }

                distortion = vp8_encode_inter_mb_segment(x, labels, i, IF_RTCD(&cpi->rtcd.encodemb)) / 4;

                labelyrate = rdcost_mbsegment_y(x, labels, i, &ts);
                rate += labelyrate;

                this_rd = RDFUNC(x->rdmult, x->rddiv, rate, distortion, cpi->target_bits_per_mb);

                if (this_rd < best_label_rd)
                {
                    sbr = rate;
                    sbd = distortion;
                    bestlabelyrate = labelyrate;
                    mode_selected = this_mode;
                    best_label_rd = this_rd;
                    vp8_setup_temp_context(&tb, &ts.a[0], &ts.l[0], 4);

                }
            }

            vp8_setup_temp_context(&t, &tb.a[0], &tb.l[0], 4);

            labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected], best_ref_mv, mvcost);

            br += sbr;
            bd += sbd;
            segmentyrate += bestlabelyrate;
            this_segment_rd += best_label_rd;

            if ((this_segment_rd > best_rd) || (this_segment_rd > best_segment_rd))
                break;
        }

        if ((this_segment_rd <= best_rd) && (this_segment_rd < best_segment_rd))
        {
            bsr = br;
            bsd = bd;
            bestsegmentyrate = segmentyrate;
            best_segment_rd = this_segment_rd;
            best_seg = segmentation;

            // store everything needed to come back to this!!
            for (i = 0; i < 16; i++)
            {
                BLOCKD *bd = &x->e_mbd.block[i];

                bmvs[i] = bd->bmi.mv.as_mv;
                bmodes[i] = bd->bmi.mode;
                beobs[i] = bd->eob;
            }
        }
    }

    // set it to the best
    for (i = 0; i < 16; i++)
    {
        BLOCKD *bd = &x->e_mbd.block[i];

        bd->bmi.mv.as_mv = bmvs[i];
        bd->bmi.mode = bmodes[i];
        bd->eob = beobs[i];
    }

    // Trap cases where the best split mode has all vectors coded 0,0 (or all the same)
    if (FALSE)
    {
        int allsame = 1;

        for (i = 1; i < 16; i++)
        {
            if ((bmvs[i].col != bmvs[i-1].col) || (bmvs[i].row != bmvs[i-1].row))
            {
                allsame = 0;
                break;
            }
        }

        if (allsame)
        {
            best_segment_rd = INT_MAX;
        }
    }

    *returntotrate = bsr;
    *returndistortion = bsd;
    *returnyrate = bestsegmentyrate;



    // save partitions
    labels = vp8_mbsplits[best_seg];
    x->e_mbd.mbmi.partitioning = best_seg;
    x->e_mbd.mbmi.partition_count = vp8_count_labels(labels);

    for (i = 0; i < x->e_mbd.mbmi.partition_count; i++)
    {
        int j;

        for (j = 0; j < 16; j++)
        {
            if (labels[j] == i)
                break;
        }

        x->e_mbd.mbmi.partition_bmi[i].mode = x->e_mbd.block[j].bmi.mode;
        x->e_mbd.mbmi.partition_bmi[i].mv.as_mv = x->e_mbd.block[j].bmi.mv.as_mv;
    }

    return best_segment_rd;
}


int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra)
{
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    MACROBLOCKD *xd = &x->e_mbd;
    B_MODE_INFO best_bmodes[16];
    MB_MODE_INFO best_mbmode;
    MV best_ref_mv;
    MV mode_mv[MB_MODE_COUNT];
    MB_PREDICTION_MODE this_mode;
    int num00;
    int best_mode_index = 0;

    int i;
    int mode_index;
    int mdcounts[4];
    int rate;
    int distortion;
    int best_rd = INT_MAX; // 1 << 30;
    int ref_frame_cost[MAX_REF_FRAMES];
    int rate2, distortion2;
    int uv_intra_rate, uv_intra_distortion, uv_intra_rate_tokenonly;
    int rate_y, UNINITIALIZED_IS_SAFE(rate_uv);

    //int all_rds[MAX_MODES];        // Experimental debug code.
    //int all_rates[MAX_MODES];
    //int all_dist[MAX_MODES];
    //int intermodecost[MAX_MODES];

    MB_PREDICTION_MODE uv_intra_mode;
    int sse;
    int sum;
    int uvintra_eob = 0;
    int tteob = 0;
    int force_no_skip = 0;

    *returnintra = INT_MAX;

    cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame

    x->skip = 0;

    ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cpi->prob_intra_coded);

    // Experimental code
    // Adjust the RD multiplier based on the best case distortion we saw in the most recently coded mb
    //if ( (cpi->last_mb_distortion) > 0 && (cpi->target_bits_per_mb > 0) )
    /*{
        int tmprdmult;

        //tmprdmult = (cpi->last_mb_distortion * 256) / ((cpi->av_per_frame_bandwidth*256)/cpi->common.MBs);
        tmprdmult = (cpi->last_mb_distortion * 256) / cpi->target_bits_per_mb;
        //tmprdmult = tmprdmult;

        //if ( tmprdmult > cpi->RDMULT * 2 )
        //  tmprdmult = cpi->RDMULT * 2;
        //else if ( tmprdmult < cpi->RDMULT / 2 )
        //  tmprdmult = cpi->RDMULT / 2;

        //tmprdmult = (tmprdmult < 25) ? 25 : tmprdmult;

        //x->rdmult = tmprdmult;

    }*/

    // Special case treatment when GF and ARF are not sensible options for reference
    if (cpi->ref_frame_flags == VP8_LAST_FLAG)
    {
        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_zero(255);
        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_one(255)
                                        + vp8_cost_zero(128);
        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_one(255)
                                        + vp8_cost_one(128);
    }
    else
    {
        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_zero(cpi->prob_last_coded);
        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_one(cpi->prob_last_coded)
                                        + vp8_cost_zero(cpi->prob_gf_coded);
        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cpi->prob_intra_coded)
                                        + vp8_cost_one(cpi->prob_last_coded)
                                        + vp8_cost_one(cpi->prob_gf_coded);
    }

    vpx_memset(mode_mv, 0, sizeof(mode_mv));

    x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
    vp8_rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
    uv_intra_mode = x->e_mbd.mbmi.uv_mode;
    {
        uvintra_eob = 0;

        for (i = 16; i < 24; i++)
            uvintra_eob += x->e_mbd.block[i].eob;
    }

    for (mode_index = 0; mode_index < MAX_MODES; mode_index++)
    {
        int frame_cost;
        int this_rd = INT_MAX;
        int lf_or_gf = 0;           // Lat Frame (01) or gf/arf (1)
        int disable_skip = 0;

        force_no_skip = 0;

        // Experimental debug code.
        // Record of rd values recorded for this MB. -1 indicates not measured
        //all_rds[mode_index] = -1;
        //all_rates[mode_index] = -1;
        //all_dist[mode_index] = -1;
        //intermodecost[mode_index] = -1;  

        // Test best rd so far against threshold for trying this mode.
        if (best_rd <= cpi->rd_threshes[mode_index])
            continue;



        // These variables hold are rolling total cost and distortion for this mode
        rate2 = 0;
        distortion2 = 0;

        // Where skip is allowable add in the default per mb cost for the no skip case.
        // where we then decide to skip we have to delete this and replace it with the
        // cost of signallying a skip
        if (cpi->common.mb_no_coeff_skip)
        {
            rate2 += vp8_cost_bit(cpi->prob_skip_false, 0);
        }

        this_mode = vp8_mode_order[mode_index];

        x->e_mbd.mbmi.mode = this_mode;
        x->e_mbd.mbmi.uv_mode = DC_PRED;
        x->e_mbd.mbmi.ref_frame = vp8_ref_frame_order[mode_index];

        //Only consider ZEROMV/ALTREF_FRAME for alt ref frame.
        if (cpi->is_src_frame_alt_ref)
        {
            if (this_mode != ZEROMV || x->e_mbd.mbmi.ref_frame != ALTREF_FRAME)
                continue;
        }

        if (x->e_mbd.mbmi.ref_frame == LAST_FRAME)
        {
            if (!(cpi->ref_frame_flags & VP8_LAST_FLAG))
                continue;

            lf_or_gf = 0;  // Local last frame vs Golden frame flag

            // Set up pointers for this macro block into the previous frame recon buffer
            x->e_mbd.pre.y_buffer = cpi->common.last_frame.y_buffer + recon_yoffset;
            x->e_mbd.pre.u_buffer = cpi->common.last_frame.u_buffer + recon_uvoffset;
            x->e_mbd.pre.v_buffer = cpi->common.last_frame.v_buffer + recon_uvoffset;
        }
        else if (x->e_mbd.mbmi.ref_frame == GOLDEN_FRAME)
        {

            // not supposed to reference gold frame
            if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG))
                continue;

            lf_or_gf = 1;  // Local last frame vs Golden frame flag

            // Set up pointers for this macro block into the previous frame recon buffer
            x->e_mbd.pre.y_buffer = cpi->common.golden_frame.y_buffer + recon_yoffset;
            x->e_mbd.pre.u_buffer = cpi->common.golden_frame.u_buffer + recon_uvoffset;
            x->e_mbd.pre.v_buffer = cpi->common.golden_frame.v_buffer + recon_uvoffset;
        }
        else if (x->e_mbd.mbmi.ref_frame == ALTREF_FRAME)
        {
            // not supposed to reference alt ref frame
            if (!(cpi->ref_frame_flags & VP8_ALT_FLAG))
                continue;

            //if ( !cpi->source_alt_ref_active )
            //  continue;

            lf_or_gf = 1;  // Local last frame vs Golden frame flag

            // Set up pointers for this macro block into the previous frame recon buffer
            x->e_mbd.pre.y_buffer = cpi->common.alt_ref_frame.y_buffer + recon_yoffset;
            x->e_mbd.pre.u_buffer = cpi->common.alt_ref_frame.u_buffer + recon_uvoffset;
            x->e_mbd.pre.v_buffer = cpi->common.alt_ref_frame.v_buffer + recon_uvoffset;
        }

        vp8_find_near_mvs(&x->e_mbd,
                          x->e_mbd.mode_info_context,
                          &mode_mv[NEARESTMV], &mode_mv[NEARMV], &best_ref_mv,
                          mdcounts, x->e_mbd.mbmi.ref_frame, cpi->common.ref_frame_sign_bias);


        // Estimate the reference frame signaling cost and add it to the rolling cost variable.
        frame_cost = ref_frame_cost[x->e_mbd.mbmi.ref_frame];
        rate2 += frame_cost;

        if (this_mode <= B_PRED)
        {
            for (i = 0; i < 16; i++)
            {
                vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
            }
        }

        // Check to see if the testing frequency for this mode is at its max
        // If so then prevent it from being tested and increase the threshold for its testing
        if (cpi->mode_test_hit_counts[mode_index] && (cpi->mode_check_freq[mode_index] > 1))
        {
            if (cpi->mbs_tested_so_far  <= cpi->mode_check_freq[mode_index] * cpi->mode_test_hit_counts[mode_index])
            {
                // Increase the threshold for coding this mode to make it less likely to be chosen
                cpi->rd_thresh_mult[mode_index] += 4;

                if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
                    cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;

                cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];

                continue;
            }
        }

        // We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
        cpi->mode_test_hit_counts[mode_index] ++;

        // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
        if (cpi->zbin_mode_boost_enabled)
        {
            if ((vp8_mode_order[mode_index] == ZEROMV) && (vp8_ref_frame_order[mode_index] != LAST_FRAME))
                cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
            else
                cpi->zbin_mode_boost = 0;

            vp8cx_mb_init_quantizer(cpi, x);
        }

        switch (this_mode)
        {
        case B_PRED:

            // Note the rate value returned here includes the cost of coding the BPRED mode : x->mbmode_cost[x->e_mbd.frame_type][BPRED];
            vp8_rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y, &distortion);
            rate2 += rate;
            //rate_y = rate;
            distortion2 += distortion;
            rate2 += uv_intra_rate;
            rate_uv = uv_intra_rate_tokenonly;
            distortion2 += uv_intra_distortion;
            break;

        case SPLITMV:
        {
            int frame_cost_rd = RDFUNC(x->rdmult, x->rddiv, frame_cost, 0, cpi->target_bits_per_mb);
            int saved_rate = rate2;

            // vp8_rd_pick_best_mbsegmentation looks only at Y and does not account for frame_cost.
            // (best_rd - frame_cost_rd) is thus a conservative breakout number.
            int breakout_rd = best_rd - frame_cost_rd;
            int tmp_rd;

            if (x->e_mbd.mbmi.ref_frame == LAST_FRAME)
                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWMV], cpi->common.full_pixel) ;
            else if (x->e_mbd.mbmi.ref_frame == GOLDEN_FRAME)
                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWG], cpi->common.full_pixel) ;
            else
                tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, breakout_rd, mdcounts, &rate, &rate_y, &distortion, cpi->compressor_speed, x->mvcost, cpi->rd_threshes[THR_NEWA], cpi->common.full_pixel) ;

            rate2 += rate;
            distortion2 += distortion;

            // If even the 'Y' rd value of split is higher than best so far then dont bother looking at UV
            if (tmp_rd < breakout_rd)
            {
                // Now work out UV cost and add it in
                vp8_rd_inter_uv(cpi, x, &rate, &distortion, cpi->common.full_pixel);
                rate2 += rate;
                rate_uv = rate;
                distortion2 += distortion;

            }
            else
            {
                this_rd = INT_MAX;
                disable_skip = 1;
            }

            // Trap cases where the best split mode has all vectors coded 0,0 (or all the same)
            if (0)
            {
                int allsame = 1;

                for (i = 1; i < 16; i++)
                {
                    BLOCKD *bd = &x->e_mbd.block[i];

                    if (bd->bmi.mv.as_int != x->e_mbd.block[0].bmi.mv.as_int)   //(bmvs[i].col != bmvs[i-1].col) || (bmvs[i].row != bmvs[i-1].row ) )
                    {
                        allsame = 0;
                        break;
                    }
                }

                if (allsame)
                {
                    // reset mode and mv and jump to newmv
                    this_mode = NEWMV;
                    distortion2 = 0;
                    rate2 = saved_rate;
                    mode_mv[NEWMV].row = x->e_mbd.block[0].bmi.mv.as_mv.row;
                    mode_mv[NEWMV].col = x->e_mbd.block[0].bmi.mv.as_mv.col;
                    rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);
                    goto mv_selected;
                }
            }

            // trap cases where the 8x8s can be promoted to 8x16s or 16x8s
            if (0)//x->e_mbd.mbmi.partition_count == 4)
            {

                if (x->e_mbd.mbmi.partition_bmi[0].mv.as_int == x->e_mbd.mbmi.partition_bmi[1].mv.as_int
                    && x->e_mbd.mbmi.partition_bmi[2].mv.as_int == x->e_mbd.mbmi.partition_bmi[3].mv.as_int)
                {
                    const int *labels = vp8_mbsplits[2];
                    x->e_mbd.mbmi.partitioning = 0;
                    rate -= vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + 2);
                    rate += vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings);
                    //rate -=  x->inter_bmode_costs[  x->e_mbd.mbmi.partition_bmi[1]];
                    //rate -=  x->inter_bmode_costs[  x->e_mbd.mbmi.partition_bmi[3]];
                    x->e_mbd.mbmi.partition_bmi[1] = x->e_mbd.mbmi.partition_bmi[2];
                }
            }

        }
        break;
        case DC_PRED:
        case V_PRED:
        case H_PRED:
        case TM_PRED:
            x->e_mbd.mbmi.ref_frame = INTRA_FRAME;
            vp8_build_intra_predictors_mby_ptr(&x->e_mbd);
            {
                macro_block_yrd(x, &rate, &distortion, IF_RTCD(&cpi->rtcd.encodemb)) ;
                rate2 += rate;
                rate_y = rate;
                distortion2 += distortion;
                rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mbmi.mode];
                rate2 += uv_intra_rate;
                rate_uv = uv_intra_rate_tokenonly;
                distortion2 += uv_intra_distortion;
            }
            break;

        case NEWMV:

            // Decrement full search counter
            if (cpi->check_freq[lf_or_gf] > 0)
                cpi->check_freq[lf_or_gf] --;

            {
                int thissme;
                int bestsme = INT_MAX;
                int step_param = cpi->sf.first_step;
                int search_range;
                int further_steps;
                int n;

                // Work out how long a search we should do
                search_range = MAXF(abs(best_ref_mv.col), abs(best_ref_mv.row)) >> 3;

                if (search_range >= x->vector_range)
                    x->vector_range = search_range;
                else if (x->vector_range > cpi->sf.min_fs_radius)
                    x->vector_range--;

                // Initial step/diamond search
                {
                    int sadpb = x->sadperbit16;

                    if (cpi->sf.search_method == HEX)
                    {
                        bestsme = vp8_hex_search(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb/*x->errorperbit*/, &num00, cpi->fn_ptr.vf, cpi->fn_ptr.sdf, x->mvsadcost, x->mvcost);
                        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
                        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
                    }
                    else
                    {
                        bestsme = cpi->diamond_search_sad(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param, sadpb / 2/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb < 9
                        mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
                        mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;

                        // Further step/diamond searches as necessary
                        n = 0;
                        further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;

                        n = num00;
                        num00 = 0;

                        while (n < further_steps)
                        {
                            n++;

                            if (num00)
                                num00--;
                            else
                            {
                                thissme = cpi->diamond_search_sad(x, b, d, &best_ref_mv, &d->bmi.mv.as_mv, step_param + n, sadpb / 4/*x->errorperbit*/, &num00, &cpi->fn_ptr, x->mvsadcost, x->mvcost); //sadpb = 9

                                if (thissme < bestsme)
                                {
                                    bestsme = thissme;
                                    mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
                                    mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;
                                }
                                else
                                {
                                    d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
                                    d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
                                }
                            }
                        }
                    }

                }

                // Should we do a full search
                if (!cpi->check_freq[lf_or_gf] || cpi->do_full[lf_or_gf])
                {
                    int thissme;
                    int full_flag_thresh = 0;

                    // Update x->vector_range based on best vector found in step search
                    search_range = MAXF(abs(d->bmi.mv.as_mv.row), abs(d->bmi.mv.as_mv.col));

                    if (search_range > x->vector_range)
                        x->vector_range = search_range;
                    else
                        search_range = x->vector_range;

                    // Apply limits
                    search_range = (search_range > cpi->sf.max_fs_radius) ? cpi->sf.max_fs_radius : search_range;
                    {
                        int sadpb = x->sadperbit16 >> 2;
                        thissme = cpi->full_search_sad(x, b, d, &best_ref_mv, sadpb, search_range, &cpi->fn_ptr, x->mvcost, x->mvsadcost);
                    }

                    // Barrier threshold to initiating full search
                    // full_flag_thresh = 10 + (thissme >> 7);
                    if ((thissme + full_flag_thresh) < bestsme)
                    {
                        cpi->do_full[lf_or_gf] ++;
                        bestsme = thissme;
                    }
                    else if (thissme < bestsme)
                        bestsme = thissme;
                    else
                    {
                        cpi->do_full[lf_or_gf] = cpi->do_full[lf_or_gf] >> 1;
                        cpi->check_freq[lf_or_gf] = cpi->sf.full_freq[lf_or_gf];

                        // The full search result is actually worse so re-instate the previous best vector
                        d->bmi.mv.as_mv.row = mode_mv[NEWMV].row;
                        d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
                    }
                }

                if (bestsme < INT_MAX)
                    // cpi->find_fractional_mv_step(x,b,d,&d->bmi.mv.as_mv,&best_ref_mv,x->errorperbit/2,cpi->fn_ptr.svf,cpi->fn_ptr.vf,x->mvcost);  // normal mvc=11
                    cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, cpi->fn_ptr.svf, cpi->fn_ptr.vf, x->mvcost);

                mode_mv[NEWMV].row = d->bmi.mv.as_mv.row;
                mode_mv[NEWMV].col = d->bmi.mv.as_mv.col;

                // Add the new motion vector cost to our rolling cost variable
                rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv, x->mvcost, 96);

            }

        case NEARESTMV:
        case NEARMV:

            // Clip "next_nearest" so that it does not extend to far out of image
            if (mode_mv[this_mode].col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN))
                mode_mv[this_mode].col = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
            else if (mode_mv[this_mode].col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN)
                mode_mv[this_mode].col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;

            if (mode_mv[this_mode].row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN))
                mode_mv[this_mode].row = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
            else if (mode_mv[this_mode].row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN)
                mode_mv[this_mode].row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;

            // Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
            if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) &&
                ((mode_mv[this_mode].row == 0) && (mode_mv[this_mode].col == 0)))
                continue;

        case ZEROMV:

        mv_selected:

            // Trap vectors that reach beyond the UMV borders
            // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
            // because of the lack of break statements in the previous two cases.
            if (((mode_mv[this_mode].row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].row >> 3) > x->mv_row_max) ||
                ((mode_mv[this_mode].col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].col >> 3) > x->mv_col_max))
                continue;

            vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]);
            vp8_build_inter_predictors_mby(&x->e_mbd);
            VARIANCE_INVOKE(&cpi->rtcd.variance, get16x16var)(x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, (unsigned int *)(&sse), &sum);

            if (cpi->active_map_enabled && x->active_ptr[0] == 0)
            {
                x->skip = 1;
            }
            else if (sse < x->encode_breakout)
            {
                // Check u and v to make sure skip is ok
                int sse2 = 0;

                sse2 = VP8_UVSSE(x, IF_RTCD(&cpi->rtcd.variance));

                if (sse2 * 2 < x->encode_breakout)
                {
                    x->skip = 1;
                    distortion2 = sse;
                    rate2 = 500;

                    disable_skip = 1;    // We have no real rate data so trying to adjust for rate_y and rate_uv below will cause problems.
                    this_rd = RDFUNC(x->rdmult, x->rddiv, rate2, distortion2, cpi->target_bits_per_mb);

                    break;              // (PGW) Move break here from below - for now at least
                }
                else
                    x->skip = 0;
            }

            //intermodecost[mode_index] = vp8_cost_mv_ref(this_mode, mdcounts);   // Experimental debug code

            // Add in the Mv/mode cost
            rate2 += vp8_cost_mv_ref(this_mode, mdcounts);

            // Y cost and distortion
            macro_block_yrd(x, &rate, &distortion, IF_RTCD(&cpi->rtcd.encodemb));
            rate2 += rate;
            rate_y = rate;
            distortion2 += distortion;

            // UV cost and distortion
            vp8_rd_inter_uv(cpi, x, &rate, &distortion, cpi->common.full_pixel);
            rate2 += rate;
            rate_uv = rate;
            distortion2 += distortion;
            break;

        default:
            break;
        }

        if (!disable_skip)
        {
            // Test for the condition where skip block will be activated because there are no non zero coefficients and make any necessary adjustment for rate
            if (cpi->common.mb_no_coeff_skip)
            {
                tteob = 0;

                for (i = 0; i <= 24; i++)
                {
                    tteob += x->e_mbd.block[i].eob;
                }

                if (tteob == 0)
                {
#if 1
                    rate2 -= (rate_y + rate_uv);

                    // Back out no skip flag costing and add in skip flag costing
                    if (cpi->prob_skip_false)
                    {
                        rate2 += vp8_cost_bit(cpi->prob_skip_false, 1);
                        rate2 -= vp8_cost_bit(cpi->prob_skip_false, 0);
                    }

#else
                    int rateuseskip;
                    int ratenotuseskip;



                    ratenotuseskip = rate_y + rate_uv + vp8_cost_bit(cpi->prob_skip_false, 0);
                    rateuseskip    = vp8_cost_bit(cpi->prob_skip_false, 1);

                    if (1) // rateuseskip<ratenotuseskip)
                    {
                        rate2 -= ratenotuseskip;
                        rate2 += rateuseskip;
                        force_no_skip = 0;
                    }
                    else
                    {
                        force_no_skip = 1;
                    }

#endif
                }

#if             0
                else
                {
                    int rateuseskip;
                    int ratenotuseskip;
                    int maxdistortion;
                    int minrate;
                    int skip_rd;

                    // distortion when no coeff is encoded
                    maxdistortion = macro_block_max_error(x);

                    ratenotuseskip = rate_y + rate_uv + vp8_cost_bit(cpi->prob_skip_false, 0);
                    rateuseskip    = vp8_cost_bit(cpi->prob_skip_false, 1);

                    minrate         = rateuseskip - ratenotuseskip;

                    skip_rd = RDFUNC(x->rdmult, x->rddiv, minrate, maxdistortion - distortion2, cpi->target_bits_per_mb);

                    if (skip_rd + 50 < 0 && x->e_mbd.mbmi.ref_frame != INTRA_FRAME && rate_y + rate_uv < 4000)
                    {
                        force_no_skip = 1;
                        rate2       = rate2 + rateuseskip - ratenotuseskip;
                        distortion2 =  maxdistortion;
                    }
                    else
                    {
                        force_no_skip = 0;
                    }

                }

#endif

            }

            // Calculate the final RD estimate for this mode
            this_rd = RDFUNC(x->rdmult, x->rddiv, rate2, distortion2, cpi->target_bits_per_mb);
        }

        // Experimental debug code.
        //all_rds[mode_index] = this_rd;
        //all_rates[mode_index] = rate2;
        //all_dist[mode_index] = distortion2;

        if ((x->e_mbd.mbmi.ref_frame == INTRA_FRAME)  && (this_rd < *returnintra))
        {
            *returnintra = this_rd ;
        }

        // Did this mode help.. i.i is it the new best mode
        if (this_rd < best_rd || x->skip)
        {
            // Note index of best mode so far
            best_mode_index = mode_index;
            x->e_mbd.mbmi.force_no_skip = force_no_skip;

            if (this_mode <= B_PRED)
            {
                x->e_mbd.mbmi.uv_mode = uv_intra_mode;
            }

            *returnrate = rate2;
            *returndistortion = distortion2;
            best_rd = this_rd;
            vpx_memcpy(&best_mbmode, &x->e_mbd.mbmi, sizeof(MB_MODE_INFO));

            for (i = 0; i < 16; i++)
            {
                vpx_memcpy(&best_bmodes[i], &x->e_mbd.block[i].bmi, sizeof(B_MODE_INFO));
            }

            // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
            cpi->rd_thresh_mult[mode_index] = (cpi->rd_thresh_mult[mode_index] >= (MIN_THRESHMULT + 2)) ? cpi->rd_thresh_mult[mode_index] - 2 : MIN_THRESHMULT;
            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
        }

        // If the mode did not help improve the best error case then raise the threshold for testing that mode next time around.
        else
        {
            cpi->rd_thresh_mult[mode_index] += 4;

            if (cpi->rd_thresh_mult[mode_index] > MAX_THRESHMULT)
                cpi->rd_thresh_mult[mode_index] = MAX_THRESHMULT;

            cpi->rd_threshes[mode_index] = (cpi->rd_baseline_thresh[mode_index] >> 7) * cpi->rd_thresh_mult[mode_index];
        }

        if (x->skip)
            break;
    }

    // Reduce the activation RD thresholds for the best choice mode
    if ((cpi->rd_baseline_thresh[best_mode_index] > 0) && (cpi->rd_baseline_thresh[best_mode_index] < (INT_MAX >> 2)))
    {
        int best_adjustment = (cpi->rd_thresh_mult[best_mode_index] >> 2);

        cpi->rd_thresh_mult[best_mode_index] = (cpi->rd_thresh_mult[best_mode_index] >= (MIN_THRESHMULT + best_adjustment)) ? cpi->rd_thresh_mult[best_mode_index] - best_adjustment : MIN_THRESHMULT;
        cpi->rd_threshes[best_mode_index] = (cpi->rd_baseline_thresh[best_mode_index] >> 7) * cpi->rd_thresh_mult[best_mode_index];

        // If we chose a split mode then reset the new MV thresholds as well
        /*if ( vp8_mode_order[best_mode_index] == SPLITMV )
        {
            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWMV] >> 4);
            cpi->rd_thresh_mult[THR_NEWMV] = (cpi->rd_thresh_mult[THR_NEWMV] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWMV]-best_adjustment: MIN_THRESHMULT;
            cpi->rd_threshes[THR_NEWMV] = (cpi->rd_baseline_thresh[THR_NEWMV] >> 7) * cpi->rd_thresh_mult[THR_NEWMV];

            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWG] >> 4);
            cpi->rd_thresh_mult[THR_NEWG] = (cpi->rd_thresh_mult[THR_NEWG] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWG]-best_adjustment: MIN_THRESHMULT;
            cpi->rd_threshes[THR_NEWG] = (cpi->rd_baseline_thresh[THR_NEWG] >> 7) * cpi->rd_thresh_mult[THR_NEWG];

            best_adjustment = 4; //(cpi->rd_thresh_mult[THR_NEWA] >> 4);
            cpi->rd_thresh_mult[THR_NEWA] = (cpi->rd_thresh_mult[THR_NEWA] >= (MIN_THRESHMULT+best_adjustment)) ? cpi->rd_thresh_mult[THR_NEWA]-best_adjustment: MIN_THRESHMULT;
            cpi->rd_threshes[THR_NEWA] = (cpi->rd_baseline_thresh[THR_NEWA] >> 7) * cpi->rd_thresh_mult[THR_NEWA];
        }*/

    }

    // If we have chosen new mv or split then decay the full search check count more quickly.
    if ((vp8_mode_order[best_mode_index] == NEWMV) || (vp8_mode_order[best_mode_index] == SPLITMV))
    {
        int lf_or_gf = (vp8_ref_frame_order[best_mode_index] == LAST_FRAME) ? 0 : 1;

        if (cpi->check_freq[lf_or_gf] && !cpi->do_full[lf_or_gf])
        {
            cpi->check_freq[lf_or_gf] --;
        }
    }

    // Keep a record of best mode index that we chose
    cpi->last_best_mode_index = best_mode_index;

    // Note how often each mode chosen as best
    cpi->mode_chosen_counts[best_mode_index] ++;


    if (cpi->is_src_frame_alt_ref && (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME))
    {
        best_mbmode.mode = ZEROMV;
        best_mbmode.ref_frame = ALTREF_FRAME;
        best_mbmode.mv.as_int = 0;
        best_mbmode.uv_mode = 0;
        best_mbmode.mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
        best_mbmode.partitioning = 0;
        best_mbmode.dc_diff = 0;

        vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));

        for (i = 0; i < 16; i++)
        {
            vpx_memset(&x->e_mbd.block[i].bmi, 0, sizeof(B_MODE_INFO));
        }

        x->e_mbd.mbmi.mv.as_int = 0;

        return best_rd;
    }


    // macroblock modes
    vpx_memcpy(&x->e_mbd.mbmi, &best_mbmode, sizeof(MB_MODE_INFO));

    for (i = 0; i < 16; i++)
    {
        vpx_memcpy(&x->e_mbd.block[i].bmi, &best_bmodes[i], sizeof(B_MODE_INFO));
    }

    x->e_mbd.mbmi.mv.as_mv = x->e_mbd.block[15].bmi.mv.as_mv;

    return best_rd;
}
#endif

