shithub: libvpx

Download patch

ref: c6f13f32784330350f176f453c8a4c2a9f6b90a6
parent: eab804558bb7ff3fb503a1f9ccaf641d0dbc0120
parent: 47a2154c0e1130a247b7920b0a0c57ada212abc1
author: John Koleszar <jkoleszar@google.com>
date: Wed Oct 17 11:15:10 EDT 2012

Merge changes Ic711a378,I43a46c36,If19ee74a into experimental

* changes:
  Move remaining per-frame data into partition 0
  Interleave modes/residual per macroblock
  Force interleaved decoding

--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -37,9 +37,9 @@
 #define DCT_VAL_CATEGORY5       9       /* 35-66     Extra Bits 5+1 */
 #define DCT_VAL_CATEGORY6       10      /* 67+       Extra Bits 13+1 */
 #define DCT_EOB_TOKEN           11      /* EOB       Extra Bits 0+0 */
-
 #define MAX_ENTROPY_TOKENS 12
 #define ENTROPY_NODES 11
+#define EOSB_TOKEN              127     /* Not signalled, encoder only */
 
 extern const vp8_tree_index vp8_coef_tree[];
 
--- a/vp8/common/pred_common.c
+++ b/vp8/common/pred_common.c
@@ -15,8 +15,8 @@
 // TBD prediction functions for various bitstream signals
 
 // Returns a context number for the given MB prediction signal
