Merge "Copy macroblock data to a buffer before encoding it"
authorYunqing Wang <yunqingwang@google.com>
Thu, 30 Jun 2011 18:14:24 +0000 (11:14 -0700)
committerCode Review <code-review@webmproject.org>
Thu, 30 Jun 2011 18:14:24 +0000 (11:14 -0700)
1  2 
vp8/encoder/block.h
vp8/encoder/encodeframe.c
vp8/encoder/firstpass.c
vp8/encoder/pickinter.c
vp8/encoder/rdopt.c

diff --combined vp8/encoder/block.h
@@@ -65,7 -65,9 +65,9 @@@ typedef struc
  {
      DECLARE_ALIGNED(16, short, src_diff[400]);       // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
      DECLARE_ALIGNED(16, short, coeff[400]);     // 16x16 Y 8x8 U 8x8 V 4x4 2nd Y
+     DECLARE_ALIGNED(16, unsigned char, thismb[256]);
  
+     unsigned char *thismb_ptr;
      // 16 Y blocks, 4 U blocks, 4 V blocks, 1 DC 2nd order block each with 16 entries
      BLOCK block[25];
  
      unsigned char *active_ptr;
      MV_CONTEXT *mvc;
  
 -    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
 +    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
      int optimize;
      int q_index;
  
@@@ -292,6 -292,9 +292,9 @@@ static void build_activity_map( VP8_COM
              xd->left_available = (mb_col != 0);
              recon_yoffset += 16;
  #endif
+             //Copy current mb to a buffer
+             RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
              // measure activity
              mb_activity = mb_activity_measure( cpi, x, mb_row, mb_col );
  
@@@ -335,8 -338,7 +338,8 @@@ void vp8_activity_masking(VP8_COMP *cpi
  {
  #if USE_ACT_INDEX
      x->rdmult += *(x->mb_activity_ptr) * (x->rdmult >> 2);
 -    x->errorperbit = x->rdmult/x->rddiv;
 +    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
 +    x->errorperbit += (x->errorperbit==0);
  #else
      INT64 a;
      INT64 b;
      b = (2*act) + cpi->activity_avg;
  
      x->rdmult = (unsigned int)(((INT64)x->rdmult*b + (a>>1))/a);
 -    x->errorperbit = x->rdmult/x->rddiv;
 -
 +    x->errorperbit = x->rdmult * 100 /(110 * x->rddiv);
 +    x->errorperbit += (x->errorperbit==0);
  #endif
  
      // Activity based Zbin adjustment
@@@ -432,6 -434,9 +435,9 @@@ void encode_mb_row(VP8_COMP *cpi
          x->rddiv = cpi->RDDIV;
          x->rdmult = cpi->RDMULT;
  
+         //Copy current mb to a buffer
+         RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
  #if CONFIG_MULTITHREAD
          if ((cpi->b_multi_threaded != 0) && (mb_row != 0))
          {
@@@ -1015,14 -1020,18 +1021,18 @@@ void vp8_build_block_offsets(MACROBLOC
      vp8_build_block_doffsets(&x->e_mbd);
  
      // y blocks
+     x->thismb_ptr = &x->thismb[0];
      for (br = 0; br < 4; br++)
      {
          for (bc = 0; bc < 4; bc++)
          {
              BLOCK *this_block = &x->block[block];
-             this_block->base_src = &x->src.y_buffer;
-             this_block->src_stride = x->src.y_stride;
-             this_block->src = 4 * br * this_block->src_stride + 4 * bc;
+             //this_block->base_src = &x->src.y_buffer;
+             //this_block->src_stride = x->src.y_stride;
+             //this_block->src = 4 * br * this_block->src_stride + 4 * bc;
+             this_block->base_src = &x->thismb_ptr;
+             this_block->src_stride = 16;
+             this_block->src = 4 * br * 16 + 4 * bc;
              ++block;
          }
      }
diff --combined vp8/encoder/firstpass.c
@@@ -16,7 -16,6 +16,7 @@@
  #include "encodeintra.h"
  #include "vp8/common/setupintrarecon.h"
  #include "mcomp.h"
 +#include "firstpass.h"
  #include "vpx_scale/vpxscale.h"
  #include "encodemb.h"
  #include "vp8/common/extend.h"
@@@ -50,7 -49,7 +50,7 @@@ extern int vp8_kf_boost_qadjustment[QIN
  
  extern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
  
 -#define IIFACTOR   1.4
 +#define IIFACTOR   1.5
  #define IIKFACTOR1 1.40
  #define IIKFACTOR2 1.5
  #define RMAX       14.0
@@@ -64,8 -63,6 +64,8 @@@
  #define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
  #define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0
  
 +#define NEW_BOOST 1
 +
  static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
  static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};
  
@@@ -99,146 -96,6 +99,146 @@@ static int lookup_next_frame_stats(VP8_
      return 1;
  }
  
 +// Read frame stats at an offset from the current position
 +static int read_frame_stats( VP8_COMP *cpi,
 +                             FIRSTPASS_STATS *frame_stats,
 +                             int offset )
 +{
 +    FIRSTPASS_STATS * fps_ptr = cpi->twopass.stats_in;
 +
 +    // Check legality of offset
 +    if ( offset >= 0 )
 +    {
 +        if ( &fps_ptr[offset] >= cpi->twopass.stats_in_end )
 +             return EOF;
 +    }
 +    else if ( offset < 0 )
 +    {
 +        if ( &fps_ptr[offset] < cpi->twopass.stats_in_start )
 +             return EOF;
 +    }
 +
 +    *frame_stats = fps_ptr[offset];
 +    return 1;
 +}
 +
 +static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
 +{
 +    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
 +        return EOF;
 +
 +    *fps = *cpi->twopass.stats_in;
 +    cpi->twopass.stats_in =
 +         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
 +    return 1;
 +}
 +
 +static void output_stats(const VP8_COMP            *cpi,
 +                         struct vpx_codec_pkt_list *pktlist,
 +                         FIRSTPASS_STATS            *stats)
 +{
 +    struct vpx_codec_cx_pkt pkt;
 +    pkt.kind = VPX_CODEC_STATS_PKT;
 +    pkt.data.twopass_stats.buf = stats;
 +    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
 +    vpx_codec_pkt_list_add(pktlist, &pkt);
 +
 +// TEMP debug code
 +#if OUTPUT_FPF
 +
 +    {
 +        FILE *fpfile;
 +        fpfile = fopen("firstpass.stt", "a");
 +
 +        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
 +                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
 +                " %12.0f %12.4f\n",
 +                stats->frame,
 +                stats->intra_error,
 +                stats->coded_error,
 +                stats->ssim_weighted_pred_err,
 +                stats->pcnt_inter,
 +                stats->pcnt_motion,
 +                stats->pcnt_second_ref,
 +                stats->pcnt_neutral,
 +                stats->MVr,
 +                stats->mvr_abs,
 +                stats->MVc,
 +                stats->mvc_abs,
 +                stats->MVrv,
 +                stats->MVcv,
 +                stats->mv_in_out_count,
 +                stats->count,
 +                stats->duration);
 +        fclose(fpfile);
 +    }
 +#endif
 +}
 +
 +static void zero_stats(FIRSTPASS_STATS *section)
 +{
 +    section->frame      = 0.0;
 +    section->intra_error = 0.0;
 +    section->coded_error = 0.0;
 +    section->ssim_weighted_pred_err = 0.0;
 +    section->pcnt_inter  = 0.0;
 +    section->pcnt_motion  = 0.0;
 +    section->pcnt_second_ref = 0.0;
 +    section->pcnt_neutral = 0.0;
 +    section->MVr        = 0.0;
 +    section->mvr_abs     = 0.0;
 +    section->MVc        = 0.0;
 +    section->mvc_abs     = 0.0;
 +    section->MVrv       = 0.0;
 +    section->MVcv       = 0.0;
 +    section->mv_in_out_count  = 0.0;
 +    section->count      = 0.0;
 +    section->duration   = 1.0;
 +}
 +
 +static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
 +{
 +    section->frame += frame->frame;
 +    section->intra_error += frame->intra_error;
 +    section->coded_error += frame->coded_error;
 +    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
 +    section->pcnt_inter  += frame->pcnt_inter;
 +    section->pcnt_motion += frame->pcnt_motion;
 +    section->pcnt_second_ref += frame->pcnt_second_ref;
 +    section->pcnt_neutral += frame->pcnt_neutral;
 +    section->MVr        += frame->MVr;
 +    section->mvr_abs     += frame->mvr_abs;
 +    section->MVc        += frame->MVc;
 +    section->mvc_abs     += frame->mvc_abs;
 +    section->MVrv       += frame->MVrv;
 +    section->MVcv       += frame->MVcv;
 +    section->mv_in_out_count  += frame->mv_in_out_count;
 +    section->count      += frame->count;
 +    section->duration   += frame->duration;
 +}
 +
 +static void avg_stats(FIRSTPASS_STATS *section)
 +{
 +    if (section->count < 1.0)
 +        return;
 +
 +    section->intra_error /= section->count;
 +    section->coded_error /= section->count;
 +    section->ssim_weighted_pred_err /= section->count;
 +    section->pcnt_inter  /= section->count;
 +    section->pcnt_second_ref /= section->count;
 +    section->pcnt_neutral /= section->count;
 +    section->pcnt_motion /= section->count;
 +    section->MVr        /= section->count;
 +    section->mvr_abs     /= section->count;
 +    section->MVc        /= section->count;
 +    section->mvc_abs     /= section->count;
 +    section->MVrv       /= section->count;
 +    section->MVcv       /= section->count;
 +    section->mv_in_out_count   /= section->count;
 +    section->duration   /= section->count;
 +}
 +
  // Calculate a modified Error used in distributing bits between easier and harder frames
  static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
  {
@@@ -357,33 -214,58 +357,33 @@@ static int frame_max_bits(VP8_COMP *cpi
      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)
      {
 -        max_bits = 2 * cpi->av_per_frame_bandwidth;
 -        max_bits -= cpi->buffered_av_per_frame_bandwidth;
 -        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
 -    }
 -    // VBR
 -    else
 -    {
 -        // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
 -        max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
 -    }
 +        double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
  
 -    // Trap case where we are out of bits
 -    if (max_bits < 0)
 -        max_bits = 0;
 -
 -    return max_bits;
 -}
 +        // 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;
  
 -static int gf_group_max_bits(VP8_COMP *cpi)
 -{
 -    // Max allocation for a golden frame group
 -    int max_bits;
 +            max_bits = (int)(max_bits * buffer_fullness_ratio);
  
 -    // For CBR we need to also consider buffer fullness.
 -    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
 -    {
 -        max_bits = cpi->av_per_frame_bandwidth * cpi->baseline_gf_interval;
 -        if (max_bits > cpi->oxcf.optimal_buffer_level)
 -        {
 -            max_bits -= cpi->oxcf.optimal_buffer_level;
 -            max_bits += cpi->buffer_level;
 +            if (max_bits < min_max_bits)
 +                max_bits = min_max_bits;       // Lowest value we will set ... which should allow the buffer to refil.
          }
 -        else
 -        {
 -            max_bits -= (cpi->buffered_av_per_frame_bandwidth
 -                         - cpi->av_per_frame_bandwidth)
 -                        * cpi->baseline_gf_interval;
 -        }
 -
 -        max_bits *= ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0);
      }
 +    // VBR
      else
      {
          // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
          max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
 -        max_bits *=  cpi->baseline_gf_interval;
      }
  
 -
      // Trap case where we are out of bits
      if (max_bits < 0)
          max_bits = 0;
      return max_bits;
  }
  
 -
 -static void output_stats(const VP8_COMP            *cpi,
 -                         struct vpx_codec_pkt_list *pktlist,
 -                         FIRSTPASS_STATS            *stats)
 -{
 -    struct vpx_codec_cx_pkt pkt;
 -    pkt.kind = VPX_CODEC_STATS_PKT;
 -    pkt.data.twopass_stats.buf = stats;
 -    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
 -    vpx_codec_pkt_list_add(pktlist, &pkt);
 -
 -// TEMP debug code
 -#if OUTPUT_FPF
 -
 -    {
 -        FILE *fpfile;
 -        fpfile = fopen("firstpass.stt", "a");
 -
 -        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
 -                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
 -                " %12.0f %12.4f\n",
 -                stats->frame,
 -                stats->intra_error,
 -                stats->coded_error,
 -                stats->ssim_weighted_pred_err,
 -                stats->pcnt_inter,
 -                stats->pcnt_motion,
 -                stats->pcnt_second_ref,
 -                stats->pcnt_neutral,
 -                stats->MVr,
 -                stats->mvr_abs,
 -                stats->MVc,
 -                stats->mvc_abs,
 -                stats->MVrv,
 -                stats->MVcv,
 -                stats->mv_in_out_count,
 -                stats->count,
 -                stats->duration);
 -        fclose(fpfile);
 -    }
 -#endif
 -}
 -
 -static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
 -{
 -    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
 -        return EOF;
 -
 -    *fps = *cpi->twopass.stats_in;
 -    cpi->twopass.stats_in =
 -         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
 -    return 1;
 -}
 -
 -static void zero_stats(FIRSTPASS_STATS *section)
 -{
 -    section->frame      = 0.0;
 -    section->intra_error = 0.0;
 -    section->coded_error = 0.0;
 -    section->ssim_weighted_pred_err = 0.0;
 -    section->pcnt_inter  = 0.0;
 -    section->pcnt_motion  = 0.0;
 -    section->pcnt_second_ref = 0.0;
 -    section->pcnt_neutral = 0.0;
 -    section->MVr        = 0.0;
 -    section->mvr_abs     = 0.0;
 -    section->MVc        = 0.0;
 -    section->mvc_abs     = 0.0;
 -    section->MVrv       = 0.0;
 -    section->MVcv       = 0.0;
 -    section->mv_in_out_count  = 0.0;
 -    section->count      = 0.0;
 -    section->duration   = 1.0;
 -}
 -static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
 -{
 -    section->frame += frame->frame;
 -    section->intra_error += frame->intra_error;
 -    section->coded_error += frame->coded_error;
 -    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
 -    section->pcnt_inter  += frame->pcnt_inter;
 -    section->pcnt_motion += frame->pcnt_motion;
 -    section->pcnt_second_ref += frame->pcnt_second_ref;
 -    section->pcnt_neutral += frame->pcnt_neutral;
 -    section->MVr        += frame->MVr;
 -    section->mvr_abs     += frame->mvr_abs;
 -    section->MVc        += frame->MVc;
 -    section->mvc_abs     += frame->mvc_abs;
 -    section->MVrv       += frame->MVrv;
 -    section->MVcv       += frame->MVcv;
 -    section->mv_in_out_count  += frame->mv_in_out_count;
 -    section->count      += frame->count;
 -    section->duration   += frame->duration;
 -}
 -static void avg_stats(FIRSTPASS_STATS *section)
 -{
 -    if (section->count < 1.0)
 -        return;
 -
 -    section->intra_error /= section->count;
 -    section->coded_error /= section->count;
 -    section->ssim_weighted_pred_err /= section->count;
 -    section->pcnt_inter  /= section->count;
 -    section->pcnt_second_ref /= section->count;
 -    section->pcnt_neutral /= section->count;
 -    section->pcnt_motion /= section->count;
 -    section->MVr        /= section->count;
 -    section->mvr_abs     /= section->count;
 -    section->MVc        /= section->count;
 -    section->mvc_abs     /= section->count;
 -    section->MVrv       /= section->count;
 -    section->MVcv       /= section->count;
 -    section->mv_in_out_count   /= section->count;
 -    section->duration   /= section->count;
 -}
 -
  void vp8_init_first_pass(VP8_COMP *cpi)
  {
      zero_stats(cpi->twopass.total_stats);
@@@ -579,6 -577,9 +579,9 @@@ void vp8_first_pass(VP8_COMP *cpi
              xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset;
              xd->left_available = (mb_col != 0);
  
+             //Copy current mb to a buffer
+             RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
              // do intra 16x16 prediction
              this_error = vp8_encode_intra(cpi, x, use_dc_pred);
  
@@@ -881,11 -882,7 +884,11 @@@ static int estimate_max_q(VP8_COMP *cpi
  
          //cpi->twopass.est_max_qcorrection_factor /= adjustment_rate;
  
 -        cpi->twopass.est_max_qcorrection_factor = (cpi->twopass.est_max_qcorrection_factor < 0.1) ? 0.1 : (cpi->twopass.est_max_qcorrection_factor > 10.0) ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
 +        cpi->twopass.est_max_qcorrection_factor =
 +            (cpi->twopass.est_max_qcorrection_factor < 0.1)
 +                ? 0.1
 +                : (cpi->twopass.est_max_qcorrection_factor > 10.0)
 +                    ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
      }
  
      // Corrections for higher compression speed settings (reduced compression expected)
              * speed_correction * cpi->twopass.est_max_qcorrection_factor
              * cpi->twopass.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->twopass.est_max_qcorrection_factor * (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0);
  
          if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
              break;
@@@ -1263,6 -1261,7 +1266,6 @@@ static double get_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;
  
@@@ -1337,257 -1336,24 +1340,257 @@@ static int detect_transition_to_still
      return trans_to_still;
  }
  
 +// This function detects a flash through the high relative pcnt_second_ref
 +// score in the frame following a flash frame. The offset passed in should
 +// reflect this
 +static BOOL detect_flash( VP8_COMP *cpi, int offset )
 +{
 +    FIRSTPASS_STATS next_frame;
 +
 +    BOOL flash_detected = FALSE;
 +
 +    // Read the frame data.
 +    // The return is FALSE (no flash detected) if not a valid frame
 +    if ( read_frame_stats(cpi, &next_frame, offset) != EOF )
 +    {
 +        // What we are looking for here is a situation where there is a
 +        // brief break in prediction (such as a flash) but subsequent frames
 +        // are reasonably well predicted by an earlier (pre flash) frame.
 +        // The recovery after a flash is indicated by a high pcnt_second_ref
 +        // comapred to pcnt_inter.
 +        if ( (next_frame.pcnt_second_ref > next_frame.pcnt_inter) &&
 +             (next_frame.pcnt_second_ref >= 0.5 ) )
 +        {
 +            flash_detected = TRUE;
 +
 +            /*if (1)
 +            {
 +                FILE *f = fopen("flash.stt", "a");
 +                fprintf(f, "%8.0f %6.2f %6.2f\n",
 +                    next_frame.frame,
 +                    next_frame.pcnt_inter,
 +                    next_frame.pcnt_second_ref);
 +                fclose(f);
 +            }*/
 +        }
 +    }
 +
 +    return flash_detected;
 +}
 +
 +// Update the motion related elements to the GF arf boost calculation
 +static void accumulate_frame_motion_stats(
 +    VP8_COMP *cpi,
 +    FIRSTPASS_STATS * this_frame,
 +    double * this_frame_mv_in_out,
 +    double * mv_in_out_accumulator,
 +    double * abs_mv_in_out_accumulator,
 +    double * mv_ratio_accumulator )
 +{
 +    //double this_frame_mv_in_out;
 +    double this_frame_mvr_ratio;
 +    double this_frame_mvc_ratio;
 +    double motion_pct;
 +
 +    // Accumulate motion stats.
 +    motion_pct = this_frame->pcnt_motion;
 +
 +    // Accumulate Motion In/Out of frame stats
 +    *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct;
 +    *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct;
 +    *abs_mv_in_out_accumulator +=
 +        fabs(this_frame->mv_in_out_count * motion_pct);
 +
 +    // Accumulate a measure of how uniform (or conversely how random)
 +    // the motion field is. (A ratio of absmv / mv)
 +    if (motion_pct > 0.05)
 +    {
 +        this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
 +                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));
 +
 +        this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
 +                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));
 +
 +         *mv_ratio_accumulator +=
 +            (this_frame_mvr_ratio < this_frame->mvr_abs)
 +                ? (this_frame_mvr_ratio * motion_pct)
 +                : this_frame->mvr_abs * motion_pct;
 +
 +        *mv_ratio_accumulator +=
 +            (this_frame_mvc_ratio < this_frame->mvc_abs)
 +                ? (this_frame_mvc_ratio * motion_pct)
 +                : this_frame->mvc_abs * motion_pct;
 +
 +    }
 +}
 +
 +// Calculate a baseline boost number for the current frame.
 +static double calc_frame_boost(
 +    VP8_COMP *cpi,
 +    FIRSTPASS_STATS * this_frame,
 +    double this_frame_mv_in_out )
 +{
 +    double frame_boost;
 +
 +    // Underlying boost factor is based on inter intra error ratio
 +    if (this_frame->intra_error > cpi->twopass.gf_intra_err_min)
 +        frame_boost = (IIFACTOR * this_frame->intra_error /
 +                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
 +    else
 +        frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min /
 +                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
 +
 +    // Increase boost for frames where new data coming into frame
 +    // (eg zoom out). Slightly reduce boost if there is a net balance
 +    // of motion out of the frame (zoom in).
 +    // The range for this_frame_mv_in_out is -1.0 to +1.0
 +    if (this_frame_mv_in_out > 0.0)
 +        frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
 +    // In extreme case boost is halved
 +    else
 +        frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
 +
 +    // Clip to maximum
 +    if (frame_boost > GF_RMAX)
 +        frame_boost = GF_RMAX;
 +
 +    return frame_boost;
 +}
 +
 +#if NEW_BOOST
 +static int calc_arf_boost(
 +    VP8_COMP *cpi,
 +    int offset,
 +    int f_frames,
 +    int b_frames,
 +    int *f_boost,
 +    int *b_boost )
 +{
 +    FIRSTPASS_STATS this_frame;
 +
 +    int i;
 +    double boost_score = 0.0;
 +    double fwd_boost_score = 0.0;
 +    double mv_ratio_accumulator = 0.0;
 +    double decay_accumulator = 1.0;
 +    double this_frame_mv_in_out = 0.0;
 +    double mv_in_out_accumulator = 0.0;
 +    double abs_mv_in_out_accumulator = 0.0;
 +    double r;
 +    BOOL flash_detected = FALSE;
 +
 +    // Search forward from the proposed arf/next gf position
 +    for ( i = 0; i < f_frames; i++ )
 +    {
 +        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
 +            break;
 +
 +        // Update the motion related elements to the boost calculation
 +        accumulate_frame_motion_stats( cpi, &this_frame,
 +            &this_frame_mv_in_out, &mv_in_out_accumulator,
 +            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
 +
 +        // Calculate the baseline boost number for this frame
 +        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
 +
 +        // We want to discount the the flash frame itself and the recovery
 +        // frame that follows as both will have poor scores.
 +        flash_detected = detect_flash(cpi, (i+offset)) ||
 +                         detect_flash(cpi, (i+offset+1));
 +
 +        // Cumulative effect of prediction quality decay
 +        if ( !flash_detected )
 +        {
 +            decay_accumulator =
 +                decay_accumulator *
 +                get_prediction_decay_rate(cpi, &this_frame);
 +            decay_accumulator =
 +                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
 +        }
 +        boost_score += (decay_accumulator * r);
 +
 +        // Break out conditions.
 +        if  ( (!flash_detected) &&
 +              ((mv_ratio_accumulator > 100.0) ||
 +               (abs_mv_in_out_accumulator > 3.0) ||
 +               (mv_in_out_accumulator < -2.0) ) )
 +        {
 +            break;
 +        }
 +    }
 +
 +    *f_boost = (int)(boost_score * 100.0) >> 4;
 +
 +    // Reset for backward looking loop
 +    boost_score = 0.0;
 +    mv_ratio_accumulator = 0.0;
 +    decay_accumulator = 1.0;
 +    this_frame_mv_in_out = 0.0;
 +    mv_in_out_accumulator = 0.0;
 +    abs_mv_in_out_accumulator = 0.0;
 +
 +    // Search forward from the proposed arf/next gf position
 +    for ( i = -1; i >= -b_frames; i-- )
 +    {
 +        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
 +            break;
 +
 +        // Update the motion related elements to the boost calculation
 +        accumulate_frame_motion_stats( cpi, &this_frame,
 +            &this_frame_mv_in_out, &mv_in_out_accumulator,
 +            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
 +
 +        // Calculate the baseline boost number for this frame
 +        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
 +
 +        // We want to discount the the flash frame itself and the recovery
 +        // frame that follows as both will have poor scores.
 +        flash_detected = detect_flash(cpi, (i+offset)) ||
 +                         detect_flash(cpi, (i+offset+1));
 +
 +        // Cumulative effect of prediction quality decay
 +        if ( !flash_detected )
 +        {
 +            decay_accumulator =
 +                decay_accumulator *
 +                get_prediction_decay_rate(cpi, &this_frame);
 +            decay_accumulator =
 +                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
 +        }
 +
 +        boost_score += (decay_accumulator * r);
 +
 +        // Break out conditions.
 +        if  ( (!flash_detected) &&
 +              ((mv_ratio_accumulator > 100.0) ||
 +               (abs_mv_in_out_accumulator > 3.0) ||
 +               (mv_in_out_accumulator < -2.0) ) )
 +        {
 +            break;
 +        }
 +    }
 +    *b_boost = (int)(boost_score * 100.0) >> 4;
 +
 +    return (*f_boost + *b_boost);
 +}
 +#endif
 +
  // Analyse and define a gf/arf group .
  static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
  {
      FIRSTPASS_STATS next_frame;
      FIRSTPASS_STATS *start_pos;
      int i;
 +    double r;
      double boost_score = 0.0;
      double old_boost_score = 0.0;
      double gf_group_err = 0.0;
      double gf_first_frame_err = 0.0;
      double mod_frame_err = 0.0;
  
 -    double mv_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 abs_mv_in_out_accumulator = 0.0;
      double mod_err_per_mb_accumulator = 0.0;
  
 -    int max_group_bits;
 +    int max_bits = frame_max_bits(cpi);     // Max for a single frame
  
      unsigned int allow_alt_ref =
                      cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
  
 +    int alt_boost = 0;
 +    int f_boost = 0;
 +    int b_boost = 0;
 +    BOOL flash_detected;
 +
      cpi->twopass.gf_group_bits = 0;
      cpi->twopass.gf_decay_rate = 0;
  
  
      vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean
  
 -    // Preload the stats for the next frame.
 +    // Load stats for the current frame.
      mod_frame_err = calculate_modified_err(cpi, this_frame);
  
      // Note the error of the frame at the start of the group (this will be
              ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) &&
             (i < cpi->twopass.frames_to_key))
      {
 -        double r;
 -        double this_frame_mvr_ratio;
 -        double this_frame_mvc_ratio;
 -        //double motion_pct = next_frame.pcnt_motion;
 -        double motion_pct;
 -
          i++;    // Increment the loop counter
  
          // Accumulate error score of frames in this gf group
          if (EOF == 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));
 +        // Test for the case where there is a brief flash but the prediction
 +        // quality back to an earlier frame is then restored.
 +        flash_detected = detect_flash(cpi, 0);
  
 -            this_frame_mvc_ratio = fabs(next_frame.mvc_abs) /
 -                                   DOUBLE_DIVIDE_CHECK(fabs(next_frame.MVc));
 +        // Update the motion related elements to the boost calculation
 +        accumulate_frame_motion_stats( cpi, &next_frame,
 +            &this_frame_mv_in_out, &mv_in_out_accumulator,
 +            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
  
 -            mv_ratio_accumulator +=
 -                (this_frame_mvr_ratio < next_frame.mvr_abs)
 -                    ? (this_frame_mvr_ratio * motion_pct)
 -                    : next_frame.mvr_abs * motion_pct;
 +        // Calculate a baseline boost number for this frame
 +        r = calc_frame_boost( cpi, &next_frame, this_frame_mv_in_out );
  
 -            mv_ratio_accumulator +=
 -                (this_frame_mvc_ratio < next_frame.mvc_abs)
 -                    ? (this_frame_mvc_ratio * motion_pct)
 -                    : next_frame.mvc_abs * motion_pct;
 -        }
 -        else
 +        // Cumulative effect of prediction quality decay
 +        if ( !flash_detected )
          {
 -            mv_ratio_accumulator += 0.0;
 -            this_frame_mvr_ratio = 1.0;
 -            this_frame_mvc_ratio = 1.0;
 +            loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
 +            decay_accumulator = decay_accumulator * loop_decay_rate;
 +            decay_accumulator =
 +                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
          }
 -
 -        // 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->twopass.gf_intra_err_min)
 -            r = (IIKFACTOR2 * next_frame.intra_error /
 -                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
 -        else
 -            r = (IIKFACTOR2 * cpi->twopass.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 = get_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.
          if ( detect_transition_to_still( cpi, i, 5,
 -                                         loop_decay_rate, decay_accumulator ) )
 +                                         loop_decay_rate,
 +                                         decay_accumulator ) )
          {
              allow_alt_ref = FALSE;
              boost_score = old_boost_score;
          }
  
          // Break out conditions.
 -        if  (   /* i>4 || */
 +        if  (
              // Break at cpi->max_gf_interval unless almost totally static
              (i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) ||
              (
                  // Dont break out very close to a key frame
                  ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) &&
                  ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
 +                (!flash_detected) &&
                  ((mv_ratio_accumulator > 100.0) ||
                   (abs_mv_in_out_accumulator > 3.0) ||
                   (mv_in_out_accumulator < -2.0) ||
              boost_score = max_boost;
      }
  
 -    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
 -
      // Dont allow conventional gf too near the next kf
      if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)
      {
          }
      }
  
 +    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
 +
 +#if NEW_BOOST
 +    // Alterrnative boost calculation for alt ref
 +    alt_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost );
 +#endif
 +
      // Should we use the alternate refernce frame
      if (allow_alt_ref &&
          (i >= MIN_GF_INTERVAL) &&
          // dont use ARF very near next kf
          (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
 -        (((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->twopass.gf_decay_rate <= (ARF_DECAY_THRESH + (cpi->gfu_boost / 200)))
 -         )
 -        )
 -       )
 +#if NEW_BOOST
 +        ((next_frame.pcnt_inter > 0.75) ||
 +         (next_frame.pcnt_second_ref > 0.5)) &&
 +        ((mv_in_out_accumulator / (double)i > -0.2) ||
 +         (mv_in_out_accumulator > -2.0)) &&
 +        (b_boost > 100) &&
 +        (f_boost > 100) )
 +#else
 +        (next_frame.pcnt_inter > 0.75) &&
 +        ((mv_in_out_accumulator / (double)i > -0.2) ||
 +         (mv_in_out_accumulator > -2.0)) &&
 +        (cpi->gfu_boost > 100) &&
 +        (cpi->twopass.gf_decay_rate <=
 +            (ARF_DECAY_THRESH + (cpi->gfu_boost / 200))) )
 +#endif
      {
          int Boost;
          int allocation_chunks;
 -        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
 +        int Q = (cpi->oxcf.fixed_q < 0)
 +                ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
          int tmp_q;
          int arf_frame_bits = 0;
          int group_bits;
  
 +#if NEW_BOOST
 +        cpi->gfu_boost = alt_boost;
 +#endif
 +
          // Estimate the bits to be allocated to the group as a whole
 -        if ((cpi->twopass.kf_group_bits > 0) && (cpi->twopass.kf_group_error_left > 0))
 -            group_bits = (int)((double)cpi->twopass.kf_group_bits * (gf_group_err / (double)cpi->twopass.kf_group_error_left));
 +        if ((cpi->twopass.kf_group_bits > 0) &&
 +            (cpi->twopass.kf_group_error_left > 0))
 +        {
 +            group_bits = (int)((double)cpi->twopass.kf_group_bits *
 +                (gf_group_err / (double)cpi->twopass.kf_group_error_left));
 +        }
          else
              group_bits = 0;
  
          // Boost for arf frame
 +#if NEW_BOOST
 +        Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
 +#else
          Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
 +#endif
          Boost += (i * 50);
 +
 +        // Set max and minimum boost and hence minimum allocation
 +        if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
 +            Boost = ((cpi->baseline_gf_interval + 1) * 200);
 +        else if (Boost < 125)
 +            Boost = 125;
 +
          allocation_chunks = (i * 100) + Boost;
  
          // Normalize Altboost and allocations chunck down to prevent overflow
              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));
 +        // 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.
 +        // Estimate if there are enough bits available to make worthwhile use
 +        // of an arf.
          tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits);
  
 -        // Only use an arf if it is likely we will be able to code it at a lower Q than the surrounding frames.
 +        // 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;
  
              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;
 +            // 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.
 +            // For alt ref frames alt ref frame is technically part of the
 +            // GF frame for the next group but we always base the error
 +            // calculation and bit allocation on the current group of frames.
 +
 +            // Set the interval till the next gf or arf.
 +            // For ARFs this is the number of frames to be coded before the
 +            // future frame that is coded as an ARF.
              // The future frame itself is part of the next group
 -            cpi->baseline_gf_interval = i - 1;
 +            cpi->baseline_gf_interval = i;
  
              // Define the arnr filter width for this group of frames:
              // We only filter frames that lie within a distance of half
              // 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->twopass.total_stats->count - this_frame->frame - 1;
 +            frames_after_arf = cpi->twopass.total_stats->count -
 +                               this_frame->frame - 1;
  
              switch (cpi->oxcf.arnr_type)
              {
          cpi->baseline_gf_interval = i;
      }
  
 -    // Now decide how many bits should be allocated to the GF group as  a proportion of those remaining in the kf group.
 -    // The final key frame group in the clip is treated as a special case where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
 -    // This is also important for short clips where there may only be one key frame.
 -    if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats->count - cpi->common.current_video_frame))
 +    // Now decide how many bits should be allocated to the GF group as  a
 +    // proportion of those remaining in the kf group.
 +    // The final key frame group in the clip is treated as a special case
 +    // where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
 +    // This is also important for short clips where there may only be one
 +    // key frame.
 +    if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats->count -
 +                                            cpi->common.current_video_frame))
      {
 -        cpi->twopass.kf_group_bits = (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
 +        cpi->twopass.kf_group_bits =
 +            (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
      }
  
      // Calculate the bits to be allocated to the group as a whole
 -    if ((cpi->twopass.kf_group_bits > 0) && (cpi->twopass.kf_group_error_left > 0))
 -        cpi->twopass.gf_group_bits = (int)((double)cpi->twopass.kf_group_bits * (gf_group_err / (double)cpi->twopass.kf_group_error_left));
 +    if ((cpi->twopass.kf_group_bits > 0) &&
 +        (cpi->twopass.kf_group_error_left > 0))
 +    {
 +        cpi->twopass.gf_group_bits =
 +            (int)((double)cpi->twopass.kf_group_bits *
 +                  (gf_group_err / (double)cpi->twopass.kf_group_error_left));
 +    }
      else
          cpi->twopass.gf_group_bits = 0;
  
 -    cpi->twopass.gf_group_bits = (cpi->twopass.gf_group_bits < 0) ? 0 : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits) ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
 +    cpi->twopass.gf_group_bits =
 +        (cpi->twopass.gf_group_bits < 0)
 +            ? 0
 +            : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits)
 +                ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
  
 -    // Clip cpi->twopass.gf_group_bits based on user supplied data rate variability limit (cpi->oxcf.two_pass_vbrmax_section)
 -    max_group_bits = gf_group_max_bits(cpi);
 -    if (cpi->twopass.gf_group_bits > max_group_bits)
 -        cpi->twopass.gf_group_bits = max_group_bits;
 +    // Clip cpi->twopass.gf_group_bits based on user supplied data rate
 +    // variability limit (cpi->oxcf.two_pass_vbrmax_section)
 +    if (cpi->twopass.gf_group_bits > max_bits * cpi->baseline_gf_interval)
 +        cpi->twopass.gf_group_bits = max_bits * cpi->baseline_gf_interval;
  
      // Reset the file position
      reset_fpf_position(cpi, start_pos);
      // Assign  bits to the arf or gf.
      for (i = 0; i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); i++) {
          int Boost;
 -        int frames_in_section;
          int allocation_chunks;
          int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
          int gf_bits;
          // For ARF frames
          if (cpi->source_alt_ref_pending && i == 0)
          {
 +#if NEW_BOOST
 +            Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
 +#else
              Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
 -            //Boost += (cpi->baseline_gf_interval * 25);
 +#endif
              Boost += (cpi->baseline_gf_interval * 50);
  
              // Set max and minimum boost and hence minimum allocation
              else if (Boost < 125)
                  Boost = 125;
  
 -            frames_in_section = cpi->baseline_gf_interval + 1;
 -            allocation_chunks = (frames_in_section * 100) + Boost;
 +            allocation_chunks =
 +                ((cpi->baseline_gf_interval + 1) * 100) + Boost;
          }
          // Else for standard golden frames
          else
              else if (Boost < 125)
                  Boost = 125;
  
 -            frames_in_section = cpi->baseline_gf_interval;
 -            allocation_chunks = (frames_in_section * 100) + (Boost - 100);
 +            allocation_chunks =
 +                (cpi->baseline_gf_interval * 100) + (Boost - 100);
          }
  
          // Normalize Altboost and allocations chunck down to prevent overflow
              allocation_chunks /= 2;
          }
  
 -        // Calculate the number of bits to be spent on the gf or arf based on the boost number
 -        gf_bits = (int)((double)Boost * (cpi->twopass.gf_group_bits / (double)allocation_chunks));
 +        // Calculate the number of bits to be spent on the gf or arf based on
 +        // the boost number
 +        gf_bits = (int)((double)Boost *
 +                        (cpi->twopass.gf_group_bits /
 +                         (double)allocation_chunks));
  
          // If the frame that is to be boosted is simpler than the average for
          // the gf/arf group then use an alternative calculation
              }
          }
  
 +        // Apply an additional limit for CBR
 +        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
 +        {
 +            if (cpi->twopass.gf_bits > (cpi->buffer_level >> 1))
 +                cpi->twopass.gf_bits = cpi->buffer_level >> 1;
 +        }
 +
          // Dont allow a negative value for gf_bits
          if (gf_bits < 0)
              gf_bits = 0;
          if (cpi->twopass.gf_group_bits < 0)
              cpi->twopass.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;
 +#if NEW_BOOST
 +            int boost = (cpi->source_alt_ref_pending)
 +                        ? b_boost : cpi->gfu_boost;
 +#else
 +            int boost = cpi->gfu_boost;
 +#endif
 +            // Set aside some bits for a mid gf sequence boost
 +            if ((boost > 150) && (cpi->baseline_gf_interval > 5))
 +            {
 +                int pct_extra = (boost - 100) / 50;
 +                pct_extra = (pct_extra > 10) ? 10 : pct_extra;
  
 -            cpi->twopass.mid_gf_extra_bits = (cpi->twopass.gf_group_bits * pct_extra) / 100;
 -            cpi->twopass.gf_group_bits -= cpi->twopass.mid_gf_extra_bits;
 +                cpi->twopass.mid_gf_extra_bits =
 +                    (cpi->twopass.gf_group_bits * pct_extra) / 100;
 +                cpi->twopass.gf_group_bits -= cpi->twopass.mid_gf_extra_bits;
 +            }
 +            else
 +                cpi->twopass.mid_gf_extra_bits = 0;
          }
 -        else
 -            cpi->twopass.mid_gf_extra_bits = 0;
      }
  
      // Adjustment to estimate_max_q based on a measure of complexity of the section
