pred_common.h 12.9 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12
13
#ifndef AV1_COMMON_PRED_COMMON_H_
#define AV1_COMMON_PRED_COMMON_H_
Jingning Han's avatar
Jingning Han committed
14

15
16
#include "av1/common/blockd.h"
#include "av1/common/onyxc_int.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "aom_dsp/aom_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
18
19
20
21

#ifdef __cplusplus
extern "C" {
#endif
22

23
#if CONFIG_SPATIAL_SEGMENTATION
24
/* Picks CDFs based on number of matching segment IDs */
25
static INLINE int pick_spatial_seg_cdf(int prev_ul, int prev_u, int prev_l) {
26
27
28
29
30
31
32
33
  if ((prev_ul == prev_u) && (prev_ul == prev_l))
    return 2;
  else if ((prev_ul == prev_u) || (prev_ul == prev_l) || (prev_u == prev_l))
    return 1;
  else
    return 0;
}

34
static INLINE int pick_spatial_seg_pred(int prev_ul, int prev_u, int prev_l) {
35
36
37
38
  /* If 2 or more are identical returns that as predictor, otherwise prev_l */
  return (prev_ul == prev_u) ? prev_u : prev_l;
}

39
40
41
42
static INLINE void set_spatial_segment_id(const AV1_COMMON *const cm,
                                          uint8_t *segment_ids,
                                          BLOCK_SIZE bsize, int mi_row,
                                          int mi_col, int segment_id) {
43
44
45
46
47
48
49
50
51
52
53
54
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
  int x, y;

  for (y = 0; y < ymis; ++y)
    for (x = 0; x < xmis; ++x)
      segment_ids[mi_offset + y * cm->mi_cols + x] = segment_id;
}
#endif
Jingning Han's avatar
Jingning Han committed
55

56
static INLINE int get_segment_id(const AV1_COMMON *const cm,
clang-format's avatar
clang-format committed
57
58
                                 const uint8_t *segment_ids, BLOCK_SIZE bsize,
                                 int mi_row, int mi_col) {
Jingning Han's avatar
Jingning Han committed
59
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
60
61
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
Yaowu Xu's avatar
Yaowu Xu committed
62
63
  const int xmis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int ymis = AOMMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
64
65
66
67
  int x, y, segment_id = MAX_SEGMENTS;

  for (y = 0; y < ymis; ++y)
    for (x = 0; x < xmis; ++x)
68
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
69
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
70
71
72
73
74

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
75
static INLINE int av1_get_pred_context_seg_id(const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
76
77
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
clang-format's avatar
clang-format committed
78
79
  const int above_sip =
      (above_mi != NULL) ? above_mi->mbmi.seg_id_predicted : 0;
Jingning Han's avatar
Jingning Han committed
80
81
82
83
84
  const int left_sip = (left_mi != NULL) ? left_mi->mbmi.seg_id_predicted : 0;

  return above_sip + left_sip;
}

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#if CONFIG_JNT_COMP
static INLINE int get_comp_index_context(const AV1_COMMON *cm,
                                         const MACROBLOCKD *xd) {
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  int bck_idx = cm->frame_refs[mbmi->ref_frame[0] - LAST_FRAME].idx;
  int fwd_idx = cm->frame_refs[mbmi->ref_frame[1] - LAST_FRAME].idx;
  int bck_frame_index = 0, fwd_frame_index = 0;
  int cur_frame_index = cm->cur_frame->cur_frame_offset;

  if (bck_idx >= 0)
    bck_frame_index = cm->buffer_pool->frame_bufs[bck_idx].cur_frame_offset;

  if (fwd_idx >= 0)
    fwd_frame_index = cm->buffer_pool->frame_bufs[fwd_idx].cur_frame_offset;
  int fwd = abs(fwd_frame_index - cur_frame_index);
  int bck = abs(cur_frame_index - bck_frame_index);

  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;

  int above_ctx = 0, left_ctx = 0;
106
  const int offset = (fwd == bck);
107
108
109

  if (above_mi) {
    const MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
110
    if (has_second_ref(above_mbmi))
111
112
113
114
115
116
117
      above_ctx = above_mbmi->compound_idx;
    else if (above_mbmi->ref_frame[0] == ALTREF_FRAME)
      above_ctx = 1;
  }

  if (left_mi) {
    const MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
118
    if (has_second_ref(left_mbmi))
119
120
121
122
123
124
125
      left_ctx = left_mbmi->compound_idx;
    else if (left_mbmi->ref_frame[0] == ALTREF_FRAME)
      left_ctx = 1;
  }

  return above_ctx + left_ctx + 3 * offset;
}
126
127
128
129
130
131
132
133
134
135
136

static INLINE int get_comp_group_idx_context(const MACROBLOCKD *xd) {
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  int above_ctx = 0, left_ctx = 0;

  if (above_mi) {
    const MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
    if (has_second_ref(above_mbmi))
      above_ctx = above_mbmi->comp_group_idx;
    else if (above_mbmi->ref_frame[0] == ALTREF_FRAME)
137
      above_ctx = 3;
138
139
140
141
142
143
  }
  if (left_mi) {
    const MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
    if (has_second_ref(left_mbmi))
      left_ctx = left_mbmi->comp_group_idx;
    else if (left_mbmi->ref_frame[0] == ALTREF_FRAME)
144
      left_ctx = 3;
145
146
147
148
  }

  return above_ctx + left_ctx;
}
149
150
#endif  // CONFIG_JNT_COMP

151
152
153
154
155
static INLINE aom_cdf_prob *av1_get_pred_cdf_seg_id(
    struct segmentation_probs *segp, const MACROBLOCKD *xd) {
  return segp->pred_cdf[av1_get_pred_context_seg_id(xd)];
}

Zoe Liu's avatar
Zoe Liu committed
156
157
158
159
160
161
162
163
164
165
#if CONFIG_EXT_SKIP
static INLINE int av1_get_skip_mode_context(const MACROBLOCKD *xd) {
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int above_skip_mode = above_mi ? above_mi->mbmi.skip_mode : 0;
  const int left_skip_mode = left_mi ? left_mi->mbmi.skip_mode : 0;
  return above_skip_mode + left_skip_mode;
}
#endif  // CONFIG_EXT_SKIP

Yaowu Xu's avatar
Yaowu Xu committed
166
static INLINE int av1_get_skip_context(const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
167
168
169
170
171
172
173
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int above_skip = (above_mi != NULL) ? above_mi->mbmi.skip : 0;
  const int left_skip = (left_mi != NULL) ? left_mi->mbmi.skip : 0;
  return above_skip + left_skip;
}

174
#if CONFIG_DUAL_FILTER
Yaowu Xu's avatar
Yaowu Xu committed
175
int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir);
176
#else
Yaowu Xu's avatar
Yaowu Xu committed
177
int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd);
178
#endif
Jingning Han's avatar
Jingning Han committed
179

