Adds support for switchable interpolation filters.

Allows for swtiching/setting interpolation filters at the MB
level. A frame level flag indicates whether to use a specifc
filter for the entire frame or to signal the interpolation
filter for each MB. When switchable filters are used, the
encoder chooses between 8-tap and 8-tap sharp filters. The
code currently has options to explore other variations as well,
which will be cleaned up subsequently.

One issue with the framework is that encoding is slow. I
tried to do some tricks to speed things up but it is still slow.
Decoding speed should not be affected since the number of
filter taps remain unchanged.

With the current version, we are up 0.5% on derf on average but
some videos city/mobile improve by close to 4 and 2% respectively.
If we did a full-search by turning the SEARCH_BEST_FILTER flag
on, the results are somewhat better.

The framework can be combined with filtered prediction, and I
seek feedback regarding that.

Rebased.

Change-Id: I8f632cb2c111e76284140a2bd480945d6d42b77a
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index dc0639f..1bbaa64 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -76,7 +76,25 @@
   INTER_FRAME = 1
 } FRAME_TYPE;
 
-typedef enum {
+typedef enum
+{
+  SIXTAP   = 0,
+  BILINEAR = 1,
+#if CONFIG_ENHANCED_INTERP
+  EIGHTTAP = 2,
+  EIGHTTAP_SHARP = 3,
+#if CONFIG_SWITCHABLE_INTERP
+  SWITCHABLE  /* should be the last one */
+#endif
+#endif
+} INTERPOLATIONFILTERTYPE;
+
+#if 0//CONFIG_SWITCHABLE_INTERP
+#define VP8_SWITCHABLE_FILTERS 2 /* number of switchable filters */
+#endif
+
+typedef enum
+{
   DC_PRED,            /* average of above and left pixels */
   V_PRED,             /* vertical prediction */
   H_PRED,             /* horizontal prediction */
@@ -226,6 +244,9 @@
   // Flag to turn prediction signal filter on(1)/off(0 ) at the MB level
   unsigned int pred_filter_enabled;
 #endif
+#if CONFIG_SWITCHABLE_INTERP
+    INTERPOLATIONFILTERTYPE interp_filter;
+#endif
 
 } MB_MODE_INFO;
 
diff --git a/vp8/common/entropy.h b/vp8/common/entropy.h
index 8bb718a..9993741 100644
--- a/vp8/common/entropy.h
+++ b/vp8/common/entropy.h
@@ -18,8 +18,8 @@
 #include "coefupdateprobs.h"
 
 
-#define SUBMVREF_COUNT 5
-#define VP8_NUMMBSPLITS 4
+//#define SUBMVREF_COUNT 5
+//#define VP8_NUMMBSPLITS 4
 
 /* Coefficient token alphabet */
 
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index e48df3b..4500e9c 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -9,10 +9,8 @@
  */
 
 
+#include "onyxc_int.h"
 #include "modecont.h"
-#include "entropymode.h"
-#include "entropymv.h"
-#include "entropy.h"
 #include "vpx_mem/vpx_mem.h"
 
 
@@ -286,6 +284,10 @@
 
   vpx_memcpy(x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_prob2, sizeof(vp8_sub_mv_ref_prob2));
   vpx_memcpy(x->fc.mbsplit_prob, vp8_mbsplit_probs, sizeof(vp8_mbsplit_probs));
+#if CONFIG_SWITCHABLE_INTERP
+  vpx_memcpy(x->fc.switchable_interp_prob, vp8_switchable_interp_prob,
+             sizeof(vp8_switchable_interp_prob));
+#endif
 
 }
 
@@ -323,6 +325,44 @@
   } while (++i < VP8_BINTRAMODES);
 }
 
