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

Side by Side Diff: source/libvpx/vp9/common/vp9_pred_common.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1
2 /*
3 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
4 *
5 * Use of this source code is governed by a BSD-style license
6 * that can be found in the LICENSE file in the root of the source
7 * tree. An additional intellectual property rights grant can be found
8 * in the file PATENTS. All contributing project authors may
9 * be found in the AUTHORS file in the root of the source tree.
10 */
11
12 #include "vp9/common/vp9_pred_common.h"
13 #include "vp9/common/vp9_seg_common.h"
14
15 // TBD prediction functions for various bitstream signals
16
17 // Returns a context number for the given MB prediction signal
18 unsigned char vp9_get_pred_context(const VP9_COMMON *const cm,
19 const MACROBLOCKD *const xd,
20 PRED_ID pred_id) {
21 int pred_context;
22 MODE_INFO *m = xd->mode_info_context;
23
24 // Note:
25 // The mode info data structure has a one element border above and to the
26 // left of the entries correpsonding to real macroblocks.
27 // The prediction flags in these dummy entries are initialised to 0.
28 switch (pred_id) {
29 case PRED_SEG_ID:
30 pred_context = (m - 1)->mbmi.seg_id_predicted +
31 (m - cm->mode_info_stride)->mbmi.seg_id_predicted;
32 break;
33
34
35 case PRED_REF:
36 pred_context = (m - 1)->mbmi.ref_predicted +
37 (m - cm->mode_info_stride)->mbmi.ref_predicted;
38 break;
39
40 case PRED_COMP:
41 // Context based on use of comp pred flag by neighbours
42 // pred_context =
43 // ((m - 1)->mbmi.second_ref_frame > INTRA_FRAME) +
44 // ((m - cm->mode_info_stride)->mbmi.second_ref_frame > INTRA_FRAME);
45
46 // Context based on mode and reference frame
47 // if ( m->mbmi.ref_frame == LAST_FRAME )
48 // pred_context = 0 + (m->mbmi.mode != ZEROMV);
49 // else if ( m->mbmi.ref_frame == GOLDEN_FRAME )
50 // pred_context = 2 + (m->mbmi.mode != ZEROMV);
51 // else
52 // pred_context = 4 + (m->mbmi.mode != ZEROMV);
53
54 if (m->mbmi.ref_frame == LAST_FRAME)
55 pred_context = 0;
56 else
57 pred_context = 1;
58
59 break;
60
61 case PRED_MBSKIP:
62 pred_context = (m - 1)->mbmi.mb_skip_coeff +
63 (m - cm->mode_info_stride)->mbmi.mb_skip_coeff;
64 break;
65
66 case PRED_SWITCHABLE_INTERP:
67 {
68 int left_in_image = (m - 1)->mbmi.mb_in_image;
69 int above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
70 int left_mode = (m - 1)->mbmi.mode;
71 int above_mode = (m - cm->mode_info_stride)->mbmi.mode;
72 int left_interp, above_interp;
73 if (left_in_image && left_mode >= NEARESTMV && left_mode <= SPLITMV)
74 left_interp = vp9_switchable_interp_map[(m - 1)->mbmi.interp_filter];
75 else
76 left_interp = VP9_SWITCHABLE_FILTERS;
77 assert(left_interp != -1);
78 if (above_in_image && above_mode >= NEARESTMV && above_mode <= SPLITMV)
79 above_interp = vp9_switchable_interp_map[
80 (m - cm->mode_info_stride)->mbmi.interp_filter];
81 else
82 above_interp = VP9_SWITCHABLE_FILTERS;
83 assert(above_interp != -1);
84
85 if (left_interp == above_interp)
86 pred_context = left_interp;
87 else if (left_interp == VP9_SWITCHABLE_FILTERS &&
88 above_interp != VP9_SWITCHABLE_FILTERS)
89 pred_context = above_interp;
90 else if (left_interp != VP9_SWITCHABLE_FILTERS &&
91 above_interp == VP9_SWITCHABLE_FILTERS)
92 pred_context = left_interp;
93 else
94 pred_context = VP9_SWITCHABLE_FILTERS;
95 }
96 break;
97
98 default:
99 // TODO *** add error trap code.
100 pred_context = 0;
101 break;
102 }
103
104 return pred_context;
105 }
106
107 // This function returns a context probability for coding a given
108 // prediction signal
109 vp9_prob vp9_get_pred_prob(const VP9_COMMON *const cm,
110 const MACROBLOCKD *const xd,
111 PRED_ID pred_id) {
112 vp9_prob pred_probability;
113 int pred_context;
114
115 // Get the appropriate prediction context
116 pred_context = vp9_get_pred_context(cm, xd, pred_id);
117
118 switch (pred_id) {
119 case PRED_SEG_ID:
120 pred_probability = cm->segment_pred_probs[pred_context];
121 break;
122
123 case PRED_REF:
124 pred_probability = cm->ref_pred_probs[pred_context];
125 break;
126
127 case PRED_COMP:
128 // In keeping with convention elsewhre the probability returned is
129 // the probability of a "0" outcome which in this case means the
130 // probability of comp pred off.
131 pred_probability = cm->prob_comppred[pred_context];
132 break;
133
134 case PRED_MBSKIP:
135 pred_probability = cm->mbskip_pred_probs[pred_context];
136 break;
137
138 default:
139 // TODO *** add error trap code.
140 pred_probability = 128;
141 break;
142 }
143
144 return pred_probability;
145 }
146
147 // This function returns a context probability ptr for coding a given
148 // prediction signal
149 const vp9_prob *vp9_get_pred_probs(const VP9_COMMON *const cm,
150 const MACROBLOCKD *const xd,
151 PRED_ID pred_id) {
152 const vp9_prob *pred_probability;
153 int pred_context;
154
155 // Get the appropriate prediction context
156 pred_context = vp9_get_pred_context(cm, xd, pred_id);
157
158 switch (pred_id) {
159 case PRED_SEG_ID:
160 pred_probability = &cm->segment_pred_probs[pred_context];
161 break;
162
163 case PRED_REF:
164 pred_probability = &cm->ref_pred_probs[pred_context];
165 break;
166
167 case PRED_COMP:
168 // In keeping with convention elsewhre the probability returned is
169 // the probability of a "0" outcome which in this case means the
170 // probability of comp pred off.
171 pred_probability = &cm->prob_comppred[pred_context];
172 break;
173
174 case PRED_MBSKIP:
175 pred_probability = &cm->mbskip_pred_probs[pred_context];
176 break;
177
178 case PRED_SWITCHABLE_INTERP:
179 pred_probability = &cm->fc.switchable_interp_prob[pred_context][0];
180 break;
181
182 default:
183 // TODO *** add error trap code.
184 pred_probability = NULL;
185 break;
186 }
187
188 return pred_probability;
189 }
190
191 // This function returns the status of the given prediction signal.
192 // I.e. is the predicted value for the given signal correct.
193 unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd,
194 PRED_ID pred_id) {
195 unsigned char pred_flag = 0;
196
197 switch (pred_id) {
198 case PRED_SEG_ID:
199 pred_flag = xd->mode_info_context->mbmi.seg_id_predicted;
200 break;
201
202 case PRED_REF:
203 pred_flag = xd->mode_info_context->mbmi.ref_predicted;
204 break;
205
206 case PRED_MBSKIP:
207 pred_flag = xd->mode_info_context->mbmi.mb_skip_coeff;
208 break;
209
210 default:
211 // TODO *** add error trap code.
212 pred_flag = 0;
213 break;
214 }
215
216 return pred_flag;
217 }
218
219 // This function sets the status of the given prediction signal.
220 // I.e. is the predicted value for the given signal correct.
221 void vp9_set_pred_flag(MACROBLOCKD *const xd,
222 PRED_ID pred_id,
223 unsigned char pred_flag) {
224 #if CONFIG_SUPERBLOCKS
225 const int mis = xd->mode_info_stride;
226 #endif
227
228 switch (pred_id) {
229 case PRED_SEG_ID:
230 xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
231 #if CONFIG_SUPERBLOCKS
232 if (xd->mode_info_context->mbmi.encoded_as_sb) {
233 if (xd->mb_to_right_edge >= 0)
234 xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
235 if (xd->mb_to_bottom_edge >= 0) {
236 xd->mode_info_context[mis].mbmi.seg_id_predicted = pred_flag;
237 if (xd->mb_to_right_edge >= 0)
238 xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
239 }
240 }
241 #endif
242 break;
243
244 case PRED_REF:
245 xd->mode_info_context->mbmi.ref_predicted = pred_flag;
246 #if CONFIG_SUPERBLOCKS
247 if (xd->mode_info_context->mbmi.encoded_as_sb) {
248 if (xd->mb_to_right_edge >= 0)
249 xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
250 if (xd->mb_to_bottom_edge >= 0) {
251 xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
252 if (xd->mb_to_right_edge >= 0)
253 xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
254 }
255 }
256 #endif
257 break;
258
259 case PRED_MBSKIP:
260 xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
261 #if CONFIG_SUPERBLOCKS
262 if (xd->mode_info_context->mbmi.encoded_as_sb) {
263 if (xd->mb_to_right_edge >= 0)
264 xd->mode_info_context[1].mbmi.mb_skip_coeff = pred_flag;
265 if (xd->mb_to_bottom_edge >= 0) {
266 xd->mode_info_context[mis].mbmi.mb_skip_coeff = pred_flag;
267 if (xd->mb_to_right_edge >= 0)
268 xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
269 }
270 }
271 #endif
272 break;
273
274 default:
275 // TODO *** add error trap code.
276 break;
277 }
278 }
279
280
281 // The following contain the guts of the prediction code used to
282 // peredict various bitstream signals.
283
284 // Macroblock segment id prediction function
285 unsigned char vp9_get_pred_mb_segid(const VP9_COMMON *const cm,
286 const MACROBLOCKD *const xd, int MbIndex) {
287 // Currently the prediction for the macroblock segment ID is
288 // the value stored for this macroblock in the previous frame.
289 #if CONFIG_SUPERBLOCKS
290 if (!xd->mode_info_context->mbmi.encoded_as_sb) {
291 #endif
292 return cm->last_frame_seg_map[MbIndex];
293 #if CONFIG_SUPERBLOCKS
294 } else {
295 int seg_id = cm->last_frame_seg_map[MbIndex];
296 int mb_col = MbIndex % cm->mb_cols;
297 int mb_row = MbIndex / cm->mb_cols;
298 if (mb_col + 1 < cm->mb_cols)
299 seg_id = seg_id && cm->last_frame_seg_map[MbIndex + 1];
300 if (mb_row + 1 < cm->mb_rows) {
301 seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols];
302 if (mb_col + 1 < cm->mb_cols)
303 seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols + 1];
304 }
305 return seg_id;
306 }
307 #endif
308 }
309
310 MV_REFERENCE_FRAME vp9_get_pred_ref(const VP9_COMMON *const cm,
311 const MACROBLOCKD *const xd) {
312 MODE_INFO *m = xd->mode_info_context;
313
314 MV_REFERENCE_FRAME left;
315 MV_REFERENCE_FRAME above;
316 MV_REFERENCE_FRAME above_left;
317 MV_REFERENCE_FRAME pred_ref = LAST_FRAME;
318
319 int segment_id = xd->mode_info_context->mbmi.segment_id;
320 int seg_ref_active;
321 int i;
322
323 unsigned char frame_allowed[MAX_REF_FRAMES] = {1, 1, 1, 1};
324 unsigned char ref_score[MAX_REF_FRAMES];
325 unsigned char best_score = 0;
326 unsigned char left_in_image;
327 unsigned char above_in_image;
328 unsigned char above_left_in_image;
329
330 // Is segment coding ennabled
331 seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);
332
333 // Special case treatment if segment coding is enabled.
334 // Dont allow prediction of a reference frame that the segment
335 // does not allow
336 if (seg_ref_active) {
337 for (i = 0; i < MAX_REF_FRAMES; i++) {
338 frame_allowed[i] =
339 vp9_check_segref(xd, segment_id, i);
340
341 // Score set to 0 if ref frame not allowed
342 ref_score[i] = cm->ref_scores[i] * frame_allowed[i];
343 }
344 } else
345 vpx_memcpy(ref_score, cm->ref_scores, sizeof(ref_score));
346
347 // Reference frames used by neighbours
348 left = (m - 1)->mbmi.ref_frame;
349 above = (m - cm->mode_info_stride)->mbmi.ref_frame;
350 above_left = (m - 1 - cm->mode_info_stride)->mbmi.ref_frame;
351
352 // Are neighbours in image
353 left_in_image = (m - 1)->mbmi.mb_in_image;
354 above_in_image = (m - cm->mode_info_stride)->mbmi.mb_in_image;
355 above_left_in_image = (m - 1 - cm->mode_info_stride)->mbmi.mb_in_image;
356
357 // Adjust scores for candidate reference frames based on neigbours
358 if (frame_allowed[left] && left_in_image) {
359 ref_score[left] += 16;
360 if (above_left_in_image && (left == above_left))
361 ref_score[left] += 4;
362 }
363 if (frame_allowed[above] && above_in_image) {
364 ref_score[above] += 16;
365 if (above_left_in_image && (above == above_left))
366 ref_score[above] += 4;
367 }
368
369 // Now choose the candidate with the highest score
370 for (i = 0; i < MAX_REF_FRAMES; i++) {
371 if (ref_score[i] > best_score) {
372 pred_ref = i;
373 best_score = ref_score[i];
374 }
375 }
376
377 return pred_ref;
378 }
379
380 // Functions to computes a set of modified reference frame probabilities
381 // to use when the prediction of the reference frame value fails
382 void vp9_calc_ref_probs(int *count, vp9_prob *probs) {
383 int tot_count;
384
385 tot_count = count[0] + count[1] + count[2] + count[3];
386 if (tot_count) {
387 probs[0] = (vp9_prob)((count[0] * 255 + (tot_count >> 1)) / tot_count);
388 probs[0] += !probs[0];
389 } else
390 probs[0] = 128;
391
392 tot_count -= count[0];
393 if (tot_count) {
394 probs[1] = (vp9_prob)((count[1] * 255 + (tot_count >> 1)) / tot_count);
395 probs[1] += !probs[1];
396 } else
397 probs[1] = 128;
398
399 tot_count -= count[1];
400 if (tot_count) {
401 probs[2] = (vp9_prob)((count[2] * 255 + (tot_count >> 1)) / tot_count);
402 probs[2] += !probs[2];
403 } else
404 probs[2] = 128;
405
406 }
407
408 // Computes a set of modified conditional probabilities for the reference frame
409 // Values willbe set to 0 for reference frame options that are not possible
410 // because wither they were predicted and prediction has failed or because
411 // they are not allowed for a given segment.
412 void vp9_compute_mod_refprobs(VP9_COMMON *const cm) {
413 int norm_cnt[MAX_REF_FRAMES];
414 int intra_count;
415 int inter_count;
416 int last_count;
417 int gfarf_count;
418 int gf_count;
419 int arf_count;
420
421 intra_count = cm->prob_intra_coded;
422 inter_count = (255 - intra_count);
423 last_count = (inter_count * cm->prob_last_coded) / 255;
424 gfarf_count = inter_count - last_count;
425 gf_count = (gfarf_count * cm->prob_gf_coded) / 255;
426 arf_count = gfarf_count - gf_count;
427
428 // Work out modified reference frame probabilities to use where prediction
429 // of the reference frame fails
430 norm_cnt[0] = 0;
431 norm_cnt[1] = last_count;
432 norm_cnt[2] = gf_count;
433 norm_cnt[3] = arf_count;
434 vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[INTRA_FRAME]);
435 cm->mod_refprobs[INTRA_FRAME][0] = 0; // This branch implicit
436
437 norm_cnt[0] = intra_count;
438 norm_cnt[1] = 0;
439 norm_cnt[2] = gf_count;
440 norm_cnt[3] = arf_count;
441 vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[LAST_FRAME]);
442 cm->mod_refprobs[LAST_FRAME][1] = 0; // This branch implicit
443
444 norm_cnt[0] = intra_count;
445 norm_cnt[1] = last_count;
446 norm_cnt[2] = 0;
447 norm_cnt[3] = arf_count;
448 vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[GOLDEN_FRAME]);
449 cm->mod_refprobs[GOLDEN_FRAME][2] = 0; // This branch implicit
450
451 norm_cnt[0] = intra_count;
452 norm_cnt[1] = last_count;
453 norm_cnt[2] = gf_count;
454 norm_cnt[3] = 0;
455 vp9_calc_ref_probs(norm_cnt, cm->mod_refprobs[ALTREF_FRAME]);
456 cm->mod_refprobs[ALTREF_FRAME][2] = 0; // This branch implicit
457
458 // Score the reference frames based on overal frequency.
459 // These scores contribute to the prediction choices.
460 // Max score 17 min 1
461 cm->ref_scores[INTRA_FRAME] = 1 + (intra_count * 16 / 255);
462 cm->ref_scores[LAST_FRAME] = 1 + (last_count * 16 / 255);
463 cm->ref_scores[GOLDEN_FRAME] = 1 + (gf_count * 16 / 255);
464 cm->ref_scores[ALTREF_FRAME] = 1 + (arf_count * 16 / 255);
465 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698