diff --git a/vp9/common/entropy.h b/vp9/common/entropy.h
index 884c6a1daf939a0fbb03d95f13868aaec1543100..fa24a058e568baea29a1e7571f3c65b37ca938de 100644
--- a/vp9/common/entropy.h
+++ b/vp9/common/entropy.h
@@ -37,6 +37,8 @@ extern const int vp9_i8x8_block[4];
 #define ENTROPY_NODES 11
 #define EOSB_TOKEN              127     /* Not signalled, encoder only */
 
+#define INTER_MODE_CONTEXTS     7
+
 extern const vp9_tree_index vp9_coef_tree[];
 
 extern struct vp9_token_struct vp9_coef_encodings[MAX_ENTROPY_TOKENS];
diff --git a/vp9/common/entropymode.c b/vp9/common/entropymode.c
index 83ba21c558e188f77da6748a6d327698a0e058de..665528d487c7c38e0db73c6b59635b86a517bc36 100644
--- a/vp9/common/entropymode.c
+++ b/vp9/common/entropymode.c
@@ -441,7 +441,6 @@ void vp9_entropy_mode_init() {
 
 void vp9_init_mode_contexts(VP9_COMMON *pc) {
   vpx_memset(pc->fc.mv_ref_ct, 0, sizeof(pc->fc.mv_ref_ct));
-  vpx_memset(pc->fc.mv_ref_ct_a, 0, sizeof(pc->fc.mv_ref_ct_a));
 
   vpx_memcpy(pc->fc.mode_context,
              vp9_default_mode_contexts,
@@ -457,10 +456,7 @@ void vp9_accum_mv_refs(VP9_COMMON *pc,
                        const int context) {
   int (*mv_ref_ct)[4][2];
 
-  if (pc->refresh_alt_ref_frame)
-    mv_ref_ct = pc->fc.mv_ref_ct_a;
-  else
-    mv_ref_ct = pc->fc.mv_ref_ct;
+  mv_ref_ct = pc->fc.mv_ref_ct;
 
   if (m == ZEROMV) {
     ++mv_ref_ct[context][0][0];
@@ -485,19 +481,18 @@ void vp9_accum_mv_refs(VP9_COMMON *pc,
 }
 
 #define MVREF_COUNT_SAT 20
-#define MVREF_MAX_UPDATE_FACTOR 144
+#define MVREF_MAX_UPDATE_FACTOR 128
 void vp9_update_mode_context(VP9_COMMON *pc) {
   int i, j;
   int (*mv_ref_ct)[4][2];
   int (*mode_context)[4];
 
   if (pc->refresh_alt_ref_frame) {
-    mv_ref_ct = pc->fc.mv_ref_ct_a;
     mode_context = pc->fc.mode_context_a;
   } else {
-    mv_ref_ct = pc->fc.mv_ref_ct;
     mode_context = pc->fc.mode_context;
   }
+  mv_ref_ct = pc->fc.mv_ref_ct;
 
   for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
     for (i = 0; i < 4; i++) {
@@ -522,14 +517,14 @@ void vp9_update_mode_context(VP9_COMMON *pc) {
 void print_mode_contexts(VP9_COMMON *pc) {
   int j, i;
   printf("\n====================\n");
-  for (j = 0; j < 6; j++) {
+  for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
     for (i = 0; i < 4; i++) {
       printf("%4d ", pc->fc.mode_context[j][i]);
     }
     printf("\n");
   }
   printf("====================\n");
-  for (j = 0; j < 6; j++) {
+  for (j = 0; j < INTER_MODE_CONTEXTS; j++) {
     for (i = 0; i < 4; i++) {
       printf("%4d ", pc->fc.mode_context_a[j][i]);
     }
diff --git a/vp9/common/findnearmv.h b/vp9/common/findnearmv.h
index 256745261bc0f56d7cd73aeb65f48e6eb4bd9d11..4e6418a51296b7a2524964bc0a56c2fee1789a26 100644
--- a/vp9/common/findnearmv.h
+++ b/vp9/common/findnearmv.h
@@ -14,7 +14,6 @@
 
 #include "mv.h"
 #include "blockd.h"
-#include "modecont.h"
 #include "treecoder.h"
 #include "onyxc_int.h"
 
diff --git a/vp9/common/modecont.c b/vp9/common/modecont.c
index ac6719a1b7fb7b47c588043a71a5acdb59221995..1a71eceb513d1eb7e4570a222ca48d11c753f295 100644
--- a/vp9/common/modecont.c
+++ b/vp9/common/modecont.c
@@ -11,19 +11,21 @@
 
 #include "entropy.h"
 
-const int vp9_default_mode_contexts[6][4] = {
-  {117,     1,     1,    141},
-  {234,     1,     1,    213},
-  {128,     90,    22,   145},
-  {30,      104,   61,   159},
-  {13,      169,   18,   206},
-  {15,      76,    24,   166}
+const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4] = {
+  {223,     1,     1,    237},  // 0,0 best: Only candidate
+  {87,      166,   26,   219},  // 0,0 best: non zero candidates
+  {89,      67,    18,   125},  // 0,0 best: non zero candidates, split
+  {16,      141,   69,   226},  // strong nz candidate(s), no split
+  {35,      122,   14,   227},  // weak nz candidate(s), no split
+  {14,      122,   22,   164},  // strong nz candidate(s), split
+  {16,      70,    9,    183},  // weak nz candidate(s), split
 };
-const int vp9_default_mode_contexts_a[6][4] = {
-  {117,     1,     1,    141},
-  {234,     1,     1,    213},
-  {128,     90,    22,   145},
-  {30,      104,   61,   159},
-  {13,      169,   18,   206},
-  {15,      76,    24,   166}
+const int vp9_default_mode_contexts_a[INTER_MODE_CONTEXTS][4] = {
+  {204,     1,     1,    213},  // 0,0 best: Only candidate
+  {106,     139,   22,   203},  // 0,0 best: non zero candidates
+  {75,      52,    15,   118},  // 0,0 best: non zero candidates, split
+  {12,      148,   61,   211},  // strong nz candidate(s), no split
+  {18,      98,    17,   199},  // weak nz candidate(s), no split
+  {11,      91,    25,   148},  // strong nz candidate(s), split
+  {10,      53,    9,    145},  // weak nz candidate(s), split
 };
diff --git a/vp9/common/modecont.h b/vp9/common/modecont.h
index c13c14f6c1a3c6b90bc0cf72679ca23278474365..1fa4558e1b2b728e7baf3c208e8d67d5fd8a2c67 100644
--- a/vp9/common/modecont.h
+++ b/vp9/common/modecont.h
@@ -12,6 +12,6 @@
 #ifndef __INC_MODECONT_H
 #define __INC_MODECONT_H
 
-extern const int vp9_default_mode_contexts[6][4];
-extern const int vp9_default_mode_contexts_a[6][4];
+extern const int vp9_default_mode_contexts[INTER_MODE_CONTEXTS][4];
+extern const int vp9_default_mode_contexts_a[INTER_MODE_CONTEXTS][4];
 #endif
diff --git a/vp9/common/mvref_common.c b/vp9/common/mvref_common.c
index 35c74ef89e9141d276df9593a1c7c6a55d578d79..ebb8fa4bd37930778a5f1f184a9c41fa5870afaa 100644
--- a/vp9/common/mvref_common.c
+++ b/vp9/common/mvref_common.c
@@ -231,6 +231,7 @@ void vp9_find_mv_refs(
   MV_REFERENCE_FRAME c2_ref_frame;
   int candidate_scores[MAX_MV_REFS];
   int index = 0;
+  int split_count = 0;
   int ref_weight = 0;
   int valid_mv_ref;
   int (*mv_ref_search)[2];
@@ -271,6 +272,7 @@ void vp9_find_mv_refs(
         scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias );
         ref_weight = ref_distance_weight[i] +
                      ((c_ref_frame == ref_frame) << 4);
+        split_count += (candidate_mi->mbmi.mode == SPLITMV);
 
         addmv_and_shuffle(candidate_mvs, candidate_scores,
                           &index, c_refmv, ref_weight);
@@ -352,35 +354,39 @@ void vp9_find_mv_refs(
     index = (MAX_MV_REFS - 1);
   }
 
+  // Define inter mode coding context.
+  // 0,0 was best
   if (candidate_mvs[0].as_int == 0) {
-    // 0,0 was best
-    if (index == 0) {
-      // No reference candidates
+    // 0,0 is only candidate
+    if (index <= 1) {
       mbmi->mb_mode_context[ref_frame] = 0;
-    } else if (index == 1) {
-      // 0,0 was only candidate
+    // non zero candidates candidates available
+    } else if (split_count == 0) {
       mbmi->mb_mode_context[ref_frame] = 1;
     } else {
-      // Other candidates available
       mbmi->mb_mode_context[ref_frame] = 2;
     }
-  } else if (candidate_scores[0] >= 32) {
-    if (candidate_scores[1] >= 16) {
-      // Strong primary and strong or moderate secondary candidate
+  // Non zero best, No Split MV cases
+  } else if (split_count == 0) {
+    if (candidate_scores[0] >= 32) {
       mbmi->mb_mode_context[ref_frame] = 3;
     } else {
-      // Strong primary but weak secondary candidate
       mbmi->mb_mode_context[ref_frame] = 4;
     }
+  // Non zero best, some split mv
   } else {
-    // Weak or moderate candidates
-    mbmi->mb_mode_context[ref_frame] = 5;
+    if (candidate_scores[0] >= 32) {
+      mbmi->mb_mode_context[ref_frame] = 5;
+    } else {
+      mbmi->mb_mode_context[ref_frame] = 6;
+    }
   }
 
   // 0,0 is always a valid reference.
-  for (i = 0; i < index; ++i)
+  for (i = 0; i < index; ++i) {
     if (candidate_mvs[i].as_int == 0)
       break;
+  }
   if (i == index) {
     c_refmv.as_int = 0;
     addmv_and_shuffle(candidate_mvs, candidate_scores,
diff --git a/vp9/common/onyxc_int.h b/vp9/common/onyxc_int.h
index d51e292bd96a9d27c81ffe0a12c23ddf7b8e1394..f76c8a0088b42db8cfbf310796bd1528581aea0a 100644
--- a/vp9/common/onyxc_int.h
+++ b/vp9/common/onyxc_int.h
@@ -42,7 +42,6 @@ void vp9_initialize_common(void);
 #define NUM_YV12_BUFFERS 4
 
 #define COMP_PRED_CONTEXTS   2
-#define INTER_MODE_CONTEXTS 6
 
 typedef struct frame_contexts {
   vp9_prob bmode_prob[VP9_NKF_BINTRAMODES - 1];
@@ -116,7 +115,6 @@ typedef struct frame_contexts {
   int mode_context_a[INTER_MODE_CONTEXTS][4];
   int vp9_mode_contexts[INTER_MODE_CONTEXTS][4];
   int mv_ref_ct[INTER_MODE_CONTEXTS][4][2];
-  int mv_ref_ct_a[INTER_MODE_CONTEXTS][4][2];
 } FRAME_CONTEXT;
 
 typedef enum {
@@ -285,12 +283,6 @@ typedef struct VP9Common {
   FRAME_CONTEXT lfc; /* last frame entropy */
   FRAME_CONTEXT fc;  /* this frame entropy */
 
-  // int mv_ref_ct[6][4][2];
-  // int mv_ref_ct_a[6][4][2];
-  // int mode_context[6][4];
-  // int mode_context_a[6][4];
-  // int vp8_mode_contexts[6][4];
-
   unsigned int current_video_frame;
   int near_boffset[3];
   int version;
diff --git a/vp9/decoder/decodframe.c b/vp9/decoder/decodframe.c
index 275bfb9ca1c5f2316f78720822151b555e988b40..2642e5a6cd299d488b23f5055effc3d4fe492a87 100644
--- a/vp9/decoder/decodframe.c
+++ b/vp9/decoder/decodframe.c
@@ -1315,6 +1315,19 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
   pc->refresh_last_frame = (pc->frame_type == KEY_FRAME)
                            || vp9_read_bit(&header_bc);
 
+  // Read inter mode probability context updates
+  if (pc->frame_type != KEY_FRAME) {
+    int i, j;
+    for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
+      for (j = 0; j < 4; j++) {
+        if (vp9_read(&header_bc, 252)) {
+          pc->fc.vp9_mode_contexts[i][j] =
+            (vp9_prob)vp9_read_literal(&header_bc, 8);
+        }
+      }
+    }
+  }
+
   if (0) {
     FILE *z = fopen("decodestats.stt", "a");
     fprintf(z, "%6d F:%d,G:%d,A:%d,L:%d,Q:%d\n",
@@ -1363,7 +1376,6 @@ int vp9_decode_frame(VP9D_COMP *pbi) {
   vp9_zero(pbi->common.fc.mbsplit_counts);
   vp9_zero(pbi->common.fc.NMVcount);
   vp9_zero(pbi->common.fc.mv_ref_ct);
-  vp9_zero(pbi->common.fc.mv_ref_ct_a);
 #if CONFIG_COMP_INTERINTRA_PRED
   vp9_zero(pbi->common.fc.interintra_counts);
 #endif
diff --git a/vp9/encoder/bitstream.c b/vp9/encoder/bitstream.c
index ccce910c76de129bc5090864e2a3fd4207a10692..6f2771adc783bce3bb4138fdb8a2b35c2b17ff01 100644
--- a/vp9/encoder/bitstream.c
+++ b/vp9/encoder/bitstream.c
@@ -255,6 +255,42 @@ static void update_refpred_stats(VP9_COMP *cpi) {
   }
 }
 
+// This function is called to update the mode probability context used to encode
+// inter modes. It assumes the branch counts table has already been populated
+// prior to the actual packing of the bitstream (in rd stage or dummy pack)
+//
+// The branch counts table is re-populated during the actual pack stage and in
+// the decoder to facilitate backwards update of the context.
+static update_mode_probs(VP9_COMMON *cm,
+                         int mode_context[INTER_MODE_CONTEXTS][4]) {
+  int i, j;
+  int (*mv_ref_ct)[4][2];
+
+  vpx_memcpy(mode_context, cm->fc.vp9_mode_contexts,
+             sizeof(cm->fc.vp9_mode_contexts));
+
+  mv_ref_ct = cm->fc.mv_ref_ct;
+
+  for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
+    for (j = 0; j < 4; j++) {
+      int new_prob, count, old_cost, new_cost;
+
+      // Work out cost of coding branches with the old and optimal probability
+      old_cost = cost_branch256(mv_ref_ct[i][j], mode_context[i][j]);
+      count = mv_ref_ct[i][j][0] + mv_ref_ct[i][j][1];
+      new_prob = count > 0 ? (255 * mv_ref_ct[i][j][0]) / count : 128;
+      new_prob = (new_prob > 0) ? new_prob : 1;
+      new_cost = cost_branch256(mv_ref_ct[i][j], new_prob);
+
+      // If cost saving is >= 14 bits then update the mode probability.
+      // This is the approximate net cost of updating one probability given
+      // that the no update case ismuch more common than the update case.
+      if (new_cost <= (old_cost - (14 << 8))) {
+        mode_context[i][j] = new_prob;
+      }
+    }
+  }
+}
 static void write_ymode(vp9_writer *bc, int m, const vp9_prob *p) {
   write_token(bc, vp9_ymode_tree, p, vp9_ymode_encodings + m);
 }
@@ -2076,6 +2112,30 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
     active_section = 7;
 #endif
 
+  // If appropriate update the inter mode probability context and code the
+  // changes in the bitstream.
+  if ((pc->frame_type != KEY_FRAME)) {
+    int i, j;
+    int new_context[INTER_MODE_CONTEXTS][4];
+    update_mode_probs(pc, new_context);
+
+    for (i = 0; i < INTER_MODE_CONTEXTS; i++) {
+      for (j = 0; j < 4; j++) {
+        if (new_context[i][j] != pc->fc.vp9_mode_contexts[i][j]) {
+          vp9_write(&header_bc, 1, 252);
+          vp9_write_literal(&header_bc, new_context[i][j], 8);
+
+          // Only update the persistent copy if this is the "real pack"
+          if (!cpi->dummy_packing) {
+            pc->fc.vp9_mode_contexts[i][j] = new_context[i][j];
+          }
+        } else {
+          vp9_write(&header_bc, 0, 252);
+        }
+      }
+    }
+  }
+
   vp9_clear_system_state();  // __asm emms;
 
   vp9_copy(cpi->common.fc.pre_coef_probs, cpi->common.fc.coef_probs);
@@ -2097,7 +2157,6 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
   vp9_zero(cpi->sub_mv_ref_count);
   vp9_zero(cpi->mbsplit_count);
   vp9_zero(cpi->common.fc.mv_ref_ct)
-  vp9_zero(cpi->common.fc.mv_ref_ct_a)
 
   update_coef_probs(cpi, &header_bc);
 
diff --git a/vp9/encoder/encodeframe.c b/vp9/encoder/encodeframe.c
index 094dc5bab2db0daf7b86bfa88ca4e14bc96f7cd4..7ac0bd3310db58f10f10546721af022702397fc0 100644
--- a/vp9/encoder/encodeframe.c
+++ b/vp9/encoder/encodeframe.c
@@ -1399,7 +1399,6 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
   vp9_zero(cpi->sub_mv_ref_count)
   vp9_zero(cpi->mbsplit_count)
   vp9_zero(cpi->common.fc.mv_ref_ct)
-  vp9_zero(cpi->common.fc.mv_ref_ct_a)
 #if CONFIG_SUPERBLOCKS
   vp9_zero(cpi->sb_ymode_count)
   cpi->sb_count = 0;
diff --git a/vp9/encoder/onyx_int.h b/vp9/encoder/onyx_int.h
index e1ddd45fb1eff80cea3b92880e71af7955a0dd5c..1177451e0979b2c4f0be8a1a43a7b8717ba1096d 100644
--- a/vp9/encoder/onyx_int.h
+++ b/vp9/encoder/onyx_int.h
@@ -123,10 +123,9 @@ typedef struct {
   vp9_prob interintra_prob;
 #endif
 
-  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];
+  int mv_ref_ct[INTER_MODE_CONTEXTS][4][2];
+  int mode_context[INTER_MODE_CONTEXTS][4];
+  int mode_context_a[INTER_MODE_CONTEXTS][4];
 
 } CODING_CONTEXT;
 
diff --git a/vp9/encoder/ratectrl.c b/vp9/encoder/ratectrl.c
index 097a54d5ad18ee6554433cec191864e2c5c4dbe1..af93d8b42625e405b1f3aff7581a341c6e1e14a4 100644
--- a/vp9/encoder/ratectrl.c
+++ b/vp9/encoder/ratectrl.c
@@ -135,9 +135,7 @@ void vp9_save_coding_context(VP9_COMP *cpi) {
   vp9_copy(cc->nmvcosts,  cpi->mb.nmvcosts);
   vp9_copy(cc->nmvcosts_hp,  cpi->mb.nmvcosts_hp);
 
-  vp9_copy(cc->mv_ref_ct, cm->fc.mv_ref_ct);
   vp9_copy(cc->mode_context, cm->fc.mode_context);
-  vp9_copy(cc->mv_ref_ct_a, cm->fc.mv_ref_ct_a);
   vp9_copy(cc->mode_context_a, cm->fc.mode_context_a);
 
   vp9_copy(cc->ymode_prob, cm->fc.ymode_prob);
@@ -193,9 +191,7 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
   vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
   vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);
 
-  vp9_copy(cm->fc.mv_ref_ct, cc->mv_ref_ct);
   vp9_copy(cm->fc.mode_context, cc->mode_context);
-  vp9_copy(cm->fc.mv_ref_ct_a, cc->mv_ref_ct_a);
   vp9_copy(cm->fc.mode_context_a, cc->mode_context_a);
 
   vp9_copy(cm->fc.ymode_prob, cc->ymode_prob);