blob: c78831173b6d5dd9556ba8cf8c90896d3f6e0e3e [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
Yaowu Xuf883b422016-08-30 14:01:10 -070043void av1_foreach_transformed_block_in_plane(
Yaowu Xuc27fc142016-08-22 16:08:15 -070044 const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
45 foreach_transformed_block_visitor visit, void *arg) {
46 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -070047 // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
48 // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
49 // transform size varies per plane, look it up in a common way.
hui su0c6244b2017-07-12 17:11:43 -070050 const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
Jingning Han18c53c82017-02-17 14:49:57 -080051 const BLOCK_SIZE plane_bsize =
52 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
Jingning Han95cff5c2016-10-25 09:47:02 -070053 const uint8_t txw_unit = tx_size_wide_unit[tx_size];
54 const uint8_t txh_unit = tx_size_high_unit[tx_size];
55 const int step = txw_unit * txh_unit;
Yaowu Xuc27fc142016-08-22 16:08:15 -070056 int i = 0, r, c;
57
58 // If mb_to_right_edge is < 0 we are in a situation in which
59 // the current block size extends into the UMV and we won't
60 // visit the sub blocks that are wholly within the UMV.
Jingning Hana9eae872016-12-01 17:55:49 -080061 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
62 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -070063
Jingning Han5b701742017-07-19 14:39:07 -070064 int blk_row, blk_col;
65
66 const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
67 int mu_blocks_wide = block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
68 int mu_blocks_high = block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
69 mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
70 mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);
71
Yaowu Xuc27fc142016-08-22 16:08:15 -070072 // Keep track of the row and column of the blocks we use so that we know
73 // if we are in the unrestricted motion border.
Jingning Han5b701742017-07-19 14:39:07 -070074 for (r = 0; r < max_blocks_high; r += mu_blocks_high) {
Luc Trudeauda9397a2017-07-21 12:00:22 -040075 const int unit_height = AOMMIN(mu_blocks_high + r, max_blocks_high);
Yaowu Xuc27fc142016-08-22 16:08:15 -070076 // Skip visiting the sub blocks that are wholly within the UMV.
Jingning Han5b701742017-07-19 14:39:07 -070077 for (c = 0; c < max_blocks_wide; c += mu_blocks_wide) {
Jingning Han5b701742017-07-19 14:39:07 -070078 const int unit_width = AOMMIN(mu_blocks_wide + c, max_blocks_wide);
79 for (blk_row = r; blk_row < unit_height; blk_row += txh_unit) {
80 for (blk_col = c; blk_col < unit_width; blk_col += txw_unit) {
81 visit(plane, i, blk_row, blk_col, plane_bsize, tx_size, arg);
82 i += step;
83 }
84 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070085 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070086 }
87}
88
Angie Chiang0397eda2017-03-15 16:57:14 -070089#if CONFIG_LV_MAP
90void av1_foreach_transformed_block(const MACROBLOCKD *const xd,
Jingning Han94652b82017-04-04 09:45:02 -070091 BLOCK_SIZE bsize, int mi_row, int mi_col,
Angie Chiang0397eda2017-03-15 16:57:14 -070092 foreach_transformed_block_visitor visit,
93 void *arg) {
94 int plane;
95
Jingning Han94652b82017-04-04 09:45:02 -070096 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
Jingning Hand3a64432017-04-06 17:04:17 -070097 if (!is_chroma_reference(mi_row, mi_col, bsize,
98 xd->plane[plane].subsampling_x,
99 xd->plane[plane].subsampling_y))
Jingning Han94652b82017-04-04 09:45:02 -0700100 continue;
Angie Chiang0397eda2017-03-15 16:57:14 -0700101 av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg);
Jingning Han94652b82017-04-04 09:45:02 -0700102 }
Angie Chiang0397eda2017-03-15 16:57:14 -0700103}
104#endif
105
Yaowu Xuf883b422016-08-30 14:01:10 -0700106void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
Jingning Haneee43152016-12-05 09:58:45 -0800107 int plane, TX_SIZE tx_size, int has_eob, int aoff,
108 int loff) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700109 ENTROPY_CONTEXT *const a = pd->above_context + aoff;
110 ENTROPY_CONTEXT *const l = pd->left_context + loff;
Jingning Hana59d71a2016-10-23 17:46:42 -0700111 const int txs_wide = tx_size_wide_unit[tx_size];
112 const int txs_high = tx_size_high_unit[tx_size];
Jingning Hand7d20472016-12-14 11:13:48 -0800113 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
Jingning Haneee43152016-12-05 09:58:45 -0800114 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115
116 // above
117 if (has_eob && xd->mb_to_right_edge < 0) {
118 int i;
Jingning Haneee43152016-12-05 09:58:45 -0800119 const int blocks_wide = max_block_wide(xd, plane_bsize, plane);
Jingning Hana59d71a2016-10-23 17:46:42 -0700120 int above_contexts = txs_wide;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121 if (above_contexts + aoff > blocks_wide)
122 above_contexts = blocks_wide - aoff;
123
124 for (i = 0; i < above_contexts; ++i) a[i] = has_eob;
Jingning Hana59d71a2016-10-23 17:46:42 -0700125 for (i = above_contexts; i < txs_wide; ++i) a[i] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700126 } else {
Jingning Hana59d71a2016-10-23 17:46:42 -0700127 memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * txs_wide);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128 }
129
130 // left
131 if (has_eob && xd->mb_to_bottom_edge < 0) {
132 int i;
Jingning Haneee43152016-12-05 09:58:45 -0800133 const int blocks_high = max_block_high(xd, plane_bsize, plane);
Jingning Hana59d71a2016-10-23 17:46:42 -0700134 int left_contexts = txs_high;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135 if (left_contexts + loff > blocks_high) left_contexts = blocks_high - loff;
136
137 for (i = 0; i < left_contexts; ++i) l[i] = has_eob;
Jingning Hana59d71a2016-10-23 17:46:42 -0700138 for (i = left_contexts; i < txs_high; ++i) l[i] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700139 } else {
Jingning Hana59d71a2016-10-23 17:46:42 -0700140 memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * txs_high);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700141 }
142}
Timothy B. Terriberrya2d5cde2017-05-10 18:33:50 -0700143void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col,
144 BLOCK_SIZE bsize) {
145 int i;
146 int nplanes;
Timothy B. Terriberrya2d5cde2017-05-10 18:33:50 -0700147 int chroma_ref;
148 chroma_ref =
149 is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
150 xd->plane[1].subsampling_y);
151 nplanes = 1 + (MAX_MB_PLANE - 1) * chroma_ref;
Timothy B. Terriberrya2d5cde2017-05-10 18:33:50 -0700152 for (i = 0; i < nplanes; i++) {
153 struct macroblockd_plane *const pd = &xd->plane[i];
Timothy B. Terriberrya2d5cde2017-05-10 18:33:50 -0700154 const BLOCK_SIZE plane_bsize =
155 AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd));
Timothy B. Terriberrya2d5cde2017-05-10 18:33:50 -0700156 const int txs_wide = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
157 const int txs_high = block_size_high[plane_bsize] >> tx_size_high_log2[0];
158 memset(pd->above_context, 0, sizeof(ENTROPY_CONTEXT) * txs_wide);
159 memset(pd->left_context, 0, sizeof(ENTROPY_CONTEXT) * txs_high);
160 }
161}
162
Yaowu Xuf883b422016-08-30 14:01:10 -0700163void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700164 int i;
165
166 for (i = 0; i < MAX_MB_PLANE; i++) {
Luc Trudeau005feb62017-02-22 13:34:01 -0500167 xd->plane[i].plane_type = get_plane_type(i);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700168 xd->plane[i].subsampling_x = i ? ss_x : 0;
169 xd->plane[i].subsampling_y = i ? ss_y : 0;
170 }
171}
172
173#if CONFIG_EXT_INTRA
174const int16_t dr_intra_derivative[90] = {
175 1, 14666, 7330, 4884, 3660, 2926, 2435, 2084, 1821, 1616, 1451, 1317, 1204,
176 1108, 1026, 955, 892, 837, 787, 743, 703, 666, 633, 603, 574, 548,
177 524, 502, 481, 461, 443, 426, 409, 394, 379, 365, 352, 339, 327,
178 316, 305, 294, 284, 274, 265, 256, 247, 238, 230, 222, 214, 207,
179 200, 192, 185, 179, 172, 166, 159, 153, 147, 141, 136, 130, 124,
180 119, 113, 108, 103, 98, 93, 88, 83, 78, 73, 68, 63, 59,
181 54, 49, 45, 40, 35, 31, 26, 22, 17, 13, 8, 4,
182};
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183#endif // CONFIG_EXT_INTRA