+#if CONFIG_SWITCHABLE_INTERP
+#if VP8_SWITCHABLE_FILTERS == 3
+const vp8_tree_index vp8_switchable_interp_tree[VP8_SWITCHABLE_FILTERS*2-2] = {
+  -0, 2,
+  -1, -2
+};
+struct vp8_token_struct vp8_switchable_interp_encodings[VP8_SWITCHABLE_FILTERS];
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+  EIGHTTAP, SIXTAP, EIGHTTAP_SHARP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {1, -1, 0, 2, -1};
+const vp8_prob vp8_switchable_interp_prob [VP8_SWITCHABLE_FILTERS+1]
+                                          [VP8_SWITCHABLE_FILTERS-1] = {
+  {248, 192}, { 32, 248}, { 32,  32}, {192, 160}
+};
+#elif VP8_SWITCHABLE_FILTERS == 2
+const vp8_tree_index vp8_switchable_interp_tree[VP8_SWITCHABLE_FILTERS*2-2] = {
+  -0, -1,
+};
+struct vp8_token_struct vp8_switchable_interp_encodings[VP8_SWITCHABLE_FILTERS];
+const vp8_prob vp8_switchable_interp_prob [VP8_SWITCHABLE_FILTERS+1]
+                                          [VP8_SWITCHABLE_FILTERS-1] = {
+  {248},
+  { 64},
+  {192},
+};
+//#define SWITCHABLE_86
+#ifdef SWITCHABLE_86
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+  EIGHTTAP, SIXTAP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {1, -1, 0, -1, -1}; //8, 6
+#else
+const INTERPOLATIONFILTERTYPE vp8_switchable_interp[VP8_SWITCHABLE_FILTERS] = {
+  EIGHTTAP, EIGHTTAP_SHARP};
+const int vp8_switchable_interp_map[SWITCHABLE+1] = {-1, -1, 0, 1, -1}; //8, 8s
+#endif
+#endif
+#endif
+
 
 void vp8_entropy_mode_init() {
   vp8_tokens_from_tree(vp8_bmode_encodings,   vp8_bmode_tree);
@@ -331,6 +371,10 @@
   vp8_tokens_from_tree(vp8_uv_mode_encodings,  vp8_uv_mode_tree);
   vp8_tokens_from_tree(vp8_i8x8_mode_encodings,  vp8_i8x8_mode_tree);
   vp8_tokens_from_tree(vp8_mbsplit_encodings, vp8_mbsplit_tree);
+#if CONFIG_SWITCHABLE_INTERP
+  vp8_tokens_from_tree(vp8_switchable_interp_encodings,
+                       vp8_switchable_interp_tree);
+#endif
 
   vp8_tokens_from_tree_offset(vp8_mv_ref_encoding_array,
                               vp8_mv_ref_tree, NEARESTMV);
diff --git a/vp8/common/entropymode.h b/vp8/common/entropymode.h
index f66c1c8..f9cc263 100644
--- a/vp8/common/entropymode.h
+++ b/vp8/common/entropymode.h
@@ -12,9 +12,12 @@
 #ifndef __INC_ENTROPYMODE_H
 #define __INC_ENTROPYMODE_H
 
-#include "onyxc_int.h"
+#include "blockd.h"
 #include "treecoder.h"
 
+#define SUBMVREF_COUNT 5
+#define VP8_NUMMBSPLITS 4
+
 typedef const int vp8_mbsplit[16];
 
 extern vp8_mbsplit vp8_mbsplits [VP8_NUMMBSPLITS];
@@ -56,10 +59,11 @@
 
 void vp8_entropy_mode_init(void);
 
-void vp8_init_mbmode_probs(VP8_COMMON *x);
-extern void vp8_init_mode_contexts(VP8_COMMON *pc);
-extern void vp8_update_mode_context(VP8_COMMON *pc);;
-extern void vp8_accum_mv_refs(VP8_COMMON *pc,
+struct VP8Common;
+void vp8_init_mbmode_probs(struct VP8Common *x);
+extern void vp8_init_mode_contexts(struct VP8Common *pc);
+extern void vp8_update_mode_context(struct VP8Common *pc);;
+extern void vp8_accum_mv_refs(struct VP8Common *pc,
                               MB_PREDICTION_MODE m,
                               const int ct[4]);
 
@@ -67,4 +71,17 @@
 void vp8_kf_default_bmode_probs(vp8_prob dest [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES - 1]);
 
 void vp8_adapt_mode_probs(struct VP8Common *);
+
+#if CONFIG_SWITCHABLE_INTERP
+#define VP8_SWITCHABLE_FILTERS 2 /* number of switchable filters */
+extern const  INTERPOLATIONFILTERTYPE vp8_switchable_interp
+                  [VP8_SWITCHABLE_FILTERS];
+extern const  int vp8_switchable_interp_map[SWITCHABLE+1];
+extern const  vp8_tree_index vp8_switchable_interp_tree
+                  [2*(VP8_SWITCHABLE_FILTERS-1)];
+extern struct vp8_token_struct vp8_switchable_interp_encodings
+                  [VP8_SWITCHABLE_FILTERS];
+extern const  vp8_prob vp8_switchable_interp_prob
+                  [VP8_SWITCHABLE_FILTERS+1][VP8_SWITCHABLE_FILTERS-1];
+#endif
 #endif
diff --git a/vp8/common/entropymv.c b/vp8/common/entropymv.c
index 3dd72cc..c1ea62d 100644
--- a/vp8/common/entropymv.c
+++ b/vp8/common/entropymv.c
@@ -116,7 +116,6 @@
 };
 struct vp8_token_struct vp8_small_mvencodings [8];
 
-
 __inline static void calc_prob(vp8_prob *p, const unsigned int ct[2], int pbits) {
   const unsigned int tot = ct[0] + ct[1];
   if (tot) {
diff --git a/vp8/common/entropymv.h b/vp8/common/entropymv.h
index 96ea7ff..c0726ec 100644
--- a/vp8/common/entropymv.h
+++ b/vp8/common/entropymv.h
@@ -14,6 +14,7 @@
 
 #include "treecoder.h"
 #include "vpx_config.h"
+#include "blockd.h"
 
 enum {
   mv_max  = 1023,              /* max absolute value of a MV component */
@@ -78,5 +79,9 @@
 #endif
 
 void vp8_entropy_mv_init();
+#if CONFIG_ADAPTIVE_ENTROPY
+struct VP8Common;
+void vp8_adapt_mv_probs(struct VP8Common *cm);
+#endif
 
 #endif
diff --git a/vp8/common/filter.c b/vp8/common/filter.c
index 856bad5..78c2390 100644
--- a/vp8/common/filter.c
+++ b/vp8/common/filter.c
@@ -46,7 +46,7 @@
 #if CONFIG_ENHANCED_INTERP
 
 #define FILTER_ALPHA       0
-#define FILTER_ALPHA_SHARP 60
+#define FILTER_ALPHA_SHARP 1
 DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8[SUBPEL_SHIFTS][2 * INTERP_EXTEND]) = {
 #if SUBPEL_SHIFTS==16
 #if FILTER_ALPHA == 0
@@ -91,24 +91,6 @@
   { 0,   3,  -9,  27, 118, -13,   3, -1},
   { 0,   2,  -6,  18, 122, -10,   2,  0},
   { 0,   1,  -3,   8, 126,  -5,   1,  0}
-#elif FILTER_ALPHA == 45
-  /* alpha = 0.45 */
-  { 0,   0,   0, 128,   0,   0,   0,  0},
-  { 0,   1,  -5, 126,   8,  -3,   1,  0},
-  { 0,   2,  -9, 122,  17,  -6,   2,  0},
-  { 0,   3, -13, 117,  27,  -8,   2,  0},
-  { -1,   4, -15, 111,  37, -11,   3,  0},
-  { -1,   4, -17, 104,  47, -13,   4,  0},
-  { -1,   5, -18,  96,  58, -15,   4, -1},
-  { -1,   5, -18,  87,  68, -17,   5, -1},
-  { -1,   5, -18,  78,  78, -18,   5, -1},
-  { -1,   5, -17,  68,  87, -18,   5, -1},
-  { -1,   4, -15,  58,  96, -18,   5, -1},
-  { 0,   4, -13,  47, 104, -17,   4, -1},
-  { 0,   3, -11,  37, 111, -15,   4, -1},
-  { 0,   2,  -8,  27, 117, -13,   3,  0},
-  { 0,   2,  -6,  17, 122,  -9,   2,  0},
-  { 0,   1,  -3,   8, 126,  -5,   1,  0}
 #endif  /* FILTER_ALPHA */
 #else   /* SUBPEL_SHIFTS==16 */
 #if FILTER_ALPHA == 0
@@ -130,23 +112,48 @@
   { -1,   5, -16,  58,  96, -18,   5, -1},
   { 0,   3, -11,  37, 112, -16,   4, -1},
   { 0,   2,  -6,  18, 122, -10,   2,  0}
-#elif FILTER_ALPHA == 45
-  /* alpha = 0.45 */
-  { 0,   0,   0, 128,   0,   0,   0,  0},
-  { 0,   2,  -9, 122,  17,  -6,   2,  0},
-  { -1,   4, -15, 111,  37, -11,   3,  0},
-  { -1,   5, -18,  96,  58, -15,   4, -1},
-  { -1,   5, -18,  78,  78, -18,   5, -1},
-  { -1,   4, -15,  58,  96, -18,   5, -1},
-  { 0,   3, -11,  37, 111, -15,   4, -1},
-  { 0,   2,  -6,  17, 122,  -9,   2,  0},
 #endif  /* FILTER_ALPHA */
 #endif  /* SUBPEL_SHIFTS==16 */
 };
 
 DECLARE_ALIGNED(16, const short, vp8_sub_pel_filters_8s[SUBPEL_SHIFTS][2 * INTERP_EXTEND]) = {
 #if SUBPEL_SHIFTS==16
-#if FILTER_ALPHA_SHARP == 65
+#if FILTER_ALPHA_SHARP == 1
+  /* dct based filter */
+  {0,   0,   0, 128,   0,   0,   0, 0},
+  {-1,   3,  -7, 127,   8,  -3,   1, 0},
+  {-2,   5, -13, 125,  17,  -6,   3, -1},
+  {-3,   7, -17, 121,  27, -10,   5, -2},
+  {-4,   9, -20, 115,  37, -13,   6, -2},
+  {-4,  10, -23, 108,  48, -16,   8, -3},
+  {-4,  10, -24, 100,  59, -19,   9, -3},
+  {-4,  11, -24,  90,  70, -21,  10, -4},
+  {-4,  11, -23,  80,  80, -23,  11, -4},
+  {-4,  10, -21,  70,  90, -24,  11, -4},
+  {-3,   9, -19,  59, 100, -24,  10, -4},
+  {-3,   8, -16,  48, 108, -23,  10, -4},
+  {-2,   6, -13,  37, 115, -20,   9, -4},
+  {-2,   5, -10,  27, 121, -17,   7, -3},
+  {-1,   3,  -6,  17, 125, -13,   5, -2},
+  {0,   1,  -3,   8, 127,  -7,   3, -1}
+#elif FILTER_ALPHA_SHARP == 75
+  {0,   0,   0, 128,   0,   0,   0, 0},
+  {-1,   2,  -6, 126,   9,  -3,   2, -1},
+  {-1,   4, -11, 123,  18,  -7,   3, -1},
+  {-2,   6, -16, 119,  28, -10,   5, -2},
+  {-2,   7, -19, 113,  38, -13,   6, -2},
+  {-3,   8, -21, 106,  49, -16,   7, -2},
+  {-3,   9, -22,  99,  59, -19,   8, -3},
+  {-3,   9, -23,  90,  70, -21,   9, -3},
+  {-3,   9, -22,  80,  80, -22,   9, -3},
+  {-3,   9, -21,  70,  90, -23,   9, -3},
+  {-3,   8, -19,  59,  99, -22,   9, -3},
+  {-2,   7, -16,  49, 106, -21,   8, -3},
+  {-2,   6, -13,  38, 113, -19,   7, -2},
+  {-2,   5, -10,  28, 119, -16,   6, -2},
+  {-1,   3,  -7,  18, 123, -11,   4, -1},
+  {-1,   2,  -3,   9, 126,  -6,   2, -1}
+#elif FILTER_ALPHA_SHARP == 65
   /* alpha = 0.65 */
   { 0,   0,   0, 128,   0,   0,   0,  0},
   { 0,   2,  -6, 126,   8,  -3,   1,  0},
@@ -164,45 +171,27 @@
   { -1,   4, -10,  27, 118, -14,   5, -1},
   { -1,   2,  -6,  18, 123, -10,   3, -1},
   { 0,   1,  -3,   8, 126,  -6,   2,  0}
-#elif FILTER_ALPHA_SHARP == 60
-  /* alpha = 0.60 */
-  { 0,   0,   0, 128,   0,   0,   0,  0},
-  { 0,   2,  -6, 126,   8,  -3,   1,  0},
-  { -1,   3, -10, 123,  18,  -6,   2, -1},
-  { -1,   4, -14, 118,  28,  -9,   3, -1},
-  { -1,   5, -17, 112,  38, -12,   4, -1},
-  { -1,   6, -19, 105,  48, -15,   5, -1},
-  { -1,   6, -20,  97,  58, -17,   6, -1},
-  { -1,   6, -20,  88,  69, -19,   6, -1},
-  { -1,   6, -20,  79,  79, -20,   6, -1},
-  { -1,   6, -19,  69,  88, -20,   6, -1},
-  { -1,   6, -17,  58,  97, -20,   6, -1},
-  { -1,   5, -15,  48, 105, -19,   6, -1},
-  { -1,   4, -12,  38, 112, -17,   5, -1},
-  { -1,   3,  -9,  28, 118, -14,   4, -1},
-  { -1,   2,  -6,  18, 123, -10,   3, -1},
-  { 0,   1,  -3,   8, 126,  -6,   2,  0}
-#elif FILTER_ALPHA_SHARP == 55
-  /* alpha = 0.55 */
-  { 0,   0,   0, 128,   0,   0,   0,  0},
-  { 0,   1,  -5, 126,   8,  -3,   1,  0},
-  { -1,   2, -10, 123,  18,  -6,   2,  0},
-  { -1,   4, -13, 118,  27,  -9,   3, -1},
-  { -1,   5, -16, 112,  37, -12,   4, -1},
-  { -1,   5, -18, 105,  48, -14,   4, -1},
-  { -1,   5, -19,  97,  58, -16,   5, -1},
-  { -1,   6, -19,  88,  68, -18,   5, -1},
-  { -1,   6, -19,  78,  78, -19,   6, -1},
-  { -1,   5, -18,  68,  88, -19,   6, -1},
-  { -1,   5, -16,  58,  97, -19,   5, -1},
-  { -1,   4, -14,  48, 105, -18,   5, -1},
-  { -1,   4, -12,  37, 112, -16,   5, -1},
-  { -1,   3,  -9,  27, 118, -13,   4, -1},
-  { 0,   2,  -6,  18, 123, -10,   2, -1},
-  { 0,   1,  -3,   8, 126,  -5,   1,  0}
 #endif  /* FILTER_ALPHA_SHARP */
 #else   /* SUBPEL_SHIFTS==16 */
-#if FILTER_ALPHA_SHARP == 65
+#if FILTER_ALPHA_SHARP == 1
+  {0,   0,   0, 128,   0,   0,   0, 0},
+  {-2,   5, -13, 125,  17,  -6,   3, -1},
+  {-4,   9, -20, 115,  37, -13,   6, -2},
+  {-4,  10, -24, 100,  59, -19,   9, -3},
+  {-4,  10, -23,  81,  81, -23,  10, -4},
+  {-3,   9, -19,  59, 100, -24,  10, -4},
+  {-2,   6, -13,  37, 115, -20,   9, -4},
+  {-1,   3,  -6,  17, 125, -13,   5, -2}
+#elif FILTER_ALPHA_SHARP == 75
+  {0,   0,   0, 128,   0,   0,   0, 0},
+  {-1,   4, -11, 123,  18,  -7,   3, -1},
+  {-2,   7, -19, 113,  38, -13,   6, -2},
+  {-3,   9, -22,  99,  59, -19,   8, -3},
+  {-3,   9, -22,  80,  80, -22,   9, -3},
+  {-3,   8, -19,  59,  99, -22,   9, -3},
+  {-2,   6, -13,  38, 113, -19,   7, -2},
+  {-1,   3,  -7,  18, 123, -11,   4, -1}
+#elif FILTER_ALPHA_SHARP == 65
   /* alpha = 0.65 */
   { 0,   0,   0, 128,   0,   0,   0, 0},
   { -1,   3, -10, 123,  18,  -6,   2, -1},
@@ -212,26 +201,6 @@
   { -2,   6, -17,  59,  98, -21,   7, -2},
   { -1,   5, -13,  38, 112, -17,   5, -1},
   { -1,   2,  -6,  18, 123, -10,   3, -1}
-#elif FILTER_ALPHA_SHARP == 60
-  /* alpha = 0.60 */
-  { 0,   0,   0, 128,   0,   0,   0, 0},
-  { -1,   3, -10, 123,  18,  -6,   2, -1},
-  { -1,   5, -17, 112,  38, -12,   4, -1},
-  { -1,   6, -20,  97,  58, -17,   6, -1},
-  { -1,   6, -20,  79,  79, -20,   6, -1},
-  { -1,   6, -17,  58,  97, -20,   6, -1},
-  { -1,   4, -12,  38, 112, -17,   5, -1},
-  { -1,   2,  -6,  18, 123, -10,   3, -1}
-#elif FILTER_ALPHA_SHARP == 55
-  /* alpha = 0.55 */
-  { 0,   0,   0, 128,   0,   0,   0,  0},
-  { -1,   2, -10, 123,  18,  -6,   2,  0},
-  { -1,   5, -16, 112,  37, -12,   4, -1},
-  { -1,   5, -19,  97,  58, -16,   5, -1},
-  { -1,   6, -19,  78,  78, -19,   6, -1},
-  { -1,   5, -16,  58,  97, -19,   5, -1},
-  { -1,   4, -12,  37, 112, -16,   5, -1},
-  { 0,   2,  -6,  18, 123, -10,   2, -1}
 #endif  /* FILTER_ALPHA_SHARP */
 #endif  /* SUBPEL_SHIFTS==16 */
 };
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index 8f2417f..ccecc49 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -17,6 +17,7 @@
 #include "loopfilter.h"
 #include "entropymv.h"
 #include "entropy.h"
+#include "entropymode.h"
 #include "idct.h"
 #include "recon.h"
 #if CONFIG_POSTPROC
@@ -82,6 +83,11 @@
 #if CONFIG_HIGH_PRECISION_MV
   unsigned int MVcount_hp [2] [MVvals_hp];
 #endif
+#if CONFIG_SWITCHABLE_INTERP
+  vp8_prob switchable_interp_prob[VP8_SWITCHABLE_FILTERS+1]
+                                 [VP8_SWITCHABLE_FILTERS-1];
+#endif
+
   int mode_context[6][4];
   int mode_context_a[6][4];
   int vp8_mode_contexts[6][4];
@@ -95,15 +101,6 @@
 } CLAMP_TYPE;
 
 typedef enum {
-  SIXTAP   = 0,
-  BILINEAR = 1,
-#if CONFIG_ENHANCED_INTERP
-  EIGHTTAP = 2,
-  EIGHTTAP_SHARP = 3,
-#endif
-} INTERPOLATIONFILTERTYPE;
-
-typedef enum {
   SINGLE_PREDICTION_ONLY = 0,
   COMP_PREDICTION_ONLY   = 1,
   HYBRID_PREDICTION      = 2,
diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c
index 2d46496..b7d52a5 100644
--- a/vp8/common/pred_common.c
+++ b/vp8/common/pred_common.c
@@ -62,6 +62,38 @@
                      (m - cm->mode_info_stride)->mbmi.mb_skip_coeff;
       break;
 
+#if CONFIG_SWITCHABLE_INTERP
+    case PRED_SWITCHABLE_INTERP:
+      {
+        int left_in_image = (m - 1)->mbmi.mb_in_image;
+        int above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
+        int left_mode = (m - 1)->mbmi.mode;
+        int above_mode = (m - cm->mode_info_stride)->mbmi.mode;
+        int left_interp, above_interp;
+        if (left_in_image && left_mode >= NEARESTMV && left_mode <= SPLITMV)
+          left_interp = vp8_switchable_interp_map[(m - 1)->mbmi.interp_filter];
+        else
+          left_interp = VP8_SWITCHABLE_FILTERS;
+        if (above_in_image && above_mode >= NEARESTMV && above_mode <= SPLITMV)
+          above_interp = vp8_switchable_interp_map[
+              (m - cm->mode_info_stride)->mbmi.interp_filter];
+        else
+          above_interp = VP8_SWITCHABLE_FILTERS;
+
+        if (left_interp == above_interp)
+          pred_context = left_interp;
+        else if (left_interp == VP8_SWITCHABLE_FILTERS &&
+                 above_interp != VP8_SWITCHABLE_FILTERS)
+          pred_context = above_interp;
+        else if (left_interp != VP8_SWITCHABLE_FILTERS &&
+                 above_interp == VP8_SWITCHABLE_FILTERS)
+          pred_context = left_interp;
+        else
+          pred_context = VP8_SWITCHABLE_FILTERS;
+      }
+      break;
+#endif
+
     default:
       // TODO *** add error trap code.
       pred_context = 0;
@@ -111,6 +143,53 @@
   return pred_probability;
 }
 
+// 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,
+                         PRED_ID pred_id) {
+  vp8_prob *pred_probability;
+  int pred_context;
+
+  // Get the appropriate prediction context
+  pred_context = get_pred_context(cm, xd, pred_id);
+
+  switch (pred_id) {
+    case PRED_SEG_ID:
+      pred_probability = &cm->segment_pred_probs[pred_context];
+      break;
+
+    case PRED_REF:
+      pred_probability = &cm->ref_pred_probs[pred_context];
+      break;
+
+    case PRED_COMP:
+      // In keeping with convention elsewhre the probability returned is
+      // the probability of a "0" outcome which in this case means the
+      // probability of comp pred off.
+      pred_probability = &cm->prob_comppred[pred_context];
+      break;
+
+#if CONFIG_NEWENTROPY
+    case PRED_MBSKIP:
+      pred_probability = &cm->mbskip_pred_probs[pred_context];
+      break;
+#endif
+
+#if CONFIG_SWITCHABLE_INTERP
+    case PRED_SWITCHABLE_INTERP:
+      pred_probability = &cm->fc.switchable_interp_prob[pred_context][0];
+      break;
+#endif
+    default:
+      // TODO *** add error trap code.
+      pred_probability = NULL;
+      break;
+  }
+
+  return pred_probability;
+}
+
 // 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,
diff --git a/vp8/common/pred_common.h b/vp8/common/pred_common.h
index a1b019f..f4992f5 100644
--- a/vp8/common/pred_common.h
+++ b/vp8/common/pred_common.h
@@ -22,6 +22,9 @@
   PRED_REF = 1,
   PRED_COMP = 2,
   PRED_MBSKIP = 3,
+#if CONFIG_SWITCHABLE_INTERP
+  PRED_SWITCHABLE_INTERP = 4,
+#endif
 } PRED_ID;
 
 
