blob: 4eb6f01eafa32d655b3cb71714d85d14a16d734e [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <math.h>
13
14#include "aom_ports/system_state.h"
15
16#include "av1/common/blockd.h"
Jingning Hana9eae872016-12-01 17:55:49 -080017#include "av1/common/onyxc_int.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070018
Yaowu Xuf883b422016-08-30 14:01:10 -070019PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi,
20 const MODE_INFO *left_mi, int b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070021 if (b == 0 || b == 2) {
22 if (!left_mi || is_inter_block(&left_mi->mbmi)) return DC_PRED;
23
24 return get_y_mode(left_mi, b + 1);
25 } else {
26 assert(b == 1 || b == 3);
27 return cur_mi->bmi[b - 1].as_mode;
28 }
29}
30
Yaowu Xuf883b422016-08-30 14:01:10 -070031PREDICTION_MODE av1_above_block_mode(const MODE_INFO *cur_mi,
32 const MODE_INFO *above_mi, int b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070033 if (b == 0 || b == 1) {
34 if (!above_mi || is_inter_block(&above_mi->mbmi)) return DC_PRED;
35
36 return get_y_mode(above_mi, b + 2);
37 } else {
38 assert(b == 2 || b == 3);
39 return cur_mi->bmi[b - 2].as_mode;
40 }
41}
42
iole moccagattaf25a4cf2016-11-11 23:57:57 -080043#if CONFIG_COEF_INTERLEAVE
44void av1_foreach_transformed_block_interleave(
45 const MACROBLOCKD *const xd, BLOCK_SIZE bsize,
46 foreach_transformed_block_visitor visit, void *arg) {
47 const struct macroblockd_plane *const pd_y = &xd->plane[0];
48 const struct macroblockd_plane *const pd_c = &xd->plane[1];
49 const MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
50
51 const TX_SIZE tx_log2_y = mbmi->tx_size;
52 const TX_SIZE tx_log2_c = get_uv_tx_size(mbmi, pd_c);
53 const int tx_sz_y = (1 << tx_log2_y);
54 const int tx_sz_c = (1 << tx_log2_c);
55
56 const BLOCK_SIZE plane_bsize_y = get_plane_block_size(bsize, pd_y);
57 const BLOCK_SIZE plane_bsize_c = get_plane_block_size(bsize, pd_c);
58
59 const int num_4x4_w_y = num_4x4_blocks_wide_lookup[plane_bsize_y];
60 const int num_4x4_w_c = num_4x4_blocks_wide_lookup[plane_bsize_c];
61 const int num_4x4_h_y = num_4x4_blocks_high_lookup[plane_bsize_y];
62 const int num_4x4_h_c = num_4x4_blocks_high_lookup[plane_bsize_c];
63
64 const int step_y = 1 << (tx_log2_y << 1);
65 const int step_c = 1 << (tx_log2_c << 1);
66
67 const int max_4x4_w_y =
68 get_max_4x4_size(num_4x4_w_y, xd->mb_to_right_edge, pd_y->subsampling_x);
69 const int max_4x4_h_y =
70 get_max_4x4_size(num_4x4_h_y, xd->mb_to_bottom_edge, pd_y->subsampling_y);
71
72 const int extra_step_y = ((num_4x4_w_y - max_4x4_w_y) >> tx_log2_y) * step_y;
73
74 const int max_4x4_w_c =
75 get_max_4x4_size(num_4x4_w_c, xd->mb_to_right_edge, pd_c->subsampling_x);
76 const int max_4x4_h_c =
77 get_max_4x4_size(num_4x4_h_c, xd->mb_to_bottom_edge, pd_c->subsampling_y);
78
79 const int extra_step_c = ((num_4x4_w_c - max_4x4_w_c) >> tx_log2_c) * step_c;
80
81 // The max_4x4_w/h may be smaller than tx_sz under some corner cases,
82 // i.e. when the SB is splitted by tile boundaries.
83 const int tu_num_w_y = (max_4x4_w_y + tx_sz_y - 1) / tx_sz_y;
84 const int tu_num_h_y = (max_4x4_h_y + tx_sz_y - 1) / tx_sz_y;
85 const int tu_num_w_c = (max_4x4_w_c + tx_sz_c - 1) / tx_sz_c;
86 const int tu_num_h_c = (max_4x4_h_c + tx_sz_c - 1) / tx_sz_c;
iole moccagattaf25a4cf2016-11-11 23:57:57 -080087 const int tu_num_c = tu_num_w_c * tu_num_h_c;
88
89 int tu_idx_c = 0;
90 int offset_y, row_y, col_y;
91 int offset_c, row_c, col_c;
92
93 for (row_y = 0; row_y < tu_num_h_y; row_y++) {
94 for (col_y = 0; col_y < tu_num_w_y; col_y++) {
95 // luma
96 offset_y = (row_y * tu_num_w_y + col_y) * step_y + row_y * extra_step_y;
97 visit(0, offset_y, row_y * tx_sz_y, col_y * tx_sz_y, plane_bsize_y,
98 tx_log2_y, arg);
99 // chroma
100 if (tu_idx_c < tu_num_c) {
101 row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
102 col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
103 offset_c = tu_idx_c * step_c + (tu_idx_c / tu_num_w_c) * extra_step_c;
104 visit(1, offset_c, row_c, col_c, plane_bsize_c, tx_log2_c, arg);
105 visit(2, offset_c, row_c, col_c, plane_bsize_c, tx_log2_c, arg);
106 tu_idx_c++;
107 }
108 }
109 }
110
111 // In 422 case, it's possible that Chroma has more TUs than Luma
112 while (tu_idx_c < tu_num_c) {
113 row_c = (tu_idx_c / tu_num_w_c) * tx_sz_c;
114 col_c = (tu_idx_c % tu_num_w_c) * tx_sz_c;
115 offset_c = tu_idx_c * step_c + row_c * extra_step_c;
116 visit(1, offset_c, row_c, col_c, plane_bsize_c, tx_log2_c, arg);
117 visit(2, offset_c, row_c, col_c, plane_bsize_c, tx_log2_c, arg);
118 tu_idx_c++;
119 }
120}
121#endif
122
Yaowu Xuf883b422016-08-30 14:01:10 -0700123void av1_foreach_transformed_block_in_plane(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
125 foreach_transformed_block_visitor visit, void *arg) {
126 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700127 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
128 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
129 // transform size varies per plane, look it up in a common way.
Angie Chiang7fcfee42017-02-24 15:51:03 -0800130 const TX_SIZE tx_size = get_tx_size(plane, xd);
Jingning Han31b6a4f2017-02-23 11:05:53 -0800131#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han18c53c82017-02-17 14:49:57 -0800132 const BLOCK_SIZE plane_bsize =
133 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
134#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Han18c53c82017-02-17 14:49:57 -0800136#endif
Jingning Han95cff5c2016-10-25 09:47:02 -0700137 const uint8_t txw_unit = tx_size_wide_unit[tx_size];
138 const uint8_t txh_unit = tx_size_high_unit[tx_size];
139 const int step = txw_unit * txh_unit;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140 int i = 0, r, c;
141
142 // If mb_to_right_edge is < 0 we are in a situation in which
143 // the current block size extends into the UMV and we won't
144 // visit the sub blocks that are wholly within the UMV.
Jingning Hana9eae872016-12-01 17:55:49 -0800145 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
146 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147
148 // Keep track of the row and column of the blocks we use so that we know
149 // if we are in the unrestricted motion border.
Jingning Han95cff5c2016-10-25 09:47:02 -0700150 for (r = 0; r < max_blocks_high; r += txh_unit) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700151 // Skip visiting the sub blocks that are wholly within the UMV.
Jingning Han95cff5c2016-10-25 09:47:02 -0700152 for (c = 0; c < max_blocks_wide; c += txw_unit) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700153 visit(plane, i, r, c, plane_bsize, tx_size, arg);
154 i += step;
155 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156 }
157}
158
Angie Chiang0397eda2017-03-15 16:57:14 -0700159#if CONFIG_LV_MAP
160void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
Jingning Han94652b82017-04-04 09:45:02 -0700161 BLOCK_SIZE bsize, int mi_row, int mi_col,
Angie Chiang0397eda2017-03-15 16:57:14 -0700162 foreach_transformed_block_visitor visit,
163 void *arg) {
164 int plane;
165
Jingning Han94652b82017-04-04 09:45:02 -0700166 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
167#if CONFIG_CB4X4
Jingning Hand3a64432017-04-06 17:04:17 -0700168 if (!is_chroma_reference(mi_row, mi_col, bsize,
169 xd->plane[plane].subsampling_x,
170 xd->plane[plane].subsampling_y))
Jingning Han94652b82017-04-04 09:45:02 -0700171 continue;
172#else
173 (void)mi_row;
174 (void)mi_col;
175#endif
Angie Chiang0397eda2017-03-15 16:57:14 -0700176 av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
Jingning Han94652b82017-04-04 09:45:02 -0700177 }
Angie Chiang0397eda2017-03-15 16:57:14 -0700178}
179#endif
180
Yushin Cho7a428ba2017-01-12 16:28:49 -0800181#if CONFIG_DAALA_DIST
182void av1_foreach_8x8_transformed_block_in_plane(
183 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
184 foreach_transformed_block_visitor visit,
185 foreach_transformed_block_visitor mi_visit, void *arg) {
186 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800187 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
188 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
189 // transform size varies per plane, look it up in a common way.
Angie Chiang7fcfee42017-02-24 15:51:03 -0800190 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yushin Cho7a428ba2017-01-12 16:28:49 -0800191 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
192 const uint8_t txw_unit = tx_size_wide_unit[tx_size];
193 const uint8_t txh_unit = tx_size_high_unit[tx_size];
194 const int step = txw_unit * txh_unit;
195 int i = 0, r, c;
196
197 // If mb_to_right_edge is < 0 we are in a situation in which
198 // the current block size extends into the UMV and we won't
199 // visit the sub blocks that are wholly within the UMV.
200 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
201 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
202
203 // Keep track of the row and column of the blocks we use so that we know
204 // if we are in the unrestricted motion border.
205 for (r = 0; r < max_blocks_high; r += txh_unit) {
206 // Skip visiting the sub blocks that are wholly within the UMV.
207 for (c = 0; c < max_blocks_wide; c += txw_unit) {
208 visit(plane, i, r, c, plane_bsize, tx_size, arg);
209 // Call whenever each 8x8 block is done
210 if ((r & 1) && (c & 1))
211 mi_visit(plane, i, r - 1, c - 1, plane_bsize, TX_8X8, arg);
212 i += step;
213 }
214 }
215}
216#endif
217
Jingning Hanab77e732017-02-28 15:20:59 -0800218#if !CONFIG_PVQ || CONFIG_VAR_TX
Yaowu Xuf883b422016-08-30 14:01:10 -0700219void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
Jingning Haneee43152016-12-05 09:58:45 -0800220 int plane, TX_SIZE tx_size, int has_eob, int aoff,
221 int loff) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 ENTROPY_CONTEXT *const a = pd->above_context + aoff;
223 ENTROPY_CONTEXT *const l = pd->left_context + loff;
Jingning Hana59d71a2016-10-23 17:46:42 -0700224 const int txs_wide = tx_size_wide_unit[tx_size];
225 const int txs_high = tx_size_high_unit[tx_size];
Jingning Hand7d20472016-12-14 11:13:48 -0800226#if CONFIG_CB4X4
227 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
228#else
Jingning Haneee43152016-12-05 09:58:45 -0800229 const BLOCK_SIZE bsize = AOMMAX(xd->mi[0]->mbmi.sb_type, BLOCK_8X8);
Jingning Hand7d20472016-12-14 11:13:48 -0800230#endif
Jingning Haneee43152016-12-05 09:58:45 -0800231 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700232
233 // above
234 if (has_eob && xd->mb_to_right_edge < 0) {
235 int i;
Jingning Haneee43152016-12-05 09:58:45 -0800236 const int blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Hana59d71a2016-10-23 17:46:42 -0700237 int above_contexts = txs_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700238 if (above_contexts + aoff > blocks_wide)
239 above_contexts = blocks_wide - aoff;
240
241 for (i = 0; i < above_contexts; ++i) a[i] = has_eob;
Jingning Hana59d71a2016-10-23 17:46:42 -0700242 for (i = above_contexts; i < txs_wide; ++i) a[i] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700243 } else {
Jingning Hana59d71a2016-10-23 17:46:42 -0700244 memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * txs_wide);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700245 }
246
247 // left
248 if (has_eob && xd->mb_to_bottom_edge < 0) {
249 int i;
Jingning Haneee43152016-12-05 09:58:45 -0800250 const int blocks_high = max_block_high(xd, plane_bsize, plane);
Jingning Hana59d71a2016-10-23 17:46:42 -0700251 int left_contexts = txs_high;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700252 if (left_contexts + loff > blocks_high) left_contexts = blocks_high - loff;
253
254 for (i = 0; i < left_contexts; ++i) l[i] = has_eob;
Jingning Hana59d71a2016-10-23 17:46:42 -0700255 for (i = left_contexts; i < txs_high; ++i) l[i] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256 } else {
Jingning Hana59d71a2016-10-23 17:46:42 -0700257 memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * txs_high);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258 }
259}
Yushin Cho77bba8d2016-11-04 16:36:56 -0700260#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700261
Yaowu Xuf883b422016-08-30 14:01:10 -0700262void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263 int i;
264
265 for (i = 0; i < MAX_MB_PLANE; i++) {
Luc Trudeau005feb62017-02-22 13:34:01 -0500266 xd->plane[i].plane_type = get_plane_type(i);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700267 xd->plane[i].subsampling_x = i ? ss_x : 0;
268 xd->plane[i].subsampling_y = i ? ss_y : 0;
269 }
270}
271
272#if CONFIG_EXT_INTRA
273const int16_t dr_intra_derivative[90] = {
274 1, 14666, 7330, 4884, 3660, 2926, 2435, 2084, 1821, 1616, 1451, 1317, 1204,
275 1108, 1026, 955, 892, 837, 787, 743, 703, 666, 633, 603, 574, 548,
276 524, 502, 481, 461, 443, 426, 409, 394, 379, 365, 352, 339, 327,
277 316, 305, 294, 284, 274, 265, 256, 247, 238, 230, 222, 214, 207,
278 200, 192, 185, 179, 172, 166, 159, 153, 147, 141, 136, 130, 124,
279 119, 113, 108, 103, 98, 93, 88, 83, 78, 73, 68, 63, 59,
280 54, 49, 45, 40, 35, 31, 26, 22, 17, 13, 8, 4,
281};
282
hui sueda3d762016-12-06 16:58:23 -0800283#if CONFIG_INTRA_INTERP
Yaowu Xuf883b422016-08-30 14:01:10 -0700284int av1_is_intra_filter_switchable(int angle) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700285 assert(angle > 0 && angle < 270);
286 if (angle % 45 == 0) return 0;
287 if (angle > 90 && angle < 180) {
288 return 1;
289 } else {
290 return ((angle < 90 ? dr_intra_derivative[angle]
291 : dr_intra_derivative[270 - angle]) &
292 0xFF) > 0;
293 }
294}
hui sueda3d762016-12-06 16:58:23 -0800295#endif // CONFIG_INTRA_INTERP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700296#endif // CONFIG_EXT_INTRA