Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <math.h> |
| 13 | |
| 14 | #include "aom_ports/system_state.h" |
| 15 | |
| 16 | #include "av1/common/blockd.h" |
Jingning Han | a9eae87 | 2016-12-01 17:55:49 -0800 | [diff] [blame] | 17 | #include "av1/common/onyxc_int.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 18 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 19 | PREDICTION_MODE av1_left_block_mode(const MODE_INFO *cur_mi, |
| 20 | const MODE_INFO *left_mi, int b) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 21 | 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 Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 31 | PREDICTION_MODE av1_above_block_mode(const MODE_INFO *cur_mi, |
| 32 | const MODE_INFO *above_mi, int b) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 33 | 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 Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 43 | void av1_foreach_transformed_block_in_plane( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 44 | 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 47 | // 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 su | 0c6244b | 2017-07-12 17:11:43 -0700 | [diff] [blame] | 50 | const TX_SIZE tx_size = av1_get_tx_size(plane, xd); |
Jingning Han | 18c53c8 | 2017-02-17 14:49:57 -0800 | [diff] [blame] | 51 | const BLOCK_SIZE plane_bsize = |
| 52 | AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd)); |
Jingning Han | 95cff5c | 2016-10-25 09:47:02 -0700 | [diff] [blame] | 53 | 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 56 | 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 Han | a9eae87 | 2016-12-01 17:55:49 -0800 | [diff] [blame] | 61 | 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 63 | |
Jingning Han | 5b70174 | 2017-07-19 14:39:07 -0700 | [diff] [blame] | 64 | 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 72 | // 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 Han | 5b70174 | 2017-07-19 14:39:07 -0700 | [diff] [blame] | 74 | for (r = 0; r < max_blocks_high; r += mu_blocks_high) { |
Luc Trudeau | da9397a | 2017-07-21 12:00:22 -0400 | [diff] [blame] | 75 | const int unit_height = AOMMIN(mu_blocks_high + r, max_blocks_high); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 76 | // Skip visiting the sub blocks that are wholly within the UMV. |
Jingning Han | 5b70174 | 2017-07-19 14:39:07 -0700 | [diff] [blame] | 77 | for (c = 0; c < max_blocks_wide; c += mu_blocks_wide) { |
Jingning Han | 5b70174 | 2017-07-19 14:39:07 -0700 | [diff] [blame] | 78 | 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 85 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 86 | } |
| 87 | } |
| 88 | |
Angie Chiang | 0397eda | 2017-03-15 16:57:14 -0700 | [diff] [blame] | 89 | #if CONFIG_LV_MAP |
| 90 | void av1_foreach_transformed_block(const MACROBLOCKD *const xd, |
Jingning Han | 94652b8 | 2017-04-04 09:45:02 -0700 | [diff] [blame] | 91 | BLOCK_SIZE bsize, int mi_row, int mi_col, |
Angie Chiang | 0397eda | 2017-03-15 16:57:14 -0700 | [diff] [blame] | 92 | foreach_transformed_block_visitor visit, |
| 93 | void *arg) { |
| 94 | int plane; |
| 95 | |
Jingning Han | 94652b8 | 2017-04-04 09:45:02 -0700 | [diff] [blame] | 96 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
Jingning Han | d3a6443 | 2017-04-06 17:04:17 -0700 | [diff] [blame] | 97 | if (!is_chroma_reference(mi_row, mi_col, bsize, |
| 98 | xd->plane[plane].subsampling_x, |
| 99 | xd->plane[plane].subsampling_y)) |
Jingning Han | 94652b8 | 2017-04-04 09:45:02 -0700 | [diff] [blame] | 100 | continue; |
Angie Chiang | 0397eda | 2017-03-15 16:57:14 -0700 | [diff] [blame] | 101 | av1_foreach_transformed_block_in_plane(xd, bsize, plane, visit, arg); |
Jingning Han | 94652b8 | 2017-04-04 09:45:02 -0700 | [diff] [blame] | 102 | } |
Angie Chiang | 0397eda | 2017-03-15 16:57:14 -0700 | [diff] [blame] | 103 | } |
| 104 | #endif |
| 105 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 106 | void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd, |
Jingning Han | eee4315 | 2016-12-05 09:58:45 -0800 | [diff] [blame] | 107 | int plane, TX_SIZE tx_size, int has_eob, int aoff, |
| 108 | int loff) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 109 | ENTROPY_CONTEXT *const a = pd->above_context + aoff; |
| 110 | ENTROPY_CONTEXT *const l = pd->left_context + loff; |
Jingning Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 111 | const int txs_wide = tx_size_wide_unit[tx_size]; |
| 112 | const int txs_high = tx_size_high_unit[tx_size]; |
Jingning Han | d7d2047 | 2016-12-14 11:13:48 -0800 | [diff] [blame] | 113 | const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
Jingning Han | eee4315 | 2016-12-05 09:58:45 -0800 | [diff] [blame] | 114 | const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 115 | |
| 116 | // above |
| 117 | if (has_eob && xd->mb_to_right_edge < 0) { |
| 118 | int i; |
Jingning Han | eee4315 | 2016-12-05 09:58:45 -0800 | [diff] [blame] | 119 | const int blocks_wide = max_block_wide(xd, plane_bsize, plane); |
Jingning Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 120 | int above_contexts = txs_wide; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 121 | 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 Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 125 | for (i = above_contexts; i < txs_wide; ++i) a[i] = 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 126 | } else { |
Jingning Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 127 | memset(a, has_eob, sizeof(ENTROPY_CONTEXT) * txs_wide); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | // left |
| 131 | if (has_eob && xd->mb_to_bottom_edge < 0) { |
| 132 | int i; |
Jingning Han | eee4315 | 2016-12-05 09:58:45 -0800 | [diff] [blame] | 133 | const int blocks_high = max_block_high(xd, plane_bsize, plane); |
Jingning Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 134 | int left_contexts = txs_high; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 135 | 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 Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 138 | for (i = left_contexts; i < txs_high; ++i) l[i] = 0; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 139 | } else { |
Jingning Han | a59d71a | 2016-10-23 17:46:42 -0700 | [diff] [blame] | 140 | memset(l, has_eob, sizeof(ENTROPY_CONTEXT) * txs_high); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 141 | } |
| 142 | } |
Timothy B. Terriberry | a2d5cde | 2017-05-10 18:33:50 -0700 | [diff] [blame] | 143 | void av1_reset_skip_context(MACROBLOCKD *xd, int mi_row, int mi_col, |
| 144 | BLOCK_SIZE bsize) { |
| 145 | int i; |
| 146 | int nplanes; |
Timothy B. Terriberry | a2d5cde | 2017-05-10 18:33:50 -0700 | [diff] [blame] | 147 | 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. Terriberry | a2d5cde | 2017-05-10 18:33:50 -0700 | [diff] [blame] | 152 | for (i = 0; i < nplanes; i++) { |
| 153 | struct macroblockd_plane *const pd = &xd->plane[i]; |
Timothy B. Terriberry | a2d5cde | 2017-05-10 18:33:50 -0700 | [diff] [blame] | 154 | const BLOCK_SIZE plane_bsize = |
| 155 | AOMMAX(BLOCK_4X4, get_plane_block_size(bsize, pd)); |
Timothy B. Terriberry | a2d5cde | 2017-05-10 18:33:50 -0700 | [diff] [blame] | 156 | 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 Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 163 | void av1_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 164 | int i; |
| 165 | |
| 166 | for (i = 0; i < MAX_MB_PLANE; i++) { |
Luc Trudeau | 005feb6 | 2017-02-22 13:34:01 -0500 | [diff] [blame] | 167 | xd->plane[i].plane_type = get_plane_type(i); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 168 | 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 |
| 174 | const 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 183 | #endif // CONFIG_EXT_INTRA |