newlpf
enhanced_interp
superblocks
+ feature_updates
"
CONFIG_LIST="
external_build
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;
{
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;
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,
// 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))
{
data = 0;
set_segdata(xd, i, j, data);
+#endif
}
}
}
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);
{
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 ) )
{
{
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