diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c
index 1d1d107ea457f7d80afa540db6bd934764e2b8ae..e4cd037e860f735c901ced106386e92d0c3de5e1 100644
--- a/vp8/common/pred_common.c
+++ b/vp8/common/pred_common.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -157,12 +157,19 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
 
     unsigned char left_pred;
     unsigned char above_pred;
+    unsigned char frame_allowed[MAX_REF_FRAMES];
 
     MV_REFERENCE_FRAME left;
     MV_REFERENCE_FRAME above;
     MV_REFERENCE_FRAME above_left;
     MV_REFERENCE_FRAME pred_ref = LAST_FRAME;
 
+    int segment_id = xd->mode_info_context->mbmi.segment_id;
+    int seg_ref_active;
+
+    // Is segment coding ennabled
+    seg_ref_active = segfeature_active( xd, segment_id, SEG_LVL_REF_FRAME );
+
     // Reference frame used by neighbours
     left = (m - 1)->mbmi.ref_frame;
     above = (m - cm->mode_info_stride)->mbmi.ref_frame;
@@ -173,6 +180,32 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
     left_pred = (m - 1)->mbmi.ref_predicted;
     above_pred = (m - cm->mode_info_stride)->mbmi.ref_predicted;
 
+    // Special case treatment if segment coding is enabled.
+    // Dont allow prediction of a reference frame that the segment
+    // does not allow
+    if ( seg_ref_active )
+    {
+        frame_allowed[INTRA_FRAME] =
+            check_segref( xd, segment_id, INTRA_FRAME );
+        frame_allowed[LAST_FRAME] =
+            check_segref( xd, segment_id, LAST_FRAME );
+        frame_allowed[GOLDEN_FRAME] =
+            check_segref( xd, segment_id, GOLDEN_FRAME );
+        frame_allowed[ALTREF_FRAME] =
+            check_segref( xd, segment_id, ALTREF_FRAME );
+    }
+    else
+    {
+        frame_allowed[INTRA_FRAME] = 1;
+        frame_allowed[LAST_FRAME] = 1;
+        frame_allowed[GOLDEN_FRAME] = 1;
+        frame_allowed[ALTREF_FRAME] = 1;
+    }
+
+    // Dont predict if not allowed
+    left_pred = left_pred * frame_allowed[left];
+    above_pred = above_pred * frame_allowed[above];
+
     // Boost prediction scores of above / left if they are predicted and match
     // the above left.
     if ( left_pred )
@@ -181,7 +214,7 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
         above_pred += (above == above_left);
 
     // Only consider "in image" mbs as giving valid prediction.
