shithub: libvpx

Download patch

ref: e55974bf86714e6403f68c010b89fbd62a4f35e5
parent: 3c755577b85f5bf0a875e5f8f33ecb99a26d316d
author: John Koleszar <jkoleszar@google.com>
date: Fri Nov 18 07:47:16 EST 2011

Speed selection support for disabled reference frames

There was an implicit reference frame test order (typically LAST,
GOLD, ARF) in the mode selection logic, but this doesn't provide the
expected results when some reference frames are disabled. For
instance, in real-time mode, the speed selection logic often disables
the ARF modes. So if the user disables the LAST and GOLD frames, the
encoder was always choosing INTRA, when in reality searching the ARF
in this case has the same speed penalty as searching LAST would have
had.

Instead, introduce the notion of a reference frame search order. This
patch preserves the former priorities, so if a frame is disabled, the
other frames bump up a slot to take its place. This patch lays the
groundwork for doing something smarter in the frame test order, for
example considering temporal distance or looking at the frames used by
nearby blocks.

Change-Id: I1199149f8662a408537c653d2c021c7f1d29a700

--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -617,6 +617,7 @@
     int i;
     VP8_COMMON *cm = &cpi->common;
     int last_improved_quant = sf->improved_quant;
+    int ref_frames;
 
     // Initialise default mode frequency sampling variables
     for (i = 0; i < MAX_MODES; i ++)
@@ -650,19 +651,28 @@
     for (i = 0; i < MAX_MODES; i++)
         sf->thresh_mult[i] = 0;
 
