diff --git a/configure b/configure
index 311f86e9c017c6d81510fc3a194e8f2ba6e4ab21..8dc8900eec3b9261768fb981c782c7c76497d89d 100755
--- a/configure
+++ b/configure
@@ -227,6 +227,7 @@ EXPERIMENT_LIST="
     newlpf
     enhanced_interp
     superblocks
+    feature_updates
 "
 CONFIG_LIST="
     external_build
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index f6ff1c2a8d3eca9904be6a4b01ad18c75ca66d67..cadc442297b367e8ea823a2f3051cfef250c01ab 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -279,6 +279,12 @@ typedef struct MacroBlockD
     signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
     unsigned int segment_feature_mask[MAX_MB_SEGMENTS];
 
+#if CONFIG_FEATUREUPDATES
+    // keep around the last set so we can figure out what updates...
+    unsigned int old_segment_feature_mask[MAX_MB_SEGMENTS];
+    signed char old_segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];
+#endif
+
     /* mode_based Loop filter adjustment */
     unsigned char mode_ref_lf_delta_enabled;
     unsigned char mode_ref_lf_delta_update;
diff --git a/vp8/common/seg_common.c b/vp8/common/seg_common.c
index 44588aa9620e149ebb888839778ad50e7ea723e9..3ba374a4952c045cb1a9ffc93988b39fdd4c82cd 100644
--- a/vp8/common/seg_common.c
+++ b/vp8/common/seg_common.c
@@ -80,7 +80,56 @@ int get_segdata( MACROBLOCKD *xd,
 {
     return xd->segment_feature_data[segment_id][feature_id];
 }
+#if CONFIG_FEATUREUPDATES
+int old_segfeature_active( MACROBLOCKD *xd,
+                           int segment_id,
+                           SEG_LVL_FEATURES feature_id )
+{
+    // Return true if mask bit set and segmentation enabled.
+    return ( xd->segmentation_enabled &&
+             ( xd->old_segment_feature_mask[segment_id] &
+               (0x01 << feature_id) ) );
+}
+
+int get_old_segdata( MACROBLOCKD *xd,
+                     int segment_id,
+                     SEG_LVL_FEATURES feature_id )
+{
+    return xd->old_segment_feature_data[segment_id][feature_id];
+}
 
+int segfeature_changed( MACROBLOCKD *xd,
+                        int segment_id,
+                        SEG_LVL_FEATURES feature_id )
+{
+    // Return true if mask bit or data is different from last time
+    return
+      ( xd->segmentation_enabled &&
+         (
+           (xd->old_segment_feature_mask[segment_id] & (1 << feature_id) ) !=
+           (xd->segment_feature_mask[segment_id] & (1 << feature_id) )
+        ||  xd->old_segment_feature_data[segment_id][feature_id] !=
+            xd->segment_feature_data[segment_id][feature_id]
+         )
+      );
+}
+
+void save_segment_info ( MACROBLOCKD *xd )
+{
+    int i,j;
+    for (i = 0; i < MAX_MB_SEGMENTS; i++)
+    {
+        xd->old_segment_feature_mask[i] = xd->segment_feature_mask[i];
+
+        // For each segmentation codable feature...
+        for (j = 0; j < SEG_LVL_MAX; j++)
+        {
+            xd->old_segment_feature_data[i][j]=xd->segment_feature_data[i][j];
+
+        }
+    }
+}
+#endif
 void clear_segref( MACROBLOCKD *xd, int segment_id )
 {
     xd->segment_feature_data[segment_id][SEG_LVL_REF_FRAME] = 0;
diff --git a/vp8/common/seg_common.h b/vp8/common/seg_common.h
index f3f2d9f1983ed4b74f7ad2ffc1b40c28fe23d97d..bfd364e6d80d3562d7caef6409134cb8689e30c3 100644
--- a/vp8/common/seg_common.h
+++ b/vp8/common/seg_common.h
@@ -46,6 +46,27 @@ int get_segdata( MACROBLOCKD *xd,
                  int segment_id,
                  SEG_LVL_FEATURES feature_id );
 
+#if CONFIG_FEATUREUPDATES
+
+int old_segfeature_active( MACROBLOCKD *xd,
+                           int segment_id,
+                           SEG_LVL_FEATURES feature_id );
+
+int get_old_segdata( MACROBLOCKD *xd,
+                     int segment_id,
+                     SEG_LVL_FEATURES feature_id );
+
+void save_segment_info ( MACROBLOCKD *xd );
+
+int segfeature_changed( MACROBLOCKD *xd,
+                        int segment_id,
+                        SEG_LVL_FEATURES feature_id );
+
+
+
+#endif
+
+
 void clear_segref( MACROBLOCKD *xd, int segment_id );
 
 void set_segref( MACROBLOCKD *xd,
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index c5385a022c02d1b667eefeeff23102b6eca64dd7..abf85eb28e955b9324e2473fa55c0b28e428f977 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -1158,6 +1158,39 @@ int vp8_decode_frame(VP8D_COMP *pbi)
                 // For each of the segments features...
                 for (j = 0; j < SEG_LVL_MAX; j++)
                 {
+
+#if CONFIG_FEATUREUPDATES
+                    // feature updated?
+                    if (vp8_read_bit(bc))
+                    {
+                        int active=1;
+
+                        if ( segfeature_active( xd, i, j ))
+                            active=vp8_read_bit(bc);
+
+                        // Is the feature enabled
+                        if (active)
+                        {
+                            // Update the feature data and mask
+                            enable_segfeature(xd, i, j);
+
+                            data = (signed char)vp8_read_literal(
+                                                bc, seg_feature_data_bits(j));
+
+                            // Is the segment data signed..
+                            if ( is_segfeature_signed(j) )
+                            {
+                                if (vp8_read_bit(bc))
+                                    data = - data;
+                            }
+                        }
+                        else
+                            data = 0;
+
+                        set_segdata(xd, i, j, data);
+                    }
+
+#else
                     // Is the feature enabled
                     if (vp8_read_bit(bc))
                     {
@@ -1178,6 +1211,7 @@ int vp8_decode_frame(VP8D_COMP *pbi)
                         data = 0;
 
                     set_segdata(xd, i, j, data);
+#endif
                 }
             }
         }
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 2eb959d795bd8e694e3199154f0886a047bc6f3b..078a297914439c7ad799acce360585cb0857e890 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -2662,7 +2662,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
     vp8_write_bit(bc, (xd->segmentation_enabled) ? 1 : 0);
 
     // Indicate which features are enabled
-    if (xd->segmentation_enabled)
+    if ( xd->segmentation_enabled )
     {
         // Indicate whether or not the segmentation map is being updated.
         vp8_write_bit(bc, (xd->update_mb_segmentation_map) ? 1 : 0);
@@ -2689,6 +2689,58 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
                 {
                     Data = get_segdata( xd, i, j );
 
+
+#if CONFIG_FEATUREUPDATES
+
+                    // check if there's an update
+                    if(segfeature_changed( xd,i,j) )
+                    {
+                        vp8_write_bit(bc, 1);
+
+                        if ( segfeature_active( xd, i, j ) )
+                        {
+                            // this bit is to say we are still
+                            // active/  if we were inactive
+                            // this is unnecessary
+                            if ( old_segfeature_active( xd, i, j ))
+                            {
+                                vp8_write_bit(bc, 1);
+                            }
+                            // Is the segment data signed..
+                            if ( is_segfeature_signed(j) )
+                            {
+                                // Encode the relevant feature data
+                                if (Data < 0)
+                                {
+                                    Data = - Data;
+                                    vp8_write_literal(bc, Data,
+                                            seg_feature_data_bits(j));
+                                    vp8_write_bit(bc, 1);
+                                }
+                                else
+                                {
+                                    vp8_write_literal(bc, Data,
+                                            seg_feature_data_bits(j));
+                                    vp8_write_bit(bc, 0);
+                                }
+                            }
+                            // Unsigned data element so no sign bit needed
+                            else
+                            vp8_write_literal(bc, Data,
+                                    seg_feature_data_bits(j));
+                        }
+                        // feature is inactive now
+                        else if ( old_segfeature_active( xd, i, j ))
+                        {
+                           vp8_write_bit(bc, 0);
+                        }
+                    }
+                    else
+                    {
+                        vp8_write_bit(bc,0);
+                    }
+#else
+
                     // If the feature is enabled...
                     if ( segfeature_active( xd, i, j ) )
                     {
@@ -2702,27 +2754,33 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
                             {
                                 Data = - Data;
                                 vp8_write_literal(bc, Data,
-                                                  seg_feature_data_bits(j));
+                                        seg_feature_data_bits(j));
                                 vp8_write_bit(bc, 1);
                             }
                             else
                             {
                                 vp8_write_literal(bc, Data,
-                                                  seg_feature_data_bits(j));
+                                        seg_feature_data_bits(j));
                                 vp8_write_bit(bc, 0);
                             }
                         }
                         // Unsigned data element so no sign bit needed
                         else
                             vp8_write_literal(bc, Data,
-                                              seg_feature_data_bits(j));
+                                    seg_feature_data_bits(j));
                     }
                     else
                         vp8_write_bit(bc, 0);
+#endif
                 }
             }
         }
 
+#if CONFIG_FEATUREUPDATES
+        // save the segment info for updates next frame
+        save_segment_info ( xd );
+#endif
+
         if (xd->update_mb_segmentation_map)
         {
             // Send the tree probabilities used to decode unpredicted