Merge CONFIGURE_SEGMENTATION experiment.

Removal of CONFIGURE_SEGMENTATION ifdefs.

Removal of legacy support code fo the old coding mechanism.

Use local reference "xd" for MACROBLOCKD structure in
encode_frame_to_data_rate()

Moved call to choose_segmap_coding_method() out of encode
loop as the cost of segmentation is not properly accounted
in the loop anyway. If this is desirable in the future it
can be moved back. The use of this function to do all the
analysis and set the probabilities also removes the need
to track segment useage in threading code.

Change-Id: I85bc8fd63440e7176c73d26cb742698f9b70cade
This commit is contained in:
Paul Wilkins
2011-11-15 16:15:23 +00:00
parent 6394ef28d7
commit 3cdfdb55e4
12 changed files with 93 additions and 175 deletions

View File

@@ -185,11 +185,10 @@ typedef struct
unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */
unsigned char need_to_clamp_mvs;
unsigned char segment_id; /* Which set of segmentation parameters should be used for this MB */
#if CONFIG_SEGMENTATION
// Flag used when temporal prediction of segment map is enabled.
// 1 means it is predicted 0 that it must be coded explicitly
unsigned char seg_id_predicted;
#endif
} MB_MODE_INFO;
@@ -266,11 +265,9 @@ typedef struct MacroBlockD
// Probability Tree used to code Segment number
vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
#if CONFIG_SEGMENTATION
// Context probabilities when using predictive coding of segment id
vp8_prob mb_segment_pred_probs[SEGMENT_PREDICTION_PROBS];
unsigned char temporal_update;
#endif
// Segment features
signed char segment_feature_data[MAX_MB_SEGMENTS][SEG_LVL_MAX];

View File

@@ -374,9 +374,6 @@ static void mb_mode_mv_init(VP8D_COMP *pbi)
{
vp8_reader *const bc = & pbi->bc;
MV_CONTEXT *const mvc = pbi->common.fc.mvc;
#if CONFIG_SEGMENTATION
MACROBLOCKD *const xd = & pbi->mb;
#endif
#if CONFIG_ERROR_CONCEALMENT
/* Default is that no macroblock is corrupt, therefore we initialize
@@ -429,10 +426,8 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
const int mis = pbi->common.mode_info_stride;
MACROBLOCKD *const xd = & pbi->mb;
#if CONFIG_SEGMENTATION
int pred_context;
int index = mb_row * pbi->common.mb_cols + mb_col;
#endif
int_mv *const mv = & mbmi->mv;
int mb_to_left_edge;
int mb_to_right_edge;
@@ -458,7 +453,6 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
/* If required read in new segmentation data for this MB */
if (xd->update_mb_segmentation_map)
{
#if CONFIG_SEGMENTATION
// Is temporal coding of the segment id for this mb enabled.
if (xd->temporal_update)
{
@@ -493,9 +487,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
pbi->segmentation_map[index] = mbmi->segment_id;
}
index++;
#else
vp8_read_mb_segid(bc, &mi->mbmi, xd);
#endif
}
//#if CONFIG_SEGFEATURES

View File

@@ -1008,11 +1008,9 @@ int vp8_decode_frame(VP8D_COMP *pbi)
// updated this frame.
xd->update_mb_segmentation_map = (unsigned char)vp8_read_bit(bc);
#if CONFIG_SEGMENTATION
// If so what method will be used.
if ( xd->update_mb_segmentation_map )
xd->temporal_update = (unsigned char)vp8_read_bit(bc);
#endif
// Is the segment data being updated
xd->update_mb_segmentation_data = (unsigned char)vp8_read_bit(bc);
@@ -1060,7 +1058,7 @@ int vp8_decode_frame(VP8D_COMP *pbi)
if (xd->update_mb_segmentation_map)
{
/* Which macro block level features are enabled */
// Which macro block level features are enabled
vpx_memset(xd->mb_segment_tree_probs, 255,
sizeof(xd->mb_segment_tree_probs));
vpx_memset(xd->mb_segment_pred_probs, 255,
@@ -1076,7 +1074,7 @@ int vp8_decode_frame(VP8D_COMP *pbi)
xd->mb_segment_tree_probs[i] =
(vp8_prob)vp8_read_literal(bc, 8);
}
#if CONFIG_SEGMENTATION
// If predictive coding of segment map is enabled read the
// prediction probabilities.
if ( xd->temporal_update )
@@ -1092,7 +1090,6 @@ int vp8_decode_frame(VP8D_COMP *pbi)
(vp8_prob)vp8_read_literal(bc, 8);
}
}
#endif
}
}
@@ -1282,11 +1279,9 @@ int vp8_decode_frame(VP8D_COMP *pbi)
vpx_memcpy(&xd->pre, &pc->yv12_fb[pc->lst_fb_idx], sizeof(YV12_BUFFER_CONFIG));
vpx_memcpy(&xd->dst, &pc->yv12_fb[pc->new_fb_idx], sizeof(YV12_BUFFER_CONFIG));
#if CONFIG_SEGMENTATION
// Create the encoder segmentation map and set all entries to 0
if (!pbi->segmentation_map)
CHECK_MEM_ERROR(pbi->segmentation_map, vpx_calloc((pc->mb_rows * pc->mb_cols), 1));
#endif
/* set up frame new frame for intra coded blocks */
#if CONFIG_MULTITHREAD