diff --combined vp8/encoder/pickinter.c
@@@ -588,10 -588,10 +588,10 @@@ void vp8_pick_inter_mode(VP8_COMP *cpi
  
              /* adjust mvp to make sure it is within MV range */
              vp8_clamp_mv(&mvp,
 -                         best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL);
 +                         best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
          }
  
          switch (this_mode)
                  rate2 += rate;
                  distortion2 = VARIANCE_INVOKE
                                  (&cpi->rtcd.variance, var16x16)(
-                                     x->src.y_buffer, x->src.y_stride,
+                                     *(b->base_src), b->src_stride,
                                      x->e_mbd.predictor, 16, &sse);
                  this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
  
              RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
                  (&x->e_mbd);
              distortion2 = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)
-                                           (x->src.y_buffer, x->src.y_stride,
+                                           (*(b->base_src), b->src_stride,
                                            x->e_mbd.predictor, 16, &sse);
              rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode];
              this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
                  mvp.as_int = best_ref_mv.as_int;
              }
  
 -            col_min = (best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL) >>3;
 -            col_max = (best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL) >>3;
 -            row_min = (best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL) >>3;
 -            row_max = (best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL) >>3;
 +            col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL)
 +                                                 :((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL);
 +            col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL)
 +                                                 :((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL);
 +            row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
 +                                                 :((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
 +            row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
 +                                                 :((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
  
              // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
              if (x->mv_col_min < col_min )
@@@ -908,6 -904,7 +908,7 @@@ void vp8_pick_intra_mode(VP8_COMP *cpi
      MB_PREDICTION_MODE mode, best_mode = DC_PRED;
      int this_rd;
      unsigned int sse;
+     BLOCK *b = &x->block[0];
  
      x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
  
          RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
              (&x->e_mbd);
          distortion = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)
-             (x->src.y_buffer, x->src.y_stride, x->e_mbd.predictor, 16, &sse);
+             (*(b->base_src), b->src_stride, x->e_mbd.predictor, 16, &sse);
          rate = x->mbmode_cost[x->e_mbd.frame_type][mode];
          this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
  
diff --combined vp8/encoder/rdopt.c
@@@ -134,8 -134,8 +134,8 @@@ const MV_REFERENCE_FRAME vp8_ref_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]
 +    unsigned int c      [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS],
 +    const vp8_prob p    [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES]
  )
  {
      int i, j, k;
@@@ -238,7 -238,7 +238,7 @@@ void vp8_initialize_rd_consts(VP8_COMP 
                  (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4;
      }
  
 -    cpi->mb.errorperbit = (cpi->RDMULT / 100);
 +    cpi->mb.errorperbit = (cpi->RDMULT / 110);
      cpi->mb.errorperbit += (cpi->mb.errorperbit==0);
  
      vp8_set_speed_features(cpi);
@@@ -543,8 -543,8 +543,8 @@@ static void macro_block_yrd( MACROBLOC
      BLOCK *beptr;
      int d;
  
-     ENCODEMB_INVOKE(rtcd, submby)( mb->src_diff, mb->src.y_buffer,
-                                    mb->e_mbd.predictor, mb->src.y_stride );
+     ENCODEMB_INVOKE(rtcd, submby)( mb->src_diff, *(mb->block[0].base_src),
+                                    mb->e_mbd.predictor, mb->block[0].src_stride );
  
      // Fdct and building the 2nd order block
      for (beptr = mb->block; beptr < mb->block + 16; beptr += 2)
@@@ -1330,14 -1330,10 +1330,14 @@@ static int vp8_rd_pick_best_mbsegmentat
  
          if (bsi.segment_rd < best_rd)
          {
 -            int col_min = (best_ref_mv->as_mv.col - MAX_FULL_PEL_VAL) >>3;
 -            int col_max = (best_ref_mv->as_mv.col + MAX_FULL_PEL_VAL) >>3;
 -            int row_min = (best_ref_mv->as_mv.row - MAX_FULL_PEL_VAL) >>3;
 -            int row_max = (best_ref_mv->as_mv.row + MAX_FULL_PEL_VAL) >>3;
 +            int col_min = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) - MAX_FULL_PEL_VAL)
 +                                                      :((best_ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL);
 +            int col_max = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) + MAX_FULL_PEL_VAL)
 +                                                      :((best_ref_mv->as_mv.col>>3) + MAX_FULL_PEL_VAL);
 +            int row_min = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) - MAX_FULL_PEL_VAL)
 +                                                      :((best_ref_mv->as_mv.row>>3) - MAX_FULL_PEL_VAL);
 +            int row_max = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) + MAX_FULL_PEL_VAL)
 +                                                      :((best_ref_mv->as_mv.row>>3) + MAX_FULL_PEL_VAL);
  
              int tmp_col_min = x->mv_col_min;
              int tmp_col_max = x->mv_col_max;
@@@ -1637,6 -1633,8 +1637,8 @@@ void vp8_cal_sad(VP8_COMP *cpi, MACROBL
  {
  
      int near_sad[8] = {0}; // 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above, 5-lf left, 6-lf right, 7-lf below
+     BLOCK *b = &x->block[0];
+     unsigned char *src_y_ptr = *(b->base_src);
  
      //calculate sad for current frame 3 nearby MBs.
      if( xd->mb_to_top_edge==0 && xd->mb_to_left_edge ==0)
      }else if(xd->mb_to_top_edge==0)
      {   //only has left MB for sad calculation.
          near_sad[0] = near_sad[2] = INT_MAX;
-         near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, xd->dst.y_buffer - 16,xd->dst.y_stride, 0x7fffffff);
+         near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16,xd->dst.y_stride, 0x7fffffff);
      }else if(xd->mb_to_left_edge ==0)
      {   //only has left MB for sad calculation.
          near_sad[1] = near_sad[2] = INT_MAX;
-         near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, xd->dst.y_buffer - xd->dst.y_stride *16,xd->dst.y_stride, 0x7fffffff);
+         near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride *16,xd->dst.y_stride, 0x7fffffff);
      }else
      {
-         near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, xd->dst.y_buffer - xd->dst.y_stride *16,xd->dst.y_stride, 0x7fffffff);
-         near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, xd->dst.y_buffer - 16,xd->dst.y_stride, 0x7fffffff);
-         near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, xd->dst.y_buffer - xd->dst.y_stride *16 -16,xd->dst.y_stride, 0x7fffffff);
+         near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride *16,xd->dst.y_stride, 0x7fffffff);
+         near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16,xd->dst.y_stride, 0x7fffffff);
+         near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride *16 -16,xd->dst.y_stride, 0x7fffffff);
      }
  
      if(cpi->common.last_frame_type != KEY_FRAME)
          if(xd->mb_to_bottom_edge==0) near_sad[7] = INT_MAX;
  
          if(near_sad[4] != INT_MAX)