+    /* Count enabled references */
+    ref_frames = 1;
+    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+        ref_frames++;
+    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+        ref_frames++;
+    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+        ref_frames++;
+
     switch (Mode)
     {
 #if !(CONFIG_REALTIME_ONLY)
     case 0: // best quality mode
-        sf->thresh_mult[THR_ZEROMV   ] = 0;
-        sf->thresh_mult[THR_ZEROG    ] = 0;
-        sf->thresh_mult[THR_ZEROA    ] = 0;
-        sf->thresh_mult[THR_NEARESTMV] = 0;
-        sf->thresh_mult[THR_NEARESTG ] = 0;
-        sf->thresh_mult[THR_NEARESTA ] = 0;
-        sf->thresh_mult[THR_NEARMV   ] = 0;
-        sf->thresh_mult[THR_NEARG    ] = 0;
-        sf->thresh_mult[THR_NEARA    ] = 0;
+        sf->thresh_mult[THR_ZERO1    ] = 0;
+        sf->thresh_mult[THR_ZERO2    ] = 0;
+        sf->thresh_mult[THR_ZERO3    ] = 0;
+        sf->thresh_mult[THR_NEAREST1 ] = 0;
+        sf->thresh_mult[THR_NEAREST2 ] = 0;
+        sf->thresh_mult[THR_NEAREST3 ] = 0;
+        sf->thresh_mult[THR_NEAR1    ] = 0;
+        sf->thresh_mult[THR_NEAR2    ] = 0;
+        sf->thresh_mult[THR_NEAR3    ] = 0;
 
         sf->thresh_mult[THR_DC       ] = 0;
 
@@ -671,13 +681,13 @@
         sf->thresh_mult[THR_B_PRED   ] = 2000;
         sf->thresh_mult[THR_TM       ] = 1000;
 
-        sf->thresh_mult[THR_NEWMV    ] = 1000;
-        sf->thresh_mult[THR_NEWG     ] = 1000;
-        sf->thresh_mult[THR_NEWA     ] = 1000;
+        sf->thresh_mult[THR_NEW1     ] = 1000;
+        sf->thresh_mult[THR_NEW2     ] = 1000;
+        sf->thresh_mult[THR_NEW3     ] = 1000;
 
-        sf->thresh_mult[THR_SPLITMV  ] = 2500;
-        sf->thresh_mult[THR_SPLITG   ] = 5000;
-        sf->thresh_mult[THR_SPLITA   ] = 5000;
+        sf->thresh_mult[THR_SPLIT1   ] = 2500;
+        sf->thresh_mult[THR_SPLIT2   ] = 5000;
+        sf->thresh_mult[THR_SPLIT3   ] = 5000;
 
 
         sf->first_step = 0;
@@ -685,33 +695,33 @@
         break;
     case 1:
     case 3:
-        sf->thresh_mult[THR_NEARESTMV] = 0;
-        sf->thresh_mult[THR_ZEROMV   ] = 0;
+        sf->thresh_mult[THR_NEAREST1 ] = 0;
+        sf->thresh_mult[THR_ZERO1    ] = 0;
         sf->thresh_mult[THR_DC       ] = 0;
-        sf->thresh_mult[THR_NEARMV   ] = 0;
+        sf->thresh_mult[THR_NEAR1    ] = 0;
         sf->thresh_mult[THR_V_PRED   ] = 1000;
         sf->thresh_mult[THR_H_PRED   ] = 1000;
         sf->thresh_mult[THR_B_PRED   ] = 2500;
         sf->thresh_mult[THR_TM       ] = 1000;
 
-        sf->thresh_mult[THR_NEARESTG ] = 1000;
-        sf->thresh_mult[THR_NEARESTA ] = 1000;
+        sf->thresh_mult[THR_NEAREST2 ] = 1000;
+        sf->thresh_mult[THR_NEAREST3 ] = 1000;
 
-        sf->thresh_mult[THR_ZEROG    ] = 1000;
-        sf->thresh_mult[THR_ZEROA    ] = 1000;
-        sf->thresh_mult[THR_NEARG    ] = 1000;
-        sf->thresh_mult[THR_NEARA    ] = 1000;
+        sf->thresh_mult[THR_ZERO2    ] = 1000;
+        sf->thresh_mult[THR_ZERO3    ] = 1000;
+        sf->thresh_mult[THR_NEAR2    ] = 1000;
+        sf->thresh_mult[THR_NEAR3    ] = 1000;
 
 #if 1
-        sf->thresh_mult[THR_ZEROMV   ] = 0;
-        sf->thresh_mult[THR_ZEROG    ] = 0;
-        sf->thresh_mult[THR_ZEROA    ] = 0;
-        sf->thresh_mult[THR_NEARESTMV] = 0;
-        sf->thresh_mult[THR_NEARESTG ] = 0;
-        sf->thresh_mult[THR_NEARESTA ] = 0;
-        sf->thresh_mult[THR_NEARMV   ] = 0;
-        sf->thresh_mult[THR_NEARG    ] = 0;
-        sf->thresh_mult[THR_NEARA    ] = 0;
+        sf->thresh_mult[THR_ZERO1    ] = 0;
+        sf->thresh_mult[THR_ZERO2    ] = 0;
+        sf->thresh_mult[THR_ZERO3    ] = 0;
+        sf->thresh_mult[THR_NEAREST1 ] = 0;
+        sf->thresh_mult[THR_NEAREST2 ] = 0;
+        sf->thresh_mult[THR_NEAREST3 ] = 0;
+        sf->thresh_mult[THR_NEAR1    ] = 0;
+        sf->thresh_mult[THR_NEAR2    ] = 0;
+        sf->thresh_mult[THR_NEAR3    ] = 0;
 
 //        sf->thresh_mult[THR_DC       ] = 0;
 
@@ -720,21 +730,21 @@
 //        sf->thresh_mult[THR_B_PRED   ] = 2000;
 //        sf->thresh_mult[THR_TM       ] = 1000;
 
-        sf->thresh_mult[THR_NEWMV    ] = 1000;
-        sf->thresh_mult[THR_NEWG     ] = 1000;
-        sf->thresh_mult[THR_NEWA     ] = 1000;
+        sf->thresh_mult[THR_NEW1     ] = 1000;
+        sf->thresh_mult[THR_NEW2     ] = 1000;
+        sf->thresh_mult[THR_NEW3     ] = 1000;
 
-        sf->thresh_mult[THR_SPLITMV  ] = 1700;
-        sf->thresh_mult[THR_SPLITG   ] = 4500;
-        sf->thresh_mult[THR_SPLITA   ] = 4500;
+        sf->thresh_mult[THR_SPLIT1   ] = 1700;
+        sf->thresh_mult[THR_SPLIT2   ] = 4500;
+        sf->thresh_mult[THR_SPLIT3   ] = 4500;
 #else
-        sf->thresh_mult[THR_NEWMV    ] = 1500;
-        sf->thresh_mult[THR_NEWG     ] = 1500;
-        sf->thresh_mult[THR_NEWA     ] = 1500;
+        sf->thresh_mult[THR_NEW1     ] = 1500;
+        sf->thresh_mult[THR_NEW2     ] = 1500;
+        sf->thresh_mult[THR_NEW3     ] = 1500;
 
-        sf->thresh_mult[THR_SPLITMV  ] = 5000;
-        sf->thresh_mult[THR_SPLITG   ] = 10000;
-        sf->thresh_mult[THR_SPLITA   ] = 10000;
+        sf->thresh_mult[THR_SPLIT1   ] = 5000;
+        sf->thresh_mult[THR_SPLIT2   ] = 10000;
+        sf->thresh_mult[THR_SPLIT3   ] = 10000;
 #endif
 
         if (Speed > 0)
@@ -746,16 +756,16 @@
 
             sf->first_step = 1;
 
-            cpi->mode_check_freq[THR_SPLITG] = 2;
-            cpi->mode_check_freq[THR_SPLITA] = 2;
-            cpi->mode_check_freq[THR_SPLITMV] = 0;
+            cpi->mode_check_freq[THR_SPLIT2] = 2;
+            cpi->mode_check_freq[THR_SPLIT3] = 2;
+            cpi->mode_check_freq[THR_SPLIT1 ] = 0;
         }
 
         if (Speed > 1)
         {
-            cpi->mode_check_freq[THR_SPLITG] = 4;
-            cpi->mode_check_freq[THR_SPLITA] = 4;
-            cpi->mode_check_freq[THR_SPLITMV] = 2;
+            cpi->mode_check_freq[THR_SPLIT2] = 4;
+            cpi->mode_check_freq[THR_SPLIT3] = 4;
+            cpi->mode_check_freq[THR_SPLIT1 ] = 2;
 
             sf->thresh_mult[THR_TM       ] = 1500;
             sf->thresh_mult[THR_V_PRED   ] = 1500;
@@ -762,36 +772,36 @@
             sf->thresh_mult[THR_H_PRED   ] = 1500;
             sf->thresh_mult[THR_B_PRED   ] = 5000;
 
-            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            if (ref_frames > 1)
             {
-                sf->thresh_mult[THR_NEWMV    ] = 2000;
-                sf->thresh_mult[THR_SPLITMV  ] = 10000;
+                sf->thresh_mult[THR_NEW1     ] = 2000;
+                sf->thresh_mult[THR_SPLIT1   ] = 10000;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 1500;
-                sf->thresh_mult[THR_ZEROG    ] = 1500;
-                sf->thresh_mult[THR_NEARG    ] = 1500;
-                sf->thresh_mult[THR_NEWG     ] = 2000;
-                sf->thresh_mult[THR_SPLITG   ] = 20000;
+                sf->thresh_mult[THR_NEAREST2 ] = 1500;
+                sf->thresh_mult[THR_ZERO2    ] = 1500;
+                sf->thresh_mult[THR_NEAR2    ] = 1500;
+                sf->thresh_mult[THR_NEW2     ] = 2000;
+                sf->thresh_mult[THR_SPLIT2   ] = 20000;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 1500;
-                sf->thresh_mult[THR_ZEROA    ] = 1500;
-                sf->thresh_mult[THR_NEARA    ] = 1500;
-                sf->thresh_mult[THR_NEWA     ] = 2000;
-                sf->thresh_mult[THR_SPLITA   ] = 20000;
+                sf->thresh_mult[THR_NEAREST3 ] = 1500;
+                sf->thresh_mult[THR_ZERO3    ] = 1500;
+                sf->thresh_mult[THR_NEAR3    ] = 1500;
+                sf->thresh_mult[THR_NEW3     ] = 2000;
+                sf->thresh_mult[THR_SPLIT3   ] = 20000;
             }
         }
 
         if (Speed > 2)
         {
-            cpi->mode_check_freq[THR_SPLITG] = 15;
-            cpi->mode_check_freq[THR_SPLITA] = 15;
-            cpi->mode_check_freq[THR_SPLITMV] = 7;
+            cpi->mode_check_freq[THR_SPLIT2] = 15;
+            cpi->mode_check_freq[THR_SPLIT3] = 15;
+            cpi->mode_check_freq[THR_SPLIT1 ] = 7;
 
             sf->thresh_mult[THR_TM       ] = 2000;
             sf->thresh_mult[THR_V_PRED   ] = 2000;
@@ -798,28 +808,28 @@
             sf->thresh_mult[THR_H_PRED   ] = 2000;
             sf->thresh_mult[THR_B_PRED   ] = 7500;
 
-            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            if (ref_frames > 1)
             {
-                sf->thresh_mult[THR_NEWMV    ] = 2000;
-                sf->thresh_mult[THR_SPLITMV  ] = 25000;
+                sf->thresh_mult[THR_NEW1     ] = 2000;
+                sf->thresh_mult[THR_SPLIT1   ] = 25000;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 2000;
-                sf->thresh_mult[THR_ZEROG    ] = 2000;
-                sf->thresh_mult[THR_NEARG    ] = 2000;
-                sf->thresh_mult[THR_NEWG     ] = 2500;
-                sf->thresh_mult[THR_SPLITG   ] = 50000;
+                sf->thresh_mult[THR_NEAREST2 ] = 2000;
+                sf->thresh_mult[THR_ZERO2    ] = 2000;
+                sf->thresh_mult[THR_NEAR2    ] = 2000;
+                sf->thresh_mult[THR_NEW2     ] = 2500;
+                sf->thresh_mult[THR_SPLIT2   ] = 50000;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 2000;
-                sf->thresh_mult[THR_ZEROA    ] = 2000;
-                sf->thresh_mult[THR_NEARA    ] = 2000;
-                sf->thresh_mult[THR_NEWA     ] = 2500;
-                sf->thresh_mult[THR_SPLITA   ] = 50000;
+                sf->thresh_mult[THR_NEAREST3 ] = 2000;
+                sf->thresh_mult[THR_ZERO3    ] = 2000;
+                sf->thresh_mult[THR_NEAR3    ] = 2000;
+                sf->thresh_mult[THR_NEW3     ] = 2500;
+                sf->thresh_mult[THR_SPLIT3   ] = 50000;
             }
 
             sf->improved_quant = 0;
@@ -833,17 +843,17 @@
 
         if (Speed > 3)
         {
-            sf->thresh_mult[THR_SPLITA  ] = INT_MAX;
-            sf->thresh_mult[THR_SPLITG  ] = INT_MAX;
-            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT3  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT2  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT1   ] = INT_MAX;
 
             cpi->mode_check_freq[THR_V_PRED] = 0;
             cpi->mode_check_freq[THR_H_PRED] = 0;
             cpi->mode_check_freq[THR_B_PRED] = 0;
-            cpi->mode_check_freq[THR_NEARG] = 0;
-            cpi->mode_check_freq[THR_NEWG] = 0;
-            cpi->mode_check_freq[THR_NEARA] = 0;
-            cpi->mode_check_freq[THR_NEWA] = 0;
+            cpi->mode_check_freq[THR_NEAR2] = 0;
+            cpi->mode_check_freq[THR_NEW2] = 0;
+            cpi->mode_check_freq[THR_NEAR3] = 0;
+            cpi->mode_check_freq[THR_NEW3] = 0;
 
             sf->auto_filter = 1;
             sf->recode_loop = 0; // recode loop off
@@ -859,32 +869,32 @@
             cpi->mode_check_freq[THR_H_PRED] = 2;
             cpi->mode_check_freq[THR_B_PRED] = 2;
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                cpi->mode_check_freq[THR_NEARG] = 2;
-                cpi->mode_check_freq[THR_NEWG] = 4;
+                cpi->mode_check_freq[THR_NEAR2] = 2;
+                cpi->mode_check_freq[THR_NEW2] = 4;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                cpi->mode_check_freq[THR_NEARA] = 2;
-                cpi->mode_check_freq[THR_NEWA] = 4;
+                cpi->mode_check_freq[THR_NEAR3] = 2;
+                cpi->mode_check_freq[THR_NEW3] = 4;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 2000;
-                sf->thresh_mult[THR_ZEROG    ] = 2000;
-                sf->thresh_mult[THR_NEARG    ] = 2000;
-                sf->thresh_mult[THR_NEWG     ] = 4000;
+                sf->thresh_mult[THR_NEAREST2 ] = 2000;
+                sf->thresh_mult[THR_ZERO2    ] = 2000;
+                sf->thresh_mult[THR_NEAR2    ] = 2000;
+                sf->thresh_mult[THR_NEW2     ] = 4000;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 2000;
-                sf->thresh_mult[THR_ZEROA    ] = 2000;
-                sf->thresh_mult[THR_NEARA    ] = 2000;
-                sf->thresh_mult[THR_NEWA     ] = 4000;
+                sf->thresh_mult[THR_NEAREST3 ] = 2000;
+                sf->thresh_mult[THR_ZERO3    ] = 2000;
+                sf->thresh_mult[THR_NEAR3    ] = 2000;
+                sf->thresh_mult[THR_NEW3     ] = 4000;
             }
         }
 
