shithub: libvpx

Download patch

ref: 13c6d1a8c80bea1eccf21bbd267afbb3825d2797
parent: f2ec452fbc8779fc2230148d7b446cc84929ff70
author: Paul Wilkins <paulwilkins@google.com>
date: Wed Apr 11 11:44:14 EDT 2012

Refactoring of encode loop and bitstream packing

Some code re-factored / moved to allow the main
pack operation inside the recode loop so  that the
size estimate is accurate.

Deletion of some redundant code relating to one pass.

Aproximate improvement over March 27 code base:
Derf 0.0%, YT 0.5%, YThd 0.3% Std_hd 0.25%

Change-Id: Id2d071794ab44f0b52935f6fcdb5733d09a6bb86

--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -55,10 +55,8 @@
     vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
     vp8_prob coef_probs_8x8 [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
     MV_CONTEXT mvc[2];
-    MV_CONTEXT pre_mvc[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
 #if CONFIG_HIGH_PRECISION_MV
     MV_CONTEXT_HP mvc_hp[2];
-    MV_CONTEXT_HP pre_mvc_hp[2];  /* not to caculate the mvcost for the frame if mvc doesn't change. */
 #endif
 } FRAME_CONTEXT;
 
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -170,6 +170,106 @@
 #endif
 }
 
+// This function updates the reference frame prediction stats
+static void update_refpred_stats( VP8_COMP *cpi )
+{
+    VP8_COMMON *const cm = & cpi->common;
+    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
+
+    int mb_row, mb_col;
+    int i;
+    int tot_count;
+    int ref_pred_count[PREDICTION_PROBS][2];
+    vp8_prob new_pred_probs[PREDICTION_PROBS];
+    unsigned char pred_context;
+    unsigned char pred_flag;
+
+    int old_cost, new_cost;
+
+    // Clear the prediction hit counters
+    vpx_memset(ref_pred_count, 0, sizeof(ref_pred_count));
+
+    // Set the prediction probability structures to defaults
+    if ( cm->frame_type == KEY_FRAME )
+    {
+        // Set the prediction probabilities to defaults
+        cm->ref_pred_probs[0] = 120;
+        cm->ref_pred_probs[1] = 80;
+        cm->ref_pred_probs[2] = 40;
+
+        vpx_memset(cpi->ref_pred_probs_update, 0,
+                   sizeof(cpi->ref_pred_probs_update) );
+    }
+    else
+    {
+        // For non-key frames.......
+
+        // Scan through the macroblocks and collate prediction counts.
+        xd->mode_info_context = cm->mi;
+        for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
+        {
+            for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
+            {
+                // Get the prediction context and status
+                pred_flag = get_pred_flag( xd, PRED_REF );
+                pred_context = get_pred_context( cm, xd, PRED_REF );
+
+                // Count prediction success
+                ref_pred_count[pred_context][pred_flag]++;
+
+                // Step on to the next mb
+                xd->mode_info_context++;
+            }
+
+            // this is to account for the border in mode_info_context
+            xd->mode_info_context++;
+        }
+
+        // From the prediction counts set the probabilities for each context
+        for ( i = 0; i < PREDICTION_PROBS; i++ )
+        {
+            // MB reference frame not relevent to key frame encoding
+            if ( cm->frame_type != KEY_FRAME )
+            {
+                // Work out the probabilities for the reference frame predictor
+                tot_count = ref_pred_count[i][0] + ref_pred_count[i][1];
+                if ( tot_count )
+                {
+                    new_pred_probs[i] =
+                        ( ref_pred_count[i][0] * 255 ) / tot_count;
+
+                    // Clamp to minimum allowed value
+                    new_pred_probs[i] += !new_pred_probs[i];
+                }
+                else
+                    new_pred_probs[i] = 128;
+            }
+            else
+                new_pred_probs[i] = 128;
+
+            // Decide whether or not to update the reference frame probs.
+            // Returned costs are in 1/256 bit units.
+            old_cost =
+                (ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
+                (ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));
+
+            new_cost =
+                (ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
+                (ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));
+
+            // Cost saving must be >= 8 bits (2048 in these units)
+            if ( (old_cost - new_cost) >= 2048 )
+            {
+                cpi->ref_pred_probs_update[i] = 1;
+                cm->ref_pred_probs[i] = new_pred_probs[i];
+            }
+            else
+                cpi->ref_pred_probs_update[i] = 0;
+
+        }
+    }
+}
+
 static void write_ymode(vp8_writer *bc, int m, const vp8_prob *p)
 {
     vp8_write_token(bc, vp8_ymode_tree, p, vp8_ymode_encodings + m);
@@ -1307,88 +1407,35 @@
     return savings;
 }
 
