vp9_pred_common.c 19.6 KB
Newer Older
Ronald S. Bultje's avatar
Ronald S. Bultje committed
1

2
/*
Paul Wilkins's avatar
Paul Wilkins committed
3
 *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
4
5
6
7
8
9
10
11
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

12
13
#include <limits.h>

Ronald S. Bultje's avatar
Ronald S. Bultje committed
14
#include "vp9/common/vp9_common.h"
15
16
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_seg_common.h"
17
#include "vp9/common/vp9_treecoder.h"
18

19
// Returns a context number for the given MB prediction signal
20
unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
21
  const MODE_INFO *const mi = xd->mode_info_context;
22
  const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
23
24
25
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
26
27
28
29
30
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  // left
31
32
33
  const int left_mv_pred = is_inter_mode(left_mbmi->mode);
  const int left_interp = left_in_image && left_mv_pred ?
          vp9_switchable_interp_map[left_mbmi->interp_filter] :
34
35
36
          VP9_SWITCHABLE_FILTERS;

  // above
37
38
39
  const int above_mv_pred = is_inter_mode(above_mbmi->mode);
  const int above_interp = above_in_image && above_mv_pred ?
          vp9_switchable_interp_map[above_mbmi->interp_filter] :
40
41
42
43
44
45
          VP9_SWITCHABLE_FILTERS;

  assert(left_interp != -1);
  assert(above_interp != -1);

  if (left_interp == above_interp)
46
47
48
49
50
51
52
    return left_interp;
  else if (left_interp == VP9_SWITCHABLE_FILTERS &&
           above_interp != VP9_SWITCHABLE_FILTERS)
    return above_interp;
  else if (left_interp != VP9_SWITCHABLE_FILTERS &&
           above_interp == VP9_SWITCHABLE_FILTERS)
    return left_interp;
53
  else
54
    return VP9_SWITCHABLE_FILTERS;
55
}
56
// Returns a context number for the given MB prediction signal
57
unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) {
John Koleszar's avatar
John Koleszar committed
58
  int pred_context;
59
  const MODE_INFO *const mi = xd->mode_info_context;
60
  const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
61
62
63
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
John Koleszar's avatar
John Koleszar committed
64
65
66
67
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
68
  if (above_in_image && left_in_image) {  // both edges available
69
70
    if (left_mbmi->ref_frame[0] == INTRA_FRAME &&
        above_mbmi->ref_frame[0] == INTRA_FRAME) {  // intra/intra (3)
71
72
      pred_context = 3;
    } else {  // intra/inter (1) or inter/inter (0)
73
74
      pred_context = left_mbmi->ref_frame[0] == INTRA_FRAME ||
                     above_mbmi->ref_frame[0] == INTRA_FRAME;
75
    }
76
  } else if (above_in_image || left_in_image) {  // one edge available
77
    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
78

79
    // inter: 0, intra: 2
80
    pred_context = 2 * (edge_mbmi->ref_frame[0] == INTRA_FRAME);
81
82
83
84
85
86
87
88
89
90
91
  } else {
    pred_context = 0;
  }
  assert(pred_context >= 0 && pred_context < INTRA_INTER_CONTEXTS);
  return pred_context;
}
// Returns a context number for the given MB prediction signal
unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm,
                                                    const MACROBLOCKD *xd) {
  int pred_context;
  const MODE_INFO *const mi = xd->mode_info_context;
92
93
94
95
  const MB_MODE_INFO *const above_mbmi = &mi[-cm->mode_info_stride].mbmi;
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
96
97
98
99
100
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  if (above_in_image && left_in_image) {  // both edges available
101
102
    if (above_mbmi->ref_frame[1] <= INTRA_FRAME &&
        left_mbmi->ref_frame[1] <= INTRA_FRAME)
103
      // neither edge uses comp pred (0/1)
104
105
106
      pred_context = (above_mbmi->ref_frame[0] == cm->comp_fixed_ref) ^
                     (left_mbmi->ref_frame[0] == cm->comp_fixed_ref);
    else if (above_mbmi->ref_frame[1] <= INTRA_FRAME)
107
      // one of two edges uses comp pred (2/3)
108
109
110
      pred_context = 2 + (above_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
                          above_mbmi->ref_frame[0] == INTRA_FRAME);
    else if (left_mbmi->ref_frame[1] <= INTRA_FRAME)
111
      // one of two edges uses comp pred (2/3)
112
113
114
      pred_context = 2 + (left_mbmi->ref_frame[0] == cm->comp_fixed_ref ||
                          left_mbmi->ref_frame[0] == INTRA_FRAME);
    else  // both edges use comp pred (4)
115
116
      pred_context = 4;
  } else if (above_in_image || left_in_image) {  // one edge available
117
    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
118

119
    if (edge_mbmi->ref_frame[1] <= INTRA_FRAME)
120
      // edge does not use comp pred (0/1)
121
122
123
      pred_context = edge_mbmi->ref_frame[0] == cm->comp_fixed_ref;
    else
      // edge uses comp pred (3)
124
125
126
127
128
129
130
      pred_context = 3;
  } else {  // no edges available (1)
    pred_context = 1;
  }
  assert(pred_context >= 0 && pred_context < COMP_INTER_CONTEXTS);
  return pred_context;
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
131

132
133
134
135
136
// Returns a context number for the given MB prediction signal
unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
                                              const MACROBLOCKD *xd) {
  int pred_context;
  const MODE_INFO *const mi = xd->mode_info_context;
137
138
139
140
  const MB_MODE_INFO *const above_mbmi = &mi[-cm->mode_info_stride].mbmi;
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
141
142
143
144
145
146
147
148
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
  const int var_ref_idx = !fix_ref_idx;

  if (above_in_image && left_in_image) {  // both edges available
149
150
    if (above_mbmi->ref_frame[0] == INTRA_FRAME &&
        left_mbmi->ref_frame[0] == INTRA_FRAME) {  // intra/intra (2)
151
      pred_context = 2;
152
153
154
155
    } else if (above_mbmi->ref_frame[0] == INTRA_FRAME ||
               left_mbmi->ref_frame[0] == INTRA_FRAME) {  // intra/inter
      const MB_MODE_INFO *edge_mbmi = above_mbmi->ref_frame[0] == INTRA_FRAME ?
                                          left_mbmi : above_mbmi;
156

157
      if (edge_mbmi->ref_frame[1] <= INTRA_FRAME)  // single pred (1/3)
158
        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
159
      else  // comp pred (1/3)
160
161
        pred_context = 1 + 2 * (edge_mbmi->ref_frame[var_ref_idx]
                                    != cm->comp_var_ref[1]);
162
    } else {  // inter/inter
163
164
165
166
167
168
      int l_sg = left_mbmi->ref_frame[1] <= INTRA_FRAME;
      int a_sg = above_mbmi->ref_frame[1] <= INTRA_FRAME;
      MV_REFERENCE_FRAME vrfa = a_sg ? above_mbmi->ref_frame[0]
                                     : above_mbmi->ref_frame[var_ref_idx];
      MV_REFERENCE_FRAME vrfl = l_sg ? left_mbmi->ref_frame[0]
                                     : left_mbmi->ref_frame[var_ref_idx];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
169

170
171
172
      if (vrfa == vrfl && cm->comp_var_ref[1] == vrfa) {
        pred_context = 0;
      } else if (l_sg && a_sg) {  // single/single
173
174
        if ((vrfa == cm->comp_fixed_ref && vrfl == cm->comp_var_ref[0]) ||
            (vrfl == cm->comp_fixed_ref && vrfa == cm->comp_var_ref[0]))
Ronald S. Bultje's avatar
Ronald S. Bultje committed
175
          pred_context = 4;
176
        else if (vrfa == vrfl)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
177
          pred_context = 3;
178
        else
179
180
181
182
          pred_context = 1;
      } else if (l_sg || a_sg) {  // single/comp
        MV_REFERENCE_FRAME vrfc = l_sg ? vrfa : vrfl;
        MV_REFERENCE_FRAME rfs = a_sg ? vrfa : vrfl;
183
        if (vrfc == cm->comp_var_ref[1] && rfs != cm->comp_var_ref[1])
184
          pred_context = 1;
185
        else if (rfs == cm->comp_var_ref[1] && vrfc != cm->comp_var_ref[1])
Ronald S. Bultje's avatar
Ronald S. Bultje committed
186
          pred_context = 2;
187
        else
188
189
190
191
          pred_context = 4;
      } else if (vrfa == vrfl) {  // comp/comp
        pred_context = 4;
      } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
192
193
194
        pred_context = 2;
      }
    }
195
  } else if (above_in_image || left_in_image) {  // one edge available
196
    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
197

198
    if (edge_mbmi->ref_frame[0] == INTRA_FRAME)
199
      pred_context = 2;
200
    else if (edge_mbmi->ref_frame[1] > INTRA_FRAME)
201
202
      pred_context = 4 * (edge_mbmi->ref_frame[var_ref_idx]
                              != cm->comp_var_ref[1]);
203
    else
204
      pred_context = 3 * (edge_mbmi->ref_frame[0] != cm->comp_var_ref[1]);
205
206
207
208
  } else {  // no edges available (2)
    pred_context = 2;
  }
  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
209

210
211
  return pred_context;
}
212
unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
213
214
  int pred_context;
  const MODE_INFO *const mi = xd->mode_info_context;
215
  const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
216
217
218
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
219
220
221
222
223
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  if (above_in_image && left_in_image) {  // both edges available
224
225
    if (above_mbmi->ref_frame[0] == INTRA_FRAME &&
        left_mbmi->ref_frame[0] == INTRA_FRAME) {
226
      pred_context = 2;
227
228
229
230
    } else if (above_mbmi->ref_frame[0] == INTRA_FRAME ||
               left_mbmi->ref_frame[0] == INTRA_FRAME) {
      const MB_MODE_INFO *edge_mbmi = above_mbmi->ref_frame[0] == INTRA_FRAME ?
                                          left_mbmi : above_mbmi;
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
      if (edge_mbmi->ref_frame[1] <= INTRA_FRAME)
        pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
      else
        pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
                            edge_mbmi->ref_frame[1] == LAST_FRAME);
    } else if (above_mbmi->ref_frame[1] <= INTRA_FRAME &&
               left_mbmi->ref_frame[1] <= INTRA_FRAME) {
      pred_context = 2 * (above_mbmi->ref_frame[0] == LAST_FRAME) +
                     2 * (left_mbmi->ref_frame[0] == LAST_FRAME);
    } else if (above_mbmi->ref_frame[1] > INTRA_FRAME &&
               left_mbmi->ref_frame[1] > INTRA_FRAME) {
      pred_context = 1 + (above_mbmi->ref_frame[0] == LAST_FRAME ||
                          above_mbmi->ref_frame[1] == LAST_FRAME ||
                          left_mbmi->ref_frame[0] == LAST_FRAME ||
                          left_mbmi->ref_frame[1] == LAST_FRAME);
247
    } else {
248
249
250
251
252
253
      MV_REFERENCE_FRAME rfs = above_mbmi->ref_frame[1] <= INTRA_FRAME ?
              above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
      MV_REFERENCE_FRAME crf1 = above_mbmi->ref_frame[1] > INTRA_FRAME ?
              above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
      MV_REFERENCE_FRAME crf2 = above_mbmi->ref_frame[1] > INTRA_FRAME ?
              above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
254

255
      if (rfs == LAST_FRAME)
256
        pred_context = 3 + (crf1 == LAST_FRAME || crf2 == LAST_FRAME);
257
      else
258
259
260
        pred_context = crf1 == LAST_FRAME || crf2 == LAST_FRAME;
    }
  } else if (above_in_image || left_in_image) {  // one edge available
261
    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
262

263
    if (edge_mbmi->ref_frame[0] == INTRA_FRAME)
264
      pred_context = 2;
265
266
267
268
269
    else if (edge_mbmi->ref_frame[1] <= INTRA_FRAME)
      pred_context = 4 * (edge_mbmi->ref_frame[0] == LAST_FRAME);
    else
      pred_context = 1 + (edge_mbmi->ref_frame[0] == LAST_FRAME ||
                          edge_mbmi->ref_frame[1] == LAST_FRAME);
270
271
272
273
274
275
  } else {  // no edges available (2)
    pred_context = 2;
  }
  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
  return pred_context;
}
Ronald S. Bultje's avatar
Ronald S. Bultje committed
276

277
unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
278
279
  int pred_context;
  const MODE_INFO *const mi = xd->mode_info_context;
280
  const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
281
282
283
284
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;

285
286
287
288
289
  // Note:
  // The mode info data structure has a one element border above and to the
  // left of the entries correpsonding to real macroblocks.
  // The prediction flags in these dummy entries are initialised to 0.
  if (above_in_image && left_in_image) {  // both edges available
290
291
    if (above_mbmi->ref_frame[0] == INTRA_FRAME &&
        left_mbmi->ref_frame[0] == INTRA_FRAME) {
292
      pred_context = 2;
293
294
295
296
    } else if (above_mbmi->ref_frame[0] == INTRA_FRAME ||
               left_mbmi->ref_frame[0] == INTRA_FRAME) {
      const MB_MODE_INFO *edge_mbmi = above_mbmi->ref_frame[0] == INTRA_FRAME ?
                                          left_mbmi : above_mbmi;
297

298
299
      if (edge_mbmi->ref_frame[1] <= INTRA_FRAME) {
        if (edge_mbmi->ref_frame[0] == LAST_FRAME)
300
          pred_context = 3;
301
302
        else
          pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
303
      } else {
304
305
        pred_context = 1 + 2 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
                                edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
306
      }
307
308
309
310
    } else if (above_mbmi->ref_frame[1] <= INTRA_FRAME &&
               left_mbmi->ref_frame[1] <= INTRA_FRAME) {
      if (above_mbmi->ref_frame[0] == LAST_FRAME &&
          left_mbmi->ref_frame[0] == LAST_FRAME) {
311
        pred_context = 3;
312
313
314
315
      } else if (above_mbmi->ref_frame[0] == LAST_FRAME ||
                 left_mbmi->ref_frame[0] == LAST_FRAME) {
        const MB_MODE_INFO *edge_mbmi = above_mbmi->ref_frame[0] == LAST_FRAME ?
                                           left_mbmi : above_mbmi;
316

317
        pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
318
      } else {
319
320
        pred_context = 2 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME) +
                       2 * (left_mbmi->ref_frame[0] == GOLDEN_FRAME);
321
      }
322
323
324
325
326
327
328
329
330
    } else if (above_mbmi->ref_frame[1] > INTRA_FRAME &&
               left_mbmi->ref_frame[1] > INTRA_FRAME) {
      if (above_mbmi->ref_frame[0] == left_mbmi->ref_frame[0] &&
          above_mbmi->ref_frame[1] == left_mbmi->ref_frame[1])
        pred_context = 3 * (above_mbmi->ref_frame[0] == GOLDEN_FRAME ||
                            above_mbmi->ref_frame[1] == GOLDEN_FRAME ||
                            left_mbmi->ref_frame[0] == GOLDEN_FRAME ||
                            left_mbmi->ref_frame[1] == GOLDEN_FRAME);
      else
Ronald S. Bultje's avatar
Ronald S. Bultje committed
331
        pred_context = 2;
332
    } else {
333
334
335
336
337
338
      MV_REFERENCE_FRAME rfs = above_mbmi->ref_frame[1] <= INTRA_FRAME ?
              above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
      MV_REFERENCE_FRAME crf1 = above_mbmi->ref_frame[1] > INTRA_FRAME ?
              above_mbmi->ref_frame[0] : left_mbmi->ref_frame[0];
      MV_REFERENCE_FRAME crf2 = above_mbmi->ref_frame[1] > INTRA_FRAME ?
              above_mbmi->ref_frame[1] : left_mbmi->ref_frame[1];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
339

340
      if (rfs == GOLDEN_FRAME)
341
        pred_context = 3 + (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
342
      else if (rfs == ALTREF_FRAME)
343
        pred_context = crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME;
344
      else
345
        pred_context = 1 + 2 * (crf1 == GOLDEN_FRAME || crf2 == GOLDEN_FRAME);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
346
    }
347
  } else if (above_in_image || left_in_image) {  // one edge available
348
    const MB_MODE_INFO *edge_mbmi = above_in_image ? above_mbmi : left_mbmi;
349

350
351
352
    if (edge_mbmi->ref_frame[0] == INTRA_FRAME ||
        (edge_mbmi->ref_frame[0] == LAST_FRAME &&
         edge_mbmi->ref_frame[1] <= INTRA_FRAME))
353
      pred_context = 2;
354
355
356
357
358
    else if (edge_mbmi->ref_frame[1] <= INTRA_FRAME)
      pred_context = 4 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME);
    else
      pred_context = 3 * (edge_mbmi->ref_frame[0] == GOLDEN_FRAME ||
                          edge_mbmi->ref_frame[1] == GOLDEN_FRAME);
359
360
  } else {  // no edges available (2)
    pred_context = 2;
John Koleszar's avatar
John Koleszar committed
361
  }
362
  assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
John Koleszar's avatar
John Koleszar committed
363
  return pred_context;
364
}
365
// Returns a context number for the given MB prediction signal
366
367
368
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real blocks.
// The prediction flags in these dummy entries are initialized to 0.
369
unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) {
370
  const MODE_INFO *const mi = xd->mode_info_context;
371
372
373
374
375
376
377
  const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
  const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
  const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
  const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
  const int max_tx_size = max_txsize_lookup[mi->mbmi.sb_type];
  int above_context = max_tx_size;
  int left_context = max_tx_size;
378
379

  if (above_in_image)
380
381
    above_context = above_mbmi->mb_skip_coeff ? max_tx_size
                                              : above_mbmi->txfm_size;
382
383

  if (left_in_image)
384
385
    left_context = left_mbmi->mb_skip_coeff ? max_tx_size
                                            : left_mbmi->txfm_size;
386
387

  if (!left_in_image)
388
    left_context = above_context;
389
390

  if (!above_in_image)
391
392
    above_context = left_context;

393
  return above_context + left_context > max_tx_size;
394
395
}

396
397
398
399
void vp9_set_pred_flag_seg_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
                              int mi_row, int mi_col, uint8_t pred_flag) {
  MODE_INFO *mi = &cm->mi[mi_row * cm->mode_info_stride + mi_col];
  const int bw = 1 << mi_width_log2(bsize);
400
  const int bh = 1 << mi_height_log2(bsize);
401
402
403
404
405
406
407
408
409
410
411
412
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
  int x, y;

  for (y = 0; y < ymis; y++)
    for (x = 0; x < xmis; x++)
      mi[y * cm->mode_info_stride + x].mbmi.seg_id_predicted = pred_flag;
}

void vp9_set_pred_flag_mbskip(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
                              int mi_row, int mi_col, uint8_t pred_flag) {
  MODE_INFO *mi = &cm->mi[mi_row * cm->mode_info_stride + mi_col];
413
  const int bw = 1 << mi_width_log2(bsize);
414
415
416
  const int bh = 1 << mi_height_log2(bsize);
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
417
  int x, y;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
418

419
420
421
  for (y = 0; y < ymis; y++)
    for (x = 0; x < xmis; x++)
      mi[y * cm->mode_info_stride + x].mbmi.mb_skip_coeff = pred_flag;
422
423
}

424
425
426
427
428
int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids,
                       BLOCK_SIZE_TYPE bsize, int mi_row, int mi_col) {
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = 1 << mi_width_log2(bsize);
  const int bh = 1 << mi_height_log2(bsize);
429
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
430
431
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
  int x, y, segment_id = INT_MAX;
432

433
434
435
436
437
438
  for (y = 0; y < ymis; y++)
    for (x = 0; x < xmis; x++)
      segment_id = MIN(segment_id,
                       segment_ids[mi_offset + y * cm->mi_cols + x]);

  assert(segment_id >= 0 && segment_id < MAX_MB_SEGMENTS);
439
  return segment_id;
440
}