@@ -895,33 +905,33 @@
         sf->recode_loop = 0;
         sf->auto_filter = 1;
         sf->iterative_sub_pixel = 1;
-        sf->thresh_mult[THR_NEARESTMV] = 0;
-        sf->thresh_mult[THR_ZEROMV   ] = 0;
+        sf->thresh_mult[THR_NEAREST1 ] = 0;
+        sf->thresh_mult[THR_ZERO1    ] = 0;
         sf->thresh_mult[THR_DC       ] = 0;
         sf->thresh_mult[THR_TM       ] = 0;
-        sf->thresh_mult[THR_NEARMV   ] = 0;
+        sf->thresh_mult[THR_NEAR1    ] = 0;
         sf->thresh_mult[THR_V_PRED   ] = 1000;
         sf->thresh_mult[THR_H_PRED   ] = 1000;
         sf->thresh_mult[THR_B_PRED   ] = 2500;
-        sf->thresh_mult[THR_NEARESTG ] = 1000;
-        sf->thresh_mult[THR_ZEROG    ] = 1000;
-        sf->thresh_mult[THR_NEARG    ] = 1000;
-        sf->thresh_mult[THR_NEARESTA ] = 1000;
-        sf->thresh_mult[THR_ZEROA    ] = 1000;
-        sf->thresh_mult[THR_NEARA    ] = 1000;
-        sf->thresh_mult[THR_NEWMV    ] = 2000;
-        sf->thresh_mult[THR_NEWG     ] = 2000;
-        sf->thresh_mult[THR_NEWA     ] = 2000;
-        sf->thresh_mult[THR_SPLITMV  ] = 5000;
-        sf->thresh_mult[THR_SPLITG   ] = 10000;
-        sf->thresh_mult[THR_SPLITA   ] = 10000;
+        sf->thresh_mult[THR_NEAREST2 ] = 1000;
+        sf->thresh_mult[THR_ZERO2    ] = 1000;
+        sf->thresh_mult[THR_NEAR2    ] = 1000;
+        sf->thresh_mult[THR_NEAREST3 ] = 1000;
+        sf->thresh_mult[THR_ZERO3    ] = 1000;
+        sf->thresh_mult[THR_NEAR3    ] = 1000;
+        sf->thresh_mult[THR_NEW1     ] = 2000;
+        sf->thresh_mult[THR_NEW2     ] = 2000;
+        sf->thresh_mult[THR_NEW3     ] = 2000;
+        sf->thresh_mult[THR_SPLIT1   ] = 5000;
+        sf->thresh_mult[THR_SPLIT2   ] = 10000;
+        sf->thresh_mult[THR_SPLIT3   ] = 10000;
         sf->search_method = NSTEP;
 
         if (Speed > 0)
         {
-            cpi->mode_check_freq[THR_SPLITG] = 4;
-            cpi->mode_check_freq[THR_SPLITA] = 4;
-            cpi->mode_check_freq[THR_SPLITMV] = 2;
+            cpi->mode_check_freq[THR_SPLIT2] = 4;
+            cpi->mode_check_freq[THR_SPLIT3] = 4;
+            cpi->mode_check_freq[THR_SPLIT1 ] = 2;
 
             sf->thresh_mult[THR_DC       ] = 0;
             sf->thresh_mult[THR_TM       ] = 1000;
@@ -929,31 +939,31 @@
             sf->thresh_mult[THR_H_PRED   ] = 2000;
             sf->thresh_mult[THR_B_PRED   ] = 5000;
 
-            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            if (ref_frames > 1)
             {
-                sf->thresh_mult[THR_NEARESTMV] = 0;
-                sf->thresh_mult[THR_ZEROMV   ] = 0;
-                sf->thresh_mult[THR_NEARMV   ] = 0;
-                sf->thresh_mult[THR_NEWMV    ] = 2000;
-                sf->thresh_mult[THR_SPLITMV  ] = 10000;
+                sf->thresh_mult[THR_NEAREST1 ] = 0;
+                sf->thresh_mult[THR_ZERO1    ] = 0;
+                sf->thresh_mult[THR_NEAR1    ] = 0;
+                sf->thresh_mult[THR_NEW1     ] = 2000;
+                sf->thresh_mult[THR_SPLIT1   ] = 10000;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 1000;
-                sf->thresh_mult[THR_ZEROG    ] = 1000;
-                sf->thresh_mult[THR_NEARG    ] = 1000;
-                sf->thresh_mult[THR_NEWG     ] = 2000;
-                sf->thresh_mult[THR_SPLITG   ] = 20000;
+                sf->thresh_mult[THR_NEAREST2 ] = 1000;
+                sf->thresh_mult[THR_ZERO2    ] = 1000;
+                sf->thresh_mult[THR_NEAR2    ] = 1000;
+                sf->thresh_mult[THR_NEW2     ] = 2000;
+                sf->thresh_mult[THR_SPLIT2   ] = 20000;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 1000;
-                sf->thresh_mult[THR_ZEROA    ] = 1000;
-                sf->thresh_mult[THR_NEARA    ] = 1000;
-                sf->thresh_mult[THR_NEWA     ] = 2000;
-                sf->thresh_mult[THR_SPLITA   ] = 20000;
+                sf->thresh_mult[THR_NEAREST3 ] = 1000;
+                sf->thresh_mult[THR_ZERO3    ] = 1000;
+                sf->thresh_mult[THR_NEAR3    ] = 1000;
+                sf->thresh_mult[THR_NEW3     ] = 2000;
+                sf->thresh_mult[THR_SPLIT3   ] = 20000;
             }
 
             sf->improved_quant = 0;
@@ -966,9 +976,9 @@
 
         if (Speed > 1)
         {
-            cpi->mode_check_freq[THR_SPLITMV] = 7;
-            cpi->mode_check_freq[THR_SPLITG] = 15;
-            cpi->mode_check_freq[THR_SPLITA] = 15;
+            cpi->mode_check_freq[THR_SPLIT1 ] = 7;
+            cpi->mode_check_freq[THR_SPLIT2] = 15;
+            cpi->mode_check_freq[THR_SPLIT3] = 15;
 
             sf->thresh_mult[THR_TM       ] = 2000;
             sf->thresh_mult[THR_V_PRED   ] = 2000;
@@ -975,28 +985,28 @@
             sf->thresh_mult[THR_H_PRED   ] = 2000;
             sf->thresh_mult[THR_B_PRED   ] = 5000;
 
-            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            if (ref_frames > 1)
             {
-                sf->thresh_mult[THR_NEWMV    ] = 2000;
-                sf->thresh_mult[THR_SPLITMV  ] = 25000;
+                sf->thresh_mult[THR_NEW1     ] = 2000;
+                sf->thresh_mult[THR_SPLIT1   ] = 25000;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 2000;
-                sf->thresh_mult[THR_ZEROG    ] = 2000;
-                sf->thresh_mult[THR_NEARG    ] = 2000;
-                sf->thresh_mult[THR_NEWG     ] = 2500;
-                sf->thresh_mult[THR_SPLITG   ] = 50000;
+                sf->thresh_mult[THR_NEAREST2 ] = 2000;
+                sf->thresh_mult[THR_ZERO2    ] = 2000;
+                sf->thresh_mult[THR_NEAR2    ] = 2000;
+                sf->thresh_mult[THR_NEW2     ] = 2500;
+                sf->thresh_mult[THR_SPLIT2   ] = 50000;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 2000;
-                sf->thresh_mult[THR_ZEROA    ] = 2000;
-                sf->thresh_mult[THR_NEARA    ] = 2000;
-                sf->thresh_mult[THR_NEWA     ] = 2500;
-                sf->thresh_mult[THR_SPLITA   ] = 50000;
+                sf->thresh_mult[THR_NEAREST3 ] = 2000;
+                sf->thresh_mult[THR_ZERO3    ] = 2000;
+                sf->thresh_mult[THR_NEAR3    ] = 2000;
+                sf->thresh_mult[THR_NEW3     ] = 2500;
+                sf->thresh_mult[THR_SPLIT3   ] = 50000;
             }
 
         }
@@ -1009,21 +1019,21 @@
             cpi->mode_check_freq[THR_H_PRED] = 2;
             cpi->mode_check_freq[THR_B_PRED] = 2;
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                cpi->mode_check_freq[THR_NEARG] = 2;
-                cpi->mode_check_freq[THR_NEWG] = 4;
+                cpi->mode_check_freq[THR_NEAR2] = 2;
+                cpi->mode_check_freq[THR_NEW2] = 4;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                cpi->mode_check_freq[THR_NEARA] = 2;
-                cpi->mode_check_freq[THR_NEWA] = 4;
+                cpi->mode_check_freq[THR_NEAR3] = 2;
+                cpi->mode_check_freq[THR_NEW3] = 4;
             }
 
