]> granicus.if.org Git - libvpx/commitdiff
vp8 - config_featureupdates
authorJim Bankoski <jimbankoski@google.com>
Mon, 13 Feb 2012 16:21:24 +0000 (08:21 -0800)
committerJim Bankoski <jimbankoski@google.com>
Mon, 13 Feb 2012 20:31:12 +0000 (12:31 -0800)
Added a bit to signify that the feature changed since
the last time we sent it, or not so that we don't need
to send all the databits for every feature change.

added config

Change-Id: I8d3064ce90d4500bf0d5c6b87c664e46138dfcac

configure
vp8/common/blockd.h
vp8/common/seg_common.c
vp8/common/seg_common.h
vp8/decoder/decodframe.c
vp8/encoder/bitstream.c

index 311f86e9c017c6d81510fc3a194e8f2ba6e4ab21..8dc8900eec3b9261768fb981c782c7c76497d89d 100755 (executable)
--- a/configure
+++ b/configure
@@ -227,6 +227,7 @@ EXPERIMENT_LIST="
     newlpf
     enhanced_interp
     superblocks
+    feature_updates
 "
 CONFIG_LIST="
     external_build
index f6ff1c2a8d3eca9904be6a4b01ad18c75ca66d67..cadc442297b367e8ea823a2f3051cfef250c01ab 100644 (file)
@@ -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;
index 44588aa9620e149ebb888839778ad50e7ea723e9..3ba374a4952c045cb1a9ffc93988b39fdd4c82cd 100644 (file)
@@ -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;
index f3f2d9f1983ed4b74f7ad2ffc1b40c28fe23d97d..bfd364e6d80d3562d7caef6409134cb8689e30c3 100644 (file)
@@ -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,
index c5385a022c02d1b667eefeeff23102b6eca64dd7..abf85eb28e955b9324e2473fa55c0b28e428f977 100644 (file)
@@ -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
                 }
             }
         }
index 2eb959d795bd8e694e3199154f0886a047bc6f3b..078a297914439c7ad799acce360585cb0857e890 100644 (file)
@@ -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