@@ -33,6 +36,10 @@
                               MACROBLOCKD *const xd,
                               PRED_ID pred_id);
 
+extern vp8_prob *get_pred_probs(VP8_COMMON *const cm,
+                                MACROBLOCKD *const xd,
+                                PRED_ID pred_id);
+
 extern unsigned char get_pred_flag(MACROBLOCKD *const xd,
                                    PRED_ID pred_id);
 
diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c
index d94ab44..6f7d963 100644
--- a/vp8/common/reconinter.c
+++ b/vp8/common/reconinter.c
@@ -19,6 +19,81 @@
 #include "onyxc_int.h"
 #endif
 
+void vp8_setup_interp_filters(MACROBLOCKD *xd,
+                              INTERPOLATIONFILTERTYPE mcomp_filter_type,
+                              VP8_COMMON *cm) {
+  if (mcomp_filter_type == SIXTAP) {
+    xd->subpixel_predict        = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap4x4);
+    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap8x4);
+    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap8x8);
+    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap16x16);
+    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap_avg4x4);
+    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap_avg8x8);
+    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, sixtap_avg16x16);
+  }
+#if CONFIG_ENHANCED_INTERP
+  else if (mcomp_filter_type == EIGHTTAP
+#if CONFIG_SWITCHABLE_INTERP
+           ||
+           mcomp_filter_type == SWITCHABLE
+#endif
+          ) {
+    xd->subpixel_predict        = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap4x4);
+    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap8x4);
+    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap8x8);
+    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap16x16);
+    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg4x4);
+    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg8x8);
+    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg16x16);
+  } else if (mcomp_filter_type == EIGHTTAP_SHARP) {
+    xd->subpixel_predict        = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap4x4_sharp);
+    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap8x4_sharp);
+    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap8x8_sharp);
+    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap16x16_sharp);
+    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg4x4_sharp);
+    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg8x8_sharp);
+    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, eighttap_avg16x16_sharp);
+  }
+#endif
+  else {
+    xd->subpixel_predict        = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear4x4);
+    xd->subpixel_predict8x4     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear8x4);
+    xd->subpixel_predict8x8     = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear8x8);
+    xd->subpixel_predict16x16   = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear16x16);
+    xd->subpixel_predict_avg    = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear_avg4x4);
+    xd->subpixel_predict_avg8x8 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear_avg8x8);
+    xd->subpixel_predict_avg16x16 = SUBPIX_INVOKE(
+        &cm->rtcd.subpix, bilinear_avg16x16);
+  }
+}
+
 void vp8_copy_mem16x16_c(
   unsigned char *src,
   int src_stride,
diff --git a/vp8/common/reconinter.h b/vp8/common/reconinter.h
index 0f8b44f..7755c52 100644
--- a/vp8/common/reconinter.h
+++ b/vp8/common/reconinter.h
@@ -12,6 +12,10 @@
 #ifndef __INC_RECONINTER_H
 #define __INC_RECONINTER_H
 
+#if CONFIG_RUNTIME_CPU_DETECT
+#include "onyxc_int.h"
+#endif
+
 extern void vp8_build_inter_predictors_mb(MACROBLOCKD *x);
 extern void vp8_build_inter16x16_predictors_mb(MACROBLOCKD *x,
                                                unsigned char *dst_y,
@@ -33,5 +37,6 @@
 
 extern void vp8_build_inter16x16_predictors_mbuv(MACROBLOCKD *x);
 extern void vp8_build_inter4x4_predictors_mbuv(MACROBLOCKD *x);
+extern void vp8_setup_interp_filters(MACROBLOCKD *x, INTERPOLATIONFILTERTYPE filter, VP8_COMMON *cm);
 
 #endif