View File

@@ -161,11 +161,10 @@ void vp8dx_remove_decompressor(VP8D_PTR ptr)
if (!pbi)
return;
#if CONFIG_SEGMENTATION
// Delete sementation map
if (pbi->segmentation_map != 0)
vpx_free(pbi->segmentation_map);
#endif
#if CONFIG_MULTITHREAD
if (pbi->b_multithreaded_rd)

View File

@@ -89,9 +89,8 @@ typedef struct VP8Decompressor
const unsigned char *partitions[MAX_PARTITIONS];
unsigned int partition_sizes[MAX_PARTITIONS];
unsigned int num_partitions;
#if CONFIG_SEGMENTATION
unsigned char *segmentation_map;
#endif
#if CONFIG_MULTITHREAD
/* variable for threading */

View File

@@ -939,11 +939,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
vp8_writer *const w = & cpi->bc;
const MV_CONTEXT *mvc = pc->fc.mvc;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
#if CONFIG_SEGMENTATION
int i;
int pred_context;
int index = 0;
#endif
const int *const rfct = cpi->count_mb_ref_frame_usage;
const int rf_intra = rfct[INTRA_FRAME];
const int rf_inter = rfct[LAST_FRAME] + rfct[GOLDEN_FRAME] + rfct[ALTREF_FRAME];
@@ -1040,7 +1040,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
if (cpi->mb.e_mbd.update_mb_segmentation_map)
{
#if CONFIG_SEGMENTATION
// Is temporal coding of the segment map enabled
if (xd->temporal_update)
{
@@ -1066,9 +1065,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
write_mb_segid(w, mi, &cpi->mb.e_mbd);
}
index++;
#else
write_mb_segid(w, mi, &cpi->mb.e_mbd);
#endif
}
//#if CONFIG_SEGFEATURES
@@ -1212,10 +1208,8 @@ static void write_kfmodes(VP8_COMP *cpi)
const VP8_COMMON *const c = & cpi->common;
/* const */
MODE_INFO *m = c->mi;
#if CONFIG_SEGMENTATION
int i;
int index = 0;
#endif
int mb_row = -1;
int prob_skip_false = 0;
@@ -1261,9 +1255,7 @@ static void write_kfmodes(VP8_COMP *cpi)
if (cpi->mb.e_mbd.update_mb_segmentation_map)
{
#if CONFIG_SEGMENTATION
index++;
#endif
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
}
@@ -1972,11 +1964,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
{
// Indicate whether or not the segmentation map is being updated.
vp8_write_bit(bc, (xd->update_mb_segmentation_map) ? 1 : 0);
#if CONFIG_SEGMENTATION
// If it is, then indicate the method that will be used.
if ( xd->update_mb_segmentation_map )
vp8_write_bit(bc, (xd->temporal_update) ? 1:0);
#endif
vp8_write_bit(bc, (xd->update_mb_segmentation_data) ? 1 : 0);
if (xd->update_mb_segmentation_data)
@@ -2046,7 +2038,7 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
else
vp8_write_bit(bc, 0);
}
#if CONFIG_SEGMENTATION
// If predictive coding of segment map is enabled send the
// prediction probabilities.
if ( xd->temporal_update )
@@ -2064,7 +2056,6 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
vp8_write_bit(bc, 0);
}
}
#endif
}
}

