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
19static INLINE const MB_MODE_INFO *get_above_mbmi(const MODE_INFO *const above) {
20  return (above != NULL) ? &above->mbmi : NULL;
21}
22
23static 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
28unsigned 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
63unsigned 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
89unsigned 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
134unsigned 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}
215unsigned 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
281unsigned 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.
371unsigned 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
399void 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
403int 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}
420