2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
14 #include "vpx_mem/vpx_mem.h"
16 #include "vp9/common/vp9_pred_common.h"
17 #include "vp9/common/vp9_tile_common.h"
19 #include "vp9/encoder/vp9_cost.h"
20 #include "vp9/encoder/vp9_segmentation.h"
22 void vp9_enable_segmentation(struct segmentation
*seg
) {
28 void vp9_disable_segmentation(struct segmentation
*seg
) {
34 void vp9_set_segment_data(struct segmentation
*seg
,
35 signed char *feature_data
,
36 unsigned char abs_delta
) {
37 seg
->abs_delta
= abs_delta
;
39 memcpy(seg
->feature_data
, feature_data
, sizeof(seg
->feature_data
));
41 void vp9_disable_segfeature(struct segmentation
*seg
, int segment_id
,
42 SEG_LVL_FEATURES feature_id
) {
43 seg
->feature_mask
[segment_id
] &= ~(1 << feature_id
);
46 void vp9_clear_segdata(struct segmentation
*seg
, int segment_id
,
47 SEG_LVL_FEATURES feature_id
) {
48 seg
->feature_data
[segment_id
][feature_id
] = 0;
51 // Based on set of segment counts calculate a probability tree
52 static void calc_segtree_probs(int *segcounts
, vp9_prob
*segment_tree_probs
) {
53 // Work out probabilities of each segment
54 const int c01
= segcounts
[0] + segcounts
[1];
55 const int c23
= segcounts
[2] + segcounts
[3];
56 const int c45
= segcounts
[4] + segcounts
[5];
57 const int c67
= segcounts
[6] + segcounts
[7];
59 segment_tree_probs
[0] = get_binary_prob(c01
+ c23
, c45
+ c67
);
60 segment_tree_probs
[1] = get_binary_prob(c01
, c23
);
61 segment_tree_probs
[2] = get_binary_prob(c45
, c67
);
62 segment_tree_probs
[3] = get_binary_prob(segcounts
[0], segcounts
[1]);
63 segment_tree_probs
[4] = get_binary_prob(segcounts
[2], segcounts
[3]);
64 segment_tree_probs
[5] = get_binary_prob(segcounts
[4], segcounts
[5]);
65 segment_tree_probs
[6] = get_binary_prob(segcounts
[6], segcounts
[7]);
68 // Based on set of segment counts and probabilities calculate a cost estimate
69 static int cost_segmap(int *segcounts
, vp9_prob
*probs
) {
70 const int c01
= segcounts
[0] + segcounts
[1];
71 const int c23
= segcounts
[2] + segcounts
[3];
72 const int c45
= segcounts
[4] + segcounts
[5];
73 const int c67
= segcounts
[6] + segcounts
[7];
74 const int c0123
= c01
+ c23
;
75 const int c4567
= c45
+ c67
;
77 // Cost the top node of the tree
78 int cost
= c0123
* vp9_cost_zero(probs
[0]) +
79 c4567
* vp9_cost_one(probs
[0]);
81 // Cost subsequent levels
83 cost
+= c01
* vp9_cost_zero(probs
[1]) +
84 c23
* vp9_cost_one(probs
[1]);
87 cost
+= segcounts
[0] * vp9_cost_zero(probs
[3]) +
88 segcounts
[1] * vp9_cost_one(probs
[3]);
90 cost
+= segcounts
[2] * vp9_cost_zero(probs
[4]) +
91 segcounts
[3] * vp9_cost_one(probs
[4]);
95 cost
+= c45
* vp9_cost_zero(probs
[2]) +
96 c67
* vp9_cost_one(probs
[2]);
99 cost
+= segcounts
[4] * vp9_cost_zero(probs
[5]) +
100 segcounts
[5] * vp9_cost_one(probs
[5]);
102 cost
+= segcounts
[6] * vp9_cost_zero(probs
[6]) +
103 segcounts
[7] * vp9_cost_one(probs
[6]);
109 static void count_segs(const VP9_COMMON
*cm
, MACROBLOCKD
*xd
,
110 const TileInfo
*tile
, MODE_INFO
**mi
,
111 int *no_pred_segcounts
,
112 int (*temporal_predictor_count
)[2],
113 int *t_unpred_seg_counts
,
114 int bw
, int bh
, int mi_row
, int mi_col
) {
117 if (mi_row
>= cm
->mi_rows
|| mi_col
>= cm
->mi_cols
)
121 segment_id
= xd
->mi
[0]->mbmi
.segment_id
;
123 set_mi_row_col(xd
, tile
, mi_row
, bh
, mi_col
, bw
, cm
->mi_rows
, cm
->mi_cols
);
125 // Count the number of hits on each segment with no prediction
126 no_pred_segcounts
[segment_id
]++;
128 // Temporal prediction not allowed on key frames
129 if (cm
->frame_type
!= KEY_FRAME
) {
130 const BLOCK_SIZE bsize
= xd
->mi
[0]->mbmi
.sb_type
;
131 // Test to see if the segment id matches the predicted value.
132 const int pred_segment_id
= get_segment_id(cm
, cm
->last_frame_seg_map
,
133 bsize
, mi_row
, mi_col
);
134 const int pred_flag
= pred_segment_id
== segment_id
;
135 const int pred_context
= vp9_get_pred_context_seg_id(xd
);
137 // Store the prediction status for this mb and update counts
139 xd
->mi
[0]->mbmi
.seg_id_predicted
= pred_flag
;
140 temporal_predictor_count
[pred_context
][pred_flag
]++;
142 // Update the "unpredicted" segment count
144 t_unpred_seg_counts
[segment_id
]++;
148 static void count_segs_sb(const VP9_COMMON
*cm
, MACROBLOCKD
*xd
,
149 const TileInfo
*tile
, MODE_INFO
**mi
,
150 int *no_pred_segcounts
,
151 int (*temporal_predictor_count
)[2],
152 int *t_unpred_seg_counts
,
153 int mi_row
, int mi_col
,
155 const int mis
= cm
->mi_stride
;
157 const int bs
= num_8x8_blocks_wide_lookup
[bsize
], hbs
= bs
/ 2;
159 if (mi_row
>= cm
->mi_rows
|| mi_col
>= cm
->mi_cols
)
162 bw
= num_8x8_blocks_wide_lookup
[mi
[0]->mbmi
.sb_type
];
163 bh
= num_8x8_blocks_high_lookup
[mi
[0]->mbmi
.sb_type
];
165 if (bw
== bs
&& bh
== bs
) {
166 count_segs(cm
, xd
, tile
, mi
, no_pred_segcounts
, temporal_predictor_count
,
167 t_unpred_seg_counts
, bs
, bs
, mi_row
, mi_col
);
168 } else if (bw
== bs
&& bh
< bs
) {
169 count_segs(cm
, xd
, tile
, mi
, no_pred_segcounts
, temporal_predictor_count
,
170 t_unpred_seg_counts
, bs
, hbs
, mi_row
, mi_col
);
171 count_segs(cm
, xd
, tile
, mi
+ hbs
* mis
, no_pred_segcounts
,
172 temporal_predictor_count
, t_unpred_seg_counts
, bs
, hbs
,
173 mi_row
+ hbs
, mi_col
);
174 } else if (bw
< bs
&& bh
== bs
) {
175 count_segs(cm
, xd
, tile
, mi
, no_pred_segcounts
, temporal_predictor_count
,
176 t_unpred_seg_counts
, hbs
, bs
, mi_row
, mi_col
);
177 count_segs(cm
, xd
, tile
, mi
+ hbs
,
178 no_pred_segcounts
, temporal_predictor_count
, t_unpred_seg_counts
,
179 hbs
, bs
, mi_row
, mi_col
+ hbs
);
181 const BLOCK_SIZE subsize
= subsize_lookup
[PARTITION_SPLIT
][bsize
];
184 assert(bw
< bs
&& bh
< bs
);
186 for (n
= 0; n
< 4; n
++) {
187 const int mi_dc
= hbs
* (n
& 1);
188 const int mi_dr
= hbs
* (n
>> 1);
190 count_segs_sb(cm
, xd
, tile
, &mi
[mi_dr
* mis
+ mi_dc
],
191 no_pred_segcounts
, temporal_predictor_count
,
193 mi_row
+ mi_dr
, mi_col
+ mi_dc
, subsize
);
198 void vp9_choose_segmap_coding_method(VP9_COMMON
*cm
, MACROBLOCKD
*xd
) {
199 struct segmentation
*seg
= &cm
->seg
;
202 int t_pred_cost
= INT_MAX
;
204 int i
, tile_col
, mi_row
, mi_col
;
206 int temporal_predictor_count
[PREDICTION_PROBS
][2] = { { 0 } };
207 int no_pred_segcounts
[MAX_SEGMENTS
] = { 0 };
208 int t_unpred_seg_counts
[MAX_SEGMENTS
] = { 0 };
210 vp9_prob no_pred_tree
[SEG_TREE_PROBS
];
211 vp9_prob t_pred_tree
[SEG_TREE_PROBS
];
212 vp9_prob t_nopred_prob
[PREDICTION_PROBS
];
214 // Set default state for the segment tree probabilities and the
215 // temporal coding probabilities
216 memset(seg
->tree_probs
, 255, sizeof(seg
->tree_probs
));
217 memset(seg
->pred_probs
, 255, sizeof(seg
->pred_probs
));
219 // First of all generate stats regarding how well the last segment map
221 for (tile_col
= 0; tile_col
< 1 << cm
->log2_tile_cols
; tile_col
++) {
224 vp9_tile_init(&tile
, cm
, 0, tile_col
);
226 mi_ptr
= cm
->mi_grid_visible
+ tile
.mi_col_start
;
227 for (mi_row
= 0; mi_row
< cm
->mi_rows
;
228 mi_row
+= 8, mi_ptr
+= 8 * cm
->mi_stride
) {
229 MODE_INFO
**mi
= mi_ptr
;
230 for (mi_col
= tile
.mi_col_start
; mi_col
< tile
.mi_col_end
;
231 mi_col
+= 8, mi
+= 8)
232 count_segs_sb(cm
, xd
, &tile
, mi
, no_pred_segcounts
,
233 temporal_predictor_count
, t_unpred_seg_counts
,
234 mi_row
, mi_col
, BLOCK_64X64
);
238 // Work out probability tree for coding segments without prediction
240 calc_segtree_probs(no_pred_segcounts
, no_pred_tree
);
241 no_pred_cost
= cost_segmap(no_pred_segcounts
, no_pred_tree
);
243 // Key frames cannot use temporal prediction
244 if (!frame_is_intra_only(cm
)) {
245 // Work out probability tree for coding those segments not
246 // predicted using the temporal method and the cost.
247 calc_segtree_probs(t_unpred_seg_counts
, t_pred_tree
);
248 t_pred_cost
= cost_segmap(t_unpred_seg_counts
, t_pred_tree
);
250 // Add in the cost of the signaling for each prediction context.
251 for (i
= 0; i
< PREDICTION_PROBS
; i
++) {
252 const int count0
= temporal_predictor_count
[i
][0];
253 const int count1
= temporal_predictor_count
[i
][1];
255 t_nopred_prob
[i
] = get_binary_prob(count0
, count1
);
257 // Add in the predictor signaling cost
258 t_pred_cost
+= count0
* vp9_cost_zero(t_nopred_prob
[i
]) +
259 count1
* vp9_cost_one(t_nopred_prob
[i
]);
263 // Now choose which coding method to use.
264 if (t_pred_cost
< no_pred_cost
) {
265 seg
->temporal_update
= 1;
266 memcpy(seg
->tree_probs
, t_pred_tree
, sizeof(t_pred_tree
));
267 memcpy(seg
->pred_probs
, t_nopred_prob
, sizeof(t_nopred_prob
));
269 seg
->temporal_update
= 0;
270 memcpy(seg
->tree_probs
, no_pred_tree
, sizeof(no_pred_tree
));
274 void vp9_reset_segment_features(struct segmentation
*seg
) {
275 // Set up default state for MB feature flags
278 seg
->update_data
= 0;
279 memset(seg
->tree_probs
, 255, sizeof(seg
->tree_probs
));
280 vp9_clearall_segfeatures(seg
);