View File

@@ -568,7 +568,6 @@ void encode_mb_row(VP8_COMP *cpi,
MACROBLOCK *x,
MACROBLOCKD *xd,
TOKENEXTRA **tp,
int *segment_counts,
int *totalrate)
{
int recon_yoffset, recon_uvoffset;
@@ -766,9 +765,6 @@ void encode_mb_row(VP8_COMP *cpi,
recon_yoffset += 16;
recon_uvoffset += 8;
#if !CONFIG_SEGMENTATION
segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
#endif
// skip to next mb
xd->mode_info_context++;
x->partition_info++;
@@ -910,7 +906,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
MACROBLOCKD *const xd = & x->e_mbd;
TOKENEXTRA *tp = cpi->tok;
int segment_counts[MAX_MB_SEGMENTS];
int totalrate;
@@ -925,7 +920,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
}
#endif
vpx_memset(segment_counts, 0, sizeof(segment_counts));
totalrate = 0;
if (cpi->compressor_speed == 2)
@@ -963,8 +957,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
// Reset frame count of inter 0,0 motion vector usage.
cpi->inter_zz_count = 0;
vpx_memset(segment_counts, 0, sizeof(segment_counts));
cpi->prediction_error = 0;
cpi->intra_error = 0;
cpi->skip_true_count = 0;
@@ -1023,7 +1015,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
tp = cpi->tok + mb_row * (cm->mb_cols * 16 * 24);
encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
encode_mb_row(cpi, cm, mb_row, x, xd, &tp, &totalrate);
// adjust to the next row of mbs
x->src.y_buffer += 16 * x->src.y_stride * (cpi->encoding_thread_count + 1) - 16 * cm->mb_cols;
@@ -1045,17 +1037,6 @@ void vp8_encode_frame(VP8_COMP *cpi)
cpi->tok_count += cpi->tplist[mb_row].stop - cpi->tplist[mb_row].start;
}
if (xd->segmentation_enabled)
{
int i, j;
for (i = 0; i < cpi->encoding_thread_count; i++)
{
for (j = 0; j < 4; j++)
segment_counts[j] += cpi->mb_row_ei[i].segment_counts[j];
}
}
for (i = 0; i < cpi->encoding_thread_count; i++)
{
totalrate += cpi->mb_row_ei[i].totalrate;
@@ -1071,7 +1052,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
vp8_zero(cm->left_context)
encode_mb_row(cpi, cm, mb_row, x, xd, &tp, segment_counts, &totalrate);
encode_mb_row(cpi, cm, mb_row, x, xd, &tp, &totalrate);
// adjust to the next row of mbs
x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
@@ -1090,41 +1071,11 @@ void vp8_encode_frame(VP8_COMP *cpi)
// Work out the segment probabilites if segmentation is enabled and
// the map is due to be updated
if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
{
int tot_count;
int i;
int count1,count2,count3,count4;
// Set to defaults
vpx_memset(xd->mb_segment_tree_probs, 255, sizeof(xd->mb_segment_tree_probs));
#if CONFIG_SEGMENTATION
// Select the coding strategy for the segment map (temporal or spatial)
choose_segmap_coding_method( cpi );
#else
tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
count1 = segment_counts[0] + segment_counts[1];
count2 = segment_counts[2] + segment_counts[3];
if (tot_count)
xd->mb_segment_tree_probs[0] = (count1 * 255) / tot_count;
if (count1 > 0)
xd->mb_segment_tree_probs[1] = (segment_counts[0] * 255) /count1;
if (count2 > 0)
xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2;
// Zero probabilities not allowed
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
{
if (xd->mb_segment_tree_probs[i] == 0)
xd->mb_segment_tree_probs[i] = 1;
}
#endif
}
//if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
//{
// // Select the coding strategy for the segment map (temporal or spatial)
// choose_segmap_coding_method( cpi );
//}
// 256 rate units to the bit
cpi->projected_frame_size = totalrate >> 8; // projected_frame_size in units of BYTES

View File

@@ -83,7 +83,6 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
MACROBLOCKD *xd = &x->e_mbd;
TOKENEXTRA *tp ;
int *segment_counts = mbri->segment_counts;
int *totalrate = &mbri->totalrate;
if (cpi->b_multi_threaded == FALSE) // we're shutting down
@@ -248,9 +247,6 @@ THREAD_FUNCTION thread_encoding_proc(void *p_data)
recon_yoffset += 16;
recon_uvoffset += 8;
// Keep track of segment useage
segment_counts[xd->mode_info_context->mbmi.segment_id]++;
// skip to next mb
xd->mode_info_context++;
x->partition_info++;
@@ -437,7 +433,6 @@ void vp8cx_init_mbrthread_data(VP8_COMP *cpi,
mb->vector_range = 32;
vpx_memset(mbr_ei[i].segment_counts, 0, sizeof(mbr_ei[i].segment_counts));
mbr_ei[i].totalrate = 0;
mb->partition_info = x->pi + x->e_mbd.mode_info_stride * (i + 1);

View File

@@ -363,10 +363,9 @@ static void dealloc_compressor_data(VP8_COMP *cpi)
// Delete sementation map
vpx_free(cpi->segmentation_map);
#if CONFIG_SEGMENTATION
vpx_free(cpi->last_segmentation_map);
#endif
cpi->segmentation_map = 0;
vpx_free(cpi->last_segmentation_map);
cpi->last_segmentation_map = 0;
vpx_free(cpi->active_map);
cpi->active_map = 0;
@@ -2124,11 +2123,9 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
// Create the encoder segmentation map and set all entries to 0
CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
#if CONFIG_SEGMENTATION
// And a copy "last_segmentation_map" for temporal coding
CHECK_MEM_ERROR(cpi->last_segmentation_map,
vpx_calloc((cpi->common.mb_rows * cpi->common.mb_cols), 1));
#endif
CHECK_MEM_ERROR(cpi->active_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1));
vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
@@ -3566,6 +3563,9 @@ static void encode_frame_to_data_rate
unsigned int *frame_flags
)
{
VP8_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &cpi->mb.e_mbd;
int Q;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
@@ -3581,7 +3581,6 @@ static void encode_frame_to_data_rate
int zbin_oq_low = 0;
int top_index;
int bottom_index;
VP8_COMMON *cm = &cpi->common;
int active_worst_qchanged = FALSE;
int overshoot_seen = FALSE;
@@ -3591,7 +3590,6 @@ static void encode_frame_to_data_rate
int drop_mark50 = drop_mark / 4;
int drop_mark25 = drop_mark / 8;
// Clear down mmx registers to allow floating point in what follows
vp8_clear_system_state();
@@ -3609,7 +3607,6 @@ static void encode_frame_to_data_rate
// For an alt ref frame in 2 pass we skip the call to the second pass function that sets the target bandwidth
#if !(CONFIG_REALTIME_ONLY)
if (cpi->pass == 2)
{
if (cpi->common.refresh_alt_ref_frame)
@@ -3660,7 +3657,7 @@ static void encode_frame_to_data_rate
}
// Set default state for segment based loop filter update flags
cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
xd->mode_ref_lf_delta_update = 0;
// Set various flags etc to special state if it is a key frame
if (cm->frame_type == KEY_FRAME)
@@ -3671,10 +3668,10 @@ static void encode_frame_to_data_rate
setup_features(cpi);
// If segmentation is enabled force a map update for key frames
if (cpi->mb.e_mbd.segmentation_enabled)
if (xd->segmentation_enabled)
{
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
xd->update_mb_segmentation_map = 1;
xd->update_mb_segmentation_data = 1;
}
// The alternate reference frame cannot be active for a key frame
@@ -4168,10 +4165,10 @@ static void encode_frame_to_data_rate
setup_features(cpi);
// If segmentation is enabled force a map update for key frames
if (cpi->mb.e_mbd.segmentation_enabled)
if (xd->segmentation_enabled)
{
cpi->mb.e_mbd.update_mb_segmentation_map = 1;
cpi->mb.e_mbd.update_mb_segmentation_data = 1;
xd->update_mb_segmentation_map = 1;
xd->update_mb_segmentation_data = 1;
}
vp8_restore_coding_context(cpi);
@@ -4502,6 +4499,18 @@ static void encode_frame_to_data_rate
sem_wait(&cpi->h_event_end_lpf);
#endif
// Work out the segment probabilites if segmentation is enabled and
// the map is due to be updated
if (xd->segmentation_enabled && xd->update_mb_segmentation_map)
{
// Select the coding strategy for the segment map (temporal or spatial)
choose_segmap_coding_method( cpi );
// Take a copy of the segment map if it changed for future comparison
vpx_memcpy( cpi->last_segmentation_map,
cpi->segmentation_map, cm->MBs );
}
// build the bitstream
vp8_pack_bitstream(cpi, dest, size);
@@ -4798,20 +4807,10 @@ static void encode_frame_to_data_rate
cpi->last_frame_percent_intra = cpi->this_frame_percent_intra;
}
// Take a copy of the segment map if it changed for future comparison
#if CONFIG_SEGMENTATION
if ( cpi->mb.e_mbd.segmentation_enabled &&
cpi->mb.e_mbd.update_mb_segmentation_map )
{
vpx_memcpy( cpi->last_segmentation_map,
cpi->segmentation_map, cm->MBs );
}
#endif
// Clear the one shot update flags for segmentation map and mode/ref loop filter deltas.
cpi->mb.e_mbd.update_mb_segmentation_map = 0;
cpi->mb.e_mbd.update_mb_segmentation_data = 0;
cpi->mb.e_mbd.mode_ref_lf_delta_update = 0;
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
xd->mode_ref_lf_delta_update = 0;
// Dont increment frame counters if this was an altref buffer update not a real frame