180
181
182
183
// Get a list of palette base colors that are used in the above and left blocks,
// referred to as "color cache". The return value is the number of colors in the
// cache (<= 2 * PALETTE_MAX_SIZE). The color values are stored in "cache"
// in ascending order.
184
185
int av1_get_palette_cache(const MACROBLOCKD *const xd, int plane,
                          uint16_t *cache);
186

Hui Su's avatar
Hui Su committed
187
static INLINE int av1_get_palette_bsize_ctx(BLOCK_SIZE bsize) {
188
  return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_4X4];
Hui Su's avatar
Hui Su committed
189
190
}

Yaowu Xu's avatar
Yaowu Xu committed
191
int av1_get_intra_inter_context(const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
192

Yaowu Xu's avatar
Yaowu Xu committed
193
int av1_get_reference_mode_context(const AV1_COMMON *cm, const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
194

195
196
197
198
static INLINE aom_cdf_prob *av1_get_reference_mode_cdf(const AV1_COMMON *cm,
                                                       const MACROBLOCKD *xd) {
  return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context(cm, xd)];
}
Jingning Han's avatar
Jingning Han committed
199

Zoe Liu's avatar
Zoe Liu committed
200
#if CONFIG_EXT_COMP_REFS
201
int av1_get_comp_reference_type_context(const MACROBLOCKD *xd);
Zoe Liu's avatar
Zoe Liu committed
202

203
int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd);
Zoe Liu's avatar
Zoe Liu committed
204

205
int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd);
Zoe Liu's avatar
Zoe Liu committed
206

207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd);

static INLINE aom_cdf_prob *av1_get_comp_reference_type_cdf(
    const MACROBLOCKD *xd) {
  const int pred_context = av1_get_comp_reference_type_context(xd);
  return xd->tile_ctx->comp_ref_type_cdf[pred_context];
}