-            sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
-            sf->thresh_mult[THR_SPLITG  ] = INT_MAX;
-            sf->thresh_mult[THR_SPLITA  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT1   ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT2  ] = INT_MAX;
+            sf->thresh_mult[THR_SPLIT3  ] = INT_MAX;
 
         }
 
@@ -1049,14 +1059,14 @@
 
             if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
             {
-                cpi->mode_check_freq[THR_NEARG] = 2;
-                cpi->mode_check_freq[THR_NEWG] = 4;
+                cpi->mode_check_freq[THR_NEAR2] = 2;
+                cpi->mode_check_freq[THR_NEW2] = 4;
             }
 
             if (cpi->ref_frame_flags & VP8_ALT_FLAG)
             {
-                cpi->mode_check_freq[THR_NEARA] = 2;
-                cpi->mode_check_freq[THR_NEWA] = 4;
+                cpi->mode_check_freq[THR_NEAR3] = 2;
+                cpi->mode_check_freq[THR_NEW3] = 4;
             }
 
             sf->thresh_mult[THR_TM       ] = 2000;
@@ -1064,18 +1074,18 @@
 
             if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
             {
-                sf->thresh_mult[THR_NEARESTG ] = 2000;
-                sf->thresh_mult[THR_ZEROG    ] = 2000;
-                sf->thresh_mult[THR_NEARG    ] = 2000;
-                sf->thresh_mult[THR_NEWG     ] = 4000;
+                sf->thresh_mult[THR_NEAREST2 ] = 2000;
+                sf->thresh_mult[THR_ZERO2    ] = 2000;
+                sf->thresh_mult[THR_NEAR2    ] = 2000;
+                sf->thresh_mult[THR_NEW2     ] = 4000;
             }
 
             if (cpi->ref_frame_flags & VP8_ALT_FLAG)
             {
-                sf->thresh_mult[THR_NEARESTA ] = 2000;
-                sf->thresh_mult[THR_ZEROA    ] = 2000;
-                sf->thresh_mult[THR_NEARA    ] = 2000;
-                sf->thresh_mult[THR_NEWA     ] = 4000;
+                sf->thresh_mult[THR_NEAREST3 ] = 2000;
+                sf->thresh_mult[THR_ZERO3    ] = 2000;
+                sf->thresh_mult[THR_NEAR3    ] = 2000;
+                sf->thresh_mult[THR_NEW3     ] = 4000;
             }
         }
 