-int vp8_estimate_entropy_savings(VP8_COMP *cpi)
+void build_coeff_contexts(VP8_COMP *cpi)
 {
-    int savings = 0;
-    int i=0;
-    VP8_COMMON *const cm = & cpi->common;
-    const int *const rfct = cpi->count_mb_ref_frame_usage;
-    const int rf_intra = rfct[INTRA_FRAME];
-    const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
-    int new_intra, new_last, new_gf_alt, oldtotal, newtotal;
-    int ref_frame_cost[MAX_REF_FRAMES];
-
-    vp8_clear_system_state(); //__asm emms;
-
-    // Estimate reference frame cost savings.
-    // For now this is just based on projected overall frequency of
-    // each reference frame coded using an unpredicted coding tree.
-    if (cpi->common.frame_type != KEY_FRAME)
+    int i = 0;
+    do
     {
-        new_intra = (rf_intra + rf_inter)
-                    ? rf_intra * 255 / (rf_intra + rf_inter) : 1;
-        new_intra += !new_intra;
-
-        new_last = rf_inter ? (rfct[LAST_FRAME] * 255) / rf_inter : 128;
-        new_last += !new_last;
-
-        new_gf_alt = (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME])
-            ? (rfct[GOLDEN_FRAME] * 255) /
-              (rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME]) : 128;
-        new_gf_alt += !new_gf_alt;
-
-        // new costs
-        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(new_intra);
-        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(new_intra)
-                                        + vp8_cost_zero(new_last);
-        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(new_intra)
-                                        + vp8_cost_one(new_last)
-                                        + vp8_cost_zero(new_gf_alt);
-        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(new_intra)
-                                        + vp8_cost_one(new_last)
-                                        + vp8_cost_one(new_gf_alt);
-
-        newtotal =
-            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
-            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
-            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
-            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
-        // old costs
-        ref_frame_cost[INTRA_FRAME]   = vp8_cost_zero(cm->prob_intra_coded);
-        ref_frame_cost[LAST_FRAME]    = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_zero(cm->prob_last_coded);
-        ref_frame_cost[GOLDEN_FRAME]  = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_one(cm->prob_last_coded)
-                                        + vp8_cost_zero(cm->prob_gf_coded);
-        ref_frame_cost[ALTREF_FRAME]  = vp8_cost_one(cm->prob_intra_coded)
-                                        + vp8_cost_one(cm->prob_last_coded)
-                                        + vp8_cost_one(cm->prob_gf_coded);
-
-        oldtotal =
-            rfct[INTRA_FRAME] * ref_frame_cost[INTRA_FRAME] +
-            rfct[LAST_FRAME] * ref_frame_cost[LAST_FRAME] +
-            rfct[GOLDEN_FRAME] * ref_frame_cost[GOLDEN_FRAME] +
-            rfct[ALTREF_FRAME] * ref_frame_cost[ALTREF_FRAME];
-
-        savings += (oldtotal - newtotal) / 256;
-
-        // Update the reference frame probability numbers to reflect
-        // the observed counts in this frame. Doing this here insures
-        // that if there are multiple recode iterations the baseline
-        // probabilities used are updated in each iteration.
-        cm->prob_intra_coded = new_intra;
-        cm->prob_last_coded = new_last;
-        cm->prob_gf_coded = new_gf_alt;
+        int j = 0;
+        do
+        {
+            int k = 0;
+            do
+            {
+                vp8_tree_probs_from_distribution(
+                    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
+                    cpi->frame_coef_probs [i][j][k],
+                    cpi->frame_branch_ct [i][j][k],
+                    cpi->coef_counts [i][j][k],
+                    256, 1
+                );
+            }
+            while (++k < PREV_COEF_CONTEXTS);
+        }
+        while (++j < COEF_BANDS);
     }
+    while (++i < BLOCK_TYPES);
 
-    savings += default_coef_context_savings(cpi);
 
-
-    /* do not do this if not evena allowed */
+    i= 0;
     if(cpi->common.txfm_mode == ALLOW_8X8)
     {
-        int savings8x8 = 0;
         do
         {
             int j = 0;
@@ -1410,29 +1457,6 @@
                         256, 1
                         );
 
-                    do
-                    {
-                        const unsigned int *ct  = cpi->frame_branch_ct_8x8 [i][j][k][t];
-                        const vp8_prob newp = cpi->frame_coef_probs_8x8 [i][j][k][t];
-
-                        const vp8_prob old = cpi->common.fc.coef_probs_8x8 [i][j][k][t];
-                        const vp8_prob upd = vp8_coef_update_probs_8x8 [i][j][k][t];
-
-                        const int old_b = vp8_cost_branch(ct, old);
-                        const int new_b = vp8_cost_branch(ct, newp);
-
-                        const int update_b = 8 + vp8_cost_upd;
-
-                        const int s = old_b - new_b - update_b;
-
-                        if (s > 0)
-                            savings8x8 += s;
-
-
-                    }
-                    while (++t < MAX_ENTROPY_TOKENS - 1);
-
-
                 }
                 while (++k < PREV_COEF_CONTEXTS);
             }
@@ -1439,11 +1463,8 @@
             while (++j < COEF_BANDS);
         }
         while (++i < BLOCK_TYPES);
-
-        savings += savings8x8 >> 8;
     }
 
-    return savings;
 }
 
 static void update_coef_probs(VP8_COMP *cpi)
@@ -1453,6 +1474,10 @@
     int update = 0;
 
     vp8_clear_system_state(); //__asm emms;
+
+    // Build the cofficient contexts based on counts collected in encode loop
+    build_coeff_contexts(cpi);
+
     /* dry run to see if there is any udpate at all needed */
     do
     {
@@ -1463,17 +1488,7 @@
             int prev_coef_savings[ENTROPY_NODES] = {0};
             do
             {
-                //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
-                /* at every context */
-                /* calc probs and branch cts for this frame only */
-                //vp8_prob new_p           [ENTROPY_NODES];
-                //unsigned int branch_ct   [ENTROPY_NODES] [2];
                 int t = 0;      /* token/prob index */
-                //vp8_tree_probs_from_distribution(
-                //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
-                //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                //    256, 1
-                //    );
                 do
                 {
                     const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1492,7 +1507,6 @@
                     update += u;
                 }
                 while (++t < ENTROPY_NODES);
-                /* Accum token counts for generation of default statistics */
             }
             while (++k < PREV_COEF_CONTEXTS);
         }
@@ -1518,18 +1532,8 @@
 
                 do
                 {
-                    //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
-                    /* at every context */
-
-                    /* calc probs and branch cts for this frame only */
-                    //vp8_prob new_p           [ENTROPY_NODES];
-                    //unsigned int branch_ct   [ENTROPY_NODES] [2];
+                    // calc probs and branch cts for this frame only
                     int t = 0;      /* token/prob index */
-                    //vp8_tree_probs_from_distribution(
-                    //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
-                    //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                    //    256, 1
-                    //    );
                     do
                     {
                         const vp8_prob newp = cpi->frame_coef_probs [i][j][k][t];
@@ -1557,7 +1561,8 @@
                         }
                     }
                     while (++t < ENTROPY_NODES);
-                    /* Accum token counts for generation of default statistics */
+
+                    // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                     t = 0;
                     do