static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p(
    const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
}

static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1(
    const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
}

static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2(
    const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
}
Zoe Liu's avatar
Zoe Liu committed
232
233
#endif  // CONFIG_EXT_COMP_REFS

Yaowu Xu's avatar
Yaowu Xu committed
234
235
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
                                    const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
236

237
238
239
240
241
242
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p(const AV1_COMMON *cm,
                                                        const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_comp_ref_p(cm, xd);
  return xd->tile_ctx->comp_ref_cdf[pred_context][0];
}

Yaowu Xu's avatar
Yaowu Xu committed
243
244
int av1_get_pred_context_comp_ref_p1(const AV1_COMMON *cm,
                                     const MACROBLOCKD *xd);
245

246
247
248
249
250
251
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1(
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_comp_ref_p1(cm, xd);
  return xd->tile_ctx->comp_ref_cdf[pred_context][1];
}

Yaowu Xu's avatar
Yaowu Xu committed
252
253
int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
                                     const MACROBLOCKD *xd);
254

255
256
257
258
259
260
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2(
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_comp_ref_p2(cm, xd);
  return xd->tile_ctx->comp_ref_cdf[pred_context][2];
}

Yaowu Xu's avatar
Yaowu Xu committed
261
262
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
                                       const MACROBLOCKD *xd);
263

264
265
266
267
268
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p(
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
  return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
}
269
270
271
272

int av1_get_pred_context_comp_bwdref_p1(const AV1_COMMON *cm,
                                        const MACROBLOCKD *xd);

273
274
275
276
277
278
static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p1(
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  const int pred_context = av1_get_pred_context_comp_bwdref_p1(cm, xd);
  return xd->tile_ctx->comp_bwdref_cdf[pred_context][1];
}

Yaowu Xu's avatar
Yaowu Xu committed
279
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
280

Yaowu Xu's avatar
Yaowu Xu committed
281
int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
282

Yaowu Xu's avatar
Yaowu Xu committed
283
int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
284

Yaowu Xu's avatar
Yaowu Xu committed
285
int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
286

Yaowu Xu's avatar
Yaowu Xu committed
287
int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
288

289
290
int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd);

291
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p1(
292
293
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
294
295
296
297
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p1(xd)][0];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p2(
298
299
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
300
301
302
303
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p2(xd)][1];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p3(
304
305
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
306
307
308
309
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p3(xd)][2];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p4(
310
311
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
312
313
314
315
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p4(xd)][3];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p5(
316
317
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
318
319
320
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p5(xd)][4];
}
321
322
323
324
325
326
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p6(
    const AV1_COMMON *cm, const MACROBLOCKD *xd) {
  (void)cm;
  return xd->tile_ctx
      ->single_ref_cdf[av1_get_pred_context_single_ref_p6(xd)][5];
}
327

Jingning Han's avatar
Jingning Han committed
328
329
330
331
// Returns a context number for the given MB prediction signal
// 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.
332
static INLINE int get_tx_size_context(const MACROBLOCKD *xd, int is_inter) {
333
  const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
334
  const TX_SIZE max_tx_size = max_txsize_rect_lookup[is_inter][mbmi->sb_type];
335
336
  const int max_tx_wide = tx_size_wide[max_tx_size];
  const int max_tx_high = tx_size_high[max_tx_size];
Jingning Han's avatar
Jingning Han committed
337
338
339
340
  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
  const int has_above = xd->up_available;
  const int has_left = xd->left_available;
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  if (!has_above || above_mbmi->skip) {
    if (!has_left || left_mbmi->skip) {
      return 1;
    } else {
      return 2 * tx_size_high[left_mbmi->tx_size] > max_tx_high;
    }
  } else {
    if (!has_left || left_mbmi->skip) {
      return 2 * tx_size_wide[above_mbmi->tx_size] > max_tx_wide;
    } else {
      const int above_ctx = (int)tx_size_wide[above_mbmi->tx_size];
      const int left_ctx = (int)tx_size_high[left_mbmi->tx_size];
      return 2 * (above_ctx + left_ctx) > max_tx_wide + max_tx_high;
    }
  }
Jingning Han's avatar
Jingning Han committed
357
358
359
360
361
362
}

#ifdef __cplusplus
}  // extern "C"
#endif

Yaowu Xu's avatar
Yaowu Xu committed
363
#endif  // AV1_COMMON_PRED_COMMON_H_