-    if ( (left == above) &&
+    if ( (left == above) && frame_allowed[left] &&
          ((m - 1)->mbmi.mb_in_image ||
           (m - cm->mode_info_stride)->mbmi.mb_in_image) )
     {
@@ -195,17 +228,44 @@ MV_REFERENCE_FRAME get_pred_ref( VP8_COMMON *const cm,
     {
         pred_ref = above;
     }
-    else
+    // If we reach this clause left_pred and above_pred must be the same
+    else if ( left_pred > 0 )
     {
         // Choose from above or left.
         // For now this is based on a fixed preference order.
         // Last,Altref,Golden
-        if ( (left == LAST_FRAME) || (above == LAST_FRAME) )
+        if ( frame_allowed[LAST_FRAME] &&
+             ((left == LAST_FRAME) || (above == LAST_FRAME)) )
+        {
+            pred_ref = LAST_FRAME;
+        }
+        else if ( frame_allowed[ALTREF_FRAME] &&
+                  ((left == ALTREF_FRAME) || (above == ALTREF_FRAME)) )
+        {
+            pred_ref = ALTREF_FRAME;
+        }
+        else if ( frame_allowed[GOLDEN_FRAME] &&
+                  ((left == GOLDEN_FRAME) || (above == GOLDEN_FRAME)) )
+        {
+            pred_ref = GOLDEN_FRAME;
+        }
+        else
+        {
+            pred_ref = INTRA_FRAME;
+        }
+    }
+    // No prediction case.. choose in fixed order from allowed options
+    // TBD could order based onf frequency.
+    else
+    {
+        if ( frame_allowed[LAST_FRAME] )
             pred_ref = LAST_FRAME;
-        else if ( (left == ALTREF_FRAME) || (above == ALTREF_FRAME) )
+        else if ( frame_allowed[ALTREF_FRAME] )
             pred_ref = ALTREF_FRAME;
-        else if ( (left == GOLDEN_FRAME) || (above == GOLDEN_FRAME) )
+        else if ( frame_allowed[GOLDEN_FRAME] )
             pred_ref = GOLDEN_FRAME;
+        else
+            pred_ref = INTRA_FRAME;
     }
 
     return pred_ref;
@@ -246,6 +306,10 @@ void calc_ref_probs( int * count, vp8_prob * probs )
 
 }
 
+// Computes a set of modified conditional probabilities for the reference frame
+// Values willbe set to 0 for reference frame options that are not possible
+// because wither they were predicted and prediction has failed or because
+// they are not allowed for a given segment.
 void compute_mod_refprobs( VP8_COMMON *const cm )
 {
     int norm_cnt[MAX_REF_FRAMES];
@@ -255,6 +319,7 @@ void compute_mod_refprobs( VP8_COMMON *const cm )
     int gfarf_count;
     int gf_count;
     int arf_count;
+    int i;
 
     intra_count = cm->prob_intra_coded;
     inter_count = (255 - intra_count);
@@ -292,6 +357,5 @@ void compute_mod_refprobs( VP8_COMMON *const cm )
     norm_cnt[3] = 0;
     calc_ref_probs( norm_cnt, cm->mod_refprobs[ALTREF_FRAME] );
     cm->mod_refprobs[ALTREF_FRAME][2] = 0;  // This branch implicit
-
 }
 #endif
diff --git a/vp8/common/pred_common.h b/vp8/common/pred_common.h
index 60476f9c5d4d43c125e6766104a18e4d9c25bb23..9463937dbe95df4b30f0b140fe75a6b689cc8770 100644
--- a/vp8/common/pred_common.h
+++ b/vp8/common/pred_common.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
diff --git a/vp8/common/seg_common.h b/vp8/common/seg_common.h
index 1f4e38dadeee39e6e2929070fc399e5d7454d49d..f3f2d9f1983ed4b74f7ad2ffc1b40c28fe23d97d 100644
--- a/vp8/common/seg_common.h
+++ b/vp8/common/seg_common.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 1dee3beea1326549c5be74c49be792cdf3979b9f..432b339b18e54f2f952480062cc68dbc8f3ed502 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -236,6 +236,7 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
 {
     MV_REFERENCE_FRAME ref_frame;
     int seg_ref_active;
+    int seg_ref_count = 0;
 
 //#if CONFIG_SEGFEATURES
     VP8_COMMON *const cm = & pbi->common;
@@ -245,8 +246,25 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
                                         segment_id,
                                         SEG_LVL_REF_FRAME );
 
-    // Segment reference frame features not available
+
+#if CONFIG_COMPRED
+
+    // If segment coding enabled does the segment allow for more than one
+    // possible reference frame
+    if ( seg_ref_active )
+    {
+        seg_ref_count = check_segref( xd, segment_id, INTRA_FRAME ) +
+                        check_segref( xd, segment_id, LAST_FRAME ) +
+                        check_segref( xd, segment_id, GOLDEN_FRAME ) +
+                        check_segref( xd, segment_id, ALTREF_FRAME );
+    }
+
+    // Segment reference frame features not available or allows for
+    // multiple reference frame options
+    if ( !seg_ref_active || (seg_ref_count > 1) )
+#else
     if ( !seg_ref_active )
+#endif
     {
 #if CONFIG_COMPRED
         // Values used in prediction model coding
@@ -274,7 +292,23 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
         // else decode the explicitly coded value
         else
         {
-            vp8_prob * mod_refprobs = cm->mod_refprobs[pred_ref];
+            //vp8_prob * mod_refprobs = cm->mod_refprobs[pred_ref];
+            vp8_prob mod_refprobs[PREDICTION_PROBS];
+            vpx_memcpy( mod_refprobs,
+                        cm->mod_refprobs[pred_ref], sizeof(mod_refprobs) );
+
+            // If segment coding enabled blank out options that cant occur by
+            // setting the branch probability to 0.
+            if ( seg_ref_active )
+            {
+                mod_refprobs[INTRA_FRAME] *=
+                    check_segref( xd, segment_id, INTRA_FRAME );
+                mod_refprobs[LAST_FRAME] *=
+                    check_segref( xd, segment_id, LAST_FRAME );
+                mod_refprobs[GOLDEN_FRAME] *=
+                    ( check_segref( xd, segment_id, GOLDEN_FRAME ) *
+                      check_segref( xd, segment_id, ALTREF_FRAME ) );
+            }
 
             // Default to INTRA_FRAME (value 0)
             ref_frame = INTRA_FRAME;
@@ -300,8 +334,19 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
                         ref_frame += vp8_read(bc, mod_refprobs[2]);
                     else
                     {
-                        ref_frame = (pred_ref == GOLDEN_FRAME)
-                                    ? ALTREF_FRAME : GOLDEN_FRAME;
+                        if ( seg_ref_active )
+                        {
+                            if ( (pred_ref == GOLDEN_FRAME) ||
+                                 !check_segref( xd, segment_id, GOLDEN_FRAME) )
+                            {
+                                ref_frame = ALTREF_FRAME;
+                            }
+                            else
+                                ref_frame = GOLDEN_FRAME;
+                        }
+                        else
+                            ref_frame = (pred_ref == GOLDEN_FRAME)
+                                        ? ALTREF_FRAME : GOLDEN_FRAME;
                     }
                 }
             }
@@ -330,8 +375,8 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
         // if it is signaled at the segment level for the purposes of the
         // common prediction model
         set_pred_flag( xd, PRED_REF, 1 );
-#endif
-
+        ref_frame = get_pred_ref( cm, xd );
+#else
         // If there are no inter reference frames enabled we can set INTRA
         if ( !check_segref_inter(xd, segment_id) )
         {
@@ -401,6 +446,7 @@ static MV_REFERENCE_FRAME read_ref_frame( VP8D_COMP *pbi,
                 }
             }
         }
+#endif
     }
 
     return (MV_REFERENCE_FRAME)ref_frame;
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 2aee8249d51558f8d577b2e293933ae43ea816a7..26f1cb4877a34f5762f66069f9c87f8ecb0b3909 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -843,13 +843,27 @@ static void encode_ref_frame( vp8_writer *const w,
                               MV_REFERENCE_FRAME rf )
 {
     int seg_ref_active;
+    int seg_ref_count = 0;
 //#if CONFIG_SEGFEATURES
     seg_ref_active = segfeature_active( xd,
                                         segment_id,
                                         SEG_LVL_REF_FRAME );
 
+#if CONFIG_COMPRED
+    if ( seg_ref_active )
+    {
+        seg_ref_count = check_segref( xd, segment_id, INTRA_FRAME ) +
+                        check_segref( xd, segment_id, LAST_FRAME ) +
+                        check_segref( xd, segment_id, GOLDEN_FRAME ) +
+                        check_segref( xd, segment_id, ALTREF_FRAME );
+    }
+
     // If segment level coding of this signal is disabled...
-    if ( !seg_ref_active )
+    // or the segment allows multiple reference frame options
+    if ( !seg_ref_active || (seg_ref_count > 1) )
+#else
+    if ( !seg_ref_active  )
+#endif
     {
 #if CONFIG_COMPRED
         // Values used in prediction model coding
@@ -869,7 +883,24 @@ static void encode_ref_frame( vp8_writer *const w,
             // Get the predicted value so that it can be excluded.
             MV_REFERENCE_FRAME pred_rf = get_pred_ref( cm, xd );
 
-            vp8_prob * mod_refprobs = cm->mod_refprobs[pred_rf];
+            //vp8_prob * mod_refprobs = cm->mod_refprobs[pred_rf];
+            vp8_prob mod_refprobs[PREDICTION_PROBS];
+
+            vpx_memcpy( mod_refprobs,
+                        cm->mod_refprobs[pred_rf], sizeof(mod_refprobs) );
+
+            // If segment coding enabled blank out options that cant occur by
+            // setting the branch probability to 0.
+            if ( seg_ref_active )
+            {
+                mod_refprobs[INTRA_FRAME] *=
+                    check_segref( xd, segment_id, INTRA_FRAME );
+                mod_refprobs[LAST_FRAME] *=
+                    check_segref( xd, segment_id, LAST_FRAME );
+                mod_refprobs[GOLDEN_FRAME] *=
+                    ( check_segref( xd, segment_id, GOLDEN_FRAME ) *
+                      check_segref( xd, segment_id, ALTREF_FRAME ) );
+            }
 
             if ( mod_refprobs[0] )
             {
@@ -915,7 +946,12 @@ static void encode_ref_frame( vp8_writer *const w,
         }
 #endif
     }
+
+    // if using the prediction mdoel we have nothing further to do because
+    // the reference frame is fully coded by the segment
+
 //#if CONFIG_SEGFEATURES
+#if !CONFIG_COMPRED
     // Else use the segment
     else
     {
@@ -958,6 +994,7 @@ static void encode_ref_frame( vp8_writer *const w,
             }
         }
     }
+#endif
 }
 
 #if CONFIG_SUPERBLOCKS
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index a0a0245925b3ed57b717aecaa9175610e812ba9b..30352d7190452b257d9177a078d515a18bc588f5 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -1979,11 +1979,8 @@ int vp8cx_encode_inter_macroblock
     // SET VARIOUS PREDICTION FLAGS
 
     // Did the chosen reference frame match its predicted value.
-    // If the reference frame is predicted at the segment level we
-    // mark it as correctly predicted
     ref_pred_flag = ( (xd->mode_info_context->mbmi.ref_frame ==
-                          get_pred_ref( cm, xd )) ||
-                       seg_ref_active );
+                           get_pred_ref( cm, xd )) );
     set_pred_flag( xd, PRED_REF, ref_pred_flag );
 #endif
 
