Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Side by Side Diff: source/libvpx/vp9/encoder/vp9_segmentation.c

Issue 54923004: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rdopt.c ('k') | source/libvpx/vp9/encoder/vp9_ssim.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 cost += segcounts[4] * vp9_cost_zero(probs[5]) + 110 cost += segcounts[4] * vp9_cost_zero(probs[5]) +
111 segcounts[5] * vp9_cost_one(probs[5]); 111 segcounts[5] * vp9_cost_one(probs[5]);
112 if (c67 > 0) 112 if (c67 > 0)
113 cost += segcounts[6] * vp9_cost_zero(probs[6]) + 113 cost += segcounts[6] * vp9_cost_zero(probs[6]) +
114 segcounts[7] * vp9_cost_one(probs[6]); 114 segcounts[7] * vp9_cost_one(probs[6]);
115 } 115 }
116 116
117 return cost; 117 return cost;
118 } 118 }
119 119
120 static void count_segs(VP9_COMP *cpi, MODE_INFO **mi_8x8, 120 static void count_segs(VP9_COMP *cpi, const TileInfo *const tile,
121 MODE_INFO **mi_8x8,
121 int *no_pred_segcounts, 122 int *no_pred_segcounts,
122 int (*temporal_predictor_count)[2], 123 int (*temporal_predictor_count)[2],
123 int *t_unpred_seg_counts, 124 int *t_unpred_seg_counts,
124 int bw, int bh, int mi_row, int mi_col) { 125 int bw, int bh, int mi_row, int mi_col) {
125 VP9_COMMON *const cm = &cpi->common; 126 VP9_COMMON *const cm = &cpi->common;
126 MACROBLOCKD *const xd = &cpi->mb.e_mbd; 127 MACROBLOCKD *const xd = &cpi->mb.e_mbd;
127 int segment_id; 128 int segment_id;
128 129
129 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 130 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
130 return; 131 return;
131 132
132 segment_id = mi_8x8[0]->mbmi.segment_id; 133 xd->mi_8x8 = mi_8x8;
134 segment_id = xd->mi_8x8[0]->mbmi.segment_id;
133 135
134 set_mi_row_col(cm, xd, mi_row, bh, mi_col, bw); 136 set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
135 137
136 // Count the number of hits on each segment with no prediction 138 // Count the number of hits on each segment with no prediction
137 no_pred_segcounts[segment_id]++; 139 no_pred_segcounts[segment_id]++;
138 140
139 // Temporal prediction not allowed on key frames 141 // Temporal prediction not allowed on key frames
140 if (cm->frame_type != KEY_FRAME) { 142 if (cm->frame_type != KEY_FRAME) {
141 const BLOCK_SIZE bsize = mi_8x8[0]->mbmi.sb_type; 143 const BLOCK_SIZE bsize = mi_8x8[0]->mbmi.sb_type;
142 // Test to see if the segment id matches the predicted value. 144 // Test to see if the segment id matches the predicted value.
143 const int pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map, 145 const int pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
144 bsize, mi_row, mi_col); 146 bsize, mi_row, mi_col);
145 const int pred_flag = pred_segment_id == segment_id; 147 const int pred_flag = pred_segment_id == segment_id;
146 const int pred_context = vp9_get_pred_context_seg_id(xd); 148 const int pred_context = vp9_get_pred_context_seg_id(xd);
147 149
148 // Store the prediction status for this mb and update counts 150 // Store the prediction status for this mb and update counts
149 // as appropriate 151 // as appropriate
150 vp9_set_pred_flag_seg_id(xd, pred_flag); 152 vp9_set_pred_flag_seg_id(xd, pred_flag);
151 temporal_predictor_count[pred_context][pred_flag]++; 153 temporal_predictor_count[pred_context][pred_flag]++;
152 154
153 if (!pred_flag) 155 if (!pred_flag)
154 // Update the "unpredicted" segment count 156 // Update the "unpredicted" segment count
155 t_unpred_seg_counts[segment_id]++; 157 t_unpred_seg_counts[segment_id]++;
156 } 158 }
157 } 159 }
158 160
159 static void count_segs_sb(VP9_COMP *cpi, MODE_INFO **mi_8x8, 161 static void count_segs_sb(VP9_COMP *cpi, const TileInfo *const tile,
162 MODE_INFO **mi_8x8,
160 int *no_pred_segcounts, 163 int *no_pred_segcounts,
161 int (*temporal_predictor_count)[2], 164 int (*temporal_predictor_count)[2],
162 int *t_unpred_seg_counts, 165 int *t_unpred_seg_counts,
163 int mi_row, int mi_col, 166 int mi_row, int mi_col,
164 BLOCK_SIZE bsize) { 167 BLOCK_SIZE bsize) {
165 const VP9_COMMON *const cm = &cpi->common; 168 const VP9_COMMON *const cm = &cpi->common;
166 const int mis = cm->mode_info_stride; 169 const int mis = cm->mode_info_stride;
167 int bw, bh; 170 int bw, bh;
168 const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2; 171 const int bs = num_8x8_blocks_wide_lookup[bsize], hbs = bs / 2;
169 172
170 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) 173 if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
171 return; 174 return;
172 175
173 bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type]; 176 bw = num_8x8_blocks_wide_lookup[mi_8x8[0]->mbmi.sb_type];
174 bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type]; 177 bh = num_8x8_blocks_high_lookup[mi_8x8[0]->mbmi.sb_type];
175 178
176 if (bw == bs && bh == bs) { 179 if (bw == bs && bh == bs) {
177 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, 180 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
178 t_unpred_seg_counts, bs, bs, mi_row, mi_col); 181 t_unpred_seg_counts, bs, bs, mi_row, mi_col);
179 } else if (bw == bs && bh < bs) { 182 } else if (bw == bs && bh < bs) {
180 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, 183 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
181 t_unpred_seg_counts, bs, hbs, mi_row, mi_col); 184 t_unpred_seg_counts, bs, hbs, mi_row, mi_col);
182 count_segs(cpi, mi_8x8 + hbs * mis, no_pred_segcounts, 185 count_segs(cpi, tile, mi_8x8 + hbs * mis, no_pred_segcounts,
183 temporal_predictor_count, t_unpred_seg_counts, bs, hbs, 186 temporal_predictor_count, t_unpred_seg_counts, bs, hbs,
184 mi_row + hbs, mi_col); 187 mi_row + hbs, mi_col);
185 } else if (bw < bs && bh == bs) { 188 } else if (bw < bs && bh == bs) {
186 count_segs(cpi, mi_8x8, no_pred_segcounts, temporal_predictor_count, 189 count_segs(cpi, tile, mi_8x8, no_pred_segcounts, temporal_predictor_count,
187 t_unpred_seg_counts, hbs, bs, mi_row, mi_col); 190 t_unpred_seg_counts, hbs, bs, mi_row, mi_col);
188 count_segs(cpi, mi_8x8 + hbs, no_pred_segcounts, temporal_predictor_count, 191 count_segs(cpi, tile, mi_8x8 + hbs,
189 t_unpred_seg_counts, hbs, bs, mi_row, mi_col + hbs); 192 no_pred_segcounts, temporal_predictor_count, t_unpred_seg_counts,
193 hbs, bs, mi_row, mi_col + hbs);
190 } else { 194 } else {
191 const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize]; 195 const BLOCK_SIZE subsize = subsize_lookup[PARTITION_SPLIT][bsize];
192 int n; 196 int n;
193 197
194 assert(bw < bs && bh < bs); 198 assert(bw < bs && bh < bs);
195 199
196 for (n = 0; n < 4; n++) { 200 for (n = 0; n < 4; n++) {
197 const int mi_dc = hbs * (n & 1); 201 const int mi_dc = hbs * (n & 1);
198 const int mi_dr = hbs * (n >> 1); 202 const int mi_dr = hbs * (n >> 1);
199 203
200 count_segs_sb(cpi, &mi_8x8[mi_dr * mis + mi_dc], 204 count_segs_sb(cpi, tile, &mi_8x8[mi_dr * mis + mi_dc],
201 no_pred_segcounts, temporal_predictor_count, 205 no_pred_segcounts, temporal_predictor_count,
202 t_unpred_seg_counts, 206 t_unpred_seg_counts,
203 mi_row + mi_dr, mi_col + mi_dc, subsize); 207 mi_row + mi_dr, mi_col + mi_dc, subsize);
204 } 208 }
205 } 209 }
206 } 210 }
207 211
208 void vp9_choose_segmap_coding_method(VP9_COMP *cpi) { 212 void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
209 VP9_COMMON *const cm = &cpi->common; 213 VP9_COMMON *const cm = &cpi->common;
210 struct segmentation *seg = &cm->seg; 214 struct segmentation *seg = &cm->seg;
(...skipping 15 matching lines...) Expand all
226 MODE_INFO **mi_ptr, **mi; 230 MODE_INFO **mi_ptr, **mi;
227 231
228 // Set default state for the segment tree probabilities and the 232 // Set default state for the segment tree probabilities and the
229 // temporal coding probabilities 233 // temporal coding probabilities
230 vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs)); 234 vpx_memset(seg->tree_probs, 255, sizeof(seg->tree_probs));
231 vpx_memset(seg->pred_probs, 255, sizeof(seg->pred_probs)); 235 vpx_memset(seg->pred_probs, 255, sizeof(seg->pred_probs));
232 236
233 // First of all generate stats regarding how well the last segment map 237 // First of all generate stats regarding how well the last segment map
234 // predicts this one 238 // predicts this one
235 for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) { 239 for (tile_col = 0; tile_col < 1 << cm->log2_tile_cols; tile_col++) {
236 vp9_get_tile_col_offsets(cm, tile_col); 240 TileInfo tile;
237 mi_ptr = cm->mi_grid_visible + cm->cur_tile_mi_col_start; 241
242 vp9_tile_init(&tile, cm, 0, tile_col);
243 mi_ptr = cm->mi_grid_visible + tile.mi_col_start;
238 for (mi_row = 0; mi_row < cm->mi_rows; 244 for (mi_row = 0; mi_row < cm->mi_rows;
239 mi_row += 8, mi_ptr += 8 * mis) { 245 mi_row += 8, mi_ptr += 8 * mis) {
240 mi = mi_ptr; 246 mi = mi_ptr;
241 for (mi_col = cm->cur_tile_mi_col_start; mi_col < cm->cur_tile_mi_col_end; 247 for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
242 mi_col += 8, mi += 8) 248 mi_col += 8, mi += 8)
243 count_segs_sb(cpi, mi, no_pred_segcounts, temporal_predictor_count, 249 count_segs_sb(cpi, &tile, mi, no_pred_segcounts,
244 t_unpred_seg_counts, mi_row, mi_col, BLOCK_64X64); 250 temporal_predictor_count, t_unpred_seg_counts,
251 mi_row, mi_col, BLOCK_64X64);
245 } 252 }
246 } 253 }
247 254
248 // Work out probability tree for coding segments without prediction 255 // Work out probability tree for coding segments without prediction
249 // and the cost. 256 // and the cost.
250 calc_segtree_probs(no_pred_segcounts, no_pred_tree); 257 calc_segtree_probs(no_pred_segcounts, no_pred_tree);
251 no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree); 258 no_pred_cost = cost_segmap(no_pred_segcounts, no_pred_tree);
252 259
253 // Key frames cannot use temporal prediction 260 // Key frames cannot use temporal prediction
254 if (cm->frame_type != KEY_FRAME) { 261 if (!frame_is_intra_only(cm)) {
255 // Work out probability tree for coding those segments not 262 // Work out probability tree for coding those segments not
256 // predicted using the temporal method and the cost. 263 // predicted using the temporal method and the cost.
257 calc_segtree_probs(t_unpred_seg_counts, t_pred_tree); 264 calc_segtree_probs(t_unpred_seg_counts, t_pred_tree);
258 t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree); 265 t_pred_cost = cost_segmap(t_unpred_seg_counts, t_pred_tree);
259 266
260 // Add in the cost of the signalling for each prediction context 267 // Add in the cost of the signaling for each prediction context.
261 for (i = 0; i < PREDICTION_PROBS; i++) { 268 for (i = 0; i < PREDICTION_PROBS; i++) {
262 const int count0 = temporal_predictor_count[i][0]; 269 const int count0 = temporal_predictor_count[i][0];
263 const int count1 = temporal_predictor_count[i][1]; 270 const int count1 = temporal_predictor_count[i][1];
264 271
265 t_nopred_prob[i] = get_binary_prob(count0, count1); 272 t_nopred_prob[i] = get_binary_prob(count0, count1);
266 273
267 // Add in the predictor signaling cost 274 // Add in the predictor signaling cost
268 t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) + 275 t_pred_cost += count0 * vp9_cost_zero(t_nopred_prob[i]) +
269 count1 * vp9_cost_one(t_nopred_prob[i]); 276 count1 * vp9_cost_one(t_nopred_prob[i]);
270 } 277 }
271 } 278 }
272 279
273 // Now choose which coding method to use. 280 // Now choose which coding method to use.
274 if (t_pred_cost < no_pred_cost) { 281 if (t_pred_cost < no_pred_cost) {
275 seg->temporal_update = 1; 282 seg->temporal_update = 1;
276 vpx_memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree)); 283 vpx_memcpy(seg->tree_probs, t_pred_tree, sizeof(t_pred_tree));
277 vpx_memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob)); 284 vpx_memcpy(seg->pred_probs, t_nopred_prob, sizeof(t_nopred_prob));
278 } else { 285 } else {
279 seg->temporal_update = 0; 286 seg->temporal_update = 0;
280 vpx_memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree)); 287 vpx_memcpy(seg->tree_probs, no_pred_tree, sizeof(no_pred_tree));
281 } 288 }
282 } 289 }
OLDNEW
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rdopt.c ('k') | source/libvpx/vp9/encoder/vp9_ssim.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698