1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #ifndef AOM_AV1_COMMON_PRED_COMMON_H_
13 #define AOM_AV1_COMMON_PRED_COMMON_H_
14
15 #include "av1/common/av1_common_int.h"
16 #include "av1/common/blockd.h"
17 #include "av1/common/mvref_common.h"
18 #include "aom_dsp/aom_dsp_common.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
get_segment_id(const CommonModeInfoParams * const mi_params,const uint8_t * segment_ids,BLOCK_SIZE bsize,int mi_row,int mi_col)24 static INLINE int get_segment_id(const CommonModeInfoParams *const mi_params,
25 const uint8_t *segment_ids, BLOCK_SIZE bsize,
26 int mi_row, int mi_col) {
27 const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
28 const int bw = mi_size_wide[bsize];
29 const int bh = mi_size_high[bsize];
30 const int xmis = AOMMIN(mi_params->mi_cols - mi_col, bw);
31 const int ymis = AOMMIN(mi_params->mi_rows - mi_row, bh);
32 int segment_id = MAX_SEGMENTS;
33
34 for (int y = 0; y < ymis; ++y) {
35 for (int x = 0; x < xmis; ++x) {
36 segment_id = AOMMIN(segment_id,
37 segment_ids[mi_offset + y * mi_params->mi_cols + x]);
38 }
39 }
40
41 assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
42 return segment_id;
43 }
44
av1_get_spatial_seg_pred(const AV1_COMMON * const cm,const MACROBLOCKD * const xd,int * cdf_index)45 static INLINE int av1_get_spatial_seg_pred(const AV1_COMMON *const cm,
46 const MACROBLOCKD *const xd,
47 int *cdf_index) {
48 int prev_ul = -1; // top left segment_id
49 int prev_l = -1; // left segment_id
50 int prev_u = -1; // top segment_id
51 const int mi_row = xd->mi_row;
52 const int mi_col = xd->mi_col;
53 const CommonModeInfoParams *const mi_params = &cm->mi_params;
54 const uint8_t *seg_map = cm->cur_frame->seg_map;
55 if ((xd->up_available) && (xd->left_available)) {
56 prev_ul =
57 get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 1, mi_col - 1);
58 }
59 if (xd->up_available) {
60 prev_u =
61 get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 1, mi_col - 0);
62 }
63 if (xd->left_available) {
64 prev_l =
65 get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 0, mi_col - 1);
66 }
67 // This property follows from the fact that get_segment_id() returns a
68 // nonnegative value. This allows us to test for all edge cases with a simple
69 // prev_ul < 0 check.
70 assert(IMPLIES(prev_ul >= 0, prev_u >= 0 && prev_l >= 0));
71
72 // Pick CDF index based on number of matching/out-of-bounds segment IDs.
73 if (prev_ul < 0) /* Edge cases */
74 *cdf_index = 0;
75 else if ((prev_ul == prev_u) && (prev_ul == prev_l))
76 *cdf_index = 2;
77 else if ((prev_ul == prev_u) || (prev_ul == prev_l) || (prev_u == prev_l))
78 *cdf_index = 1;
79 else
80 *cdf_index = 0;
81
82 // If 2 or more are identical returns that as predictor, otherwise prev_l.
83 if (prev_u == -1) // edge case
84 return prev_l == -1 ? 0 : prev_l;
85 if (prev_l == -1) // edge case
86 return prev_u;
87 return (prev_ul == prev_u) ? prev_u : prev_l;
88 }
89
av1_get_pred_context_seg_id(const MACROBLOCKD * xd)90 static INLINE int av1_get_pred_context_seg_id(const MACROBLOCKD *xd) {
91 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
92 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
93 const int above_sip = (above_mi != NULL) ? above_mi->seg_id_predicted : 0;
94 const int left_sip = (left_mi != NULL) ? left_mi->seg_id_predicted : 0;
95
96 return above_sip + left_sip;
97 }
98
get_comp_index_context(const AV1_COMMON * cm,const MACROBLOCKD * xd)99 static INLINE int get_comp_index_context(const AV1_COMMON *cm,
100 const MACROBLOCKD *xd) {
101 MB_MODE_INFO *mbmi = xd->mi[0];
102 const RefCntBuffer *const bck_buf = get_ref_frame_buf(cm, mbmi->ref_frame[0]);
103 const RefCntBuffer *const fwd_buf = get_ref_frame_buf(cm, mbmi->ref_frame[1]);
104 int bck_frame_index = 0, fwd_frame_index = 0;
105 int cur_frame_index = cm->cur_frame->order_hint;
106
107 if (bck_buf != NULL) bck_frame_index = bck_buf->order_hint;
108 if (fwd_buf != NULL) fwd_frame_index = fwd_buf->order_hint;
109
110 int fwd = abs(get_relative_dist(&cm->seq_params.order_hint_info,
111 fwd_frame_index, cur_frame_index));
112 int bck = abs(get_relative_dist(&cm->seq_params.order_hint_info,
113 cur_frame_index, bck_frame_index));
114
115 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
116 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
117
118 int above_ctx = 0, left_ctx = 0;
119 const int offset = (fwd == bck);
120
121 if (above_mi != NULL) {
122 if (has_second_ref(above_mi))
123 above_ctx = above_mi->compound_idx;
124 else if (above_mi->ref_frame[0] == ALTREF_FRAME)
125 above_ctx = 1;
126 }
127
128 if (left_mi != NULL) {
129 if (has_second_ref(left_mi))
130 left_ctx = left_mi->compound_idx;
131 else if (left_mi->ref_frame[0] == ALTREF_FRAME)
132 left_ctx = 1;
133 }
134
135 return above_ctx + left_ctx + 3 * offset;
136 }
137
get_comp_group_idx_context(const MACROBLOCKD * xd)138 static INLINE int get_comp_group_idx_context(const MACROBLOCKD *xd) {
139 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
140 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
141 int above_ctx = 0, left_ctx = 0;
142
143 if (above_mi) {
144 if (has_second_ref(above_mi))
145 above_ctx = above_mi->comp_group_idx;
146 else if (above_mi->ref_frame[0] == ALTREF_FRAME)
147 above_ctx = 3;
148 }
149 if (left_mi) {
150 if (has_second_ref(left_mi))
151 left_ctx = left_mi->comp_group_idx;
152 else if (left_mi->ref_frame[0] == ALTREF_FRAME)
153 left_ctx = 3;
154 }
155
156 return AOMMIN(5, above_ctx + left_ctx);
157 }
158
av1_get_pred_cdf_seg_id(struct segmentation_probs * segp,const MACROBLOCKD * xd)159 static INLINE aom_cdf_prob *av1_get_pred_cdf_seg_id(
160 struct segmentation_probs *segp, const MACROBLOCKD *xd) {
161 return segp->pred_cdf[av1_get_pred_context_seg_id(xd)];
162 }
163
av1_get_skip_mode_context(const MACROBLOCKD * xd)164 static INLINE int av1_get_skip_mode_context(const MACROBLOCKD *xd) {
165 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
166 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
167 const int above_skip_mode = above_mi ? above_mi->skip_mode : 0;
168 const int left_skip_mode = left_mi ? left_mi->skip_mode : 0;
169 return above_skip_mode + left_skip_mode;
170 }
171
av1_get_skip_context(const MACROBLOCKD * xd)172 static INLINE int av1_get_skip_context(const MACROBLOCKD *xd) {
173 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
174 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
175 const int above_skip = above_mi ? above_mi->skip : 0;
176 const int left_skip = left_mi ? left_mi->skip : 0;
177 return above_skip + left_skip;
178 }
179
180 int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir);
181
182 // Get a list of palette base colors that are used in the above and left blocks,
183 // referred to as "color cache". The return value is the number of colors in the
184 // cache (<= 2 * PALETTE_MAX_SIZE). The color values are stored in "cache"
185 // in ascending order.
186 int av1_get_palette_cache(const MACROBLOCKD *const xd, int plane,
187 uint16_t *cache);
188
av1_get_palette_bsize_ctx(BLOCK_SIZE bsize)189 static INLINE int av1_get_palette_bsize_ctx(BLOCK_SIZE bsize) {
190 assert(bsize < BLOCK_SIZES_ALL);
191 return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8];
192 }
193
av1_get_palette_mode_ctx(const MACROBLOCKD * xd)194 static INLINE int av1_get_palette_mode_ctx(const MACROBLOCKD *xd) {
195 const MB_MODE_INFO *const above_mi = xd->above_mbmi;
196 const MB_MODE_INFO *const left_mi = xd->left_mbmi;
197 int ctx = 0;
198 if (above_mi) ctx += (above_mi->palette_mode_info.palette_size[0] > 0);
199 if (left_mi) ctx += (left_mi->palette_mode_info.palette_size[0] > 0);
200 return ctx;
201 }
202
203 int av1_get_intra_inter_context(const MACROBLOCKD *xd);
204
205 int av1_get_reference_mode_context(const MACROBLOCKD *xd);
206
av1_get_reference_mode_cdf(const MACROBLOCKD * xd)207 static INLINE aom_cdf_prob *av1_get_reference_mode_cdf(const MACROBLOCKD *xd) {
208 return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context(xd)];
209 }
210
av1_get_skip_cdf(const MACROBLOCKD * xd)211 static INLINE aom_cdf_prob *av1_get_skip_cdf(const MACROBLOCKD *xd) {
212 return xd->tile_ctx->skip_cdfs[av1_get_skip_context(xd)];
213 }
214
215 int av1_get_comp_reference_type_context(const MACROBLOCKD *xd);
216
217 // == Uni-directional contexts ==
218
219 int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd);
220
221 int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd);
222
223 int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd);
224
av1_get_comp_reference_type_cdf(const MACROBLOCKD * xd)225 static INLINE aom_cdf_prob *av1_get_comp_reference_type_cdf(
226 const MACROBLOCKD *xd) {
227 const int pred_context = av1_get_comp_reference_type_context(xd);
228 return xd->tile_ctx->comp_ref_type_cdf[pred_context];
229 }
230
av1_get_pred_cdf_uni_comp_ref_p(const MACROBLOCKD * xd)231 static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p(
232 const MACROBLOCKD *xd) {
233 const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
234 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
235 }
236
av1_get_pred_cdf_uni_comp_ref_p1(const MACROBLOCKD * xd)237 static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1(
238 const MACROBLOCKD *xd) {
239 const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
240 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
241 }
242
av1_get_pred_cdf_uni_comp_ref_p2(const MACROBLOCKD * xd)243 static INLINE aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2(
244 const MACROBLOCKD *xd) {
245 const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
246 return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
247 }
248
249 // == Bi-directional contexts ==
250
251 int av1_get_pred_context_comp_ref_p(const MACROBLOCKD *xd);
252
253 int av1_get_pred_context_comp_ref_p1(const MACROBLOCKD *xd);
254
255 int av1_get_pred_context_comp_ref_p2(const MACROBLOCKD *xd);
256
257 int av1_get_pred_context_comp_bwdref_p(const MACROBLOCKD *xd);
258
259 int av1_get_pred_context_comp_bwdref_p1(const MACROBLOCKD *xd);
260
av1_get_pred_cdf_comp_ref_p(const MACROBLOCKD * xd)261 static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p(const MACROBLOCKD *xd) {
262 const int pred_context = av1_get_pred_context_comp_ref_p(xd);
263 return xd->tile_ctx->comp_ref_cdf[pred_context][0];
264 }
265
av1_get_pred_cdf_comp_ref_p1(const MACROBLOCKD * xd)266 static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1(
267 const MACROBLOCKD *xd) {
268 const int pred_context = av1_get_pred_context_comp_ref_p1(xd);
269 return xd->tile_ctx->comp_ref_cdf[pred_context][1];
270 }
271
av1_get_pred_cdf_comp_ref_p2(const MACROBLOCKD * xd)272 static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2(
273 const MACROBLOCKD *xd) {
274 const int pred_context = av1_get_pred_context_comp_ref_p2(xd);
275 return xd->tile_ctx->comp_ref_cdf[pred_context][2];
276 }
277
av1_get_pred_cdf_comp_bwdref_p(const MACROBLOCKD * xd)278 static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p(
279 const MACROBLOCKD *xd) {
280 const int pred_context = av1_get_pred_context_comp_bwdref_p(xd);
281 return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
282 }
283
av1_get_pred_cdf_comp_bwdref_p1(const MACROBLOCKD * xd)284 static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p1(
285 const MACROBLOCKD *xd) {
286 const int pred_context = av1_get_pred_context_comp_bwdref_p1(xd);
287 return xd->tile_ctx->comp_bwdref_cdf[pred_context][1];
288 }
289
290 // == Single contexts ==
291
292 int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
293
294 int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
295
296 int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
297
298 int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
299
300 int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
301
302 int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd);
303
av1_get_pred_cdf_single_ref_p1(const MACROBLOCKD * xd)304 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p1(
305 const MACROBLOCKD *xd) {
306 return xd->tile_ctx
307 ->single_ref_cdf[av1_get_pred_context_single_ref_p1(xd)][0];
308 }
av1_get_pred_cdf_single_ref_p2(const MACROBLOCKD * xd)309 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p2(
310 const MACROBLOCKD *xd) {
311 return xd->tile_ctx
312 ->single_ref_cdf[av1_get_pred_context_single_ref_p2(xd)][1];
313 }
av1_get_pred_cdf_single_ref_p3(const MACROBLOCKD * xd)314 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p3(
315 const MACROBLOCKD *xd) {
316 return xd->tile_ctx
317 ->single_ref_cdf[av1_get_pred_context_single_ref_p3(xd)][2];
318 }
av1_get_pred_cdf_single_ref_p4(const MACROBLOCKD * xd)319 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p4(
320 const MACROBLOCKD *xd) {
321 return xd->tile_ctx
322 ->single_ref_cdf[av1_get_pred_context_single_ref_p4(xd)][3];
323 }
av1_get_pred_cdf_single_ref_p5(const MACROBLOCKD * xd)324 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p5(
325 const MACROBLOCKD *xd) {
326 return xd->tile_ctx
327 ->single_ref_cdf[av1_get_pred_context_single_ref_p5(xd)][4];
328 }
av1_get_pred_cdf_single_ref_p6(const MACROBLOCKD * xd)329 static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p6(
330 const MACROBLOCKD *xd) {
331 return xd->tile_ctx
332 ->single_ref_cdf[av1_get_pred_context_single_ref_p6(xd)][5];
333 }
334
335 // Returns a context number for the given MB prediction signal
336 // The mode info data structure has a one element border above and to the
337 // left of the entries corresponding to real blocks.
338 // The prediction flags in these dummy entries are initialized to 0.
get_tx_size_context(const MACROBLOCKD * xd)339 static INLINE int get_tx_size_context(const MACROBLOCKD *xd) {
340 const MB_MODE_INFO *mbmi = xd->mi[0];
341 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
342 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
343 const TX_SIZE max_tx_size = max_txsize_rect_lookup[mbmi->sb_type];
344 const int max_tx_wide = tx_size_wide[max_tx_size];
345 const int max_tx_high = tx_size_high[max_tx_size];
346 const int has_above = xd->up_available;
347 const int has_left = xd->left_available;
348
349 int above = xd->above_txfm_context[0] >= max_tx_wide;
350 int left = xd->left_txfm_context[0] >= max_tx_high;
351
352 if (has_above)
353 if (is_inter_block(above_mbmi))
354 above = block_size_wide[above_mbmi->sb_type] >= max_tx_wide;
355
356 if (has_left)
357 if (is_inter_block(left_mbmi))
358 left = block_size_high[left_mbmi->sb_type] >= max_tx_high;
359
360 if (has_above && has_left)
361 return (above + left);
362 else if (has_above)
363 return above;
364 else if (has_left)
365 return left;
366 else
367 return 0;
368 }
369
370 #ifdef __cplusplus
371 } // extern "C"
372 #endif
373
374 #endif // AOM_AV1_COMMON_PRED_COMMON_H_
375