Commit 3e3a6bf0 authored by Yaowu Xu's avatar Yaowu Xu

misc-fix: use generic model for segment probs

This commit merges the fix that makes use of generic probability model
for segmentation related probabilities.

Related tracking issue:
https://bugs.chromium.org/p/webm/issues/detail?id=1040
point#1
Original libvpx commit:
6e5a1165

Change-Id: Ia1be5df86ac223b967b50dbfb3cb59239f171b36
parent 7cb3498f
......@@ -829,7 +829,6 @@ static const aom_prob default_switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
};
#endif // CONFIG_EXT_INTERP
#if CONFIG_MISC_FIXES
// FIXME(someone) need real defaults here
static const aom_prob default_segment_tree_probs[SEG_TREE_PROBS] = {
128, 128, 128, 128, 128, 128, 128
......@@ -839,7 +838,6 @@ static const aom_prob default_segment_pred_probs[PREDICTION_PROBS] = {
128, 128, 128
};
// clang-format on
#endif
const aom_tree_index av1_ext_tx_tree[TREE_SIZE(TX_TYPES)] = {
-DCT_DCT, 2, -ADST_ADST, 4, -ADST_DCT, -DCT_ADST
......@@ -893,10 +891,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#if CONFIG_MOTION_VAR
av1_copy(fc->motion_mode_prob, default_motion_mode_prob);
#endif // CONFIG_MOTION_VAR
#if CONFIG_MISC_FIXES
av1_copy(fc->seg.tree_probs, default_segment_tree_probs);
av1_copy(fc->seg.pred_probs, default_segment_pred_probs);
#endif
av1_copy(fc->intra_ext_tx_prob, default_intra_ext_tx_prob);
av1_copy(fc->inter_ext_tx_prob, default_inter_ext_tx_prob);
#if CONFIG_DAALA_EC
......@@ -916,10 +912,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
fc->inter_ext_tx_cdf, EXT_TX_SIZES);
av1_tree_to_cdf_2D(av1_intra_mode_tree, av1_kf_y_mode_prob, av1_kf_y_mode_cdf,
INTRA_MODES, INTRA_MODES);
#if CONFIG_MISC_FIXES
av1_tree_to_cdf(av1_segment_tree, fc->seg.tree_probs, fc->seg.tree_cdf);
#endif
#endif
#if CONFIG_DELTA_Q
av1_copy(fc->delta_q_prob, default_delta_q_probs);
#endif
......@@ -1090,7 +1084,6 @@ void av1_adapt_intra_frame_probs(AV1_COMMON *cm) {
#endif
}
#if CONFIG_MISC_FIXES
if (cm->seg.temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++)
fc->seg.pred_probs[i] =
......@@ -1103,6 +1096,7 @@ void av1_adapt_intra_frame_probs(AV1_COMMON *cm) {
counts->seg.tree_total, fc->seg.tree_probs);
}
#if CONFIG_MISC_FIXES
for (i = 0; i < INTRA_MODES; ++i)
aom_tree_merge_probs(av1_intra_mode_tree, pre_fc->uv_mode_prob[i],
counts->uv_mode[i], fc->uv_mode_prob[i]);
......
......@@ -126,9 +126,7 @@ typedef struct frame_contexts {
#else
nmv_context nmvc;
#endif
#if CONFIG_MISC_FIXES
struct segmentation_probs seg;
#endif
aom_prob intra_ext_tx_prob[EXT_TX_SIZES][TX_TYPES][TX_TYPES - 1];
aom_prob inter_ext_tx_prob[EXT_TX_SIZES][TX_TYPES - 1];
int initialized;
......@@ -193,9 +191,7 @@ typedef struct FRAME_COUNTS {
#else
nmv_context_counts mv;
#endif
#if CONFIG_MISC_FIXES
struct seg_counts seg;
#endif
#if CONFIG_DELTA_Q
unsigned int delta_q[DELTA_Q_CONTEXTS][2];
#endif
......
......@@ -285,9 +285,6 @@ typedef struct AV1Common {
struct loopfilter lf;
struct segmentation seg;
#if !CONFIG_MISC_FIXES
struct segmentation_probs segp;
#endif
int frame_parallel_decode; // frame-based threading.
......
......@@ -659,7 +659,6 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
cm->counts.inter_ext_tx[i][k] += counts->inter_ext_tx[i][k];
}
#if CONFIG_MISC_FIXES
for (i = 0; i < PREDICTION_PROBS; i++)
for (j = 0; j < 2; j++) cm->counts.seg.pred[i][j] += counts->seg.pred[i][j];
......@@ -667,7 +666,6 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
cm->counts.seg.tree_total[i] += counts->seg.tree_total[i];
cm->counts.seg.tree_mispred[i] += counts->seg.tree_mispred[i];
}
#endif
#if CONFIG_DELTA_Q
for (i = 0; i < DELTA_Q_CONTEXTS; i++)
......
......@@ -721,9 +721,6 @@ static void read_coef_probs(FRAME_CONTEXT *fc, TX_MODE tx_mode, aom_reader *r) {
static void setup_segmentation(AV1_COMMON *const cm,
struct aom_read_bit_buffer *rb) {
struct segmentation *const seg = &cm->seg;
#if !CONFIG_MISC_FIXES
struct segmentation_probs *const segp = &cm->segp;
#endif
int i, j;
seg->update_map = 0;
......@@ -739,29 +736,11 @@ static void setup_segmentation(AV1_COMMON *const cm,
seg->update_map = aom_rb_read_bit(rb);
}
if (seg->update_map) {
#if !CONFIG_MISC_FIXES
for (i = 0; i < SEG_TREE_PROBS; i++) {
segp->tree_probs[i] =
aom_rb_read_bit(rb) ? aom_rb_read_literal(rb, 8) : MAX_PROB;
}
#if CONFIG_DAALA_EC
av1_tree_to_cdf(av1_segment_tree, segp->tree_probs, segp->tree_cdf);
#endif
#endif
if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
seg->temporal_update = 0;
} else {
seg->temporal_update = aom_rb_read_bit(rb);
}
#if !CONFIG_MISC_FIXES
if (seg->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++)
segp->pred_probs[i] =
aom_rb_read_bit(rb) ? aom_rb_read_literal(rb, 8) : MAX_PROB;
} else {
for (i = 0; i < PREDICTION_PROBS; i++) segp->pred_probs[i] = MAX_PROB;
}
#endif
}
// Segmentation data update
......@@ -2079,7 +2058,6 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
av1_diff_update_prob(&r, &fc->delta_q_prob[k], ACCT_STR);
#endif
#if CONFIG_MISC_FIXES
if (cm->seg.enabled && cm->seg.update_map) {
if (cm->seg.temporal_update) {
for (k = 0; k < PREDICTION_PROBS; k++)
......@@ -2093,6 +2071,7 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
#endif
}
#if CONFIG_MISC_FIXES
for (j = 0; j < INTRA_MODES; j++) {
for (i = 0; i < INTRA_MODES - 1; ++i)
av1_diff_update_prob(&r, &fc->uv_mode_prob[j][i], ACCT_STR);
......
......@@ -285,26 +285,16 @@ static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int mi_offset, int x_mis, int y_mis,
aom_reader *r) {
struct segmentation *const seg = &cm->seg;
#if CONFIG_MISC_FIXES
FRAME_COUNTS *counts = xd->counts;
struct segmentation_probs *const segp = &cm->fc->seg;
#else
struct segmentation_probs *const segp = &cm->segp;
#endif
int segment_id;
#if !CONFIG_MISC_FIXES
(void)xd;
#endif
if (!seg->enabled) return 0; // Default for disabled segmentation
assert(seg->update_map && !seg->temporal_update);
segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
if (counts) ++counts->seg.tree_total[segment_id];
#endif
set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
return segment_id;
}
......@@ -325,12 +315,8 @@ static void copy_segment_id(const AV1_COMMON *cm,
static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
int mi_row, int mi_col, aom_reader *r) {
struct segmentation *const seg = &cm->seg;
#if CONFIG_MISC_FIXES
FRAME_COUNTS *counts = xd->counts;
struct segmentation_probs *const segp = &cm->fc->seg;
#else
struct segmentation_probs *const segp = &cm->segp;
#endif
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
int predicted_segment_id, segment_id;
const int mi_offset = mi_row * cm->mi_cols + mi_col;
......@@ -358,22 +344,16 @@ static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
const int ctx = av1_get_pred_context_seg_id(xd);
const aom_prob pred_prob = segp->pred_probs[ctx];
mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
#if CONFIG_MISC_FIXES
if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
#endif
if (mbmi->seg_id_predicted) {
segment_id = predicted_segment_id;
} else {
segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
if (counts) ++counts->seg.tree_mispred[segment_id];
#endif
}
} else {
segment_id = read_segment_id(r, segp);
#if CONFIG_MISC_FIXES
if (counts) ++counts->seg.tree_total[segment_id];
#endif
}
set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
return segment_id;
......
......@@ -767,11 +767,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
const MACROBLOCKD *const xd = &x->e_mbd;
#endif
const struct segmentation *const seg = &cm->seg;
#if CONFIG_MISC_FIXES
const struct segmentation_probs *const segp = &cm->fc->seg;
#else
const struct segmentation_probs *const segp = &cm->segp;
#endif
const MB_MODE_INFO *const mbmi = &mi->mbmi;
const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
const PREDICTION_MODE mode = mbmi->mode;
......@@ -975,11 +971,7 @@ static void write_mb_modes_kf(const AV1_COMMON *cm, const MACROBLOCKD *xd,
MODE_INFO **mi_8x8, aom_writer *w) {
#endif
const struct segmentation *const seg = &cm->seg;
#if CONFIG_MISC_FIXES
const struct segmentation_probs *const segp = &cm->fc->seg;
#else
const struct segmentation_probs *const segp = &cm->segp;
#endif
const MODE_INFO *const mi = mi_8x8[0];
const MODE_INFO *const above_mi = xd->above_mi;
const MODE_INFO *const left_mi = xd->left_mi;
......@@ -1521,9 +1513,6 @@ static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd,
int i, j;
const struct segmentation *seg = &cm->seg;
#if !CONFIG_MISC_FIXES
const struct segmentation_probs *segp = &cm->segp;
#endif
aom_wb_write_bit(wb, seg->enabled);
if (!seg->enabled) return;
......@@ -1537,15 +1526,6 @@ static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd,
if (seg->update_map) {
// Select the coding strategy (temporal or spatial)
av1_choose_segmap_coding_method(cm, xd);
#if !CONFIG_MISC_FIXES
// Write out probabilities used to decode unpredicted macro-block segments
for (i = 0; i < SEG_TREE_PROBS; i++) {
const int prob = segp->tree_probs[i];
const int update = prob != MAX_PROB;
aom_wb_write_bit(wb, update);
if (update) aom_wb_write_literal(wb, prob, 8);
}
#endif
// Write out the chosen coding method.
if (!frame_is_intra_only(cm) && !cm->error_resilient_mode) {
......@@ -1553,17 +1533,6 @@ static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd,
} else {
assert(seg->temporal_update == 0);
}
#if !CONFIG_MISC_FIXES
if (seg->temporal_update) {
for (i = 0; i < PREDICTION_PROBS; i++) {
const int prob = segp->pred_probs[i];
const int update = prob != MAX_PROB;
aom_wb_write_bit(wb, update);
if (update) aom_wb_write_literal(wb, prob, 8);
}
}
#endif
}
// Segmentation data
......@@ -1591,7 +1560,6 @@ static void encode_segmentation(AV1_COMMON *cm, MACROBLOCKD *xd,
}
}
#if CONFIG_MISC_FIXES
static void update_seg_probs(AV1_COMP *cpi, aom_writer *w) {
AV1_COMMON *cm = &cpi->common;
#if CONFIG_TILE_GROUPS
......@@ -1621,6 +1589,7 @@ static void update_seg_probs(AV1_COMP *cpi, aom_writer *w) {
#endif
}
#if CONFIG_MISC_FIXES
static void write_txfm_mode(TX_MODE mode, struct aom_write_bit_buffer *wb) {
aom_wb_write_bit(wb, mode == TX_MODE_SELECT);
if (mode != TX_MODE_SELECT) aom_wb_write_literal(wb, mode, 2);
......@@ -2217,9 +2186,9 @@ static size_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
#if CONFIG_DELTA_Q
update_delta_q_probs(cm, header_bc, counts);
#endif
#if CONFIG_MISC_FIXES
update_seg_probs(cpi, header_bc);
#if CONFIG_MISC_FIXES
for (i = 0; i < INTRA_MODES; ++i) {
prob_diff_update(av1_intra_mode_tree, fc->uv_mode_prob[i],
counts->uv_mode[i], INTRA_MODES, probwt, header_bc);
......
......@@ -441,11 +441,6 @@ static void save_coding_context(AV1_COMP *cpi) {
av1_copy(cc->nmvcosts, cpi->nmvcosts);
av1_copy(cc->nmvcosts_hp, cpi->nmvcosts_hp);
#if !CONFIG_MISC_FIXES
av1_copy(cc->segment_pred_probs, cm->segp.pred_probs);
#endif
av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
......@@ -473,11 +468,6 @@ static void restore_coding_context(AV1_COMP *cpi) {
av1_copy(cpi->nmvcosts, cc->nmvcosts);
av1_copy(cpi->nmvcosts_hp, cc->nmvcosts_hp);
#if !CONFIG_MISC_FIXES
av1_copy(cm->segp.pred_probs, cc->segment_pred_probs);
#endif
av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
......
......@@ -66,10 +66,6 @@ typedef struct {
int nmv_costs_hp[NMV_CONTEXTS][2][MV_VALS];
#endif
#if !CONFIG_MISC_FIXES
aom_prob segment_pred_probs[PREDICTION_PROBS];
#endif
// 0 = Intra, Last, GF, ARF
signed char last_ref_lf_deltas[MAX_REF_FRAMES];
// 0 = ZERO_MV, MV
......
......@@ -59,11 +59,7 @@ static void calc_segtree_probs(unsigned *segcounts,
segcounts[4] + segcounts[5],
segcounts[6] + segcounts[7] };
const unsigned ccc[2] = { cc[0] + cc[1], cc[2] + cc[3] };
#if CONFIG_MISC_FIXES
int i;
#else
(void)probwt;
#endif
segment_tree_probs[0] = get_binary_prob(ccc[0], ccc[1]);
segment_tree_probs[1] = get_binary_prob(cc[0], cc[1]);
......@@ -73,7 +69,6 @@ static void calc_segtree_probs(unsigned *segcounts,
segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
#if CONFIG_MISC_FIXES
for (i = 0; i < 7; i++) {
const unsigned *ct =
i == 0 ? ccc : i < 3 ? cc + (i & 2) : segcounts + (i - 3) * 2;
......@@ -81,9 +76,6 @@ static void calc_segtree_probs(unsigned *segcounts,
&segment_tree_probs[i],
DIFF_UPDATE_PROB, probwt);
}
#else
(void)cur_tree_probs;
#endif
}
// Based on set of segment counts and probabilities calculate a cost estimate
......@@ -210,12 +202,7 @@ 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;
#if CONFIG_MISC_FIXES
struct segmentation_probs *segp = &cm->fc->seg;
#else
struct segmentation_probs *segp = &cm->segp;
#endif
int no_pred_cost;
int t_pred_cost = INT_MAX;
......@@ -225,30 +212,14 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
#else
const int probwt = 1;
#endif
#if CONFIG_MISC_FIXES
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;
#else
unsigned temporal_predictor_count[PREDICTION_PROBS][2] = { { 0 } };
unsigned no_pred_segcounts[MAX_SEGMENTS] = { 0 };
unsigned t_unpred_seg_counts[MAX_SEGMENTS] = { 0 };
#endif
aom_prob no_pred_tree[SEG_TREE_PROBS];
aom_prob t_pred_tree[SEG_TREE_PROBS];
aom_prob t_nopred_prob[PREDICTION_PROBS];
#if CONFIG_MISC_FIXES
(void)xd;
av1_zero(cm->counts.seg);
#else
// Set default state for the segment tree probabilities and the
// temporal coding probabilities
memset(segp->tree_probs, 255, sizeof(segp->tree_probs));
memset(segp->pred_probs, 255, sizeof(segp->pred_probs));
#endif
// First of all generate stats regarding how well the last segment map
// predicts this one
......@@ -288,11 +259,9 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
const int count1 = temporal_predictor_count[i][1];
t_nopred_prob[i] = get_binary_prob(count0, count1);
#if CONFIG_MISC_FIXES
av1_prob_diff_update_savings_search(
temporal_predictor_count[i], segp->pred_probs[i], &t_nopred_prob[i],
DIFF_UPDATE_PROB, probwt);
#endif
// Add in the predictor signaling cost
t_pred_cost += count0 * av1_cost_zero(t_nopred_prob[i]) +
......@@ -304,15 +273,8 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
if (t_pred_cost < no_pred_cost) {
assert(!cm->error_resilient_mode);
seg->temporal_update = 1;
#if !CONFIG_MISC_FIXES
memcpy(segp->tree_probs, t_pred_tree, sizeof(t_pred_tree));
memcpy(segp->pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
#endif
} else {
seg->temporal_update = 0;
#if !CONFIG_MISC_FIXES
memcpy(segp->tree_probs, no_pred_tree, sizeof(no_pred_tree));
#endif
}
#if CONFIG_DAALA_EC
av1_tree_to_cdf(av1_segment_tree, segp->tree_probs, segp->tree_cdf);
......@@ -321,16 +283,10 @@ void av1_choose_segmap_coding_method(AV1_COMMON *cm, MACROBLOCKD *xd) {
void av1_reset_segment_features(AV1_COMMON *cm) {
struct segmentation *seg = &cm->seg;
#if !CONFIG_MISC_FIXES
struct segmentation_probs *segp = &cm->segp;
#endif
// Set up default state for MB feature flags
seg->enabled = 0;
seg->update_map = 0;
seg->update_data = 0;
#if !CONFIG_MISC_FIXES
memset(segp->tree_probs, 255, sizeof(segp->tree_probs));
#endif
av1_clearall_segfeatures(seg);
}
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