-             near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - pre_y_stride *16, pre_y_stride, 0x7fffffff);
+             near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - pre_y_stride *16, pre_y_stride, 0x7fffffff);
          if(near_sad[5] != INT_MAX)
-             near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff);
-         near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff);
+             near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff);
+         near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer, pre_y_stride, 0x7fffffff);
          if(near_sad[6] != INT_MAX)
-             near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer + 16, pre_y_stride, 0x7fffffff);
+             near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + 16, pre_y_stride, 0x7fffffff);
          if(near_sad[7] != INT_MAX)
-             near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer + pre_y_stride *16, pre_y_stride, 0x7fffffff);
+             near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + pre_y_stride *16, pre_y_stride, 0x7fffffff);
      }
  
      if(cpi->common.last_frame_type != KEY_FRAME)
@@@ -1880,10 -1878,10 +1882,10 @@@ void vp8_rd_pick_inter_mode(VP8_COMP *c
  
              /* adjust mvp to make sure it is within MV range */
              vp8_clamp_mv(&mvp,
 -                         best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL,
 -                         best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL);
 +                         best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
 +                         best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
          }
  
          // Check to see if the testing frequency for this mode is at its max
  
              int sadpb = x->sadperbit16;
  
 -            int col_min = (best_ref_mv.as_mv.col - MAX_FULL_PEL_VAL) >>3;
 -            int col_max = (best_ref_mv.as_mv.col + MAX_FULL_PEL_VAL) >>3;
 -            int row_min = (best_ref_mv.as_mv.row - MAX_FULL_PEL_VAL) >>3;
 -            int row_max = (best_ref_mv.as_mv.row + MAX_FULL_PEL_VAL) >>3;
 +            int col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL)
 +                                                     :((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL);
 +            int col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL)
 +                                                     :((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL);
 +            int row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
 +                                                     :((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
 +            int row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
 +                                                     :((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
  
              int tmp_col_min = x->mv_col_min;
              int tmp_col_max = x->mv_col_max;
                      threshold = x->encode_breakout;
  
                  var = VARIANCE_INVOKE(&cpi->rtcd.variance, var16x16)
-                         (x->src.y_buffer, x->src.y_stride,
+                         (*(b->base_src), b->src_stride,
                          x->e_mbd.predictor, 16, &sse);
  
                  if (sse < threshold)