diff --git a/vp8/encoder/mbgraph.c b/vp8/encoder/mbgraph.c
index 18c30a4177b13d54c50251f38f9997d0e9b1c7d1..e0fed4a4741ff52f65d270c36839ae358d860bcc 100644
--- a/vp8/encoder/mbgraph.c
+++ b/vp8/encoder/mbgraph.c
@@ -91,7 +91,8 @@ static unsigned int do_16x16_motion_iteration
 
     vp8_set_mbmode_and_mvs(x, NEWMV, dst_mv);
     vp8_build_inter16x16_predictors_mby(xd);
-    VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    //VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    best_err = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16)
                     (xd->dst.y_buffer, xd->dst.y_stride,
                      xd->predictor, 16, &best_err);
 
@@ -138,7 +139,8 @@ static int do_16x16_motion_search
     // FIXME should really use something like near/nearest MV and/or MV prediction
     xd->pre.y_buffer = ref->y_buffer + mb_y_offset;
     xd->pre.y_stride = ref->y_stride;
-    VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    //VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    err = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16)
                     (ref->y_buffer + mb_y_offset,
                      ref->y_stride, xd->dst.y_buffer,
                      xd->dst.y_stride, &err);
@@ -203,10 +205,12 @@ static int do_16x16_zerozero_search
     // FIXME should really use something like near/nearest MV and/or MV prediction
     xd->pre.y_buffer = ref->y_buffer + mb_y_offset;
     xd->pre.y_stride = ref->y_stride;
