1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h>
13b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
15b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_pred_common.h"
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_tile_common.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
19b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_cost.h"
20b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "vp9/encoder/vp9_segmentation.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_enable_segmentation(struct segmentation *seg) {
231184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->enabled = 1;
241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->update_map = 1;
251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->update_data = 1;
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_disable_segmentation(struct segmentation *seg) {
291184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->enabled = 0;
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
32b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_set_segmentation_map(VP9_COMP *cpi, unsigned char *segmentation_map) {
331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct segmentation *const seg = &cpi->common.seg;
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Copy in the new segmentation map
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_memcpy(cpi->segmentation_map, segmentation_map,
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             (cpi->common.mi_rows * cpi->common.mi_cols));
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Signal that the map should be updated.
401184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->update_map = 1;
411184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->update_data = 1;
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
44b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_set_segment_data(struct segmentation *seg,
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          signed char *feature_data,
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          unsigned char abs_delta) {
471184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  seg->abs_delta = abs_delta;
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vpx_memcpy(seg->feature_data, feature_data, sizeof(seg->feature_data));
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // TBD ?? Set the feature mask
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // vpx_memcpy(cpi->mb.e_mbd.segment_feature_mask, 0,
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  //            sizeof(cpi->mb.e_mbd.segment_feature_mask));
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
55b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_disable_segfeature(struct segmentation *seg, int segment_id,
56b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                            SEG_LVL_FEATURES feature_id) {
57b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  seg->feature_mask[segment_id] &= ~(1 << feature_id);
58b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
59b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
60b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_clear_segdata(struct segmentation *seg, int segment_id,
61b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian                       SEG_LVL_FEATURES feature_id) {
62b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  seg->feature_data[segment_id][feature_id] = 0;
63b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Based on set of segment counts calculate a probability tree
66f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic void calc_segtree_probs(int *segcounts, vp9_prob *segment_tree_probs) {
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Work out probabilities of each segment
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c01 = segcounts[0] + segcounts[1];
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c23 = segcounts[2] + segcounts[3];
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c45 = segcounts[4] + segcounts[5];
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c67 = segcounts[6] + segcounts[7];
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[0] = get_binary_prob(c01 + c23, c45 + c67);
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[1] = get_binary_prob(c01, c23);
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[2] = get_binary_prob(c45, c67);
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[3] = get_binary_prob(segcounts[0], segcounts[1]);
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[4] = get_binary_prob(segcounts[2], segcounts[3]);
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[5] = get_binary_prob(segcounts[4], segcounts[5]);
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  segment_tree_probs[6] = get_binary_prob(segcounts[6], segcounts[7]);
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Based on set of segment counts and probabilities calculate a cost estimate
83f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangstatic int cost_segmap(int *segcounts, vp9_prob *probs) {
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c01 = segcounts[0] + segcounts[1];
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c23 = segcounts[2] + segcounts[3];
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c45 = segcounts[4] + segcounts[5];
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c67 = segcounts[6] + segcounts[7];
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c0123 = c01 + c23;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int c4567 = c45 + c67;
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Cost the top node of the tree
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int cost = c0123 * vp9_cost_zero(probs[0]) +
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             c4567 * vp9_cost_one(probs[0]);
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Cost subsequent levels
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (c0123 > 0) {
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cost += c01 * vp9_cost_zero(probs[1]) +
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            c23 * vp9_cost_one(probs[1]);
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (c01 > 0)
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += segcounts[0] * vp9_cost_zero(probs[3]) +
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              segcounts[1] * vp9_cost_one(probs[3]);
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (c23 > 0)
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += segcounts[2] * vp9_cost_zero(probs[4]) +
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              segcounts[3] * vp9_cost_one(probs[4]);
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (c4567 > 0) {
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cost += c45 * vp9_cost_zero(probs[2]) +
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang            c67 * vp9_cost_one(probs[2]);
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (c45 > 0)
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += segcounts[4] * vp9_cost_zero(probs[5]) +
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              segcounts[5] * vp9_cost_one(probs[5]);
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (c67 > 0)
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cost += segcounts[6] * vp9_cost_zero(probs[6]) +
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang              segcounts[7] * vp9_cost_one(probs[6]);
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return cost;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void count_segs(VP9_COMP *cpi, const TileInfo *const tile,
1245ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                       MODE_INFO **mi_8x8,
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int *no_pred_segcounts,
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int (*temporal_predictor_count)[2],
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int *t_unpred_seg_counts,
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       int bw, int bh, int mi_row, int mi_col) {
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int segment_id;
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1366ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  xd->mi = mi_8x8;
1376ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  segment_id = xd->mi[0]->mbmi.segment_id;
1381184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1395ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Count the number of hits on each segment with no prediction
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  no_pred_segcounts[segment_id]++;
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Temporal prediction not allowed on key frames
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cm->frame_type != KEY_FRAME) {
1461184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    const BLOCK_SIZE bsize = mi_8x8[0]->mbmi.sb_type;
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Test to see if the segment id matches the predicted value.
14891037db265ecdd914a26e056cf69207b4f50924ehkuang    const int pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
14991037db265ecdd914a26e056cf69207b4f50924ehkuang                                                   bsize, mi_row, mi_col);
15091037db265ecdd914a26e056cf69207b4f50924ehkuang    const int pred_flag = pred_segment_id == segment_id;
15191037db265ecdd914a26e056cf69207b4f50924ehkuang    const int pred_context = vp9_get_pred_context_seg_id(xd);
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Store the prediction status for this mb and update counts
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // as appropriate
1556ac915abcdb404a00d927fe6308a47fcf09d9519hkuang    xd->mi[0]->mbmi.seg_id_predicted = pred_flag;
15691037db265ecdd914a26e056cf69207b4f50924ehkuang    temporal_predictor_count[pred_context][pred_flag]++;
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
15891037db265ecdd914a26e056cf69207b4f50924ehkuang    if (!pred_flag)
159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Update the "unpredicted" segment count
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t_unpred_seg_counts[segment_id]++;
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangstatic void count_segs_sb(VP9_COMP *cpi, const TileInfo *const tile,
1655ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                          MODE_INFO **mi_8x8,
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int *no_pred_segcounts,
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int (*temporal_predictor_count)[2],
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int *t_unpred_seg_counts,
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          int mi_row, int mi_col,
1701184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                          BLOCK_SIZE bsize) {
1711184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const VP9_COMMON *const cm = &cpi->common;
1726ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int mis = cm->mi_stride;
1731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int bw, bh;
1741184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2;
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return;
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1791184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type];
1801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type];
1811184aebb761cbeac9124c37189a80a1a58f04b6bhkuang
1821184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  if (bw == bs && bh == bs) {
1835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
1841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               t_unpred_seg_counts, bs, bs, mi_row, mi_col);
1851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (bw == bs && bh < bs) {
1865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
1871184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               t_unpred_seg_counts, bs, hbs, mi_row, mi_col);
1885ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    count_segs(cpi, tile, mi_8x8 + hbs * mis, no_pred_segcounts,
1891184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               temporal_predictor_count, t_unpred_seg_counts, bs, hbs,
1901184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               mi_row + hbs, mi_col);
1911184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  } else if (bw < bs && bh == bs) {
1925ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
1931184aebb761cbeac9124c37189a80a1a58f04b6bhkuang               t_unpred_seg_counts, hbs, bs, mi_row, mi_col);
1945ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    count_segs(cpi, tile, mi_8x8 + hbs,
1955ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts,
1965ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang               hbs, bs, mi_row, mi_col + hbs);
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
1981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int n;
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2011184aebb761cbeac9124c37189a80a1a58f04b6bhkuang    assert(bw < bs && bh < bs);
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (n = 0; n < 4; n++) {
2041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int mi_dc = hbs * (n & 1);
2051184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      const int mi_dr = hbs * (n >> 1);
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2075ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      count_segs_sb(cpi, tile, &mi_8x8[mi_dr * mis + mi_dc],
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    no_pred_segcounts, temporal_predictor_count,
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                    t_unpred_seg_counts,
2101184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                    mi_row + mi_dr, mi_col + mi_dc, subsize);
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
2171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct segmentation *seg = &cm->seg;
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int no_pred_cost;
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int t_pred_cost = INT_MAX;
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22291037db265ecdd914a26e056cf69207b4f50924ehkuang  int i, tile_col, mi_row, mi_col;
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int temporal_predictor_count[PREDICTION_PROBS][2] = { { 0 } };
2251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int no_pred_segcounts[MAX_SEGMENTS] = { 0 };
2261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  int t_unpred_seg_counts[MAX_SEGMENTS] = { 0 };
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
22891037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_prob no_pred_tree[SEG_TREE_PROBS];
22991037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_prob t_pred_tree[SEG_TREE_PROBS];
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_prob t_nopred_prob[PREDICTION_PROBS];
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2326ac915abcdb404a00d927fe6308a47fcf09d9519hkuang  const int mis = cm->mi_stride;
2331184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  MODE_INFO **mi_ptr, **mi;
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Set default state for the segment tree probabilities and the
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // temporal coding probabilities
237f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs));
238f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  vpx_memset(seg->pred_probs, 255, sizeof(seg->pred_probs));
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // First of all generate stats regarding how well the last segment map
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // predicts this one
24291037db265ecdd914a26e056cf69207b4f50924ehkuang  for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) {
2435ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    TileInfo tile;
2445ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
2455ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    vp9_tile_init(&tile, cm, 0, tile_col);
2465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    mi_ptr = cm->mi_grid_visible + tile.mi_col_start;
247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (mi_row = 0; mi_row < cm->mi_rows;
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang         mi_row += 8, mi_ptr += 8 * mis) {
249ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mi = mi_ptr;
2505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
25191037db265ecdd914a26e056cf69207b4f50924ehkuang           mi_col += 8, mi += 8)
2525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang        count_segs_sb(cpi, &tile, mi, no_pred_segcounts,
2535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                      temporal_predictor_count, t_unpred_seg_counts,
2545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                      mi_row, mi_col, BLOCK_64X64);
255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Work out probability tree for coding segments without prediction
259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // and the cost.
260f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  calc_segtree_probs(no_pred_segcounts, no_pred_tree);
261f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree);
262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Key frames cannot use temporal prediction
2645ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  if (!frame_is_intra_only(cm)) {
265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Work out probability tree for coding those segments not
266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // predicted using the temporal method and the cost.
267f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    calc_segtree_probs(t_unpred_seg_counts, t_pred_tree);
268f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree);
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    // Add in the cost of the signaling for each prediction context.
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (i = 0; i < PREDICTION_PROBS; i++) {
272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      const int count0 = temporal_predictor_count[i][0];
273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      const int count1 = temporal_predictor_count[i][1];
274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t_nopred_prob[i] = get_binary_prob(count0, count1);
276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Add in the predictor signaling cost
278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) +
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     count1 * vp9_cost_one(t_nopred_prob[i]);
280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Now choose which coding method to use.
284ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (t_pred_cost < no_pred_cost) {
285f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    seg->temporal_update = 1;
286f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree));
287f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
289f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    seg->temporal_update = 0;
290f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang    vpx_memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree));
291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
293b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian
294b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianvoid vp9_reset_segment_features(struct segmentation *seg) {
295b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  // Set up default state for MB feature flags
296b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  seg->enabled = 0;
297b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  seg->update_map = 0;
298b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  seg->update_data = 0;
299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs));
300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian  vp9_clearall_segfeatures(seg);
301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}
302