@@ -1122,25 +1132,25 @@
             if (thresh < 2000)
                 thresh = 2000;
 
-            if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+            if (ref_frames > 1)
             {
-                sf->thresh_mult[THR_NEWMV] = thresh;
-                sf->thresh_mult[THR_NEARESTMV ] = thresh >> 1;
-                sf->thresh_mult[THR_NEARMV    ] = thresh >> 1;
+                sf->thresh_mult[THR_NEW1 ] = thresh;
+                sf->thresh_mult[THR_NEAREST1  ] = thresh >> 1;
+                sf->thresh_mult[THR_NEAR1     ] = thresh >> 1;
             }
 
-            if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+            if (ref_frames > 2)
             {
-                sf->thresh_mult[THR_NEWG] = thresh << 1;
-                sf->thresh_mult[THR_NEARESTG ] = thresh;
-                sf->thresh_mult[THR_NEARG    ] = thresh;
+                sf->thresh_mult[THR_NEW2] = thresh << 1;
+                sf->thresh_mult[THR_NEAREST2 ] = thresh;
+                sf->thresh_mult[THR_NEAR2    ] = thresh;
             }
 
-            if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+            if (ref_frames > 3)
             {
-                sf->thresh_mult[THR_NEWA] = thresh << 1;
-                sf->thresh_mult[THR_NEARESTA ] = thresh;
-                sf->thresh_mult[THR_NEARA    ] = thresh;
+                sf->thresh_mult[THR_NEW3] = thresh << 1;
+                sf->thresh_mult[THR_NEAREST3 ] = thresh;
+                sf->thresh_mult[THR_NEAR3    ] = thresh;
             }
 
             // Disable other intra prediction modes