-    VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    //VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+    err = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16)
                     (ref->y_buffer + mb_y_offset,
                      ref->y_stride, xd->dst.y_buffer,
                      xd->dst.y_stride, &err);
+
     dst_mv->as_int = 0;
 
     return err;
@@ -232,7 +236,8 @@ static int find_best_16x16_intra
 
         xd->mode_info_context->mbmi.mode = mode;
         RECON_INVOKE(&cpi->rtcd.common->recon, build_intra_predictors_mby)(xd);
-        VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+        //VARIANCE_INVOKE(&cpi->rtcd.variance, satd16x16)
+        err = VARIANCE_INVOKE(&cpi->rtcd.variance, sad16x16)
                         (xd->predictor, 16,
                          buf->y_buffer + mb_y_offset,
                          buf->y_stride, &err);
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index b3b0790ff1d94ef9b7dbaea524622eba7b941092..2ea41ab355d022f7f1bd85f90ec098acfc968d75 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -474,7 +474,7 @@ static void init_seg_features(VP8_COMP *cpi)
     VP8_COMMON *cm = &cpi->common;
     MACROBLOCKD *xd = &cpi->mb.e_mbd;
 
-    int high_q = (int)(cpi->avg_q > 32.0);
+    int high_q = (int)(cpi->avg_q > 48.0);
     int qi_delta;
 
     // For now at least dont enable seg features alongside cyclic refresh.
@@ -575,15 +575,10 @@ static void init_seg_features(VP8_COMP *cpi)
                 set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 );
                 enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
 
-#if CONFIG_COMPRED
                 // Segment coding disabled for compred testing
                 if ( high_q || (cpi->static_mb_pct == 100) )
-                //if ( 0 )
-#else
-                if ( high_q || (cpi->static_mb_pct == 100) )
-                //if ( 0 )
-#endif
                 {
+                    //set_segref(xd, 1, LAST_FRAME);
                     set_segref(xd, 1, ALTREF_FRAME);
                     enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
 
@@ -618,14 +613,8 @@ static void init_seg_features(VP8_COMP *cpi)
 
         // Special case where we are coding over the top of a previous
         // alt ref frame
-#if CONFIG_COMPRED
         // Segment coding disabled for compred testing
         else if ( cpi->is_src_frame_alt_ref )
-        //else if ( 0 )
-#else
-        else if ( cpi->is_src_frame_alt_ref )
-        //else if ( 0 )
-#endif
         {
             // Enable mode and ref frame features for segment 0 as well
             enable_segfeature(xd, 0, SEG_LVL_REF_FRAME);
diff --git a/vp8/encoder/segmentation.c b/vp8/encoder/segmentation.c
index 91dffe166c32dbf864769f1aa699fa7afb857034..4a1ce649c78463f325da0ffd09e8ce3dc4e2d55e 100644
--- a/vp8/encoder/segmentation.c
+++ b/vp8/encoder/segmentation.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source