@@ -1589,17 +1594,8 @@
                 int k = 0;
                 do
                 {
-                    //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
-                    /* at every context */
-                    /* calc probs and branch cts for this frame only */
-                    //vp8_prob new_p           [ENTROPY_NODES];
-                    //unsigned int branch_ct   [ENTROPY_NODES] [2];
+                    // calc probs and branch cts for this frame only
                     int t = 0;      /* token/prob index */
-                    //vp8_tree_probs_from_distribution(
-                    //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
-                    //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                    //    256, 1
-                    //    );
                     do
                     {
                         const unsigned int *ct  = cpi->frame_branch_ct_8x8 [i][j][k][t];
@@ -1620,7 +1616,7 @@
                     }
                     while (++t < MAX_ENTROPY_TOKENS - 1);
 
-                    /* Accum token counts for generation of default statistics */
+                    // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                     t = 0;
 
@@ -1655,17 +1651,7 @@
                     int k = 0;
                     do
                     {
-                        //note: use result from vp8_estimate_entropy_savings, so no need to call vp8_tree_probs_from_distribution here.
-                        /* at every context */
-                        /* calc probs and branch cts for this frame only */
-                        //vp8_prob new_p           [ENTROPY_NODES];
-                        //unsigned int branch_ct   [ENTROPY_NODES] [2];
                         int t = 0;      /* token/prob index */
-                        //vp8_tree_probs_from_distribution(
-                        //    MAX_ENTROPY_TOKENS, vp8_coef_encodings, vp8_coef_tree,
-                        //    new_p, branch_ct, (unsigned int *)cpi->coef_counts [i][j][k],
-                        //    256, 1
-                        //    );
                         do
                         {
                             const unsigned int *ct  = cpi->frame_branch_ct_8x8 [i][j][k][t];
@@ -1690,7 +1676,7 @@
                             }
                         }
                         while (++t < MAX_ENTROPY_TOKENS - 1);
-                        /* Accum token counts for generation of default statistics */
+                        // Accum token counts for generation of default statistics
 #ifdef ENTROPY_STATS
                         t = 0;
                         do
@@ -1851,7 +1837,18 @@
 
         // If it is, then indicate the method that will be used.
         if ( xd->update_mb_segmentation_map )
+        {
+            // Select the coding strategy (temporal or spatial)
+            choose_segmap_coding_method( cpi );
+
+            // Take a copy of the segment map if it changed for
+            // future comparison
+            vpx_memcpy( pc->last_frame_seg_map,
+                        cpi->segmentation_map, pc->MBs );
+
+            // Write out the chosen coding method.
             vp8_write_bit(bc, (pc->temporal_update) ? 1:0);
+        }
 
         vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
 
@@ -2002,6 +1999,7 @@
 
     // Encode the common prediction model status flag probability updates for
     // the reference frame
+    update_refpred_stats( cpi );
     if ( pc->frame_type != KEY_FRAME )
     {
         for (i = 0; i < PREDICTION_PROBS; i++)
@@ -2111,6 +2109,12 @@
         // Should the GF or ARF be updated using the transmitted frame or buffer
         vp8_write_bit(bc, pc->refresh_golden_frame);
         vp8_write_bit(bc, pc->refresh_alt_ref_frame);
+
+        // For inter frames the current default behavior is that when
+        // cm->refresh_golden_frame is set we copy the old GF over to
+        // the ARF buffer. This is purely an encoder decision at present.
+        if (pc->refresh_golden_frame)
+            pc->copy_buffer_to_arf  = 2;
 
         // If not being updated from current frame should either GF or ARF be updated from another buffer
         if (!pc->refresh_golden_frame)
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1217,55 +1217,6 @@
     // projected_frame_size in units of BYTES
     cpi->projected_frame_size = totalrate >> 8;
 
-    // Make a note of the percentage MBs coded Intra.
-    if (cm->frame_type == KEY_FRAME)
-    {
-        cpi->this_frame_percent_intra = 100;
-    }
-    else
-    {
-        int tot_modes;
-
-        tot_modes = cpi->count_mb_ref_frame_usage[INTRA_FRAME]
-                    + cpi->count_mb_ref_frame_usage[LAST_FRAME]
-                    + cpi->count_mb_ref_frame_usage[GOLDEN_FRAME]
-                    + cpi->count_mb_ref_frame_usage[ALTREF_FRAME];
-
-        if (tot_modes)
-            cpi->this_frame_percent_intra =
-                   cpi->count_mb_ref_frame_usage[INTRA_FRAME] * 100 / tot_modes;
-
-    }
-
-#if 0
-    {
-        int cnt = 0;
-        int flag[2] = {0, 0};
-
-        for (cnt = 0; cnt < MVPcount; cnt++)
-        {
-            if (cm->fc.pre_mvc[0][cnt] != cm->fc.mvc[0][cnt])
-            {
-                flag[0] = 1;
-                vpx_memcpy(cm->fc.pre_mvc[0], cm->fc.mvc[0], MVPcount);
-                break;
-            }
-        }
-
-        for (cnt = 0; cnt < MVPcount; cnt++)
-        {
-            if (cm->fc.pre_mvc[1][cnt] != cm->fc.mvc[1][cnt])
-            {
-                flag[1] = 1;
-                vpx_memcpy(cm->fc.pre_mvc[1], cm->fc.mvc[1], MVPcount);
-                break;
-            }
-        }
-
-        if (flag[0] || flag[1])
-            vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
-    }
-#endif
 
 #if 0
     // Keep record of the total distortion this time around for future use
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -1845,6 +1845,7 @@
 
     // Should we use the alternate refernce frame
     if (allow_alt_ref &&
+        (i < cpi->oxcf.lag_in_frames ) &&
         (i >= MIN_GF_INTERVAL) &&
         // dont use ARF very near next kf
         (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -70,7 +70,6 @@
 extern void vp8_yv12_copy_src_frame_func_neon(YV12_BUFFER_CONFIG *src_ybc, YV12_BUFFER_CONFIG *dst_ybc);
 #endif
 
-int vp8_estimate_entropy_savings(VP8_COMP *cpi);
 int vp8_calc_ss_err(YV12_BUFFER_CONFIG *source, YV12_BUFFER_CONFIG *dest, const vp8_variance_rtcd_vtable_t *rtcd);
 
 extern void vp8_temporal_filter_prepare_c(VP8_COMP *cpi, int distance);
@@ -413,6 +412,8 @@
     cpi->segmentation_map = 0;
     vpx_free(cpi->common.last_frame_seg_map);
     cpi->common.last_frame_seg_map = 0;
+    vpx_free(cpi->coding_context.last_frame_seg_map_copy);
+    cpi->coding_context.last_frame_seg_map_copy = 0;
 
     vpx_free(cpi->active_map);
     cpi->active_map = 0;
@@ -1660,6 +1661,11 @@
     CHECK_MEM_ERROR(cm->last_frame_seg_map,
         vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
 
+    // And a place holder structure is the coding context
+    // for use if we want to save and restore it
+    CHECK_MEM_ERROR(cpi->coding_context.last_frame_seg_map_copy,
+        vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
+
     CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
     vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
     cpi->active_map_enabled = 0;
@@ -2480,47 +2486,6 @@
     }
 }
 
-// 1 = key, 0 = inter
-static int decide_key_frame(VP8_COMP *cpi)
-{
-    VP8_COMMON *cm = &cpi->common;
-
-    int code_key_frame = FALSE;
-
-    cpi->kf_boost = 0;
-
-    if (cpi->Speed > 11)
-        return FALSE;
-
-    // Clear down mmx registers
-    vp8_clear_system_state();  //__asm emms;
-
-    // If the following are true we might as well code a key frame
-    if (((cpi->this_frame_percent_intra == 100) &&
-         (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 2))) ||
-        ((cpi->this_frame_percent_intra > 95) &&
-         (cpi->this_frame_percent_intra >= (cpi->last_frame_percent_intra + 5))))
-    {
-        code_key_frame = TRUE;
-    }
-    // in addition if the following are true and this is not a golden frame then code a key frame
-    // Note that on golden frames there often seems to be a pop in intra useage anyway hence this
-    // restriction is designed to prevent spurious key frames. The Intra pop needs to be investigated.
-    else if (((cpi->this_frame_percent_intra > 60) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 2))) ||
-             ((cpi->this_frame_percent_intra > 75) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra * 3 / 2))) ||
-             ((cpi->this_frame_percent_intra > 90) &&
-              (cpi->this_frame_percent_intra > (cpi->last_frame_percent_intra + 10))))
-    {
-        if (!cm->refresh_golden_frame)
-            code_key_frame = TRUE;
-    }
-
-    return code_key_frame;
-
-}
-
 int find_fp_qindex()
 {
     int i;
@@ -2812,106 +2777,6 @@
 
 }
 