@@ -1165,21 +1175,21 @@
 
             if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
             {
-                cpi->mode_check_freq[THR_ZEROG] = 1 << (Tmp - 1);
-                cpi->mode_check_freq[THR_NEARESTG] = 1 << (Tmp - 1);
-                cpi->mode_check_freq[THR_NEARG] = 1 << Tmp;
-                cpi->mode_check_freq[THR_NEWG] = 1 << (Tmp + 1);
+                cpi->mode_check_freq[THR_ZERO2] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEAREST2] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEAR2] = 1 << Tmp;
+                cpi->mode_check_freq[THR_NEW2] = 1 << (Tmp + 1);
             }
 
             if (cpi->ref_frame_flags & VP8_ALT_FLAG)
             {
-                cpi->mode_check_freq[THR_ZEROA] = 1 << (Tmp - 1);
-                cpi->mode_check_freq[THR_NEARESTA] = 1 << (Tmp - 1);
-                cpi->mode_check_freq[THR_NEARA] = 1 << Tmp;
-                cpi->mode_check_freq[THR_NEWA] = 1 << (Tmp + 1);
+                cpi->mode_check_freq[THR_ZERO3] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEAREST3] = 1 << (Tmp - 1);
+                cpi->mode_check_freq[THR_NEAR3] = 1 << Tmp;
+                cpi->mode_check_freq[THR_NEW3] = 1 << (Tmp + 1);
             }
 
-            cpi->mode_check_freq[THR_NEWMV] = 1 << (Tmp - 1);
+            cpi->mode_check_freq[THR_NEW1 ] = 1 << (Tmp - 1);
         }
 
         cm->filter_type = NORMAL_LOOPFILTER;
@@ -1195,35 +1205,6 @@
         vpx_memset(cpi->error_bins, 0, sizeof(cpi->error_bins));
 
     }; /* switch */
