Commit 661b2c2d authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Further work on Segmentation Experiment:

This check in includes quite a lot of clean up and refactoring.

Most of the analysis and set up for the different coding options for the
segment map (currently simple distribution based coding or temporaly
predicted coding), has been moved to one location (the function
choose_segmap_coding_method() in segmenation.c). This code was previously
scattered around in various locations making integration with other
experiments and modification / debug more difficult.

Currently the functionality is as it was with the exception that the
prediction probabilities are now only transmitted when the temporal
prediction mode is selected.

There is still quite a bit more clean up work that will be possible
when the #ifdef is removed. Also at that time I may rename and alter
the sense of macroblock based variable "segment_flag" which indicates
(1 that the segmnet id is not predicted vs 0 that it is predicted).

I also intend to experiment with a spatial prediction mode that can be
used when coding a key frame segment map or in cases where temporal
prediction does not work well but there is spatial correlation.

In a later check in when the ifdefs have gone I may also move the call
to choose_segmap_coding_method() to just before where the bitsream is
packed (currently it is in vp8_encode_frame()) to further reduce the
possibility of clashes with other experiments and prevent it being called
on each itteration of the recode loop.

Change-Id: I3d4aba2a2826ec21f367678d5b07c1d1c36db168
parent c9130bdb
...@@ -32,6 +32,7 @@ void vpx_log(const char *format, ...); ...@@ -32,6 +32,7 @@ void vpx_log(const char *format, ...);
#define DCPREDCNTTHRESH 3 #define DCPREDCNTTHRESH 3
#define MB_FEATURE_TREE_PROBS 3 #define MB_FEATURE_TREE_PROBS 3
#define SEGMENT_PREDICTION_PROBS 3
#define MAX_MB_SEGMENTS 4 #define MAX_MB_SEGMENTS 4
...@@ -187,6 +188,7 @@ typedef struct ...@@ -187,6 +188,7 @@ typedef struct
unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ 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 need_to_clamp_mvs;
unsigned char segment_id; /* Which set of segmentation parameters should be used for this MB */ unsigned char segment_id; /* Which set of segmentation parameters should be used for this MB */
} MB_MODE_INFO; } MB_MODE_INFO;
typedef struct typedef struct
...@@ -258,11 +260,14 @@ typedef struct MacroBlockD ...@@ -258,11 +260,14 @@ typedef struct MacroBlockD
/* Per frame flags that define which MB level features (such as quantizer or loop filter level) */ /* Per frame flags that define which MB level features (such as quantizer or loop filter level) */
/* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */ /* are enabled and when enabled the proabilities used to decode the per MB flags in MB_MODE_INFO */
// Probability Tree used to code Segment number
vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS + 3]; // Probability Tree used to code Segment number // Context probabilities when using predictive coding of segment id
vp8_prob mb_segment_pred_probs[SEGMENT_PREDICTION_PROBS];
unsigned char temporal_update; unsigned char temporal_update;
#else
vp8_prob mb_segment_tree_probs[MB_FEATURE_TREE_PROBS];
#endif #endif
// Segment features // Segment features
......
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
//#if CONFIG_SEGFEATURES //#if CONFIG_SEGFEATURES
#include "vp8/common/seg_common.h" #include "vp8/common/seg_common.h"
#if CONFIG_SEGMENTATION
#include "vp8/common/seg_common.h"
#endif
#if CONFIG_DEBUG #if CONFIG_DEBUG
#include <assert.h> #include <assert.h>
#endif #endif
...@@ -434,7 +430,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ...@@ -434,7 +430,7 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
MACROBLOCKD *const xd = & pbi->mb; MACROBLOCKD *const xd = & pbi->mb;
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
int sum; int pred_context;
int index = mb_row * pbi->common.mb_cols + mb_col; int index = mb_row * pbi->common.mb_cols + mb_col;
#endif #endif
int_mv *const mv = & mbmi->mv; int_mv *const mv = & mbmi->mv;
...@@ -465,14 +461,16 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, ...@@ -465,14 +461,16 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
if (xd->temporal_update) if (xd->temporal_update)
{ {
sum = 0; pred_context = 0;
if (mb_col != 0) if (mb_col != 0)
sum += (mi-1)->mbmi.segment_flag; pred_context += (mi-1)->mbmi.segment_flag;
if (mb_row != 0) if (mb_row != 0)
sum += (mi-pbi->common.mb_cols)->mbmi.segment_flag; pred_context +=
(mi-pbi->common.mb_cols)->mbmi.segment_flag;
if (vp8_read(bc, xd->mb_segment_tree_probs[3+sum]) == 0) if (vp8_read(bc,
xd->mb_segment_pred_probs[pred_context]) == 0)
{ {
mbmi->segment_id = pbi->segmentation_map[index]; mbmi->segment_id = pbi->segmentation_map[index];
mbmi->segment_flag = 0; mbmi->segment_flag = 0;
......
...@@ -1061,18 +1061,38 @@ int vp8_decode_frame(VP8D_COMP *pbi) ...@@ -1061,18 +1061,38 @@ int vp8_decode_frame(VP8D_COMP *pbi)
if (xd->update_mb_segmentation_map) 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_tree_probs, 255,
#if CONFIG_SEGMENTATION sizeof(xd->mb_segment_tree_probs));
/* Read the probs used to decode the segment id for each macro block. */ vpx_memset(xd->mb_segment_pred_probs, 255,
for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++) sizeof(xd->mb_segment_pred_probs));
#else
// Read the probs used to decode the segment id for each macro
// block.
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
#endif
{ {
/* If not explicitly set value is defaulted to 255 by memset above */ // If not explicitly set value is defaulted to 255 by
//memset above
if (vp8_read_bit(bc)) if (vp8_read_bit(bc))
xd->mb_segment_tree_probs[i] = (vp8_prob)vp8_read_literal(bc, 8); 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 )
{
// Read the prediction probs needed to decode the segment id
// when predictive coding enabled
for (i = 0; i < SEGMENT_PREDICTION_PROBS; i++)
{
// If not explicitly set value is defaulted to 255 by
// memset above
if (vp8_read_bit(bc))
xd->mb_segment_pred_probs[i] =
(vp8_prob)vp8_read_literal(bc, 8);
}
}
#endif
} }
} }
......
...@@ -64,10 +64,6 @@ extern unsigned int active_section; ...@@ -64,10 +64,6 @@ extern unsigned int active_section;
#ifdef MODE_STATS #ifdef MODE_STATS
int count_mb_seg[4] = { 0, 0, 0, 0 }; int count_mb_seg[4] = { 0, 0, 0, 0 };
#if CONFIG_SEGMENTATION
int segment_modes_intra[MAX_MB_SEGMENTS] = { 0, 0, 0, 0 };
int segment_modes_inter[MAX_MB_SEGMENTS] = { 0, 0, 0, 0 };
#endif
#endif #endif
...@@ -945,7 +941,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -945,7 +941,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
MACROBLOCKD *xd = &cpi->mb.e_mbd; MACROBLOCKD *xd = &cpi->mb.e_mbd;
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
int i; int i;
int sum; int pred_context;
int index = 0; int index = 0;
#endif #endif
const int *const rfct = cpi->count_mb_ref_frame_usage; const int *const rfct = cpi->count_mb_ref_frame_usage;
...@@ -1042,37 +1038,30 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) ...@@ -1042,37 +1038,30 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
active_section = 9; active_section = 9;
#endif #endif
#ifdef MODE_STATS
#if CONFIG_SEGMENTATION
segment_modes_inter[segment_id]++;
#endif
#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map) if (cpi->mb.e_mbd.update_mb_segmentation_map)
{ {
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
if (xd->temporal_update) if (xd->temporal_update)
{ {
sum = 0; pred_context = 0;
if (mb_col != 0) if (mb_col != 0)
sum += (m-1)->mbmi.segment_flag; pred_context += (m-1)->mbmi.segment_flag;
if (mb_row != 0) if (mb_row != 0)
sum += (m-pc->mb_cols)->mbmi.segment_flag; pred_context += (m-pc->mb_cols)->mbmi.segment_flag;
if (m->mbmi.segment_flag == 0) if (m->mbmi.segment_flag == 0)
{ {
vp8_write(w,0,xd->mb_segment_tree_probs[3+sum]); vp8_write(w,0,xd->mb_segment_pred_probs[pred_context]);
} }
else else
{ {
vp8_write(w,1,xd->mb_segment_tree_probs[3+sum]); vp8_write(w,1,xd->mb_segment_pred_probs[pred_context]);
write_mb_segid(w, mi, &cpi->mb.e_mbd); write_mb_segid(w, mi, &cpi->mb.e_mbd);
cpi->segmentation_map[index] = segment_id;
} }
} }
else else
{ {
write_mb_segid(w, mi, &cpi->mb.e_mbd); write_mb_segid(w, mi, &cpi->mb.e_mbd);
cpi->segmentation_map[index] = segment_id;
} }
index++; index++;
#else #else
...@@ -1268,21 +1257,12 @@ static void write_kfmodes(VP8_COMP *cpi) ...@@ -1268,21 +1257,12 @@ static void write_kfmodes(VP8_COMP *cpi)
const int ym = m->mbmi.mode; const int ym = m->mbmi.mode;
int segment_id = m->mbmi.segment_id; int segment_id = m->mbmi.segment_id;
#ifdef MODE_STATS
#if CONFIG_SEGMENTATION
segment_modes_intra[segment_id]++;
#endif
#endif
if (cpi->mb.e_mbd.update_mb_segmentation_map) if (cpi->mb.e_mbd.update_mb_segmentation_map)
{ {
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
cpi->segmentation_map[index] = segment_id;
index++; index++;
#else
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
#endif #endif
write_mb_segid(bc, &m->mbmi, &cpi->mb.e_mbd);
} }
//#if CONFIG_SEGFEATURES //#if CONFIG_SEGFEATURES
...@@ -2050,12 +2030,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) ...@@ -2050,12 +2030,9 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
if (xd->update_mb_segmentation_map) if (xd->update_mb_segmentation_map)
{ {
#if CONFIG_SEGMENTATION // Send the tree probabilities used to decode unpredicted
// Write the probs used to decode the segment id for each macro block. // macro-block segments
for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
#else
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
#endif
{ {
int Data = xd->mb_segment_tree_probs[i]; int Data = xd->mb_segment_tree_probs[i];
...@@ -2067,6 +2044,25 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size) ...@@ -2067,6 +2044,25 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
else else
vp8_write_bit(bc, 0); vp8_write_bit(bc, 0);
} }
#if CONFIG_SEGMENTATION
// If predictive coding of segment map is enabled send the
// prediction probabilities.
if ( xd->temporal_update )
{
for (i = 0; i < SEGMENT_PREDICTION_PROBS; i++)
{
int Data = xd->mb_segment_pred_probs[i];
if (Data != 255)
{
vp8_write_bit(bc, 1);
vp8_write_literal(bc, Data, 8);
}
else
vp8_write_bit(bc, 0);
}
}
#endif
} }
} }
......
...@@ -578,9 +578,7 @@ void encode_mb_row(VP8_COMP *cpi, ...@@ -578,9 +578,7 @@ void encode_mb_row(VP8_COMP *cpi,
int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride; int recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride;
int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride; int recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;
int map_index = (mb_row * cpi->common.mb_cols); int map_index = (mb_row * cpi->common.mb_cols);
#if CONFIG_SEGMENTATION
int sum;
#endif
#if CONFIG_MULTITHREAD #if CONFIG_MULTITHREAD
const int nsync = cpi->mt_sync_range; const int nsync = cpi->mt_sync_range;
const int rightmost_col = cm->mb_cols - 1; const int rightmost_col = cm->mb_cols - 1;
...@@ -768,43 +766,7 @@ void encode_mb_row(VP8_COMP *cpi, ...@@ -768,43 +766,7 @@ void encode_mb_row(VP8_COMP *cpi,
recon_yoffset += 16; recon_yoffset += 16;
recon_uvoffset += 8; recon_uvoffset += 8;
#if CONFIG_SEGMENTATION #if !CONFIG_SEGMENTATION
//cpi->segmentation_map[mb_row * cm->mb_cols + mb_col] = xd->mbmi.segment_id;
if (cm->frame_type == KEY_FRAME)
{
segment_counts[xd->mode_info_context->mbmi.segment_id]++;
}
else
{
sum = 0;
if (mb_col != 0)
sum += (xd->mode_info_context-1)->mbmi.segment_flag;
if (mb_row != 0)
sum += (xd->mode_info_context-cm->mb_cols)->mbmi.segment_flag;
if ( xd->mode_info_context->mbmi.segment_id ==
cpi->last_segmentation_map[(mb_row*cm->mb_cols) + mb_col] )
{
xd->mode_info_context->mbmi.segment_flag = 0;
}
else
xd->mode_info_context->mbmi.segment_flag = 1;
if (xd->mode_info_context->mbmi.segment_flag == 0)
{
segment_counts[SEEK_SAMEID + sum]++;
segment_counts[10]++;
}
else
{
segment_counts[SEEK_DIFFID + sum]++;
segment_counts[11]++;
//calculate individual segment ids
segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
}
}
segment_counts[SEEK_SEGID + xd->mode_info_context->mbmi.segment_id] ++;
#else
segment_counts[xd->mode_info_context->mbmi.segment_id] ++; segment_counts[xd->mode_info_context->mbmi.segment_id] ++;
#endif #endif
// skip to next mb // skip to next mb
...@@ -948,12 +910,7 @@ void vp8_encode_frame(VP8_COMP *cpi) ...@@ -948,12 +910,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
MACROBLOCKD *const xd = & x->e_mbd; MACROBLOCKD *const xd = & x->e_mbd;
TOKENEXTRA *tp = cpi->tok; TOKENEXTRA *tp = cpi->tok;
#if CONFIG_SEGMENTATION
int segment_counts[MAX_MB_SEGMENTS + SEEK_SEGID];
#else
int segment_counts[MAX_MB_SEGMENTS]; int segment_counts[MAX_MB_SEGMENTS];
#endif
int totalrate; int totalrate;
...@@ -1144,7 +1101,7 @@ void vp8_encode_frame(VP8_COMP *cpi) ...@@ -1144,7 +1101,7 @@ void vp8_encode_frame(VP8_COMP *cpi)
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
// Select the coding strategy for the segment map (temporal or spatial) // Select the coding strategy for the segment map (temporal or spatial)
choose_segmap_coding_method( cpi, segment_counts ); choose_segmap_coding_method( cpi );
#else #else
tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3]; tot_count = segment_counts[0] + segment_counts[1] + segment_counts[2] + segment_counts[3];
count1 = segment_counts[0] + segment_counts[1]; count1 = segment_counts[0] + segment_counts[1];
...@@ -1159,17 +1116,14 @@ void vp8_encode_frame(VP8_COMP *cpi) ...@@ -1159,17 +1116,14 @@ void vp8_encode_frame(VP8_COMP *cpi)
if (count2 > 0) if (count2 > 0)
xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2; xd->mb_segment_tree_probs[2] = (segment_counts[2] * 255) /count2;
#endif
// Zero probabilities not allowed // Zero probabilities not allowed
#if CONFIG_SEGMENTATION for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
for (i = 0; i < MB_FEATURE_TREE_PROBS+3; i++)
#else {
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 #endif
{
if (xd->mb_segment_tree_probs[i] == 0)
xd->mb_segment_tree_probs[i] = 1;
}
} }
// 256 rate units to the bit // 256 rate units to the bit
......
...@@ -152,10 +152,6 @@ extern int b_modes[10] ; ...@@ -152,10 +152,6 @@ extern int b_modes[10] ;
extern int inter_y_modes[10] ; extern int inter_y_modes[10] ;
extern int inter_uv_modes[4] ; extern int inter_uv_modes[4] ;
extern unsigned int inter_b_modes[15]; extern unsigned int inter_b_modes[15];
#if CONFIG_SEGMENTATION
extern int segment_modes_intra[MAX_MB_SEGMENTS];
extern int segment_modes_inter[MAX_MB_SEGMENTS];
#endif
#endif #endif
extern void (*vp8_short_fdct4x4)(short *input, short *output, int pitch); extern void (*vp8_short_fdct4x4)(short *input, short *output, int pitch);
...@@ -2529,9 +2525,6 @@ void vp8_remove_compressor(VP8_PTR *ptr) ...@@ -2529,9 +2525,6 @@ void vp8_remove_compressor(VP8_PTR *ptr)
fprintf(f, "\n"); fprintf(f, "\n");
} }
#if CONFIG_SEGMENTATION
fprintf(f, "Segments:%8d, %8d, %8d, %8d\n", segment_modes_intra[0], segment_modes_intra[1], segment_modes_intra[2], segment_modes_intra[3]);
#endif
fprintf(f, "Modes in Inter Frames:\n"); fprintf(f, "Modes in Inter Frames:\n");
fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n", fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d, %8d\n",
...@@ -2550,10 +2543,6 @@ void vp8_remove_compressor(VP8_PTR *ptr) ...@@ -2550,10 +2543,6 @@ void vp8_remove_compressor(VP8_PTR *ptr)
} }
fprintf(f, "P:%8d, %8d, %8d, %8d\n", count_mb_seg[0], count_mb_seg[1], count_mb_seg[2], count_mb_seg[3]); fprintf(f, "P:%8d, %8d, %8d, %8d\n", count_mb_seg[0], count_mb_seg[1], count_mb_seg[2], count_mb_seg[3]);
fprintf(f, "PB:%8d, %8d, %8d, %8d\n", inter_b_modes[LEFT4X4], inter_b_modes[ABOVE4X4], inter_b_modes[ZERO4X4], inter_b_modes[NEW4X4]); fprintf(f, "PB:%8d, %8d, %8d, %8d\n", inter_b_modes[LEFT4X4], inter_b_modes[ABOVE4X4], inter_b_modes[ZERO4X4], inter_b_modes[NEW4X4]);
#if CONFIG_SEGMENTATION
fprintf(f, "Segments:%8d, %8d, %8d, %8d\n", segment_modes_inter[0], segment_modes_inter[1], segment_modes_inter[2], segment_modes_inter[3]);
#endif
fclose(f); fclose(f);
} }
#endif #endif
......
...@@ -56,12 +56,6 @@ ...@@ -56,12 +56,6 @@
#define VP8_TEMPORAL_ALT_REF 1 #define VP8_TEMPORAL_ALT_REF 1
#endif #endif
#if CONFIG_SEGMENTATION
#define SEEK_SEGID 12
#define SEEK_SAMEID 4
#define SEEK_DIFFID 7
#endif
typedef struct typedef struct
{ {
int kf_indicated; int kf_indicated;
...@@ -226,11 +220,7 @@ typedef struct ...@@ -226,11 +220,7 @@ typedef struct
typedef struct typedef struct
{ {
MACROBLOCK mb; MACROBLOCK mb;
#if CONFIG_SEGMENTATION
int segment_counts[MAX_MB_SEGMENTS + 8];
#else
int segment_counts[MAX_MB_SEGMENTS]; int segment_counts[MAX_MB_SEGMENTS];
#endif
int totalrate; int totalrate;
} MB_ROW_COMP; } MB_ROW_COMP;
......
...@@ -116,123 +116,209 @@ void vp8_set_segment_data(VP8_PTR ptr, ...@@ -116,123 +116,209 @@ void vp8_set_segment_data(VP8_PTR ptr,
} }
#if CONFIG_SEGMENTATION #if CONFIG_SEGMENTATION
void choose_segmap_coding_method( VP8_COMP *cpi, // Based on set of segment counts calculate a probability tree
int * segment_counts ) void calc_segtree_probs( MACROBLOCKD * xd,
int * segcounts,
vp8_prob * segment_tree_probs )
{ {
VP8_COMMON *const cm = & cpi->common; int count1,count2;
MACROBLOCKD *const xd = & cpi->mb.e_mbd;
int tot_count; int tot_count;
int i; int i;
int count1,count2,count3,count4;
int prob[3];
int new_cost, original_cost;
// Select the coding strategy for the segment map (temporal or spatial) // Blank the strtucture to start with
tot_count = segment_counts[12] + segment_counts[13] + vpx_memset(segment_tree_probs, 0, sizeof(segment_tree_probs));
segment_counts[14] + segment_counts[15];
count1 = segment_counts[12] + segment_counts[13]; // Total count for all segments
count2 = segment_counts[14] + segment_counts[15]; count1 = segcounts[0] + segcounts[1];
count2 = segcounts[2] + segcounts[3];
tot_count = count1 + count2;
// Work out probabilities of each segment
if (tot_count) if (tot_count)
prob[0] = (count1 * 255) / tot_count; segment_tree_probs[0] = (count1 * 255) / tot_count;
if (count1 > 0)
segment_tree_probs[1] = (segcounts[0] * 255) / count1;
if (count2 > 0)
segment_tree_probs[2] = (segcounts[2] * 255) / count2;
// Clamp probabilities to minimum allowed value
for (i = 0; i < MB_FEATURE_TREE_PROBS; i++)
{
if (segment_tree_probs[i] == 0)
segment_tree_probs[i] = 1;
}
}
// Based on set of segment counts and probabilities calculate a cost estimate
int cost_segmap( MACROBLOCKD * xd,
int * segcounts,
vp8_prob * probs )
{
int cost;
int count1,count2;
// Cost the top node of the tree
count1 = segcounts[0] + segcounts[1];
count2 = segcounts[2] + segcounts[3];
cost = count1 * vp8_cost_zero(probs[0]) +
count2 * vp8_cost_one(probs[0]);
// Now add the cost of each individual segment branch