-unsigned char get_pred_context(VP8_COMMON *const cm,
-                               MACROBLOCKD *const xd,
+unsigned char get_pred_context(const VP8_COMMON *const cm,
+                               const MACROBLOCKD *const xd,
                                PRED_ID pred_id) {
   int pred_context;
   MODE_INFO *m = xd->mode_info_context;
@@ -106,8 +106,8 @@
 
 // This function returns a context probability for coding a given
 // prediction signal
-vp8_prob get_pred_prob(VP8_COMMON *const cm,
-                       MACROBLOCKD *const xd,
+vp8_prob get_pred_prob(const VP8_COMMON *const cm,
+                       const MACROBLOCKD *const xd,
                        PRED_ID pred_id) {
   vp8_prob pred_probability;
   int pred_context;
@@ -146,10 +146,10 @@
 
 // This function returns a context probability ptr for coding a given
 // prediction signal
-vp8_prob *get_pred_probs(VP8_COMMON *const cm,
-                         MACROBLOCKD *const xd,
+const vp8_prob *get_pred_probs(const VP8_COMMON *const cm,
+                         const MACROBLOCKD *const xd,
                          PRED_ID pred_id) {
-  vp8_prob *pred_probability;
+  const vp8_prob *pred_probability;
   int pred_context;
 
   // Get the appropriate prediction context
@@ -191,7 +191,7 @@
 
 // This function returns the status of the given prediction signal.
 // I.e. is the predicted value for the given signal correct.
-unsigned char get_pred_flag(MACROBLOCKD *const xd,
+unsigned char get_pred_flag(const MACROBLOCKD *const xd,
                             PRED_ID pred_id) {
   unsigned char pred_flag = 0;
 
@@ -260,14 +260,14 @@
 // peredict various bitstream signals.
 
 // Macroblock segment id prediction function
-unsigned char get_pred_mb_segid(VP8_COMMON *const cm, int MbIndex) {
+unsigned char get_pred_mb_segid(const VP8_COMMON *const cm, int MbIndex) {
   // Currently the prediction for the macroblock segment ID is
   // the value stored for this macroblock in the previous frame.
   return cm->last_frame_seg_map[MbIndex];
 }
 
-MV_REFERENCE_FRAME get_pred_ref(VP8_COMMON *const cm,
-                                MACROBLOCKD *const xd) {
+MV_REFERENCE_FRAME get_pred_ref(const VP8_COMMON *const cm,
+                                const MACROBLOCKD *const xd) {
   MODE_INFO *m = xd->mode_info_context;
 
   MV_REFERENCE_FRAME left;
--- a/vp8/common/pred_common.h
+++ b/vp8/common/pred_common.h
@@ -28,19 +28,19 @@
 } PRED_ID;
 
 
-extern unsigned char get_pred_context(VP8_COMMON *const cm,
-                                      MACROBLOCKD *const xd,
+extern unsigned char get_pred_context(const VP8_COMMON *const cm,
+                                      const MACROBLOCKD *const xd,
                                       PRED_ID pred_id);
 
-extern vp8_prob get_pred_prob(VP8_COMMON *const cm,
-                              MACROBLOCKD *const xd,
+extern vp8_prob get_pred_prob(const VP8_COMMON *const cm,
+                              const MACROBLOCKD *const xd,
                               PRED_ID pred_id);
 
-extern vp8_prob *get_pred_probs(VP8_COMMON *const cm,
-                                MACROBLOCKD *const xd,
+extern const vp8_prob *get_pred_probs(const VP8_COMMON *const cm,
+                                const MACROBLOCKD *const xd,
                                 PRED_ID pred_id);
 
-extern unsigned char get_pred_flag(MACROBLOCKD *const xd,
+extern unsigned char get_pred_flag(const MACROBLOCKD *const xd,
                                    PRED_ID pred_id);
 
 extern void set_pred_flag(MACROBLOCKD *const xd,
@@ -48,10 +48,10 @@
                           unsigned char pred_flag);
 
 
-extern unsigned char get_pred_mb_segid(VP8_COMMON *const cm, int MbIndex);
+extern unsigned char get_pred_mb_segid(const VP8_COMMON *const cm, int MbIndex);
 
-extern MV_REFERENCE_FRAME get_pred_ref(VP8_COMMON *const cm,
-                                       MACROBLOCKD *const xd);
+extern MV_REFERENCE_FRAME get_pred_ref(const VP8_COMMON *const cm,
+                                       const MACROBLOCKD *const xd);
 extern void compute_mod_refprobs(VP8_COMMON *const cm);
 
 #endif /* __INC_PRED_COMMON_H__ */
--- a/vp8/common/seg_common.c
+++ b/vp8/common/seg_common.c
@@ -19,7 +19,7 @@
 // the coding mechanism is still subject to change so these provide a
 // convenient single point of change.
 
-int segfeature_active(MACROBLOCKD *xd,
+int segfeature_active(const MACROBLOCKD *xd,
                       int segment_id,
                       SEG_LVL_FEATURES feature_id) {
   // Return true if mask bit set and segmentation enabled.
@@ -66,7 +66,7 @@
   xd->segment_feature_data[segment_id][feature_id] = seg_data;
 }
 
-int get_segdata(MACROBLOCKD *xd,
+int get_segdata(const MACROBLOCKD *xd,
                 int segment_id,
                 SEG_LVL_FEATURES feature_id) {
   return xd->segment_feature_data[segment_id][feature_id];
@@ -126,7 +126,7 @@
     (1 << ref_frame);
 }
 
-int check_segref(MACROBLOCKD *xd,
+int check_segref(const MACROBLOCKD *xd,
                  int segment_id,
                  MV_REFERENCE_FRAME ref_frame) {
   return (xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] &
--- a/vp8/common/seg_common.h
+++ b/vp8/common/seg_common.h
@@ -15,7 +15,7 @@
 #ifndef __INC_SEG_COMMON_H__
 #define __INC_SEG_COMMON_H__ 1
 
-int segfeature_active(MACROBLOCKD *xd,
+int segfeature_active(const MACROBLOCKD *xd,
                       int segment_id,
                       SEG_LVL_FEATURES feature_id);
 
@@ -42,7 +42,7 @@
                  SEG_LVL_FEATURES feature_id,
                  int seg_data);
 
-int get_segdata(MACROBLOCKD *xd,
+int get_segdata(const MACROBLOCKD *xd,
                 int segment_id,
                 SEG_LVL_FEATURES feature_id);
 
@@ -73,7 +73,7 @@
                 int segment_id,
                 MV_REFERENCE_FRAME ref_frame);
 
-int check_segref(MACROBLOCKD *xd,
+int check_segref(const MACROBLOCKD *xd,
                  int segment_id,
                  MV_REFERENCE_FRAME ref_frame);
 
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -78,7 +78,7 @@
                              int mb_row,
                              int mb_col) {
   VP8_COMMON *const cm = & pbi->common;
-  vp8_reader *const bc = & pbi->bc;
+  vp8_reader *const bc = pbi->mb.current_bc;
   const int mis = pbi->common.mode_info_stride;
   int map_index = mb_row * pbi->common.mb_cols + mb_col;
   MB_PREDICTION_MODE y_mode;
@@ -612,9 +612,8 @@
 }
 #endif
 
-static void mb_mode_mv_init(VP8D_COMP *pbi) {
+static void mb_mode_mv_init(VP8D_COMP *pbi, vp8_reader *bc) {
   VP8_COMMON *const cm = & pbi->common;
-  vp8_reader *const bc = & pbi->bc;
 #if CONFIG_NEWMVENTROPY
   nmv_context *const nmvc = &pbi->common.fc.nmvc;
 #else
@@ -623,14 +622,10 @@
 #endif
   MACROBLOCKD *const xd  = & pbi->mb;
 
-  vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
-  if (pbi->common.mb_no_coeff_skip) {
-    int k;
-    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-      cm->mbskip_pred_probs[k] = (vp8_prob)vp8_read_literal(bc, 8);
-  }
-
-  if (cm->frame_type != KEY_FRAME) {
+  if (cm->frame_type == KEY_FRAME) {
+    if (!cm->kf_ymode_probs_update)
+      cm->kf_ymode_probs_index = vp8_read_literal(bc, 3);
+  } else {
 #if CONFIG_PRED_FILTER
     cm->pred_filter_mode = (vp8_prob)vp8_read_literal(bc, 2);
 
@@ -682,9 +677,9 @@
 // value
 static void read_mb_segment_id(VP8D_COMP *pbi,
                                int mb_row, int mb_col) {
-  vp8_reader *const bc = & pbi->bc;
   VP8_COMMON *const cm = & pbi->common;
   MACROBLOCKD *const xd  = & pbi->mb;
+  vp8_reader *const bc = xd->current_bc;
   MODE_INFO *mi = xd->mode_info_context;
   MB_MODE_INFO *mbmi = &mi->mbmi;
   int index = mb_row * pbi->common.mb_cols + mb_col;
@@ -755,7 +750,6 @@
                              MODE_INFO *prev_mi,
                              int mb_row, int mb_col) {
   VP8_COMMON *const cm = & pbi->common;
-  vp8_reader *const bc = & pbi->bc;
 #if CONFIG_NEWMVENTROPY
   nmv_context *const nmvc = &pbi->common.fc.nmvc;
 #else
@@ -764,6 +758,7 @@
 #endif
   const int mis = pbi->common.mode_info_stride;
   MACROBLOCKD *const xd  = & pbi->mb;
+  vp8_reader *const bc = xd->current_bc;
 
   int_mv *const mv = & mbmi->mv;
   int mb_to_left_edge;
@@ -1302,96 +1297,17 @@
   }
 }
 
-void vp8_decode_mode_mvs(VP8D_COMP *pbi) {
-  int i;
+void vpx_decode_mode_mvs_init(VP8D_COMP *pbi){
   VP8_COMMON *cm = &pbi->common;
-  MODE_INFO *mi = cm->mi;
-  MACROBLOCKD *const xd  = &pbi->mb;
-  int sb_row, sb_col;
-  int sb_rows = (cm->mb_rows + 1) >> 1;
-  int sb_cols = (cm->mb_cols + 1) >> 1;
-  int row_delta[4] = { 0, +1,  0, -1};
-  int col_delta[4] = { +1, -1, +1, +1};
 
-  MODE_INFO *prev_mi = cm->prev_mi;
-
-  mb_mode_mv_init(pbi);
-
-  if (cm->frame_type == KEY_FRAME && !cm->kf_ymode_probs_update) {
-    cm->kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
+  vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
+  if (pbi->common.mb_no_coeff_skip) {
+    int k;
+    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
+      cm->mbskip_pred_probs[k] = (vp8_prob)vp8_read_literal(&pbi->bc, 8);
   }
 
-  for (sb_row = 0; sb_row < sb_rows; sb_row++) {
-    int mb_col = 0;
-    int mb_row = (sb_row << 1);
-
-    for (sb_col = 0; sb_col < sb_cols; sb_col++) {
-#if CONFIG_SUPERBLOCKS
-      mi->mbmi.encoded_as_sb = vp8_read(&pbi->bc, cm->sb_coded);
-#endif
-      for (i = 0; i < 4; i++) {
-
-        int dy = row_delta[i];
-        int dx = col_delta[i];
-        int offset_extended = dy * cm->mode_info_stride + dx;
-
-        if ((mb_row >= cm->mb_rows) || (mb_col >= cm->mb_cols)) {
-          /* next macroblock */
-          mb_row += dy;
-          mb_col += dx;
-          mi += offset_extended;
-          prev_mi += offset_extended;
-          continue;
-        }
-#if CONFIG_SUPERBLOCKS
-        if (i)
-          mi->mbmi.encoded_as_sb = 0;
-#endif
-
-        // Make sure the MacroBlockD mode info pointer is set correctly
-        xd->mode_info_context = mi;
-        xd->prev_mode_info_context = prev_mi;
-
-        pbi->mb.mb_to_top_edge = -((mb_row * 16)) << 3;
-        pbi->mb.mb_to_bottom_edge =
-            ((pbi->common.mb_rows - 1 - mb_row) * 16) << 3;
-
-        if (cm->frame_type == KEY_FRAME)
-          vp8_kfread_modes(pbi, mi, mb_row, mb_col);
-        else
-          read_mb_modes_mv(pbi, mi, &mi->mbmi, prev_mi, mb_row,
-                           mb_col);
-
-#if CONFIG_SUPERBLOCKS
-        if (mi->mbmi.encoded_as_sb) {
-          assert(!i);
-          mb_col += 2;
-          mi[1] = mi[cm->mode_info_stride] =
-            mi[cm->mode_info_stride + 1] = mi[0];
-          mi += 2;
-          prev_mi += 2;
-          break;
-        }
-#endif
-
-        /* next macroblock */
-        mb_row += dy;
-        mb_col += dx;
-        mi += offset_extended;
-        prev_mi += offset_extended;
-      }
-    }
-
-    mi += cm->mode_info_stride + (1 - (cm->mb_cols & 0x1));
-    prev_mi += cm->mode_info_stride + (1 - (cm->mb_cols & 0x1));
-  }
-}
-
-void vpx_decode_mode_mvs_init(VP8D_COMP *pbi){
-  VP8_COMMON *cm = &pbi->common;
-  mb_mode_mv_init(pbi);
-  if (cm->frame_type == KEY_FRAME && !cm->kf_ymode_probs_update)
-    cm->kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
+  mb_mode_mv_init(pbi, &pbi->bc);
 }
 void vpx_decode_mb_mode_mv(VP8D_COMP *pbi,
                            MACROBLOCKD *xd,
--- a/vp8/decoder/decodemv.h
+++ b/vp8/decoder/decodemv.h
@@ -11,7 +11,6 @@
 
 #include "onyxd_int.h"
 
-void vp8_decode_mode_mvs(VP8D_COMP *);
 void vpx_decode_mb_mode_mv(VP8D_COMP *pbi,
                            MACROBLOCKD *xd,
                            int mb_row,
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -627,8 +627,7 @@
     MODE_INFO *mi = xd->mode_info_context;
 
 #if CONFIG_SUPERBLOCKS
-    if (pbi->interleaved_decoding)
-      mi->mbmi.encoded_as_sb = vp8_read(&pbi->bc, pc->sb_coded);
+    mi->mbmi.encoded_as_sb = vp8_read(&pbi->bc, pc->sb_coded);
 #endif
 
     // Process the 4 MBs within the SB in the order:
@@ -677,8 +676,7 @@
       if (i)
         mi->mbmi.encoded_as_sb = 0;
 #endif
-      if(pbi->interleaved_decoding)
-        vpx_decode_mb_mode_mv(pbi, xd, mb_row, mb_col);
+      vpx_decode_mb_mode_mv(pbi, xd, mb_row, mb_col);
 
       update_blockd_bmi(xd);
 
@@ -1143,7 +1141,7 @@
 
   init_frame(pbi);
 
-  if (vp8dx_start_decode(bc, data, data_end - data))
+  if (vp8dx_start_decode(bc, data, first_partition_length_in_bytes))
     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder 0");
   if (pc->frame_type == KEY_FRAME) {
@@ -1502,10 +1500,7 @@
   /* Read the mb_no_coeff_skip flag */
   pc->mb_no_coeff_skip = (int)vp8_read_bit(bc);
 
-  if(pbi->interleaved_decoding)
-    vpx_decode_mode_mvs_init(pbi);
-  else
-    vp8_decode_mode_mvs(pbi);
+  vpx_decode_mode_mvs_init(pbi);
 
   vpx_memset(pc->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES) * pc->mb_cols);
 
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -149,8 +149,6 @@
 
   pbi->decoded_key_frame = 0;
 
-  pbi->interleaved_decoding = CONFIG_NEWBESTREFMV || CONFIG_SUPERBLOCKS;
-
   return (VP8D_PTR) pbi;
 }
 
--- a/vp8/decoder/onyxd_int.h
+++ b/vp8/decoder/onyxd_int.h
@@ -82,8 +82,6 @@
 
   int decoded_key_frame;
 
-  int interleaved_decoding;
-
 } VP8D_COMP;
 
 int vp8_decode_frame(VP8D_COMP *cpi);
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -454,13 +454,15 @@
   return bestsavings;
 }
 
-static void pack_tokens_c(vp8_writer *w, const TOKENEXTRA *p, int xcount) {
-  const TOKENEXTRA *const stop = p + xcount;
+static void pack_mb_tokens(vp8_writer *w,
+                           TOKENEXTRA **tp,
+                           const TOKENEXTRA *const stop) {
   unsigned int split;
   unsigned int shift;
   int count = w->count;
   unsigned int range = w->range;
   unsigned int lowvalue = w->lowvalue;
+  TOKENEXTRA *p = *tp;
 
   while (p < stop) {
     const int t = p->Token;
@@ -471,6 +473,12 @@
     int v = a->value;
     int n = a->Len;
 
+    if (t == EOSB_TOKEN)
+    {
+      ++p;
+      break;
+    }
+
     /* skip one or two nodes */
     if (p->skip_eob_node) {
       n -= p->skip_eob_node;
@@ -604,7 +612,6 @@
       }
 
     }
-
     ++p;
   }
 
@@ -611,7 +618,7 @@
   w->count = count;
   w->lowvalue = lowvalue;
   w->range = range;
-
+  *tp = p;
 }
 
 static void write_partition_size(unsigned char *cx_data, int size) {
@@ -844,7 +851,7 @@
 static void pack_inter_mode_mvs(VP8_COMP *const cpi) {
   int i;
   VP8_COMMON *const pc = & cpi->common;
-  vp8_writer *const w = & cpi->bc;
+  vp8_writer *const w = & cpi->bc2;
 #if CONFIG_NEWMVENTROPY
   const nmv_context *nmvc = &pc->fc.nmvc;
 #else
@@ -855,6 +862,8 @@
   MACROBLOCKD *xd = &cpi->mb.e_mbd;
   MODE_INFO *m;
   MODE_INFO *prev_m;
+  TOKENEXTRA *tok = cpi->tok;
+  TOKENEXTRA *tok_end = tok + cpi->tok_count;
 
   const int mis = pc->mode_info_stride;
   int mb_row, mb_col;
@@ -871,73 +880,6 @@
 
   cpi->mb.partition_info = cpi->mb.pi;
 
-  // Update the probabilities used to encode reference frame data
-  update_ref_probs(cpi);
-
-#ifdef ENTROPY_STATS
-  active_section = 1;
-#endif
-
-  if (pc->mb_no_coeff_skip) {
-    int k;
-
-    update_skip_probs(cpi);
-    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
-      vp8_write_literal(w, pc->mbskip_pred_probs[k], 8);
-  }
-
-#if CONFIG_PRED_FILTER
-  // Write the prediction filter mode used for this frame
-  vp8_write_literal(w, pc->pred_filter_mode, 2);
-
-  // Write prediction filter on/off probability if signaling at MB level
-  if (pc->pred_filter_mode == 2)
-    vp8_write_literal(w, pc->prob_pred_filter_off, 8);
-
-  // printf("pred_filter_mode:%d  prob_pred_filter_off:%d\n",
-  //       pc->pred_filter_mode, pc->prob_pred_filter_off);
-#endif
-#if CONFIG_SWITCHABLE_INTERP
-  if (pc->mcomp_filter_type == SWITCHABLE)
-    update_switchable_interp_probs(cpi);
-#endif
-
-  vp8_write_literal(w, pc->prob_intra_coded, 8);
-  vp8_write_literal(w, pc->prob_last_coded, 8);
-  vp8_write_literal(w, pc->prob_gf_coded, 8);
-
-  if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
-    vp8_write(w, 1, 128);
-    vp8_write(w, 1, 128);
-    for (i = 0; i < COMP_PRED_CONTEXTS; i++) {
-      if (cpi->single_pred_count[i] + cpi->comp_pred_count[i]) {
-        pc->prob_comppred[i] = cpi->single_pred_count[i] * 255 /
-                               (cpi->single_pred_count[i] + cpi->comp_pred_count[i]);
-        if (pc->prob_comppred[i] < 1)
-          pc->prob_comppred[i] = 1;
-      } else {
-        pc->prob_comppred[i] = 128;
-      }
-      vp8_write_literal(w, pc->prob_comppred[i], 8);
-    }
-  } else if (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY) {
-    vp8_write(w, 0, 128);
-  } else { /* compound prediction only */
-    vp8_write(w, 1, 128);
-    vp8_write(w, 0, 128);
-  }
-
-  update_mbintra_mode_probs(cpi);
-
-#if CONFIG_NEWMVENTROPY
-  vp8_write_nmvprobs(cpi, xd->allow_high_precision_mv);
-#else
-  if (xd->allow_high_precision_mv)
-    vp8_write_mvprobs_hp(cpi);
-  else
-    vp8_write_mvprobs(cpi);
-#endif
-
   mb_row = 0;
   for (row = 0; row < pc->mb_rows; row += 2) {
     m = pc->mi + row * mis;
@@ -1315,6 +1257,12 @@
         }
 #endif
 
+#ifdef ENTROPY_STATS
+        active_section = 1;
+#endif
+        assert(tok < tok_end);
+        pack_mb_tokens(w, &tok, tok_end);
+
 #if CONFIG_SUPERBLOCKS
         if (m->mbmi.encoded_as_sb) {
           assert(!i);
@@ -1348,8 +1296,110 @@
 }
 
 
+static void write_mb_modes_kf(const VP8_COMMON  *c,
+                              const MACROBLOCKD *xd,
+                              const MODE_INFO   *m,
+                              int                mode_info_stride,
+                              vp8_writer *const  bc) {
+  const int mis = mode_info_stride;
+  int ym;
+  int segment_id;
+
+  ym = m->mbmi.mode;
+  segment_id = m->mbmi.segment_id;
+
+  if (xd->update_mb_segmentation_map) {
+    write_mb_segid(bc, &m->mbmi, xd);
+  }
+
+  if (c->mb_no_coeff_skip &&
+      (!segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
+       (get_segdata(xd, segment_id, SEG_LVL_EOB) != 0))) {
+        int skip_coeff = m->mbmi.mb_skip_coeff;
+#if CONFIG_SUPERBLOCKS
+        if (m->mbmi.encoded_as_sb) {
+          skip_coeff &= m[1].mbmi.mb_skip_coeff;
+          skip_coeff &= m[mis].mbmi.mb_skip_coeff;
+          skip_coeff &= m[mis + 1].mbmi.mb_skip_coeff;
+        }
+#endif
+        vp8_encode_bool(bc, skip_coeff,
+                    get_pred_prob(c, xd, PRED_MBSKIP));
+  }
+
+#if CONFIG_SUPERBLOCKS
+  if (m->mbmi.encoded_as_sb) {
+    sb_kfwrite_ymode(bc, ym,
+                     c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
+  } else
+#endif
+  {
+    kfwrite_ymode(bc, ym,
+                  c->kf_ymode_prob[c->kf_ymode_probs_index]);
+  }
+
+  if (ym == B_PRED) {
+    const int mis = c->mode_info_stride;
+    int i = 0;
+#if CONFIG_COMP_INTRA_PRED
+    int uses_second =
+      m->bmi[0].as_mode.second !=
+      (B_PREDICTION_MODE)(B_DC_PRED - 1);
+    vp8_write(bc, uses_second, 128);
+#endif
+    do {
+      const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
+      const B_PREDICTION_MODE L = left_block_mode(m, i);
+      const int bm = m->bmi[i].as_mode.first;
+#if CONFIG_COMP_INTRA_PRED
+      const int bm2 = m->bmi[i].as_mode.second;
+#endif
+
+#ifdef ENTROPY_STATS
+      ++intra_mode_stats [A] [L] [bm];
+#endif
+
+      write_bmode(bc, bm, c->kf_bmode_prob [A] [L]);
+      // printf("    mode: %d\n", bm);
+#if CONFIG_COMP_INTRA_PRED
+      if (uses_second) {
+        write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]);
+      }
+#endif
+    } while (++i < 16);
+  }
+  if (ym == I8X8_PRED) {
+    write_i8x8_mode(bc, m->bmi[0].as_mode.first,
+                    c->fc.i8x8_mode_prob);
+    // printf("    mode: %d\n", m->bmi[0].as_mode.first); fflush(stdout);
+    write_i8x8_mode(bc, m->bmi[2].as_mode.first,
+                    c->fc.i8x8_mode_prob);
+    // printf("    mode: %d\n", m->bmi[2].as_mode.first); fflush(stdout);
+    write_i8x8_mode(bc, m->bmi[8].as_mode.first,
+                    c->fc.i8x8_mode_prob);
+    // printf("    mode: %d\n", m->bmi[8].as_mode.first); fflush(stdout);
+    write_i8x8_mode(bc, m->bmi[10].as_mode.first,
+                    c->fc.i8x8_mode_prob);
+    // printf("    mode: %d\n", m->bmi[10].as_mode.first); fflush(stdout);
+  } else
+    write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
+
+#if CONFIG_TX_SELECT
+  if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
+      !((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
+        (segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
+         get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
+    TX_SIZE sz = m->mbmi.txfm_size;
+    // FIXME(rbultje) code ternary symbol once all experiments are merged
+    vp8_write(bc, sz != TX_4X4, c->prob_tx[0]);
+    if (sz != TX_4X4 && ym <= TM_PRED)
+      vp8_write(bc, sz != TX_8X8, c->prob_tx[1]);
+  }
+#endif
+}
+
 static void write_kfmodes(VP8_COMP *cpi) {
-  vp8_writer *const bc = & cpi->bc;
+  vp8_writer *const bc = & cpi->bc2;
   VP8_COMMON *const c = & cpi->common;
   const int mis = c->mode_info_stride;
   MACROBLOCKD *xd = &cpi->mb.e_mbd;
@@ -1359,17 +1409,9 @@
   int mb_row, mb_col;
   int row_delta[4] = { 0, +1,  0, -1};
   int col_delta[4] = { +1, -1, +1, +1};
+  TOKENEXTRA *tok = cpi->tok;
+  TOKENEXTRA *tok_end = tok + cpi->tok_count;
 
-  if (c->mb_no_coeff_skip) {
-    update_skip_probs(cpi);
-    for (i = 0; i < MBSKIP_CONTEXTS; ++i)
-      vp8_write_literal(bc, c->mbskip_pred_probs[i], 8);
-  }
-
-  if (!c->kf_ymode_probs_update) {
-    vp8_write_literal(bc, c->kf_ymode_probs_index, 3);
-  }
-
   mb_row = 0;
   for (row = 0; row < c->mb_rows; row += 2) {
     m = c->mi + row * mis;
@@ -1382,8 +1424,6 @@
       // Process the 4 MBs in the order:
       // top-left, top-right, bottom-left, bottom-right
       for (i = 0; i < 4; i++) {
-        int ym;
-        int segment_id;
         int dy = row_delta[i];
         int dx = col_delta[i];
         int offset_extended = dy * mis + dx;
@@ -1399,98 +1439,13 @@
         // Make sure the MacroBlockD mode info pointer is set correctly
         xd->mode_info_context = m;
 
-        ym = m->mbmi.mode;
-        segment_id = m->mbmi.segment_id;
-
-        if (cpi->mb.e_mbd.update_mb_segmentation_map) {
-          write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
-        }
-
-        if (c->mb_no_coeff_skip &&
-            (!segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
-             (get_segdata(xd, segment_id, SEG_LVL_EOB) != 0))) {
-              int skip_coeff = m->mbmi.mb_skip_coeff;
-#if CONFIG_SUPERBLOCKS
-              if (m->mbmi.encoded_as_sb) {
-                skip_coeff &= m[1].mbmi.mb_skip_coeff;
-                skip_coeff &= m[mis].mbmi.mb_skip_coeff;
-                skip_coeff &= m[mis + 1].mbmi.mb_skip_coeff;
-              }
-#endif
-              vp8_encode_bool(bc, skip_coeff,
-                          get_pred_prob(c, xd, PRED_MBSKIP));
-        }
-
-#if CONFIG_SUPERBLOCKS
-        if (m->mbmi.encoded_as_sb) {
-          sb_kfwrite_ymode(bc, ym,
-                           c->sb_kf_ymode_prob[c->kf_ymode_probs_index]);
-        } else
-#endif
-        {
-          kfwrite_ymode(bc, ym,
-                        c->kf_ymode_prob[c->kf_ymode_probs_index]);
-        }
-
-        if (ym == B_PRED) {
-          const int mis = c->mode_info_stride;
-          int i = 0;
-#if CONFIG_COMP_INTRA_PRED
-          int uses_second =
-            m->bmi[0].as_mode.second !=
-            (B_PREDICTION_MODE)(B_DC_PRED - 1);
-          vp8_write(bc, uses_second, 128);
-#endif
-          do {
-            const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
-            const B_PREDICTION_MODE L = left_block_mode(m, i);
-            const int bm = m->bmi[i].as_mode.first;
-#if CONFIG_COMP_INTRA_PRED
-            const int bm2 = m->bmi[i].as_mode.second;
-#endif
-
+        write_mb_modes_kf(c, xd, m, mis, bc);
 #ifdef ENTROPY_STATS
-            ++intra_mode_stats [A] [L] [bm];
+        active_section = 8;
 #endif
+        assert(tok < tok_end);
+        pack_mb_tokens(bc, &tok, tok_end);
 
-            write_bmode(bc, bm, c->kf_bmode_prob [A] [L]);
-            // printf("    mode: %d\n", bm);
-#if CONFIG_COMP_INTRA_PRED
-            if (uses_second) {
-              write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]);
-            }
-#endif
-          } while (++i < 16);
-        }
-        if (ym == I8X8_PRED) {
-          write_i8x8_mode(bc, m->bmi[0].as_mode.first,
-                          c->fc.i8x8_mode_prob);
-          // printf("    mode: %d\n", m->bmi[0].as_mode.first); fflush(stdout);
-          write_i8x8_mode(bc, m->bmi[2].as_mode.first,
-                          c->fc.i8x8_mode_prob);
-          // printf("    mode: %d\n", m->bmi[2].as_mode.first); fflush(stdout);
-          write_i8x8_mode(bc, m->bmi[8].as_mode.first,
-                          c->fc.i8x8_mode_prob);
-          // printf("    mode: %d\n", m->bmi[8].as_mode.first); fflush(stdout);
-          write_i8x8_mode(bc, m->bmi[10].as_mode.first,
-                          c->fc.i8x8_mode_prob);
-          // printf("    mode: %d\n", m->bmi[10].as_mode.first); fflush(stdout);
-        } else
-          write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
-
-#if CONFIG_TX_SELECT
-        if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
-            !((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
-              (segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
-               get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
-          TX_SIZE sz = m->mbmi.txfm_size;
-          // FIXME(rbultje) code ternary symbol once all experiments are merged
-          vp8_write(bc, sz != TX_4X4, c->prob_tx[0]);
-          if (sz != TX_4X4 && ym <= TM_PRED)
-            vp8_write(bc, sz != TX_8X8, c->prob_tx[1]);
-        }
-#endif
-
 #if CONFIG_SUPERBLOCKS
         if (m->mbmi.encoded_as_sb) {
           assert(!i);
@@ -2835,21 +2790,80 @@
 
   // Write out the mb_no_coeff_skip flag
   vp8_write_bit(bc, pc->mb_no_coeff_skip);
+  if (pc->mb_no_coeff_skip) {
+    int k;
 
-  if (pc->frame_type == KEY_FRAME) {
-    decide_kf_ymode_entropy(cpi);
-    write_kfmodes(cpi);
+    update_skip_probs(cpi);
+    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
+      vp8_write_literal(bc, pc->mbskip_pred_probs[k], 8);
+  }
 
-#ifdef ENTROPY_STATS
-    active_section = 8;
-#endif
+  if (pc->frame_type == KEY_FRAME) {
+    if (!pc->kf_ymode_probs_update) {
+      vp8_write_literal(bc, pc->kf_ymode_probs_index, 3);
+    }
   } else {
-    pack_inter_mode_mvs(cpi);
-    vp8_update_mode_context(&cpi->common);
+    // Update the probabilities used to encode reference frame data
+    update_ref_probs(cpi);
 
 #ifdef ENTROPY_STATS
     active_section = 1;
 #endif
+
+#if CONFIG_PRED_FILTER
+    // Write the prediction filter mode used for this frame
+    vp8_write_literal(bc, pc->pred_filter_mode, 2);
+
+    // Write prediction filter on/off probability if signaling at MB level
+    if (pc->pred_filter_mode == 2)
+      vp8_write_literal(bc, pc->prob_pred_filter_off, 8);
+
+#endif
+#if CONFIG_SWITCHABLE_INTERP
+    if (pc->mcomp_filter_type == SWITCHABLE)
+      update_switchable_interp_probs(cpi);
+#endif
+
+    vp8_write_literal(bc, pc->prob_intra_coded, 8);
+    vp8_write_literal(bc, pc->prob_last_coded, 8);
+    vp8_write_literal(bc, pc->prob_gf_coded, 8);
+
+    {
+      const int comp_pred_mode = cpi->common.comp_pred_mode;
+      const int use_compound_pred = (comp_pred_mode != SINGLE_PREDICTION_ONLY);
+      const int use_hybrid_pred = (comp_pred_mode == HYBRID_PREDICTION);
+
+      vp8_write(bc, use_compound_pred, 128);
+      if (use_compound_pred) {
+        vp8_write(bc, use_hybrid_pred, 128);
+        if (use_hybrid_pred) {
+          for (i = 0; i < COMP_PRED_CONTEXTS; i++) {
+            if (cpi->single_pred_count[i] + cpi->comp_pred_count[i]) {
+              pc->prob_comppred[i] = cpi->single_pred_count[i] * 255 /
+                                     (cpi->single_pred_count[i]
+                                      + cpi->comp_pred_count[i]);
+              if (pc->prob_comppred[i] < 1)
+                pc->prob_comppred[i] = 1;
+            } else {
+              pc->prob_comppred[i] = 128;
+            }
+            vp8_write_literal(bc, pc->prob_comppred[i], 8);
+          }
+        }
+      }
+    }
+
+    update_mbintra_mode_probs(cpi);
+
+#if CONFIG_NEWMVENTROPY
+    vp8_write_nmvprobs(cpi, xd->allow_high_precision_mv);
+#else
+    if (xd->allow_high_precision_mv) {
+      vp8_write_mvprobs_hp(cpi);
+    } else {
+      vp8_write_mvprobs(cpi);
+    }
+#endif
   }
 
   vp8_stop_encode(bc);
@@ -2869,10 +2883,16 @@
   }
 
   *size = VP8_HEADER_SIZE + extra_bytes_packed + cpi->bc.pos;
-
   vp8_start_encode(&cpi->bc2, cx_data + bc->pos);
 
-  pack_tokens(&cpi->bc2, cpi->tok, cpi->tok_count);
+  if (pc->frame_type == KEY_FRAME) {
+    decide_kf_ymode_entropy(cpi);
+    write_kfmodes(cpi);
+  } else {
+    pack_inter_mode_mvs(cpi);
+    vp8_update_mode_context(&cpi->common);
+  }
+
 
   vp8_stop_encode(&cpi->bc2);
 
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1051,9 +1051,6 @@
         cpi->inter_zz_count++;
     }
 
-    // TODO Partitioning is broken!
-    cpi->tplist[mb_row].stop = *tp;
-
 #if CONFIG_SUPERBLOCKS
     if (xd->mode_info_context->mbmi.encoded_as_sb) {
       x->src.y_buffer += 32;
@@ -1065,6 +1062,9 @@
       xd->mode_info_context += 2;
       xd->prev_mode_info_context += 2;
       
+      (*tp)->Token = EOSB_TOKEN;
+      (*tp)++;
+      cpi->tplist[mb_row].stop = *tp;
       break;
     }
 #endif
@@ -1086,6 +1086,9 @@
     assert((xd->prev_mode_info_context - cpi->common.prev_mip) ==
            (xd->mode_info_context - cpi->common.mip));
 #endif
+    (*tp)->Token = EOSB_TOKEN;
+    (*tp)++;
+    cpi->tplist[mb_row].stop = *tp;
   }
 
   // debug output