media/libvpx/vp9/common/vp9_pred_common.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:72549f391745
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 <limits.h>
13
14 #include "vp9/common/vp9_common.h"
15 #include "vp9/common/vp9_pred_common.h"
16 #include "vp9/common/vp9_seg_common.h"
17 #include "vp9/common/vp9_treecoder.h"
18
19 static INLINE const MB_MODE_INFO *get_above_mbmi(const MODE_INFO *const above) {
20 return (above != NULL) ? &above->mbmi : NULL;
21 }
22
23 static INLINE const MB_MODE_INFO *get_left_mbmi(const MODE_INFO *const left) {
24 return (left != NULL) ? &left->mbmi : NULL;
25 }
26
27 // Returns a context number for the given MB prediction signal
28 unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
29 const MODE_INFO *const above_mi = get_above_mi(xd);
30 const MODE_INFO *const left_mi = get_left_mi(xd);
31 const int above_in_image = above_mi != NULL;
32 const int left_in_image = left_mi != NULL;
33 // Note:
34 // The mode info data structure has a one element border above and to the
35 // left of the entries correpsonding to real macroblocks.
36 // The prediction flags in these dummy entries are initialised to 0.
37 // left
38 const int left_mv_pred = left_in_image ? is_inter_block(&left_mi->mbmi)
39 : 0;
40 const int left_interp = left_in_image && left_mv_pred
41 ? left_mi->mbmi.interp_filter
42 : SWITCHABLE_FILTERS;
43
44 // above
45 const int above_mv_pred = above_in_image ? is_inter_block(&above_mi->mbmi)
46 : 0;
47 const int above_interp = above_in_image && above_mv_pred
48 ? above_mi->mbmi.interp_filter
49 : SWITCHABLE_FILTERS;
50
51 if (left_interp == above_interp)
52 return left_interp;
53 else if (left_interp == SWITCHABLE_FILTERS &&
54 above_interp != SWITCHABLE_FILTERS)
55 return above_interp;
56 else if (left_interp != SWITCHABLE_FILTERS &&
57 above_interp == SWITCHABLE_FILTERS)
58 return left_interp;
59 else
60 return SWITCHABLE_FILTERS;
61 }
62 // Returns a context number for the given MB prediction signal
63 unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) {
64 const MODE_INFO *const above_mi = get_above_mi(xd);
65 const MODE_INFO *const left_mi = get_left_mi(xd);
66 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
67 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
68 const int above_in_image = above_mi != NULL;
69 const int left_in_image = left_mi != NULL;
70 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
71 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
72
73 // The mode info data structure has a one element border above and to the
74 // left of the entries corresponding to real macroblocks.
75 // The prediction flags in these dummy entries are initialized to 0.
76 // 0 - inter/inter, inter/--, --/inter, --/--
77 // 1 - intra/inter, inter/intra
78 // 2 - intra/--, --/intra
79 // 3 - intra/intra
80 if (above_in_image && left_in_image) // both edges available
81 return left_intra && above_intra ? 3
82 : left_intra || above_intra;
83 else if (above_in_image || left_in_image) // one edge available
84 return 2 * (above_in_image ? above_intra : left_intra);
85 else
86 return 0;
87 }
88 // Returns a context number for the given MB prediction signal
89 unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm,
90 const MACROBLOCKD *xd) {
91 int pred_context;
92 const MODE_INFO *const above_mi = get_above_mi(xd);
93 const MODE_INFO *const left_mi = get_left_mi(xd);
94 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
95 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
96 const int above_in_image = above_mi != NULL;
97 const int left_in_image = left_mi != NULL;
98 // Note:
99 // The mode info data structure has a one element border above and to the
100 // left of the entries correpsonding to real macroblocks.
101 // The prediction flags in these dummy entries are initialised to 0.
102 if (above_in_image && left_in_image) { // both edges available
103 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi))
104 // neither edge uses comp pred (0/1)
105 pred_context = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^
106 (left_mbmi->ref_frame[0] == cm->comp_fixed_ref);
107 else if (!has_second_ref(above_mbmi))
108 // one of two edges uses comp pred (2/3)
109 pred_context = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
110 !is_inter_block(above_mbmi));
111 else if (!has_second_ref(left_mbmi))
112 // one of two edges uses comp pred (2/3)
113 pred_context = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
114 !is_inter_block(left_mbmi));
115 else // both edges use comp pred (4)
116 pred_context = 4;
117 } else if (above_in_image || left_in_image) { // one edge available
118 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
119
120 if (!has_second_ref(edge_mbmi))
121 // edge does not use comp pred (0/1)
122 pred_context = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref;
123 else
124 // edge uses comp pred (3)
125 pred_context = 3;
126 } else { // no edges available (1)
127 pred_context = 1;
128 }
129 assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS);
130 return pred_context;
131 }
132
133 // Returns a context number for the given MB prediction signal
134 unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
135 const MACROBLOCKD *xd) {
136 int pred_context;
137 const MODE_INFO *const above_mi = get_above_mi(xd);
138 const MODE_INFO *const left_mi = get_left_mi(xd);
139 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
140 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
141 const int above_in_image = above_mi != NULL;
142 const int left_in_image = left_mi != NULL;
143 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
144 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
145 // Note:
146 // The mode info data structure has a one element border above and to the
147 // left of the entries correpsonding to real macroblocks.
148 // The prediction flags in these dummy entries are initialised to 0.
149 const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
150 const int var_ref_idx = !fix_ref_idx;
151
152 if (above_in_image && left_in_image) { // both edges available
153 if (above_intra && left_intra) { // intra/intra (2)
154 pred_context = 2;
155 } else if (above_intra || left_intra) { // intra/inter
156 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
157
158 if (!has_second_ref(edge_mbmi)) // single pred (1/3)
159 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
160 else // comp pred (1/3)
161 pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
162 != cm->comp_var_ref[1]);
163 } else { // inter/inter
164 const int l_sg = !has_second_ref(left_mbmi);
165 const int a_sg = !has_second_ref(above_mbmi);
166 MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
167 : above_mbmi->ref_frame[var_ref_idx];
168 MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
169 : left_mbmi->ref_frame[var_ref_idx];
170
171 if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
172 pred_context = 0;
173 } else if (l_sg && a_sg) { // single/single
174 if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
175 (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
176 pred_context = 4;
177 else if (vrfa == vrfl)
178 pred_context = 3;
179 else
180 pred_context = 1;
181 } else if (l_sg || a_sg) { // single/comp
182 MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
183 MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
184 if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
185 pred_context = 1;
186 else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
187 pred_context = 2;
188 else
189 pred_context = 4;
190 } else if (vrfa == vrfl) { // comp/comp
191 pred_context = 4;
192 } else {
193 pred_context = 2;
194 }
195 }
196 } else if (above_in_image || left_in_image) { // one edge available
197 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
198
199 if (!is_inter_block(edge_mbmi)) {
200 pred_context = 2;
201 } else {
202 if (has_second_ref(edge_mbmi))
203 pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx]
204 != cm->comp_var_ref[1]);
205 else
206 pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
207 }
208 } else { // no edges available (2)
209 pred_context = 2;
210 }
211 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
212
213 return pred_context;
214 }
215 unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
216 int pred_context;
217 const MODE_INFO *const above_mi = get_above_mi(xd);
218 const MODE_INFO *const left_mi = get_left_mi(xd);
219 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
220 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
221 const int above_in_image = above_mi != NULL;
222 const int left_in_image = left_mi != NULL;
223 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
224 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
225 // Note:
226 // The mode info data structure has a one element border above and to the
227 // left of the entries correpsonding to real macroblocks.
228 // The prediction flags in these dummy entries are initialised to 0.
229 if (above_in_image && left_in_image) { // both edges available
230 if (above_intra && left_intra) { // intra/intra
231 pred_context = 2;
232 } else if (above_intra || left_intra) { // intra/inter or inter/intra
233 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
234 if (!has_second_ref(edge_mbmi))
235 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
236 else
237 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
238 edge_mbmi->ref_frame[1] == LAST_FRAME);
239 } else { // inter/inter
240 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) {
241 pred_context = 2 * (above_mbmi->ref_frame[0] == LAST_FRAME) +
242 2 * (left_mbmi->ref_frame[0] == LAST_FRAME);
243 } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) {
244 pred_context = 1 + (above_mbmi->ref_frame[0] == LAST_FRAME ||
245 above_mbmi->ref_frame[1] == LAST_FRAME ||
246 left_mbmi->ref_frame[0] == LAST_FRAME ||
247 left_mbmi->ref_frame[1] == LAST_FRAME);
248 } else {
249 const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ?
250 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
251 const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ?
252 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
253 const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ?
254 above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
255
256 if (rfs == LAST_FRAME)
257 pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
258 else
259 pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME;
260 }
261 }
262 } else if (above_in_image || left_in_image) { // one edge available
263 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
264 if (!is_inter_block(edge_mbmi)) { // intra
265 pred_context = 2;
266 } else { // inter
267 if (!has_second_ref(edge_mbmi))
268 pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
269 else
270 pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
271 edge_mbmi->ref_frame[1] == LAST_FRAME);
272 }
273 } else { // no edges available
274 pred_context = 2;
275 }
276
277 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
278 return pred_context;
279 }
280
281 unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
282 int pred_context;
283 const MODE_INFO *const above_mi = get_above_mi(xd);
284 const MODE_INFO *const left_mi = get_left_mi(xd);
285 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
286 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
287 const int above_in_image = above_mi != NULL;
288 const int left_in_image = left_mi != NULL;
289 const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1;
290 const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1;
291
292 // Note:
293 // The mode info data structure has a one element border above and to the
294 // left of the entries correpsonding to real macroblocks.
295 // The prediction flags in these dummy entries are initialised to 0.
296 if (above_in_image && left_in_image) { // both edges available
297 if (above_intra && left_intra) { // intra/intra
298 pred_context = 2;
299 } else if (above_intra || left_intra) { // intra/inter or inter/intra
300 const MB_MODE_INFO *edge_mbmi = above_intra ? left_mbmi : above_mbmi;
301 if (!has_second_ref(edge_mbmi)) {
302 if (edge_mbmi->ref_frame[0] == LAST_FRAME)
303 pred_context = 3;
304 else
305 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
306 } else {
307 pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
308 edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
309 }
310 } else { // inter/inter
311 if (!has_second_ref(above_mbmi) && !has_second_ref(left_mbmi)) {
312 if (above_mbmi->ref_frame[0] == LAST_FRAME &&
313 left_mbmi->ref_frame[0] == LAST_FRAME) {
314 pred_context = 3;
315 } else if (above_mbmi->ref_frame[0] == LAST_FRAME ||
316 left_mbmi->ref_frame[0] == LAST_FRAME) {
317 const MB_MODE_INFO *edge_mbmi =
318 above_mbmi->ref_frame[0] == LAST_FRAME ? left_mbmi : above_mbmi;
319
320 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
321 } else {
322 pred_context = 2 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME) +
323 2 * (left_mbmi->ref_frame[0] == GOLDEN_FRAME);
324 }
325 } else if (has_second_ref(above_mbmi) && has_second_ref(left_mbmi)) {
326 if (above_mbmi->ref_frame[0] == left_mbmi->ref_frame[0] &&
327 above_mbmi->ref_frame[1] == left_mbmi->ref_frame[1])
328 pred_context = 3 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME ||
329 above_mbmi->ref_frame[1] == GOLDEN_FRAME ||
330 left_mbmi->ref_frame[0] == GOLDEN_FRAME ||
331 left_mbmi->ref_frame[1] == GOLDEN_FRAME);
332 else
333 pred_context = 2;
334 } else {
335 const MV_REFERENCE_FRAME rfs = !has_second_ref(above_mbmi) ?
336 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
337 const MV_REFERENCE_FRAME crf1 = has_second_ref(above_mbmi) ?
338 above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
339 const MV_REFERENCE_FRAME crf2 = has_second_ref(above_mbmi) ?
340 above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
341
342 if (rfs == GOLDEN_FRAME)
343 pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
344 else if (rfs == ALTREF_FRAME)
345 pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
346 else
347 pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
348 }
349 }
350 } else if (above_in_image || left_in_image) { // one edge available
351 const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
352
353 if (!is_inter_block(edge_mbmi) ||
354 (edge_mbmi->ref_frame[0] == LAST_FRAME && !has_second_ref(edge_mbmi)))
355 pred_context = 2;
356 else if (!has_second_ref(edge_mbmi))
357 pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
358 else
359 pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
360 edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
361 } else { // no edges available (2)
362 pred_context = 2;
363 }
364 assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
365 return pred_context;
366 }
367 // Returns a context number for the given MB prediction signal
368 // The mode info data structure has a one element border above and to the
369 // left of the entries corresponding to real blocks.
370 // The prediction flags in these dummy entries are initialized to 0.
371 unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) {
372 const MODE_INFO *const above_mi = get_above_mi(xd);
373 const MODE_INFO *const left_mi = get_left_mi(xd);
374 const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi);
375 const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi);
376 const int above_in_image = above_mi != NULL;
377 const int left_in_image = left_mi != NULL;
378 const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type];
379 int above_context = max_tx_size;
380 int left_context = max_tx_size;
381
382 if (above_in_image)
383 above_context = above_mbmi->skip_coeff ? max_tx_size
384 : above_mbmi->tx_size;
385
386 if (left_in_image)
387 left_context = left_mbmi->skip_coeff ? max_tx_size
388 : left_mbmi->tx_size;
389
390 if (!left_in_image)
391 left_context = above_context;
392
393 if (!above_in_image)
394 above_context = left_context;
395
396 return above_context + left_context > max_tx_size;
397 }
398
399 void vp9_set_pred_flag_seg_id(MACROBLOCKD *xd, uint8_t pred_flag) {
400 xd->mi_8x8[0]->mbmi.seg_id_predicted = pred_flag;
401 }
402
403 int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids,
404 BLOCK_SIZE bsize, int mi_row, int mi_col) {
405 const int mi_offset = mi_row * cm->mi_cols + mi_col;
406 const int bw = num_8x8_blocks_wide_lookup[bsize];
407 const int bh = num_8x8_blocks_high_lookup[bsize];
408 const int xmis = MIN(cm->mi_cols - mi_col, bw);
409 const int ymis = MIN(cm->mi_rows - mi_row, bh);
410 int x, y, segment_id = INT_MAX;
411
412 for (y = 0; y < ymis; y++)
413 for (x = 0; x < xmis; x++)
414 segment_id = MIN(segment_id,
415 segment_ids[mi_offset + y * cm->mi_cols + x]);
416
417 assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
418 return segment_id;
419 }

mercurial