-
-    /* disable frame modes if flags not set */
-    if (!(cpi->ref_frame_flags & VP8_LAST_FLAG))
-    {
-        sf->thresh_mult[THR_NEWMV    ] = INT_MAX;
-        sf->thresh_mult[THR_NEARESTMV] = INT_MAX;
-        sf->thresh_mult[THR_ZEROMV   ] = INT_MAX;
-        sf->thresh_mult[THR_NEARMV   ] = INT_MAX;
-        sf->thresh_mult[THR_SPLITMV  ] = INT_MAX;
-    }
-
-    if (!(cpi->ref_frame_flags & VP8_GOLD_FLAG))
-    {
-        sf->thresh_mult[THR_NEARESTG ] = INT_MAX;
-        sf->thresh_mult[THR_ZEROG    ] = INT_MAX;
-        sf->thresh_mult[THR_NEARG    ] = INT_MAX;
-        sf->thresh_mult[THR_NEWG     ] = INT_MAX;
-        sf->thresh_mult[THR_SPLITG   ] = INT_MAX;
-    }
-
-    if (!(cpi->ref_frame_flags & VP8_ALT_FLAG))
-    {
-        sf->thresh_mult[THR_NEARESTA ] = INT_MAX;
-        sf->thresh_mult[THR_ZEROA    ] = INT_MAX;
-        sf->thresh_mult[THR_NEARA    ] = INT_MAX;
-        sf->thresh_mult[THR_NEWA     ] = INT_MAX;
-        sf->thresh_mult[THR_SPLITA   ] = INT_MAX;
-    }
-
 
     // Slow quant, dct and trellis not worthwhile for first pass
     // so make sure they are always turned off.
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -133,32 +133,32 @@
 
 typedef enum
 {
-    THR_ZEROMV         = 0,
+    THR_ZERO1          = 0,
     THR_DC             = 1,
 
-    THR_NEARESTMV      = 2,
-    THR_NEARMV         = 3,
+    THR_NEAREST1       = 2,
+    THR_NEAR1          = 3,
 
-    THR_ZEROG          = 4,
-    THR_NEARESTG       = 5,
+    THR_ZERO2          = 4,
+    THR_NEAREST2       = 5,
 
-    THR_ZEROA          = 6,
-    THR_NEARESTA       = 7,
+    THR_ZERO3          = 6,
+    THR_NEAREST3       = 7,
 
-    THR_NEARG          = 8,
-    THR_NEARA          = 9,
+    THR_NEAR2          = 8,
+    THR_NEAR3          = 9,
 
     THR_V_PRED         = 10,
     THR_H_PRED         = 11,
     THR_TM             = 12,
 
-    THR_NEWMV          = 13,
-    THR_NEWG           = 14,
-    THR_NEWA           = 15,
+    THR_NEW1           = 13,
+    THR_NEW2           = 14,
+    THR_NEW3           = 15,
 
-    THR_SPLITMV        = 16,
-    THR_SPLITG         = 17,
-    THR_SPLITA         = 18,
+    THR_SPLIT1         = 16,
+    THR_SPLIT2         = 17,
+    THR_SPLIT3         = 18,
 
     THR_B_PRED         = 19,
 }
--- a/vp8/encoder/pickinter.c
+++ b/vp8/encoder/pickinter.c
@@ -39,7 +39,7 @@
 extern unsigned int cnt_pm;
 #endif
 
-extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
+extern const int vp8_ref_frame_order[MAX_MODES];
 extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
 
 extern unsigned int (*vp8_get4x4sse_cs)(unsigned char *src_ptr, int  source_stride, unsigned char *ref_ptr, int  recon_stride);
@@ -439,8 +439,9 @@
     unsigned char *y_buffer[4];
     unsigned char *u_buffer[4];
     unsigned char *v_buffer[4];
+    int i;
+    int ref_frame_map[4];
 
-    int skip_mode[4] = {0, 0, 0, 0};
     int found_near_mvs[4] = {0, 0, 0, 0};
 
     int have_subp_search = cpi->sf.half_pixel_search;  /* In real-time mode, when Speed >= 15, no sub-pixel search. */
@@ -450,6 +451,17 @@
     vpx_memset(near_mv, 0, sizeof(near_mv));
     vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
 
+    /* Setup search priorities */
+    i=0;
+    ref_frame_map[i++] = INTRA_FRAME;
+    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+        ref_frame_map[i++] = LAST_FRAME;
+    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+        ref_frame_map[i++] = GOLDEN_FRAME;
+    if (cpi->ref_frame_flags & VP8_ALT_FLAG) // &&(cpi->source_alt_ref_active || cpi->oxcf.number_of_layers > 1)
+        ref_frame_map[i++] = ALTREF_FRAME;
+    for(; i<4; i++)
+        ref_frame_map[i] = -1;
 
     // set up all the refframe dependent pointers.
     if (cpi->ref_frame_flags & VP8_LAST_FLAG)
@@ -459,8 +471,6 @@
         u_buffer[LAST_FRAME] = lst_yv12->u_buffer + recon_uvoffset;
         v_buffer[LAST_FRAME] = lst_yv12->v_buffer + recon_uvoffset;
     }
-    else
-        skip_mode[LAST_FRAME] = 1;
 
     if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
     {
@@ -469,11 +479,8 @@
         u_buffer[GOLDEN_FRAME] = gld_yv12->u_buffer + recon_uvoffset;
         v_buffer[GOLDEN_FRAME] = gld_yv12->v_buffer + recon_uvoffset;
     }
-    else
-        skip_mode[GOLDEN_FRAME] = 1;
 
-    if ((cpi->ref_frame_flags & VP8_ALT_FLAG) &&
-        (cpi->source_alt_ref_active || cpi->oxcf.number_of_layers > 1))
+    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
     {
         YV12_BUFFER_CONFIG *alt_yv12 = &cpi->common.yv12_fb[cpi->common.alt_fb_idx];
         y_buffer[ALTREF_FRAME] = alt_yv12->y_buffer + recon_yoffset;
@@ -480,8 +487,6 @@
         u_buffer[ALTREF_FRAME] = alt_yv12->u_buffer + recon_uvoffset;
         v_buffer[ALTREF_FRAME] = alt_yv12->v_buffer + recon_uvoffset;
     }
-    else
-        skip_mode[ALTREF_FRAME] = 1;
 
     cpi->mbs_tested_so_far++;          // Count of the number of MBs tested so far this frame
 