View File

@@ -220,7 +220,6 @@ typedef struct
typedef struct
{
MACROBLOCK mb;
int segment_counts[MAX_MB_SEGMENTS];
int totalrate;
} MB_ROW_COMP;
@@ -506,9 +505,7 @@ typedef struct VP8_COMP
#endif
unsigned char *segmentation_map;
#if CONFIG_SEGMENTATION
unsigned char *last_segmentation_map;
#endif
// segment threashold for encode breakout
int segment_encode_breakout[MAX_MB_SEGMENTS];

View File

@@ -115,9 +115,8 @@ void vp8_set_segment_data(VP8_PTR ptr,
// sizeof(cpi->mb.e_mbd.segment_feature_mask));
}
#if CONFIG_SEGMENTATION
// Based on set of segment counts calculate a probability tree
void calc_segtree_probs( MACROBLOCKD * xd,
static void calc_segtree_probs( MACROBLOCKD * xd,
int * segcounts,
vp8_prob * segment_tree_probs )
{
@@ -150,7 +149,7 @@ void calc_segtree_probs( MACROBLOCKD * xd,
}
// Based on set of segment counts and probabilities calculate a cost estimate
int cost_segmap( MACROBLOCKD * xd,
static int cost_segmap( MACROBLOCKD * xd,
int * segcounts,
vp8_prob * probs )
{
@@ -199,6 +198,13 @@ void choose_segmap_coding_method( VP8_COMP *cpi )
vp8_prob t_pred_tree[MB_FEATURE_TREE_PROBS];
vp8_prob t_nopred_prob[SEGMENT_PREDICTION_PROBS];
// Set default state for the segment tree probabilities and the
// temporal coding probabilities
vpx_memset(xd->mb_segment_tree_probs, 255,
sizeof(xd->mb_segment_tree_probs));
vpx_memset(xd->mb_segment_pred_probs, 255,
sizeof(xd->mb_segment_pred_probs));
vpx_memset(no_pred_segcounts, 0, sizeof(no_pred_segcounts));
vpx_memset(t_unpred_seg_counts, 0, sizeof(t_unpred_seg_counts));
vpx_memset(temporal_predictor_count, 0, sizeof(temporal_predictor_count));
@@ -320,4 +326,3 @@ void choose_segmap_coding_method( VP8_COMP *cpi )
no_pred_tree, sizeof(no_pred_tree) );
}
}
#endif

View File

@@ -38,8 +38,6 @@ extern void vp8_set_segmentation_map(VP8_PTR ptr, unsigned char *segmentation_ma
//
extern void vp8_set_segment_data(VP8_PTR ptr, signed char *feature_data, unsigned char abs_delta);
#if CONFIG_SEGMENTATION
extern void choose_segmap_coding_method( VP8_COMP *cpi );
#endif
#endif /* __INC_SEGMENTATION_H__ */