vp8 - config_featureupdates

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
This commit is contained in:
Jim Bankoski 2012-02-13 08:21:24 -08:00
parent 2d1ead342c
commit af8f1928d1
6 changed files with 173 additions and 4 deletions

1
configure vendored
View File

@ -227,6 +227,7 @@ EXPERIMENT_LIST="
newlpf
enhanced_interp
superblocks
feature_updates
"
CONFIG_LIST="
external_build

View 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;

View 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;

View 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,

View 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
}
}
}

View 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