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