-// This function updates the reference frame prediction stats
-static void update_refpred_stats( VP8_COMP *cpi )
-{
-    VP8_COMMON *const cm = & cpi->common;
-    MACROBLOCKD *const xd = & cpi->mb.e_mbd;
-
-    int mb_row, mb_col;
-    int i;
-    int tot_count;
-    int ref_pred_count[PREDICTION_PROBS][2];
-    vp8_prob new_pred_probs[PREDICTION_PROBS];
-    unsigned char pred_context;
-    unsigned char pred_flag;
-
-    int old_cost, new_cost;
-
-    // Clear the prediction hit counters
-    vpx_memset(ref_pred_count, 0, sizeof(ref_pred_count));
-
-    // Set the prediction probability structures to defaults
-    if ( cm->frame_type == KEY_FRAME )
-    {
-        // Set the prediction probabilities to defaults
-        cm->ref_pred_probs[0] = 120;
-        cm->ref_pred_probs[1] = 80;
-        cm->ref_pred_probs[2] = 40;
-
-        vpx_memset(cpi->ref_pred_probs_update, 0,
-                   sizeof(cpi->ref_pred_probs_update) );
-    }
-    else
-    {
-        // For non-key frames.......
-
-        // Scan through the macroblocks and collate prediction counts.
-        xd->mode_info_context = cm->mi;
-        for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
-        {
-            for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
-            {
-                // Get the prediction context and status
-                pred_flag = get_pred_flag( xd, PRED_REF );
-                pred_context = get_pred_context( cm, xd, PRED_REF );
-
-                // Count prediction success
-                ref_pred_count[pred_context][pred_flag]++;
-
-                // Step on to the next mb
-                xd->mode_info_context++;
-            }
-
-            // this is to account for the border in mode_info_context
-            xd->mode_info_context++;
-        }
-
-        // From the prediction counts set the probabilities for each context
-        for ( i = 0; i < PREDICTION_PROBS; i++ )
-        {
-            // MB reference frame not relevent to key frame encoding
-            if ( cm->frame_type != KEY_FRAME )
-            {
-                // Work out the probabilities for the reference frame predictor
-                tot_count = ref_pred_count[i][0] + ref_pred_count[i][1];
-                if ( tot_count )
-                {
-                    new_pred_probs[i] =
-                        ( ref_pred_count[i][0] * 255 ) / tot_count;
-
-                    // Clamp to minimum allowed value
-                    new_pred_probs[i] += !new_pred_probs[i];
-                }
-                else
-                    new_pred_probs[i] = 128;
-            }
-            else
-                new_pred_probs[i] = 128;
-
-            // Decide whether or not to update the reference frame probs.
-            // Returned costs are in 1/256 bit units.
-            old_cost =
-                (ref_pred_count[i][0] * vp8_cost_zero(cm->ref_pred_probs[i])) +
-                (ref_pred_count[i][1] * vp8_cost_one(cm->ref_pred_probs[i]));
-
-            new_cost =
-                (ref_pred_count[i][0] * vp8_cost_zero(new_pred_probs[i])) +
-                (ref_pred_count[i][1] * vp8_cost_one(new_pred_probs[i]));
-
-            // Cost saving must be >= 8 bits (2048 in these units)
-            if ( (old_cost - new_cost) >= 2048 )
-            {
-                cpi->ref_pred_probs_update[i] = 1;
-                cm->ref_pred_probs[i] = new_pred_probs[i];
-            }
-            else
-                cpi->ref_pred_probs_update[i] = 0;
-
-        }
-    }
-}
-
 static void encode_frame_to_data_rate
 (
     VP8_COMP *cpi,
@@ -3028,12 +2893,7 @@
     init_seg_features( cpi );
 
     // Decide how big to make the frame
-    if (!vp8_pick_frame_size(cpi))
-    {
-        cm->current_video_frame++;
-        cpi->frames_since_key++;
-        return;
-    }
+    vp8_pick_frame_size(cpi);
 
     vp8_clear_system_state();
 
@@ -3156,7 +3016,6 @@
     q_low  = cpi->active_best_quality;
     q_high = cpi->active_worst_quality;
 
-    vp8_save_coding_context(cpi);
 
     loop_count = 0;
 
@@ -3235,98 +3094,101 @@
         vp8_set_quantizer(cpi, Q);
         this_q = Q;
 
-        // setup skip prob for costing in mode/mv decision
-        if (cpi->common.mb_no_coeff_skip)
+        if ( loop_count == 0 )
         {
+            // setup skip prob for costing in mode/mv decision
+            if (cpi->common.mb_no_coeff_skip)
+            {
 #if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; k++)
-                cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
-#else
-            cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
+                int k;
+                for (k=0; k<MBSKIP_CONTEXTS; k++)
+                    cm->mbskip_pred_probs[k] = cpi->base_skip_false_prob[Q][k];
+#else
+                cpi->prob_skip_false = cpi->base_skip_false_prob[Q];
 #endif
 
-            if (cm->frame_type != KEY_FRAME)
-            {
-                if (cpi->common.refresh_alt_ref_frame)
+                if (cm->frame_type != KEY_FRAME)
                 {
-#if CONFIG_NEWENTROPY
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
+                    if (cpi->common.refresh_alt_ref_frame)
                     {
-                        if (cpi->last_skip_false_probs[2][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
-                    }
+#if CONFIG_NEWENTROPY
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[2][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[2][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[2] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[2];
+                        if (cpi->last_skip_false_probs[2] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[2];
 #endif
-                }
-                else if (cpi->common.refresh_golden_frame)
-                {
-#if CONFIG_NEWENTROPY
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
-                    {
-                        if (cpi->last_skip_false_probs[1][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
                     }
+                    else if (cpi->common.refresh_golden_frame)
+                    {
+#if CONFIG_NEWENTROPY
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[1][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[1][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[1] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[1];
+                        if (cpi->last_skip_false_probs[1] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[1];
 #endif
-                }
-                else
-                {
-#if CONFIG_NEWENTROPY
-                    int k;
-                    for (k=0; k<MBSKIP_CONTEXTS; k++)
-                    {
-                        if (cpi->last_skip_false_probs[0][k] != 0)
-                            cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
                     }
+                    else
+                    {
+#if CONFIG_NEWENTROPY
+                        int k;
+                        for (k=0; k<MBSKIP_CONTEXTS; k++)
+                        {
+                            if (cpi->last_skip_false_probs[0][k] != 0)
+                                cm->mbskip_pred_probs[k] = cpi->last_skip_false_probs[0][k];
+                        }
 #else
-                    if (cpi->last_skip_false_probs[0] != 0)
-                        cpi->prob_skip_false = cpi->last_skip_false_probs[0];
+                        if (cpi->last_skip_false_probs[0] != 0)
+                            cpi->prob_skip_false = cpi->last_skip_false_probs[0];
 #endif
-                }
+                    }
 
-                // as this is for cost estimate, let's make sure it does not
-                // get extreme either way
+                    // as this is for cost estimate, let's make sure it does not
+                    // get extreme either way
 #if CONFIG_NEWENTROPY
-                {
-                    int k;
-                    for (k=0; k<MBSKIP_CONTEXTS; ++k)
                     {
-                    if (cm->mbskip_pred_probs[k] < 5)
-                        cm->mbskip_pred_probs[k] = 5;
+                        int k;
+                        for (k=0; k<MBSKIP_CONTEXTS; ++k)
+                        {
+                        if (cm->mbskip_pred_probs[k] < 5)
+                            cm->mbskip_pred_probs[k] = 5;
 
-                    if (cm->mbskip_pred_probs[k] > 250)
-                        cm->mbskip_pred_probs[k] = 250;
+                        if (cm->mbskip_pred_probs[k] > 250)
+                            cm->mbskip_pred_probs[k] = 250;
 
-                    if (cpi->is_src_frame_alt_ref)
-                        cm->mbskip_pred_probs[k] = 1;
+                        if (cpi->is_src_frame_alt_ref)
+                            cm->mbskip_pred_probs[k] = 1;
+                        }
                     }
-                }
 #else
-                if (cpi->prob_skip_false < 5)
-                    cpi->prob_skip_false = 5;
+                    if (cpi->prob_skip_false < 5)
+                        cpi->prob_skip_false = 5;
 
-                if (cpi->prob_skip_false > 250)
-                    cpi->prob_skip_false = 250;
+                    if (cpi->prob_skip_false > 250)
+                        cpi->prob_skip_false = 250;
 
-                if (cpi->is_src_frame_alt_ref)
-                    cpi->prob_skip_false = 1;
+                    if (cpi->is_src_frame_alt_ref)
+                        cpi->prob_skip_false = 1;
 #endif
 
 
+                }
             }
+
+            // Set up entropy depending on frame type.
+            if (cm->frame_type == KEY_FRAME)
+                vp8_setup_key_frame(cpi);
+            else
+                vp8_setup_inter_frame(cpi);
         }
 
-        // Set up entropy depending on frame type.
-        if (cm->frame_type == KEY_FRAME)
-            vp8_setup_key_frame(cpi);
-        else
-            vp8_setup_inter_frame(cpi);
-
         // transform / motion compensation build reconstruction frame
         vp8_encode_frame(cpi);
 
@@ -3334,9 +3196,6 @@
         // seen in the last encoder iteration.
         update_base_skip_probs( cpi );
 
-        cpi->projected_frame_size -= vp8_estimate_entropy_savings(cpi);
-        cpi->projected_frame_size = (cpi->projected_frame_size > 0) ? cpi->projected_frame_size : 0;
-
         vp8_clear_system_state();  //__asm emms;
 
         if (frame_over_shoot_limit == 0)
@@ -3344,6 +3203,14 @@
 
         active_worst_qchanged = FALSE;
 
+        // Dummy pack of the bitstream using up to date stats to get an
+        // accurate estimate of output frame size to determine if we need
+        // to recode.
+        vp8_save_coding_context(cpi);
+        vp8_pack_bitstream(cpi, dest, size);
+        cpi->projected_frame_size = (*size) << 3;
+        vp8_restore_coding_context(cpi);
+
         // Special case handling for forced key frames
         if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced )
         {
@@ -3353,7 +3220,7 @@
                                          IF_RTCD(&cpi->rtcd.variance));
 
             int high_err_target = cpi->ambient_err;
-            int low_err_target = ((cpi->ambient_err * 3) >> 2);
+            int low_err_target = (cpi->ambient_err >> 1);
 
             // Prevent possible divide by zero error below for perfect KF
             kf_err += (!kf_err);
@@ -3521,7 +3388,6 @@
 
         if (Loop == TRUE)
         {
-            vp8_restore_coding_context(cpi);
             loop_count++;
 #if CONFIG_INTERNAL_STATS
             cpi->tot_recode_hits++;
@@ -3530,28 +3396,6 @@
     }
     while (Loop == TRUE);
 
-#if 0
-    // Experimental code for lagged and one pass
-    // Update stats used for one pass GF selection
-    {
-        /*
-            int frames_so_far;
-            double frame_intra_error;
-            double frame_coded_error;
-            double frame_pcnt_inter;
-            double frame_pcnt_motion;
-            double frame_mvr;
-            double frame_mvr_abs;
-            double frame_mvc;
-            double frame_mvc_abs;
-        */
-
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_coded_error = (double)cpi->prediction_error;
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_intra_error = (double)cpi->intra_error;
-        cpi->one_pass_frame_stats[cpi->one_pass_frame_index].frame_pcnt_inter = (double)(100 - cpi->this_frame_percent_intra) / 100.0;
-    }
-#endif
-
     // Special case code to reduce pulsing when key frames are forced at a
     // fixed interval. Note the reconstruction error if it is the frame before
     // the force key frame
@@ -3562,13 +3406,15 @@
                                            IF_RTCD(&cpi->rtcd.variance));
     }
 
-    // This frame's MVs are saved and will be used in next frame's MV prediction.
-    // Last frame has one more line(add to bottom) and one more column(add to right) than cm->mip. The edge elements are initialized to 0.
+    // This frame's MVs are saved and will be used in next frame's MV
+    // prediction. Last frame has one more line(add to bottom) and one
+    // more column(add to right) than cm->mip. The edge elements are
+    // initialized to 0.
     if(cm->show_frame)   //do not save for altref frame
     {
         int mb_row;
         int mb_col;
-        MODE_INFO *tmp = cm->mip; //point to beginning of allocated MODE_INFO arrays.
+        MODE_INFO *tmp = cm->mip;
 
         if(cm->frame_type != KEY_FRAME)
         {
@@ -3588,8 +3434,8 @@
     }
 
     // Update the GF useage maps.
-    // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
-    // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter
+    // This is done after completing the compression of a frame when all modes
+    // etc. are finalized but before loop filter
     vp8_update_gf_useage_maps(cpi, cm, &cpi->mb);
 
     if (cm->frame_type == KEY_FRAME)
@@ -3603,12 +3449,6 @@
     }
 #endif
 
-    // For inter frames the current default behavior is that when
-    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
-    // This is purely an encoder decision at present.
-    if (cm->refresh_golden_frame)
-        cm->copy_buffer_to_arf  = 2;
-
     cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
 
 #if WRITE_RECON_BUFFER
@@ -3620,34 +3460,13 @@
             cm->current_video_frame+1000);
 #endif
 
-    {
-        loopfilter_frame(cpi, cm);
-    }
+    // Pick the loop filter level for the frame.
+    loopfilter_frame(cpi, cm);
 
-    if(cm->show_frame)
-        write_yuv_frame_to_file(cm->frame_to_show);
-
-    update_reference_frames(cm);
-
-    // Work out the segment probabilities if segmentation is enabled and
-    // the map is due to be updated
-    if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
-    {
-        // Select the coding strategy for the segment map (temporal or spatial)
-        choose_segmap_coding_method( cpi );
-
-        // Take a copy of the segment map if it changed for future comparison
-        vpx_memcpy( cm->last_frame_seg_map,
-                    cpi->segmentation_map, cm->MBs );
-    }
-
-    // Update the common prediction model probabilities to reflect
-    // the what was seen in the current frame.
-    update_refpred_stats( cpi );
-
     // build the bitstream
     vp8_pack_bitstream(cpi, dest, size);
 
+    update_reference_frames(cm);
 
     /* Move storing frame_type out of the above loop since it is also
      * needed in motion search besides loopfilter */
@@ -3745,53 +3564,7 @@
     // Update the skip mb flag probabilities based on the distribution seen
     // in this frame.
     update_base_skip_probs( cpi );
-/*
-    if (cm->frame_type != KEY_FRAME)
-    {
-        if (cpi->common.refresh_alt_ref_frame)
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[2][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[2] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[2] = cm->base_qindex;
-        }
-        else if (cpi->common.refresh_golden_frame)
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[1][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[1] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[1] = cm->base_qindex;
-        }
-        else
-        {
-#if CONFIG_NEWENTROPY
-            int k;
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->last_skip_false_probs[0][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->last_skip_false_probs[0] = cpi->prob_skip_false;
-#endif
-            cpi->last_skip_probs_q[0] = cm->base_qindex;
 
-            //update the baseline
-#if CONFIG_NEWENTROPY
-            for (k=0; k<MBSKIP_CONTEXTS; ++k)
-                cpi->base_skip_false_prob[cm->base_qindex][k] = cm->mbskip_pred_probs[k];
-#else
-            cpi->base_skip_false_prob[cm->base_qindex] = cpi->prob_skip_false;
-#endif
-
-        }
-    }
-*/
 #if 0 && CONFIG_INTERNAL_STATS
     {
         FILE *f = fopen("tmp.stt", "a");
@@ -3942,14 +3715,10 @@
 
         // As this frame is a key frame  the next defaults to an inter frame.
         cm->frame_type = INTER_FRAME;
-
-        cpi->last_frame_percent_intra = 100;
     }
     else
     {
         *frame_flags = cm->frame_flags&~FRAMEFLAGS_KEY;
-
-        cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
     }
 
     // Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -55,13 +55,6 @@
 
 typedef struct
 {
-    int kf_indicated;
-    unsigned int frames_since_key;
-    unsigned int frames_since_golden;
-    int filter_level;
-    int frames_till_gf_update_due;
-    int recent_ref_frame_usage[MAX_REF_FRAMES];
-
     MV_CONTEXT mvc[2];
     int mvcosts[2][MVvals+1];
 #if CONFIG_HIGH_PRECISION_MV
@@ -79,31 +72,29 @@
     int inter_uv_modes[VP8_UV_MODES];
     int inter_b_modes[B_MODE_COUNT];
 #endif
-    /* interframe intra mode probs */
-    vp8_prob ymode_prob[VP8_YMODES-1];
-    /* keyframe intra mode probs */
-#if CONFIG_QIMODE
-    vp8_prob kf_ymode_prob[8][VP8_YMODES-1];
-#else
-    vp8_prob kf_ymode_prob[VP8_YMODES-1];
-#endif
 
-#if CONFIG_UVINTRA
-    vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
-    vp8_prob uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
-#else
-    vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1];
-    vp8_prob uv_mode_prob[VP8_UV_MODES-1];
-#endif
-    /* intra MB type cts this frame */
-    int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES];
+    vp8_prob segment_pred_probs[PREDICTION_PROBS];
+    unsigned char ref_pred_probs_update[PREDICTION_PROBS];
+    vp8_prob ref_pred_probs[PREDICTION_PROBS];
+    vp8_prob prob_comppred[COMP_PRED_CONTEXTS];
 
-    int count_mb_ref_frame_usage[MAX_REF_FRAMES];
+    unsigned char * last_frame_seg_map_copy;
 
-    int this_frame_percent_intra;
-    int last_frame_percent_intra;
+    // 0 = Intra, Last, GF, ARF
+    signed char last_ref_lf_deltas[MAX_REF_LF_DELTAS];
+    // 0 = BPRED, ZERO_MV, MV, SPLIT
+    signed char last_mode_lf_deltas[MAX_MODE_LF_DELTAS];
 
+    vp8_prob coef_probs[BLOCK_TYPES]
+                       [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
+    vp8_prob coef_probs_8x8[BLOCK_TYPES]
+                           [COEF_BANDS][PREV_COEF_CONTEXTS][ENTROPY_NODES];
 
+    int mv_ref_ct[6][4][2];
+    int mode_context[6][4];
+    int mv_ref_ct_a[6][4][2];
+    int mode_context_a[6][4];
+
 } CODING_CONTEXT;
 
 typedef struct
@@ -490,17 +481,15 @@
     int pass;
 
 #if CONFIG_NEWENTROPY
-    int last_skip_false_probs[3][MBSKIP_CONTEXTS];
+    vp8_prob last_skip_false_probs[3][MBSKIP_CONTEXTS];
 #else
-    int prob_skip_false;
-    int last_skip_false_probs[3];
+    vp8_prob prob_skip_false;
+    vp8_prob last_skip_false_probs[3];
 #endif
     int last_skip_probs_q[3];
 
     int recent_ref_frame_usage[MAX_REF_FRAMES];
     int count_mb_ref_frame_usage[MAX_REF_FRAMES];
-    int this_frame_percent_intra;
-    int last_frame_percent_intra;
     int ref_frame_flags;
 
     unsigned char ref_pred_probs_update[PREDICTION_PROBS];
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -135,6 +135,8 @@
 void vp8_save_coding_context(VP8_COMP *cpi)
 {
     CODING_CONTEXT *const cc = & cpi->coding_context;
+    VP8_COMMON *cm = &cpi->common;
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     // Stores a snapshot of key state variables which can subsequently be
     // restored with a call to vp8_restore_coding_context. These functions are
@@ -141,27 +143,18 @@
     // intended for use in a re-code loop in vp8_compress_frame where the
     // quantizer value is adjusted between loop iterations.
 
-    cc->frames_since_key          = cpi->frames_since_key;
-    cc->filter_level             = cpi->common.filter_level;
-    cc->frames_till_gf_update_due   = cpi->frames_till_gf_update_due;
-    cc->frames_since_golden       = cpi->common.frames_since_golden;
-
-    vp8_copy(cc->mvc,      cpi->common.fc.mvc);
+    vp8_copy(cc->mvc,      cm->fc.mvc);
     vp8_copy(cc->mvcosts,  cpi->mb.mvcosts);
 #if CONFIG_HIGH_PRECISION_MV
-    vp8_copy(cc->mvc_hp,      cpi->common.fc.mvc_hp);
+    vp8_copy(cc->mvc_hp,     cm->fc.mvc_hp);
     vp8_copy(cc->mvcosts_hp,  cpi->mb.mvcosts_hp);
 #endif
 
-    vp8_copy(cc->kf_ymode_prob,   cpi->common.kf_ymode_prob);
-    vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
-    vp8_copy(cc->kf_uv_mode_prob,  cpi->common.kf_uv_mode_prob);
-    vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
+    vp8_copy( cc->mv_ref_ct, cm->mv_ref_ct );
+    vp8_copy( cc->mode_context, cm->mode_context );
+    vp8_copy( cc->mv_ref_ct_a, cm->mv_ref_ct_a );
+    vp8_copy( cc->mode_context_a, cm->mode_context_a );
 
-    vp8_copy(cc->ymode_count, cpi->ymode_count);
-    vp8_copy(cc->uv_mode_count, cpi->uv_mode_count);
-
-
     // Stats
 #ifdef MODE_STATS
     vp8_copy(cc->y_modes,       y_modes);
@@ -172,37 +165,41 @@
     vp8_copy(cc->inter_b_modes,  inter_b_modes);
 #endif
 
-    cc->this_frame_percent_intra = cpi->this_frame_percent_intra;
-}
+    vp8_copy( cc->segment_pred_probs, cm->segment_pred_probs );
+    vp8_copy( cc->ref_pred_probs_update, cpi->ref_pred_probs_update );
+    vp8_copy( cc->ref_pred_probs, cm->ref_pred_probs );
+    vp8_copy( cc->prob_comppred, cm->prob_comppred );
 
+    vpx_memcpy( cpi->coding_context.last_frame_seg_map_copy,
+                cm->last_frame_seg_map, (cm->mb_rows * cm->mb_cols) );
 
+    vp8_copy( cc->last_ref_lf_deltas, xd->last_ref_lf_deltas );
+    vp8_copy( cc->last_mode_lf_deltas, xd->last_mode_lf_deltas );
+
+    vp8_copy( cc->coef_probs, cm->fc.coef_probs );
+    vp8_copy( cc->coef_probs_8x8, cm->fc.coef_probs_8x8 );
+}
+
 void vp8_restore_coding_context(VP8_COMP *cpi)
 {
     CODING_CONTEXT *const cc = & cpi->coding_context;
+    VP8_COMMON *cm = &cpi->common;
+    MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
     // Restore key state variables to the snapshot state stored in the
     // previous call to vp8_save_coding_context.
 
-    cpi->frames_since_key         =   cc->frames_since_key;
-    cpi->common.filter_level     =   cc->filter_level;
-    cpi->frames_till_gf_update_due  =   cc->frames_till_gf_update_due;
-    cpi->common.frames_since_golden       =   cc->frames_since_golden;
-
-    vp8_copy(cpi->common.fc.mvc, cc->mvc);
-
+    vp8_copy(cm->fc.mvc, cc->mvc);
     vp8_copy(cpi->mb.mvcosts, cc->mvcosts);
 #if CONFIG_HIGH_PRECISION_MV
-    vp8_copy(cpi->common.fc.mvc_hp, cc->mvc_hp);
-
+    vp8_copy(cm->fc.mvc_hp, cc->mvc_hp);
     vp8_copy(cpi->mb.mvcosts_hp, cc->mvcosts_hp);
 #endif
-    vp8_copy(cpi->common.kf_ymode_prob,   cc->kf_ymode_prob);
-    vp8_copy(cpi->common.fc.ymode_prob,   cc->ymode_prob);
-    vp8_copy(cpi->common.kf_uv_mode_prob,  cc->kf_uv_mode_prob);
-    vp8_copy(cpi->common.fc.uv_mode_prob,  cc->uv_mode_prob);
 
-    vp8_copy(cpi->ymode_count, cc->ymode_count);
-    vp8_copy(cpi->uv_mode_count, cc->uv_mode_count);
+    vp8_copy( cm->mv_ref_ct, cc->mv_ref_ct );
+    vp8_copy( cm->mode_context, cc->mode_context );
+    vp8_copy( cm->mv_ref_ct_a, cc->mv_ref_ct_a );
+    vp8_copy( cm->mode_context_a, cc->mode_context_a );
 
     // Stats
 #ifdef MODE_STATS
@@ -214,8 +211,20 @@
     vp8_copy(inter_b_modes, cc->inter_b_modes);
 #endif
 
+    vp8_copy( cm->segment_pred_probs, cc->segment_pred_probs );
+    vp8_copy( cpi->ref_pred_probs_update, cc->ref_pred_probs_update );
+    vp8_copy( cm->ref_pred_probs, cc->ref_pred_probs );
+    vp8_copy( cm->prob_comppred, cc->prob_comppred );
 
-    cpi->this_frame_percent_intra = cc->this_frame_percent_intra;
+    vpx_memcpy( cm->last_frame_seg_map,
+                cpi->coding_context.last_frame_seg_map_copy,
+                (cm->mb_rows * cm->mb_cols) );
+
+    vp8_copy( xd->last_ref_lf_deltas, cc->last_ref_lf_deltas );
+    vp8_copy( xd->last_mode_lf_deltas, cc->last_mode_lf_deltas );
+
+    vp8_copy( cm->fc.coef_probs, cc->coef_probs );
+    vp8_copy( cm->fc.coef_probs_8x8, cc->coef_probs_8x8 );
 }
 
 
@@ -231,7 +240,6 @@
         int flag[2] = {1, 1};
         vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cpi->common.fc.mvc, flag);
     }
-    vpx_memset(cpi->common.fc.pre_mvc, 0, sizeof(cpi->common.fc.pre_mvc));  //initialize pre_mvc to all zero.
 #if CONFIG_HIGH_PRECISION_MV
     vpx_memcpy(cpi->common.fc.mvc_hp, vp8_default_mv_context_hp, sizeof(vp8_default_mv_context_hp));
     {
@@ -238,7 +246,6 @@
         int flag[2] = {1, 1};
         vp8_build_component_cost_table_hp(cpi->mb.mvcost_hp, (const MV_CONTEXT_HP *) cpi->common.fc.mvc_hp, flag);
     }
-    vpx_memset(cpi->common.fc.pre_mvc_hp, 0, sizeof(cpi->common.fc.pre_mvc_hp));  //initialize pre_mvc to all zero.
 #endif
 
     cpi->common.txfm_mode = ONLY_4X4;
@@ -270,17 +277,6 @@
                 default_vp8_mode_contexts,
                 sizeof(default_vp8_mode_contexts));
 
-    /* make sure coding_context is correct in key frame recode */
-    {
-        CODING_CONTEXT *const cc = & cpi->coding_context;
-
-        vp8_copy(cc->mvc,      cpi->common.fc.mvc);
-#if CONFIG_HIGH_PRECISION_MV
-        vp8_copy(cc->mvc_hp,      cpi->common.fc.mvc_hp);
-#endif
-        vp8_copy(cc->ymode_prob,   cpi->common.fc.ymode_prob);
-        vp8_copy(cc->uv_mode_prob,  cpi->common.fc.uv_mode_prob);
-    }
 }
 void vp8_setup_inter_frame(VP8_COMP *cpi)
 {
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -144,7 +144,7 @@
     RANGE_CHECK_HI(cfg, rc_max_quantizer,   63);
     RANGE_CHECK_HI(cfg, rc_min_quantizer,   cfg->rc_max_quantizer);
     RANGE_CHECK_HI(cfg, g_threads,          64);
-    RANGE_CHECK_HI(cfg, g_lag_in_frames,    25);
+    RANGE_CHECK_HI(cfg, g_lag_in_frames,    MAX_LAG_BUFFERS);
     RANGE_CHECK(cfg, rc_end_usage,          VPX_VBR, VPX_CQ);
     RANGE_CHECK_HI(cfg, rc_undershoot_pct,  1000);
     RANGE_CHECK_HI(cfg, rc_overshoot_pct,   1000);