@@ -496,14 +501,16 @@
     {
         int frame_cost;
         int this_rd = INT_MAX;
+        int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
 
         if (best_rd <= cpi->rd_threshes[mode_index])
             continue;
 
-        x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index];
-
-        if (skip_mode[x->e_mbd.mode_info_context->mbmi.ref_frame])
+        if (this_ref_frame < 0)
             continue;
+
+        x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
+
 
         // Check to see if the testing frequency for this mode is at its max
         // If so then prevent it from being tested and increase the threshold for its testing
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -28,7 +28,6 @@
 #define MAX_BPB_FACTOR          50
 
 extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
-extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
 
 
 
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -100,36 +100,39 @@
     B_PRED,
 };
 
-const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] =
+/* This table determines the search order in reference frame priority order,
+ * which may not necessarily match INTRA,LAST,GOLDEN,ARF
+ */
+const int vp8_ref_frame_order[MAX_MODES] =
 {
-    LAST_FRAME,
-    INTRA_FRAME,
+    1,
+    0,
 
-    LAST_FRAME,
-    LAST_FRAME,
+    1,
+    1,
 
-    GOLDEN_FRAME,
-    GOLDEN_FRAME,
+    2,
+    2,
 
-    ALTREF_FRAME,
-    ALTREF_FRAME,
+    3,
+    3,
 
-    GOLDEN_FRAME,
-    ALTREF_FRAME,
+    2,
+    3,
 
-    INTRA_FRAME,
-    INTRA_FRAME,
-    INTRA_FRAME,
+    0,
+    0,
+    0,
 
-    LAST_FRAME,
-    GOLDEN_FRAME,
-    ALTREF_FRAME,
+    1,
+    2,
+    3,
 
-    LAST_FRAME,
-    GOLDEN_FRAME,
-    ALTREF_FRAME,
+    1,
+    2,
+    3,
 
-    INTRA_FRAME,
+    0,
 };
 
 static void fill_token_costs(
@@ -1789,11 +1792,24 @@
     unsigned char *y_buffer[4];
     unsigned char *u_buffer[4];
     unsigned char *v_buffer[4];
+    int ref_frame_map[4];
 
     vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
     vpx_memset(&best_bmodes, 0, sizeof(best_bmodes));
 
+    /* Setup search priorities */
+    i=0;
+    ref_frame_map[i++] = INTRA_FRAME;
     if (cpi->ref_frame_flags & VP8_LAST_FLAG)
+        ref_frame_map[i++] = LAST_FRAME;
+    if (cpi->ref_frame_flags & VP8_GOLD_FLAG)
+        ref_frame_map[i++] = GOLDEN_FRAME;
+    if (cpi->ref_frame_flags & VP8_ALT_FLAG)
+        ref_frame_map[i++] = ALTREF_FRAME;
+    for(; i<4; i++)
+        ref_frame_map[i] = -1;
+
+    if (cpi->ref_frame_flags & VP8_LAST_FLAG)
     {
         YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];
 
@@ -1852,6 +1868,7 @@
         int lf_or_gf = 0;           // Lat Frame (01) or gf/arf (1)
         int disable_skip = 0;
         int other_cost = 0;
+        int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
 
         // Experimental debug code.
         // Record of rd values recorded for this MB. -1 indicates not measured
@@ -1864,6 +1881,9 @@
         if (best_rd <= cpi->rd_threshes[mode_index])
             continue;
 
+        if (this_ref_frame < 0)
+            continue;
+
         // These variables hold are rolling total cost and distortion for this mode
         rate2 = 0;
         distortion2 = 0;
@@ -1872,7 +1892,7 @@
 
         x->e_mbd.mode_info_context->mbmi.mode = this_mode;
         x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
-        x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index];
+        x->e_mbd.mode_info_context->mbmi.ref_frame = this_ref_frame;
 
         // Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
         // unless ARNR filtering is enabled in which case we want
@@ -1920,13 +1940,13 @@
         // Experimental code. Special case for gf and arf zeromv modes. Increase zbin size to supress noise
         if (cpi->zbin_mode_boost_enabled)
         {
-            if ( vp8_ref_frame_order[mode_index] == INTRA_FRAME )
+            if ( this_ref_frame == INTRA_FRAME )
                 cpi->zbin_mode_boost = 0;
             else
             {
                 if (vp8_mode_order[mode_index] == ZEROMV)
                 {
-                    if (vp8_ref_frame_order[mode_index] != LAST_FRAME)
+                    if (this_ref_frame != LAST_FRAME)
                         cpi->zbin_mode_boost = GF_ZEROMV_ZBIN_BOOST;
                     else
                         cpi->zbin_mode_boost = LF_ZEROMV_ZBIN_BOOST;
@@ -1971,8 +1991,8 @@
             int tmp_rd;
             int this_rd_thresh;
 
-            this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == LAST_FRAME) ? cpi->rd_threshes[THR_NEWMV] : cpi->rd_threshes[THR_NEWA];
-            this_rd_thresh = (x->e_mbd.mode_info_context->mbmi.ref_frame == GOLDEN_FRAME) ? cpi->rd_threshes[THR_NEWG]: this_rd_thresh;
+            this_rd_thresh = (vp8_ref_frame_order[mode_index] == 1) ? cpi->rd_threshes[THR_NEW1] : cpi->rd_threshes[THR_NEW3];
+            this_rd_thresh = (vp8_ref_frame_order[mode_index] == 2) ? cpi->rd_threshes[THR_NEW2] : this_rd_thresh;
 
             tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv,
                                                      best_yrd, mdcounts,