Commit 52b1ba2b authored by Hui Su's avatar Hui Su Committed by Sebastien Alaiwan

Remove the probability model about segmentation map

At this point, av1_adapt_intra_frame_probs() can be removed.

Change-Id: I7e9f97e8e782b88c10e108230e5d12309460c477
parent 14fb1af6
......@@ -1870,17 +1870,15 @@ static const aom_cdf_prob default_filter_intra_cdfs[TX_SIZES_ALL][CDF_SIZE(2)] =
#endif // CONFIG_FILTER_INTRA
// FIXME(someone) need real defaults here
static const aom_prob default_segment_tree_probs[SEG_TREE_PROBS] = {
128, 128, 128, 128, 128, 128, 128
static const aom_cdf_prob default_seg_tree_cdf[CDF_SIZE(MAX_SEGMENTS)] = {
AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672)
};
// clang-format off
static const aom_cdf_prob
default_segment_pred_cdf[PREDICTION_PROBS][CDF_SIZE(2)] = {
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(128 * 128) },
{ AOM_CDF2(128 * 128) }
};
// clang-format on
default_segment_pred_cdf[SEG_TEMPORAL_PRED_CTXS][CDF_SIZE(2)] = {
{ AOM_CDF2(128 * 128) }, { AOM_CDF2(128 * 128) }, { AOM_CDF2(128 * 128) }
};
#if CONFIG_DUAL_FILTER
#if USE_EXTRA_FILTER
static const aom_cdf_prob
......@@ -1922,10 +1920,6 @@ static const aom_cdf_prob
};
#endif // CONFIG_DUAL_FILTER
static const aom_cdf_prob default_seg_tree_cdf[CDF_SIZE(MAX_SEGMENTS)] = {
AOM_CDF8(4096, 8192, 12288, 16384, 20480, 24576, 28672)
};
#if CONFIG_SPATIAL_SEGMENTATION
static const aom_cdf_prob
default_spatial_pred_seg_tree_cdf[SPATIAL_PREDICTION_PROBS][CDF_SIZE(
......@@ -3373,8 +3367,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->interintra_cdf, default_interintra_cdf);
av1_copy(fc->wedge_interintra_cdf, default_wedge_interintra_cdf);
av1_copy(fc->interintra_mode_cdf, default_interintra_mode_cdf);
av1_copy(fc->seg.tree_probs, default_segment_tree_probs);
av1_copy(fc->seg.pred_cdf, default_segment_pred_cdf);
av1_copy(fc->seg.tree_cdf, default_seg_tree_cdf);
#if CONFIG_FILTER_INTRA
av1_copy(fc->filter_intra_cdfs, default_filter_intra_cdfs);
av1_copy(fc->filter_intra_mode_cdf, default_filter_intra_mode_cdf);
......@@ -3395,7 +3389,6 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif // CONFIG_EXT_SKIP
av1_copy(fc->skip_cdfs, default_skip_cdfs);
av1_copy(fc->intra_inter_cdf, default_intra_inter_cdf);
av1_copy(fc->seg.tree_cdf, default_seg_tree_cdf);
#if CONFIG_SPATIAL_SEGMENTATION
for (int i = 0; i < SPATIAL_PREDICTION_PROBS; i++)
av1_copy(fc->seg.spatial_pred_seg_cdf[i],
......@@ -3454,20 +3447,6 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
}
void av1_adapt_intra_frame_probs(AV1_COMMON *cm) {
FRAME_CONTEXT *fc = cm->fc;
const FRAME_CONTEXT *pre_fc = cm->pre_fc;
const FRAME_COUNTS *counts = &cm->counts;
if (cm->seg.temporal_update) {
aom_tree_merge_probs(av1_segment_tree, pre_fc->seg.tree_probs,
counts->seg.tree_mispred, fc->seg.tree_probs);
} else {
aom_tree_merge_probs(av1_segment_tree, pre_fc->seg.tree_probs,
counts->seg.tree_total, fc->seg.tree_probs);
}
}
static void set_default_lf_deltas(struct loopfilter *lf) {
lf->mode_ref_delta_enabled = 1;
lf->mode_ref_delta_update = 1;
......
......@@ -74,12 +74,6 @@ typedef struct {
const int16_t *neighbors;
} SCAN_ORDER;
struct seg_counts {
unsigned int tree_total[MAX_SEGMENTS];
unsigned int tree_mispred[MAX_SEGMENTS];
unsigned int pred[PREDICTION_PROBS][2];
};
typedef struct frame_contexts {
coeff_cdf_model coef_tail_cdfs[TX_SIZES][PLANE_TYPES];
coeff_cdf_model coef_head_cdfs[TX_SIZES][PLANE_TYPES];
......@@ -355,7 +349,6 @@ typedef struct FRAME_COUNTS {
unsigned int intra_ext_tx[EXT_TX_SETS_INTRA][EXT_TX_SIZES][INTRA_MODES]
[TX_TYPES];
#endif // CONFIG_ENTROPY_STATS
struct seg_counts seg;
#if CONFIG_FILTER_INTRA
unsigned int filter_intra_mode[FILTER_INTRA_MODES];
unsigned int filter_intra_tx[TX_SIZES_ALL][2];
......@@ -446,8 +439,6 @@ static const int av1_ext_tx_inv[EXT_TX_SET_TYPES][TX_TYPES] = {
void av1_setup_frame_contexts(struct AV1Common *cm);
void av1_setup_past_independence(struct AV1Common *cm);
void av1_adapt_intra_frame_probs(struct AV1Common *cm);
void av1_adapt_inter_frame_probs(struct AV1Common *cm);
static INLINE int av1_ceil_log2(int n) {
......
......@@ -21,7 +21,7 @@ extern "C" {
#define MAX_SEGMENTS 8
#define SEG_TREE_PROBS (MAX_SEGMENTS - 1)
#define PREDICTION_PROBS 3
#define SEG_TEMPORAL_PRED_CTXS 3
#if CONFIG_SPATIAL_SEGMENTATION
#define SPATIAL_PREDICTION_PROBS 3
#endif
......@@ -65,9 +65,8 @@ struct segmentation {
};
struct segmentation_probs {
aom_prob tree_probs[SEG_TREE_PROBS];
aom_cdf_prob tree_cdf[CDF_SIZE(MAX_SEGMENTS)];
aom_cdf_prob pred_cdf[PREDICTION_PROBS][CDF_SIZE(2)];
aom_cdf_prob pred_cdf[SEG_TEMPORAL_PRED_CTXS][CDF_SIZE(2)];
#if CONFIG_SPATIAL_SEGMENTATION
aom_cdf_prob spatial_pred_seg_cdf[SPATIAL_PREDICTION_PROBS]
[CDF_SIZE(MAX_SEGMENTS)];
......
......@@ -3483,7 +3483,6 @@ void av1_decode_tg_tiles_and_wrapup(AV1Decoder *pbi, const uint8_t *data,
#if CONFIG_SYMBOLRATE
av1_dump_symbol_rate(cm);
#endif
av1_adapt_intra_frame_probs(cm);
av1_average_tile_coef_cdfs(pbi->common.fc, tile_ctxs, cdf_ptrs,
num_bwd_ctxs);
av1_average_tile_intra_cdfs(pbi->common.fc, tile_ctxs, cdf_ptrs,
......
......@@ -555,8 +555,6 @@ static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
(void)mbmi;
const int segment_id = read_segment_id(r, &ec_ctx->seg);
#endif
FRAME_COUNTS *counts = xd->counts;
if (counts) ++counts->seg.tree_total[segment_id];
set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
return segment_id;
}
......@@ -576,7 +574,6 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int mi_row, int mi_col, int preskip,
aom_reader *r) {
struct segmentation *const seg = &cm->seg;
FRAME_COUNTS *counts = xd->counts;
FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
struct segmentation_probs *const segp = &ec_ctx->seg;
......@@ -610,12 +607,9 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
if (cm->preskip_segid) return mbmi->segment_id;
if (mbmi->skip) {
if (seg->temporal_update) {
const int ctx = av1_get_pred_context_seg_id(xd);
mbmi->seg_id_predicted = 0;
if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
}
segment_id = read_segment_id(cm, xd, mi_row, mi_col, r, 0);
if (counts) ++counts->seg.tree_total[segment_id];
set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
return segment_id;
}
......@@ -626,7 +620,6 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
const int ctx = av1_get_pred_context_seg_id(xd);
aom_cdf_prob *pred_cdf = segp->pred_cdf[ctx];
mbmi->seg_id_predicted = aom_read_symbol(r, pred_cdf, 2, ACCT_STR);
if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
if (mbmi->seg_id_predicted) {
segment_id = predicted_segment_id;
} else {
......@@ -635,7 +628,6 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
#else
segment_id = read_segment_id(r, segp);
#endif
if (counts) ++counts->seg.tree_mispred[segment_id];
}
} else {
#if CONFIG_SPATIAL_SEGMENTATION
......@@ -643,7 +635,6 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
#else
segment_id = read_segment_id(r, segp);
#endif
if (counts) ++counts->seg.tree_total[segment_id];
}
set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
return segment_id;
......
......@@ -1192,22 +1192,8 @@ static void write_inter_segment_id(AV1_COMP *cpi, aom_writer *w,
} else {
if (cm->preskip_segid) return;
if (skip) {
int prev_segid = mbmi->segment_id;
write_segment_id(cpi, mbmi, w, seg, segp, mi_row, mi_col, 0);
if (seg->temporal_update) {
const int pred_flag = mbmi->seg_id_predicted;
const int pred_context = av1_get_pred_context_seg_id(xd);
unsigned(*temporal_predictor_count)[2] = cm->counts.seg.pred;
unsigned *t_unpred_seg_counts = cm->counts.seg.tree_mispred;
temporal_predictor_count[pred_context][pred_flag]--;
if (!pred_flag) t_unpred_seg_counts[prev_segid]--;
((MB_MODE_INFO *)mbmi)->seg_id_predicted = 0;
temporal_predictor_count[pred_context][0]--;
t_unpred_seg_counts[mbmi->segment_id]--;
}
if (seg->temporal_update) ((MB_MODE_INFO *)mbmi)->seg_id_predicted = 0;
return;
}
}
......
......@@ -6255,7 +6255,6 @@ static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
&cm->counts);
#endif // CONFIG_ENTROPY_STATS
if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
av1_adapt_intra_frame_probs(cm);
#if CONFIG_SIMPLE_BWD_ADAPT
make_update_tile_list_enc(cpi, cm->largest_tile_id, 1, tile_ctxs);
#else
......
......@@ -42,74 +42,6 @@ void av1_clear_segdata(struct segmentation *seg, int segment_id,
seg->feature_data[segment_id][feature_id] = 0;
}
// Based on set of segment counts calculate a probability tree
static void calc_segtree_probs(unsigned *segcounts,
aom_prob *segment_tree_probs,
const aom_prob *cur_tree_probs,
const int probwt) {
// Work out probabilities of each segment
const unsigned cc[4] = { segcounts[0] + segcounts[1],
segcounts[2] + segcounts[3],
segcounts[4] + segcounts[5],
segcounts[6] + segcounts[7] };
const unsigned ccc[2] = { cc[0] + cc[1], cc[2] + cc[3] };
int i;
segment_tree_probs[0] = get_binary_prob(ccc[0], ccc[1]);
segment_tree_probs[1] = get_binary_prob(cc[0], cc[1]);
segment_tree_probs[2] = get_binary_prob(cc[2], cc[3]);
segment_tree_probs[3] = get_binary_prob(segcounts[0], segcounts[1]);
segment_tree_probs[4] = get_binary_prob(segcounts[2], segcounts[3]);
segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
for (i = 0; i < 7; i++) {
const unsigned *ct =
i == 0 ? ccc : i < 3 ? cc + (i & 2) : segcounts + (i - 3) * 2;
av1_prob_diff_update_savings_search(ct, cur_tree_probs[i],
&segment_tree_probs[i],
DIFF_UPDATE_PROB, probwt);
}
}
// Based on set of segment counts and probabilities calculate a cost estimate
static int cost_segmap(unsigned *segcounts, aom_prob *probs) {
const int c01 = segcounts[0] + segcounts[1];
const int c23 = segcounts[2] + segcounts[3];
const int c45 = segcounts[4] + segcounts[5];
const int c67 = segcounts[6] + segcounts[7];
const int c0123 = c01 + c23;
const int c4567 = c45 + c67;
// Cost the top node of the tree
int cost = c0123 * av1_cost_zero(probs[0]) + c4567 * av1_cost_one(probs[0]);
// Cost subsequent levels
if (c0123 > 0) {
cost += c01 * av1_cost_zero(probs[1]) + c23 * av1_cost_one(probs[1]);
if (c01 > 0)
cost += segcounts[0] * av1_cost_zero(probs[3]) +
segcounts[1] * av1_cost_one(probs[3]);
if (c23 > 0)
cost += segcounts[2] * av1_cost_zero(probs[4]) +
segcounts[3] * av1_cost_one(probs[4]);
}
if (c4567 > 0) {
cost += c45 * av1_cost_zero(probs[2]) + c67 * av1_cost_one(probs[2]);
if (c45 > 0)
cost += segcounts[4] * av1_cost_zero(probs[5]) +
segcounts[5] * av1_cost_one(probs[5]);
if (c67 > 0)
cost += segcounts[6] * av1_cost_zero(probs[6]) +
segcounts[7] * av1_cost_one(probs[6]);
}
return cost;
}
static void count_segs(const AV1_COMMON *cm, MACROBLOCKD *xd,
const TileInfo *tile, MODE_INFO **mi,
unsigned *no_pred_segcounts,
......@@ -275,25 +207,14 @@ static void count_segs_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
struct segmentation *seg = &cm->seg;
struct segmentation_probs *segp = &cm->fc->seg;
int no_pred_cost;
int t_pred_cost = INT_MAX;
int tile_col, tile_row, mi_row, mi_col;
const int probwt = cm->num_tg;
unsigned(*temporal_predictor_count)[2] = cm->counts.seg.pred;
unsigned *no_pred_segcounts = cm->counts.seg.tree_total;
unsigned *t_unpred_seg_counts = cm->counts.seg.tree_mispred;
aom_prob no_pred_tree[SEG_TREE_PROBS];
aom_prob t_pred_tree[SEG_TREE_PROBS];
unsigned temporal_predictor_count[SEG_TEMPORAL_PRED_CTXS][2] = { { 0 } };
unsigned no_pred_segcounts[MAX_SEGMENTS] = { 0 };
unsigned t_unpred_seg_counts[MAX_SEGMENTS] = { 0 };
(void)xd;
// We are about to recompute all the segment counts, so zero the accumulators.
av1_zero(cm->counts.seg);
// First of all generate stats regarding how well the last segment map
// predicts this one
for (tile_row = 0; tile_row < cm->tile_rows; tile_row++) {
......@@ -320,18 +241,26 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
}
}
// Work out probability tree for coding segments without prediction
// and the cost.
calc_segtree_probs(no_pred_segcounts, no_pred_tree, segp->tree_probs, probwt);
no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree);
int seg_id_cost[MAX_SEGMENTS];
av1_cost_tokens_from_cdf(seg_id_cost, segp->tree_cdf, NULL);
no_pred_cost = 0;
for (int i = 0; i < MAX_SEGMENTS; ++i)
no_pred_cost += no_pred_segcounts[i] * seg_id_cost[i];
// Key frames cannot use temporal prediction
if (!frame_is_intra_only(cm) && !cm->error_resilient_mode) {
// Work out probability tree for coding those segments not
// predicted using the temporal method and the cost.
calc_segtree_probs(t_unpred_seg_counts, t_pred_tree, segp->tree_probs,
probwt);
t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree);
int pred_flag_cost[SEG_TEMPORAL_PRED_CTXS][2];
for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i)
av1_cost_tokens_from_cdf(pred_flag_cost[i], segp->pred_cdf[i], NULL);
t_pred_cost = 0;
// Cost for signaling the prediction flag.
for (int i = 0; i < SEG_TEMPORAL_PRED_CTXS; ++i) {
for (int j = 0; j < 2; ++j)
t_pred_cost += temporal_predictor_count[i][j] * pred_flag_cost[i][j];
}
// Cost for signaling the unpredicted segment id.
for (int i = 0; i < MAX_SEGMENTS; ++i)
t_pred_cost += t_unpred_seg_counts[i] * seg_id_cost[i];
}
// Now choose which coding method to use.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment