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 <assert.h> |
| 13 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 14 | #include "./aom_scale_rtcd.h" |
| 15 | #include "./aom_dsp_rtcd.h" |
| 16 | #include "./aom_config.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 18 | #include "aom/aom_integer.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 19 | #include "aom_dsp/blend.h" |
| 20 | |
| 21 | #include "av1/common/blockd.h" |
| 22 | #include "av1/common/reconinter.h" |
| 23 | #include "av1/common/reconintra.h" |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 24 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 25 | #include "av1/common/onyxc_int.h" |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 26 | #endif // CONFIG_MOTION_VAR |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 27 | #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 28 | #include "av1/common/warped_motion.h" |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 29 | #endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 30 | |
| 31 | #if CONFIG_EXT_INTER |
| 32 | |
| 33 | #define NSMOOTHERS 1 |
| 34 | static int get_masked_weight(int m, int smoothness) { |
| 35 | #define SMOOTHER_LEN 32 |
| 36 | static const uint8_t smoothfn[NSMOOTHERS][2 * SMOOTHER_LEN + 1] = { { |
clang-format | 67948d3 | 2016-09-07 22:40:40 -0700 | [diff] [blame] | 37 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 7, 13, 21, 32, 43, |
| 39 | 51, 57, 60, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 40 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 41 | } }; |
| 42 | if (m < -SMOOTHER_LEN) |
| 43 | return 0; |
| 44 | else if (m > SMOOTHER_LEN) |
| 45 | return (1 << WEDGE_WEIGHT_BITS); |
| 46 | else |
| 47 | return smoothfn[smoothness][m + SMOOTHER_LEN]; |
| 48 | } |
| 49 | |
| 50 | // [smoother][negative][direction] |
clang-format | 67948d3 | 2016-09-07 22:40:40 -0700 | [diff] [blame] | 51 | DECLARE_ALIGNED(16, static uint8_t, |
| 52 | wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS] |
| 53 | [MASK_MASTER_SIZE * MASK_MASTER_SIZE]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 54 | |
| 55 | DECLARE_ALIGNED(16, static uint8_t, |
| 56 | wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]); |
| 57 | |
| 58 | // 3 * MAX_WEDGE_SQUARE is an easy to compute and fairly tight upper bound |
| 59 | // on the sum of all mask sizes up to an including MAX_WEDGE_SQUARE. |
| 60 | DECLARE_ALIGNED(16, static uint8_t, |
| 61 | wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]); |
| 62 | |
| 63 | static wedge_masks_type wedge_masks[BLOCK_SIZES][2]; |
| 64 | |
| 65 | // Some unused wedge codebooks left temporarily to facilitate experiments. |
| 66 | // To be removed when setteld. |
| 67 | static wedge_code_type wedge_codebook_8_hgtw[8] = { |
| 68 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 69 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 70 | { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 }, |
| 71 | { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 }, |
| 72 | }; |
| 73 | |
| 74 | static wedge_code_type wedge_codebook_8_hltw[8] = { |
| 75 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 76 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 77 | { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 }, |
| 78 | { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 }, |
| 79 | }; |
| 80 | |
| 81 | static wedge_code_type wedge_codebook_8_heqw[8] = { |
| 82 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 83 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 84 | { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 }, |
| 85 | { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 }, |
| 86 | }; |
| 87 | |
| 88 | #if !USE_LARGE_WEDGE_CODEBOOK |
| 89 | static const wedge_code_type wedge_codebook_16_hgtw[16] = { |
| 90 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 91 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 92 | { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 }, |
| 93 | { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 }, |
| 94 | { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 }, |
| 95 | { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 }, |
| 96 | { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 }, |
| 97 | { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 }, |
| 98 | }; |
| 99 | |
| 100 | static const wedge_code_type wedge_codebook_16_hltw[16] = { |
| 101 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 102 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 103 | { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 }, |
| 104 | { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 }, |
| 105 | { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 }, |
| 106 | { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 }, |
| 107 | { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 }, |
| 108 | { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 }, |
| 109 | }; |
| 110 | |
| 111 | static const wedge_code_type wedge_codebook_16_heqw[16] = { |
| 112 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 113 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 114 | { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 }, |
| 115 | { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 }, |
| 116 | { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 }, |
| 117 | { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 }, |
| 118 | { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 }, |
| 119 | { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 }, |
| 120 | }; |
| 121 | |
| 122 | const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = { |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 123 | #if CONFIG_CB4X4 |
| 124 | { 0, NULL, NULL, 0, NULL }, |
| 125 | { 0, NULL, NULL, 0, NULL }, |
| 126 | { 0, NULL, NULL, 0, NULL }, |
| 127 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 128 | { 0, NULL, NULL, 0, NULL }, |
| 129 | { 0, NULL, NULL, 0, NULL }, |
| 130 | { 0, NULL, NULL, 0, NULL }, |
| 131 | { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] }, |
| 132 | { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] }, |
| 133 | { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] }, |
| 134 | { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] }, |
| 135 | { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] }, |
| 136 | { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] }, |
| 137 | { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] }, |
| 138 | { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] }, |
| 139 | { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] }, |
| 140 | { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] }, |
| 141 | #if CONFIG_EXT_PARTITION |
| 142 | { 0, NULL, NULL, 0, NULL }, |
| 143 | { 0, NULL, NULL, 0, NULL }, |
| 144 | { 0, NULL, NULL, 0, NULL }, |
| 145 | #endif // CONFIG_EXT_PARTITION |
| 146 | }; |
| 147 | |
| 148 | #else |
| 149 | |
| 150 | static const wedge_code_type wedge_codebook_32_hgtw[32] = { |
| 151 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 152 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 153 | { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 }, |
| 154 | { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 }, |
| 155 | { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 }, |
| 156 | { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 }, |
| 157 | { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 }, |
| 158 | { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 }, |
| 159 | { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 }, |
| 160 | { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 }, |
| 161 | { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 }, |
| 162 | { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 }, |
| 163 | { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 }, |
| 164 | { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 }, |
| 165 | { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 }, |
| 166 | { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 }, |
| 167 | }; |
| 168 | |
| 169 | static const wedge_code_type wedge_codebook_32_hltw[32] = { |
| 170 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 171 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 172 | { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 }, |
| 173 | { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 }, |
| 174 | { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 }, |
| 175 | { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 }, |
| 176 | { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 }, |
| 177 | { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 }, |
| 178 | { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 }, |
| 179 | { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 }, |
| 180 | { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 }, |
| 181 | { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 }, |
| 182 | { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 }, |
| 183 | { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 }, |
| 184 | { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 }, |
| 185 | { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 }, |
| 186 | }; |
| 187 | |
| 188 | static const wedge_code_type wedge_codebook_32_heqw[32] = { |
| 189 | { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 }, |
| 190 | { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 }, |
| 191 | { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 }, |
| 192 | { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 }, |
| 193 | { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 }, |
| 194 | { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 }, |
| 195 | { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 }, |
| 196 | { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 }, |
| 197 | { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 }, |
| 198 | { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 }, |
| 199 | { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 }, |
| 200 | { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 }, |
| 201 | { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 }, |
| 202 | { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 }, |
| 203 | { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 }, |
| 204 | { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 }, |
| 205 | }; |
| 206 | |
| 207 | const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = { |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 208 | #if CONFIG_CB4X4 |
| 209 | { 0, NULL, NULL, 0, NULL }, |
| 210 | { 0, NULL, NULL, 0, NULL }, |
| 211 | { 0, NULL, NULL, 0, NULL }, |
| 212 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 213 | { 0, NULL, NULL, 0, NULL }, |
| 214 | { 0, NULL, NULL, 0, NULL }, |
| 215 | { 0, NULL, NULL, 0, NULL }, |
| 216 | { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] }, |
| 217 | { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] }, |
| 218 | { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] }, |
| 219 | { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] }, |
| 220 | { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] }, |
| 221 | { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] }, |
| 222 | { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] }, |
| 223 | { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] }, |
| 224 | { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] }, |
| 225 | { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] }, |
| 226 | #if CONFIG_EXT_PARTITION |
| 227 | { 0, NULL, NULL, 0, NULL }, |
| 228 | { 0, NULL, NULL, 0, NULL }, |
| 229 | { 0, NULL, NULL, 0, NULL }, |
| 230 | #endif // CONFIG_EXT_PARTITION |
| 231 | }; |
| 232 | #endif // USE_LARGE_WEDGE_CODEBOOK |
| 233 | |
| 234 | static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg, |
| 235 | BLOCK_SIZE sb_type) { |
| 236 | const uint8_t *master; |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 237 | const int bh = block_size_high[sb_type]; |
| 238 | const int bw = block_size_wide[sb_type]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 239 | const wedge_code_type *a = |
| 240 | wedge_params_lookup[sb_type].codebook + wedge_index; |
| 241 | const int smoother = wedge_params_lookup[sb_type].smoother; |
| 242 | int woff, hoff; |
| 243 | const uint8_t wsignflip = wedge_params_lookup[sb_type].signflip[wedge_index]; |
| 244 | |
| 245 | assert(wedge_index >= 0 && |
| 246 | wedge_index < (1 << get_wedge_bits_lookup(sb_type))); |
| 247 | woff = (a->x_offset * bw) >> 3; |
| 248 | hoff = (a->y_offset * bh) >> 3; |
| 249 | master = wedge_mask_obl[smoother][neg ^ wsignflip][a->direction] + |
| 250 | MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) + |
| 251 | MASK_MASTER_SIZE / 2 - woff; |
| 252 | return master; |
| 253 | } |
| 254 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 255 | const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign, |
| 256 | BLOCK_SIZE sb_type, int offset_x, |
| 257 | int offset_y) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 258 | const uint8_t *mask = |
| 259 | get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type); |
| 260 | if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE); |
| 261 | return mask; |
| 262 | } |
| 263 | |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 264 | #if CONFIG_COMPOUND_SEGMENT |
| 265 | static uint8_t *invert_mask(uint8_t *mask_inv_buffer, const uint8_t *const mask, |
| 266 | int h, int w, int stride) { |
| 267 | int i, j; |
| 268 | |
| 269 | for (i = 0; i < h; ++i) |
| 270 | for (j = 0; j < w; ++j) { |
| 271 | mask_inv_buffer[i * stride + j] = |
| 272 | AOM_BLEND_A64_MAX_ALPHA - mask[i * stride + j]; |
| 273 | } |
| 274 | return mask_inv_buffer; |
| 275 | } |
| 276 | #endif // CONFIG_COMPOUND_SEGMENT |
| 277 | |
| 278 | const uint8_t *av1_get_compound_type_mask_inverse( |
| 279 | const INTERINTER_COMPOUND_DATA *const comp_data, |
| 280 | #if CONFIG_COMPOUND_SEGMENT |
| 281 | uint8_t *mask_buffer, int h, int w, int stride, |
| 282 | #endif |
| 283 | BLOCK_SIZE sb_type) { |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 284 | assert(is_masked_compound_type(comp_data->type)); |
| 285 | switch (comp_data->type) { |
| 286 | case COMPOUND_WEDGE: |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 287 | return av1_get_contiguous_soft_mask(comp_data->wedge_index, |
| 288 | !comp_data->wedge_sign, sb_type); |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 289 | #if CONFIG_COMPOUND_SEGMENT |
| 290 | case COMPOUND_SEG: |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 291 | return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride); |
| 292 | #endif // CONFIG_COMPOUND_SEGMENT |
| 293 | default: assert(0); return NULL; |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | const uint8_t *av1_get_compound_type_mask( |
| 298 | const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) { |
| 299 | assert(is_masked_compound_type(comp_data->type)); |
| 300 | switch (comp_data->type) { |
| 301 | case COMPOUND_WEDGE: |
| 302 | return av1_get_contiguous_soft_mask(comp_data->wedge_index, |
| 303 | comp_data->wedge_sign, sb_type); |
| 304 | #if CONFIG_COMPOUND_SEGMENT |
| 305 | case COMPOUND_SEG: return comp_data->seg_mask; |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 306 | #endif // CONFIG_COMPOUND_SEGMENT |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 307 | default: assert(0); return NULL; |
| 308 | } |
| 309 | } |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 310 | |
| 311 | #if CONFIG_COMPOUND_SEGMENT |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 312 | #if COMPOUND_SEGMENT_TYPE == 0 |
| 313 | static void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type, |
| 314 | int h, int w, int mask_val) { |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 315 | int i, j; |
| 316 | int block_stride = block_size_wide[sb_type]; |
| 317 | for (i = 0; i < h; ++i) |
| 318 | for (j = 0; j < w; ++j) { |
| 319 | mask[i * block_stride + j] = |
| 320 | which_inverse ? AOM_BLEND_A64_MAX_ALPHA - mask_val : mask_val; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type, |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 325 | const uint8_t *src0, int src0_stride, |
| 326 | const uint8_t *src1, int src1_stride, |
| 327 | BLOCK_SIZE sb_type, int h, int w) { |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 328 | (void)src0; |
| 329 | (void)src1; |
| 330 | (void)src0_stride; |
| 331 | (void)src1_stride; |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 332 | switch (mask_type) { |
| 333 | case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break; |
| 334 | case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break; |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 335 | default: assert(0); |
| 336 | } |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 337 | } |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 338 | |
| 339 | #if CONFIG_AOM_HIGHBITDEPTH |
| 340 | void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type, |
| 341 | const uint8_t *src0, int src0_stride, |
| 342 | const uint8_t *src1, int src1_stride, |
| 343 | BLOCK_SIZE sb_type, int h, int w, int bd) { |
| 344 | (void)src0; |
| 345 | (void)src1; |
| 346 | (void)src0_stride; |
| 347 | (void)src1_stride; |
| 348 | (void)bd; |
| 349 | switch (mask_type) { |
| 350 | case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break; |
| 351 | case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break; |
| 352 | default: assert(0); |
| 353 | } |
| 354 | } |
| 355 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 356 | |
| 357 | #elif COMPOUND_SEGMENT_TYPE == 1 |
| 358 | #define DIFF_FACTOR 16 |
| 359 | static void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base, |
| 360 | const uint8_t *src0, int src0_stride, |
| 361 | const uint8_t *src1, int src1_stride, |
| 362 | BLOCK_SIZE sb_type, int h, int w) { |
| 363 | int i, j, m, diff; |
| 364 | int block_stride = block_size_wide[sb_type]; |
| 365 | for (i = 0; i < h; ++i) { |
| 366 | for (j = 0; j < w; ++j) { |
| 367 | diff = |
| 368 | abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]); |
| 369 | m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA); |
| 370 | mask[i * block_stride + j] = |
| 371 | which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m; |
| 372 | } |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type, |
| 377 | const uint8_t *src0, int src0_stride, |
| 378 | const uint8_t *src1, int src1_stride, |
| 379 | BLOCK_SIZE sb_type, int h, int w) { |
| 380 | switch (mask_type) { |
Yaowu Xu | a93e65e | 2017-01-24 10:58:48 -0800 | [diff] [blame] | 381 | case DIFFWTD_42: |
| 382 | diffwtd_mask(mask, 0, 42, src0, src0_stride, src1, src1_stride, sb_type, |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 383 | h, w); |
| 384 | break; |
Yaowu Xu | a93e65e | 2017-01-24 10:58:48 -0800 | [diff] [blame] | 385 | case DIFFWTD_42_INV: |
| 386 | diffwtd_mask(mask, 1, 42, src0, src0_stride, src1, src1_stride, sb_type, |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 387 | h, w); |
| 388 | break; |
| 389 | default: assert(0); |
| 390 | } |
| 391 | } |
| 392 | |
| 393 | #if CONFIG_AOM_HIGHBITDEPTH |
| 394 | static void diffwtd_mask_highbd(uint8_t *mask, int which_inverse, int mask_base, |
| 395 | const uint16_t *src0, int src0_stride, |
| 396 | const uint16_t *src1, int src1_stride, |
| 397 | BLOCK_SIZE sb_type, int h, int w, int bd) { |
| 398 | int i, j, m, diff; |
| 399 | int block_stride = block_size_wide[sb_type]; |
| 400 | for (i = 0; i < h; ++i) { |
| 401 | for (j = 0; j < w; ++j) { |
| 402 | diff = abs((int)src0[i * src0_stride + j] - |
| 403 | (int)src1[i * src1_stride + j]) >> |
| 404 | (bd - 8); |
| 405 | m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA); |
| 406 | mask[i * block_stride + j] = |
| 407 | which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m; |
| 408 | } |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type, |
| 413 | const uint8_t *src0, int src0_stride, |
| 414 | const uint8_t *src1, int src1_stride, |
| 415 | BLOCK_SIZE sb_type, int h, int w, int bd) { |
| 416 | switch (mask_type) { |
| 417 | case DIFFWTD_42: |
| 418 | diffwtd_mask_highbd(mask, 0, 42, CONVERT_TO_SHORTPTR(src0), src0_stride, |
| 419 | CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w, |
| 420 | bd); |
| 421 | break; |
| 422 | case DIFFWTD_42_INV: |
| 423 | diffwtd_mask_highbd(mask, 1, 42, CONVERT_TO_SHORTPTR(src0), src0_stride, |
| 424 | CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w, |
| 425 | bd); |
| 426 | break; |
| 427 | default: assert(0); |
| 428 | } |
| 429 | } |
| 430 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 431 | #endif // COMPOUND_SEGMENT_TYPE |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 432 | #endif // CONFIG_COMPOUND_SEGMENT |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 433 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 434 | static void init_wedge_master_masks() { |
| 435 | int i, j, s; |
| 436 | const int w = MASK_MASTER_SIZE; |
| 437 | const int h = MASK_MASTER_SIZE; |
| 438 | const int stride = MASK_MASTER_STRIDE; |
| 439 | const int a[2] = { 2, 1 }; |
| 440 | const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]); |
| 441 | for (s = 0; s < NSMOOTHERS; s++) { |
| 442 | for (i = 0; i < h; ++i) |
| 443 | for (j = 0; j < w; ++j) { |
| 444 | int x = (2 * j + 1 - w); |
| 445 | int y = (2 * i + 1 - h); |
| 446 | int m = (int)rint((a[0] * x + a[1] * y) / asqrt); |
| 447 | wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] = |
| 448 | wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] = |
| 449 | get_masked_weight(m, s); |
| 450 | wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] = |
| 451 | wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] = |
| 452 | (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s); |
| 453 | wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] = |
| 454 | wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] = |
| 455 | (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s); |
| 456 | wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] = |
| 457 | wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] = |
| 458 | get_masked_weight(m, s); |
| 459 | wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] = |
| 460 | wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] = |
| 461 | get_masked_weight(x, s); |
| 462 | wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] = |
| 463 | wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] = |
| 464 | (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s); |
| 465 | } |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | // If the signs for the wedges for various blocksizes are |
| 470 | // inconsistent flip the sign flag. Do it only once for every |
| 471 | // wedge codebook. |
| 472 | static void init_wedge_signs() { |
| 473 | BLOCK_SIZE sb_type; |
| 474 | memset(wedge_signflip_lookup, 0, sizeof(wedge_signflip_lookup)); |
| 475 | for (sb_type = BLOCK_4X4; sb_type < BLOCK_SIZES; ++sb_type) { |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 476 | const int bw = block_size_wide[sb_type]; |
| 477 | const int bh = block_size_high[sb_type]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 478 | const wedge_params_type wedge_params = wedge_params_lookup[sb_type]; |
| 479 | const int wbits = wedge_params.bits; |
| 480 | const int wtypes = 1 << wbits; |
| 481 | int i, w; |
| 482 | if (wbits == 0) continue; |
| 483 | for (w = 0; w < wtypes; ++w) { |
| 484 | const uint8_t *mask = get_wedge_mask_inplace(w, 0, sb_type); |
| 485 | int sum = 0; |
| 486 | for (i = 0; i < bw; ++i) sum += mask[i]; |
| 487 | for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE]; |
| 488 | sum = (sum + (bw + bh) / 2) / (bw + bh); |
| 489 | wedge_params.signflip[w] = (sum < 32); |
| 490 | } |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | static void init_wedge_masks() { |
| 495 | uint8_t *dst = wedge_mask_buf; |
| 496 | BLOCK_SIZE bsize; |
| 497 | memset(wedge_masks, 0, sizeof(wedge_masks)); |
| 498 | for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES; ++bsize) { |
| 499 | const uint8_t *mask; |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 500 | const int bw = block_size_wide[bsize]; |
| 501 | const int bh = block_size_high[bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 502 | const wedge_params_type *wedge_params = &wedge_params_lookup[bsize]; |
| 503 | const int wbits = wedge_params->bits; |
| 504 | const int wtypes = 1 << wbits; |
| 505 | int w; |
| 506 | if (wbits == 0) continue; |
| 507 | for (w = 0; w < wtypes; ++w) { |
| 508 | mask = get_wedge_mask_inplace(w, 0, bsize); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 509 | aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 510 | bh); |
| 511 | wedge_params->masks[0][w] = dst; |
| 512 | dst += bw * bh; |
| 513 | |
| 514 | mask = get_wedge_mask_inplace(w, 1, bsize); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 515 | aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 516 | bh); |
| 517 | wedge_params->masks[1][w] = dst; |
| 518 | dst += bw * bh; |
| 519 | } |
| 520 | assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf)); |
| 521 | } |
| 522 | } |
| 523 | |
| 524 | // Equation of line: f(x, y) = a[0]*(x - a[2]*w/8) + a[1]*(y - a[3]*h/8) = 0 |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 525 | void av1_init_wedge_masks() { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 526 | init_wedge_master_masks(); |
| 527 | init_wedge_signs(); |
| 528 | init_wedge_masks(); |
| 529 | } |
| 530 | |
| 531 | #if CONFIG_SUPERTX |
| 532 | static void build_masked_compound_wedge_extend( |
| 533 | uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride, |
| 534 | const uint8_t *src1, int src1_stride, int wedge_index, int wedge_sign, |
| 535 | BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w) { |
| 536 | const int subh = (2 << b_height_log2_lookup[sb_type]) == h; |
| 537 | const int subw = (2 << b_width_log2_lookup[sb_type]) == w; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 538 | const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type, |
| 539 | wedge_offset_x, wedge_offset_y); |
| 540 | aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 541 | mask, MASK_MASTER_STRIDE, h, w, subh, subw); |
| 542 | } |
| 543 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 544 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 545 | static void build_masked_compound_wedge_extend_highbd( |
| 546 | uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride, |
| 547 | const uint8_t *src1_8, int src1_stride, int wedge_index, int wedge_sign, |
| 548 | BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w, |
| 549 | int bd) { |
| 550 | const int subh = (2 << b_height_log2_lookup[sb_type]) == h; |
| 551 | const int subw = (2 << b_width_log2_lookup[sb_type]) == w; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 552 | const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type, |
| 553 | wedge_offset_x, wedge_offset_y); |
| 554 | aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 555 | src1_stride, mask, MASK_MASTER_STRIDE, h, w, subh, |
| 556 | subw, bd); |
| 557 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 558 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 559 | #endif // CONFIG_SUPERTX |
| 560 | |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 561 | static void build_masked_compound( |
| 562 | uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride, |
| 563 | const uint8_t *src1, int src1_stride, |
| 564 | const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h, |
| 565 | int w) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 566 | // Derive subsampling from h and w passed in. May be refactored to |
| 567 | // pass in subsampling factors directly. |
| 568 | const int subh = (2 << b_height_log2_lookup[sb_type]) == h; |
| 569 | const int subw = (2 << b_width_log2_lookup[sb_type]) == w; |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 570 | const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 571 | aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride, |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 572 | mask, block_size_wide[sb_type], h, w, subh, subw); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 573 | } |
| 574 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 575 | #if CONFIG_AOM_HIGHBITDEPTH |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 576 | static void build_masked_compound_highbd( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 577 | uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride, |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 578 | const uint8_t *src1_8, int src1_stride, |
| 579 | const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h, |
| 580 | int w, int bd) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 581 | // Derive subsampling from h and w passed in. May be refactored to |
| 582 | // pass in subsampling factors directly. |
| 583 | const int subh = (2 << b_height_log2_lookup[sb_type]) == h; |
| 584 | const int subw = (2 << b_width_log2_lookup[sb_type]) == w; |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 585 | const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type); |
| 586 | // const uint8_t *mask = |
| 587 | // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type); |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 588 | aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8, |
| 589 | src1_stride, mask, block_size_wide[sb_type], h, w, |
| 590 | subh, subw, bd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 591 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 592 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 593 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 594 | void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride, |
| 595 | uint8_t *dst, int dst_stride, |
| 596 | const int subpel_x, const int subpel_y, |
| 597 | const struct scale_factors *sf, int w, |
| 598 | int h, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 599 | #if CONFIG_DUAL_FILTER |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 600 | const InterpFilter *interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 601 | #else |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 602 | const InterpFilter interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 603 | #endif |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 604 | int xs, int ys, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 605 | #if CONFIG_SUPERTX |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 606 | int wedge_offset_x, int wedge_offset_y, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 607 | #endif // CONFIG_SUPERTX |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 608 | #if CONFIG_COMPOUND_SEGMENT |
| 609 | int plane, |
| 610 | #endif // CONFIG_COMPOUND_SEGMENT |
| 611 | MACROBLOCKD *xd) { |
| 612 | MODE_INFO *mi = xd->mi[0]; |
| 613 | INTERINTER_COMPOUND_DATA *comp_data = &mi->mbmi.interinter_compound_data; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 614 | // The prediction filter types used here should be those for |
| 615 | // the second reference block. |
| 616 | #if CONFIG_DUAL_FILTER |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 617 | InterpFilter tmp_ipf[4] = { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 618 | interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3], |
| 619 | }; |
| 620 | #else |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 621 | InterpFilter tmp_ipf = interp_filter; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 622 | #endif // CONFIG_DUAL_FILTER |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 623 | ConvolveParams conv_params = get_conv_params(0); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 624 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 625 | DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]); |
| 626 | uint8_t *tmp_dst = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
| 627 | ? CONVERT_TO_BYTEPTR(tmp_dst_) |
| 628 | : tmp_dst_; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 629 | av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 630 | subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys, |
| 631 | xd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 632 | #if CONFIG_SUPERTX |
| 633 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
| 634 | build_masked_compound_wedge_extend_highbd( |
| 635 | dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 636 | comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type, |
| 637 | wedge_offset_x, wedge_offset_y, h, w, xd->bd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 638 | else |
| 639 | build_masked_compound_wedge_extend( |
| 640 | dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 641 | comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type, |
| 642 | wedge_offset_x, wedge_offset_y, h, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 643 | #else |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 644 | #if CONFIG_COMPOUND_SEGMENT |
| 645 | if (!plane && comp_data->type == COMPOUND_SEG) { |
| 646 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
| 647 | build_compound_seg_mask_highbd(comp_data->seg_mask, comp_data->mask_type, |
| 648 | dst, dst_stride, tmp_dst, MAX_SB_SIZE, |
| 649 | mi->mbmi.sb_type, h, w, xd->bd); |
| 650 | else |
| 651 | build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst, |
| 652 | dst_stride, tmp_dst, MAX_SB_SIZE, |
| 653 | mi->mbmi.sb_type, h, w); |
| 654 | } |
| 655 | #endif // CONFIG_COMPOUND_SEGMENT |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 656 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 657 | build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst, |
| 658 | MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w, |
| 659 | xd->bd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 660 | else |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 661 | build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, |
| 662 | MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 663 | #endif // CONFIG_SUPERTX |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 664 | #else // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 665 | DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 666 | av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 667 | subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys, |
| 668 | xd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 669 | #if CONFIG_SUPERTX |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 670 | build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst, |
| 671 | MAX_SB_SIZE, comp_data->wedge_index, |
| 672 | comp_data->wedge_sign, mi->mbmi.sb_type, |
| 673 | wedge_offset_x, wedge_offset_y, h, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 674 | #else |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 675 | #if CONFIG_COMPOUND_SEGMENT |
| 676 | if (!plane && comp_data->type == COMPOUND_SEG) |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 677 | build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst, |
| 678 | dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type, |
| 679 | h, w); |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 680 | #endif // CONFIG_COMPOUND_SEGMENT |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 681 | build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, |
| 682 | comp_data, mi->mbmi.sb_type, h, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 683 | #endif // CONFIG_SUPERTX |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 684 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 685 | } |
| 686 | #endif // CONFIG_EXT_INTER |
| 687 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 688 | #if CONFIG_AOM_HIGHBITDEPTH |
| 689 | void av1_highbd_build_inter_predictor( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 690 | const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, |
| 691 | const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref, |
| 692 | #if CONFIG_DUAL_FILTER |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 693 | const InterpFilter *interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 694 | #else |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 695 | const InterpFilter interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 696 | #endif |
| 697 | enum mv_precision precision, int x, int y, int bd) { |
| 698 | const int is_q4 = precision == MV_PRECISION_Q4; |
| 699 | const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, |
| 700 | is_q4 ? src_mv->col : src_mv->col * 2 }; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 701 | MV32 mv = av1_scale_mv(&mv_q4, x, y, sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 702 | const int subpel_x = mv.col & SUBPEL_MASK; |
| 703 | const int subpel_y = mv.row & SUBPEL_MASK; |
| 704 | |
| 705 | src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); |
| 706 | |
| 707 | highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, |
| 708 | sf, w, h, ref, interp_filter, sf->x_step_q4, |
| 709 | sf->y_step_q4, bd); |
| 710 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 711 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 712 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 713 | void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst, |
| 714 | int dst_stride, const MV *src_mv, |
| 715 | const struct scale_factors *sf, int w, int h, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 716 | ConvolveParams *conv_params, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 717 | #if CONFIG_DUAL_FILTER |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 718 | const InterpFilter *interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 719 | #else |
James Zern | 7b9407a | 2016-05-18 23:48:05 -0700 | [diff] [blame] | 720 | const InterpFilter interp_filter, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 721 | #endif |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 722 | enum mv_precision precision, int x, int y) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 723 | const int is_q4 = precision == MV_PRECISION_Q4; |
| 724 | const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, |
| 725 | is_q4 ? src_mv->col : src_mv->col * 2 }; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 726 | MV32 mv = av1_scale_mv(&mv_q4, x, y, sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 727 | const int subpel_x = mv.col & SUBPEL_MASK; |
| 728 | const int subpel_y = mv.row & SUBPEL_MASK; |
| 729 | |
| 730 | src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS); |
| 731 | |
| 732 | inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 733 | h, conv_params, interp_filter, sf->x_step_q4, sf->y_step_q4); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 734 | } |
| 735 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 736 | typedef struct SubpelParams { |
| 737 | int xs; |
| 738 | int ys; |
| 739 | int subpel_x; |
| 740 | int subpel_y; |
| 741 | } SubpelParams; |
| 742 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 743 | void build_inter_predictors(MACROBLOCKD *xd, int plane, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 744 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 745 | int mi_col_offset, int mi_row_offset, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 746 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 747 | int block, int bw, int bh, int x, int y, int w, |
| 748 | int h, |
| 749 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 750 | int wedge_offset_x, int wedge_offset_y, |
| 751 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 752 | int mi_x, int mi_y) { |
| 753 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 754 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 755 | const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset]; |
Yue Chen | f27b160 | 2017-01-13 11:11:43 -0800 | [diff] [blame] | 756 | #if !CONFIG_CB4X4 |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 757 | const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0); |
Yue Chen | f27b160 | 2017-01-13 11:11:43 -0800 | [diff] [blame] | 758 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 759 | #else |
| 760 | const MODE_INFO *mi = xd->mi[0]; |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 761 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 762 | const int is_compound = has_second_ref(&mi->mbmi); |
| 763 | int ref; |
| 764 | #if CONFIG_GLOBAL_MOTION |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 765 | WarpedMotionParams *gm[2]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 766 | int is_global[2]; |
| 767 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 768 | gm[ref] = &xd->global_motion[mi->mbmi.ref_frame[ref]]; |
| 769 | is_global[ref] = |
Debargha Mukherjee | e3e0079 | 2016-11-13 11:35:44 -0800 | [diff] [blame] | 770 | (get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype > TRANSLATION); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 771 | } |
| 772 | // TODO(sarahparker) remove these once gm works with all experiments |
| 773 | (void)gm; |
| 774 | (void)is_global; |
| 775 | #endif // CONFIG_GLOBAL_MOTION |
| 776 | |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 777 | #if CONFIG_CB4X4 |
| 778 | (void)block; |
| 779 | #endif |
| 780 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 781 | // TODO(sarahparker) enable the use of DUAL_FILTER in warped motion functions |
| 782 | // in order to allow GLOBAL_MOTION and DUAL_FILTER to work together |
Jingning Han | 4600314 | 2016-11-02 14:57:11 -0700 | [diff] [blame] | 783 | #if CONFIG_SUB8X8_MC |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 784 | #if CONFIG_MOTION_VAR |
| 785 | if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) { |
| 786 | #else |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 787 | if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) { |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 788 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 789 | // block size in log2 |
| 790 | const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type]; |
| 791 | const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type]; |
| 792 | const int b8_sl = b_width_log2_lookup[BLOCK_8X8]; |
| 793 | |
| 794 | // block size |
| 795 | const int b4_w = 1 << b4_wl; |
| 796 | const int b4_h = 1 << b4_hl; |
| 797 | const int b8_s = 1 << b8_sl; |
| 798 | int idx, idy; |
| 799 | |
| 800 | const int x_base = x; |
| 801 | const int y_base = y; |
| 802 | |
| 803 | // processing unit size |
| 804 | const int x_step = w >> (b8_sl - b4_wl); |
| 805 | const int y_step = h >> (b8_sl - b4_hl); |
| 806 | |
| 807 | for (idy = 0; idy < b8_s; idy += b4_h) { |
| 808 | for (idx = 0; idx < b8_s; idx += b4_w) { |
| 809 | const int chr_idx = (idy * 2) + idx; |
| 810 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 811 | const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
| 812 | struct buf_2d *const pre_buf = &pd->pre[ref]; |
| 813 | struct buf_2d *const dst_buf = &pd->dst; |
| 814 | uint8_t *dst = dst_buf->buf; |
| 815 | const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv; |
| 816 | const MV mv_q4 = clamp_mv_to_umv_border_sb( |
| 817 | xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y); |
| 818 | uint8_t *pre; |
| 819 | MV32 scaled_mv; |
| 820 | int xs, ys, subpel_x, subpel_y; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 821 | const int is_scaled = av1_is_scaled(sf); |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 822 | ConvolveParams conv_params = get_conv_params(ref); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 823 | |
| 824 | x = x_base + idx * x_step; |
| 825 | y = y_base + idy * y_step; |
| 826 | |
| 827 | dst += dst_buf->stride * y + x; |
| 828 | |
| 829 | if (is_scaled) { |
| 830 | pre = |
| 831 | pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 832 | scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 833 | xs = sf->x_step_q4; |
| 834 | ys = sf->y_step_q4; |
| 835 | } else { |
| 836 | pre = pre_buf->buf + y * pre_buf->stride + x; |
| 837 | scaled_mv.row = mv_q4.row; |
| 838 | scaled_mv.col = mv_q4.col; |
| 839 | xs = ys = 16; |
| 840 | } |
| 841 | |
| 842 | subpel_x = scaled_mv.col & SUBPEL_MASK; |
| 843 | subpel_y = scaled_mv.row & SUBPEL_MASK; |
| 844 | pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride + |
| 845 | (scaled_mv.col >> SUBPEL_BITS); |
| 846 | |
| 847 | #if CONFIG_EXT_INTER |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 848 | if (ref && |
| 849 | is_masked_compound_type(mi->mbmi.interinter_compound_data.type)) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 850 | av1_make_masked_inter_predictor( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 851 | pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y, |
| 852 | sf, w, h, mi->mbmi.interp_filter, xs, ys, |
| 853 | #if CONFIG_SUPERTX |
| 854 | wedge_offset_x, wedge_offset_y, |
| 855 | #endif // CONFIG_SUPERTX |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 856 | #if CONFIG_COMPOUND_SEGMENT |
| 857 | plane, |
| 858 | #endif // CONFIG_COMPOUND_SEGMENT |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 859 | xd); |
| 860 | else |
| 861 | #endif // CONFIG_EXT_INTER |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 862 | av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride, |
| 863 | subpel_x, subpel_y, sf, x_step, y_step, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 864 | &conv_params, mi->mbmi.interp_filter, xs, |
| 865 | ys, xd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 866 | } |
| 867 | } |
| 868 | } |
| 869 | return; |
| 870 | } |
| 871 | #endif |
| 872 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 873 | { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 874 | struct buf_2d *const dst_buf = &pd->dst; |
| 875 | uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 876 | uint8_t *pre[2]; |
| 877 | MV32 scaled_mv[2]; |
| 878 | SubpelParams subpel_params[2]; |
Angie Chiang | 117aa0d | 2017-01-18 15:27:03 -0800 | [diff] [blame] | 879 | #if CONVOLVE_POST_ROUNDING |
| 880 | int32_t tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE]; |
| 881 | #endif // CONVOLVE_POST_ROUNDING |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 882 | |
| 883 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 884 | const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
| 885 | struct buf_2d *const pre_buf = &pd->pre[ref]; |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 886 | #if CONFIG_CB4X4 |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 887 | const MV mv = mi->mbmi.mv[ref].as_mv; |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 888 | #else |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 889 | const MV mv = |
| 890 | mi->mbmi.sb_type < BLOCK_8X8 |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 891 | #if CONFIG_MOTION_VAR |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 892 | ? (build_for_obmc ? mi->bmi[block].as_mv[ref].as_mv |
| 893 | : average_split_mvs(pd, mi, ref, block)) |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 894 | #else |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 895 | ? average_split_mvs(pd, mi, ref, block) |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 896 | #endif // CONFIG_MOTION_VAR |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 897 | : mi->mbmi.mv[ref].as_mv; |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 898 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 899 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 900 | // TODO(jkoleszar): This clamping is done in the incorrect place for the |
| 901 | // scaling case. It needs to be done on the scaled MV, not the pre-scaling |
| 902 | // MV. Note however that it performs the subsampling aware scaling so |
| 903 | // that the result is always q4. |
| 904 | // mv_precision precision is MV_PRECISION_Q4. |
| 905 | const MV mv_q4 = clamp_mv_to_umv_border_sb( |
| 906 | xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 907 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 908 | const int is_scaled = av1_is_scaled(sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 909 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 910 | if (is_scaled) { |
| 911 | pre[ref] = |
| 912 | pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf); |
| 913 | scaled_mv[ref] = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); |
| 914 | subpel_params[ref].xs = sf->x_step_q4; |
| 915 | subpel_params[ref].ys = sf->y_step_q4; |
| 916 | } else { |
| 917 | pre[ref] = pre_buf->buf + (y * pre_buf->stride + x); |
| 918 | scaled_mv[ref].row = mv_q4.row; |
| 919 | scaled_mv[ref].col = mv_q4.col; |
| 920 | subpel_params[ref].xs = 16; |
| 921 | subpel_params[ref].ys = 16; |
| 922 | } |
| 923 | |
| 924 | subpel_params[ref].subpel_x = scaled_mv[ref].col & SUBPEL_MASK; |
| 925 | subpel_params[ref].subpel_y = scaled_mv[ref].row & SUBPEL_MASK; |
| 926 | pre[ref] += (scaled_mv[ref].row >> SUBPEL_BITS) * pre_buf->stride + |
| 927 | (scaled_mv[ref].col >> SUBPEL_BITS); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 928 | } |
| 929 | |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 930 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
| 931 | const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 932 | struct buf_2d *const pre_buf = &pd->pre[ref]; |
Angie Chiang | 117aa0d | 2017-01-18 15:27:03 -0800 | [diff] [blame] | 933 | #if CONVOLVE_POST_ROUNDING |
| 934 | ConvolveParams conv_params = |
| 935 | get_conv_params_no_round(ref, tmp_dst, MAX_SB_SIZE); |
| 936 | #else |
| 937 | ConvolveParams conv_params = get_conv_params(ref); |
| 938 | #endif // CONVOLVE_POST_ROUNDING |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 939 | #if CONFIG_EXT_INTER |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 940 | if (ref && |
| 941 | is_masked_compound_type(mi->mbmi.interinter_compound_data.type)) |
| 942 | av1_make_masked_inter_predictor( |
| 943 | pre[ref], pre_buf->stride, dst, dst_buf->stride, |
| 944 | subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h, |
| 945 | mi->mbmi.interp_filter, subpel_params[ref].xs, |
| 946 | subpel_params[ref].ys, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 947 | #if CONFIG_SUPERTX |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 948 | wedge_offset_x, wedge_offset_y, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 949 | #endif // CONFIG_SUPERTX |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 950 | #if CONFIG_COMPOUND_SEGMENT |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 951 | plane, |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 952 | #endif // CONFIG_COMPOUND_SEGMENT |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 953 | xd); |
| 954 | else |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 955 | #else // CONFIG_EXT_INTER |
| 956 | #if CONFIG_GLOBAL_MOTION |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 957 | if (is_global[ref]) |
| 958 | av1_warp_plane(gm[ref], |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 959 | #if CONFIG_AOM_HIGHBITDEPTH |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 960 | xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 961 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 962 | pre_buf->buf0, pre_buf->width, pre_buf->height, |
| 963 | pre_buf->stride, dst, (mi_x >> pd->subsampling_x) + x, |
| 964 | (mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride, |
| 965 | pd->subsampling_x, pd->subsampling_y, |
| 966 | subpel_params[ref].xs, subpel_params[ref].ys, ref); |
| 967 | else |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 968 | #endif // CONFIG_GLOBAL_MOTION |
| 969 | #endif // CONFIG_EXT_INTER |
Angie Chiang | 907230e | 2017-01-17 17:39:14 -0800 | [diff] [blame] | 970 | av1_make_inter_predictor( |
| 971 | pre[ref], pre_buf->stride, dst, dst_buf->stride, |
| 972 | subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h, |
| 973 | &conv_params, mi->mbmi.interp_filter, subpel_params[ref].xs, |
| 974 | subpel_params[ref].ys, xd); |
| 975 | } |
Angie Chiang | 117aa0d | 2017-01-18 15:27:03 -0800 | [diff] [blame] | 976 | |
| 977 | #if CONVOLVE_POST_ROUNDING |
Angie Chiang | 5429419 | 2017-01-20 17:27:13 -0800 | [diff] [blame] | 978 | // TODO(angiebird): This part needs optimization |
| 979 | #if CONFIG_AOM_HIGHBITDEPTH |
| 980 | if (!(xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)) |
| 981 | av1_convolve_rounding(tmp_dst, MAX_SB_SIZE, dst, dst_buf->stride, w, h); |
| 982 | #else |
Angie Chiang | 117aa0d | 2017-01-18 15:27:03 -0800 | [diff] [blame] | 983 | av1_convolve_rounding(tmp_dst, MAX_SB_SIZE, dst, dst_buf->stride, w, h); |
Angie Chiang | 5429419 | 2017-01-20 17:27:13 -0800 | [diff] [blame] | 984 | #endif |
Angie Chiang | 117aa0d | 2017-01-18 15:27:03 -0800 | [diff] [blame] | 985 | #endif // CONVOLVE_POST_ROUNDING |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 986 | } |
| 987 | } |
| 988 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 989 | void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir, |
| 990 | int ic, int mi_row, int mi_col) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 991 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 992 | MODE_INFO *const mi = xd->mi[0]; |
| 993 | const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd); |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 994 | const int width = block_size_wide[plane_bsize]; |
| 995 | const int height = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 996 | uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2]; |
| 997 | int ref; |
| 998 | const int is_compound = has_second_ref(&mi->mbmi); |
| 999 | |
| 1000 | for (ref = 0; ref < 1 + is_compound; ++ref) { |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 1001 | ConvolveParams conv_params = get_conv_params(ref); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1002 | const uint8_t *pre = |
| 1003 | &pd->pre[ref].buf[(ir * pd->pre[ref].stride + ic) << 2]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1004 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1005 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1006 | av1_highbd_build_inter_predictor( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1007 | pre, pd->pre[ref].stride, dst, pd->dst.stride, |
| 1008 | &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height, |
| 1009 | ref, mi->mbmi.interp_filter, MV_PRECISION_Q3, |
| 1010 | mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir, xd->bd); |
| 1011 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1012 | av1_build_inter_predictor( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1013 | pre, pd->pre[ref].stride, dst, pd->dst.stride, |
| 1014 | &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 1015 | &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1016 | mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir); |
| 1017 | } |
| 1018 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1019 | av1_build_inter_predictor( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1020 | pre, pd->pre[ref].stride, dst, pd->dst.stride, |
| 1021 | &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 1022 | &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3, |
| 1023 | mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1024 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1025 | } |
| 1026 | } |
| 1027 | |
| 1028 | static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize, |
| 1029 | int mi_row, int mi_col, |
| 1030 | int plane_from, int plane_to) { |
| 1031 | int plane; |
| 1032 | const int mi_x = mi_col * MI_SIZE; |
| 1033 | const int mi_y = mi_row * MI_SIZE; |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 1034 | #if CONFIG_CB4X4 |
| 1035 | const int unify_bsize = 1; |
| 1036 | #else |
| 1037 | const int unify_bsize = 0; |
| 1038 | #endif |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1039 | for (plane = plane_from; plane <= plane_to; ++plane) { |
| 1040 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 1041 | const int bw = block_size_wide[bsize] >> pd->subsampling_x; |
| 1042 | const int bh = block_size_high[bsize] >> pd->subsampling_y; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1043 | |
Jingning Han | b46540c | 2016-12-14 10:59:20 -0800 | [diff] [blame] | 1044 | if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !unify_bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1045 | const PARTITION_TYPE bp = bsize - xd->mi[0]->mbmi.sb_type; |
| 1046 | const int have_vsplit = bp != PARTITION_HORZ; |
| 1047 | const int have_hsplit = bp != PARTITION_VERT; |
| 1048 | const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x); |
| 1049 | const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y); |
| 1050 | const int pw = 8 >> (have_vsplit | pd->subsampling_x); |
| 1051 | const int ph = 8 >> (have_hsplit | pd->subsampling_y); |
| 1052 | int x, y; |
| 1053 | assert(bp != PARTITION_NONE && bp < PARTITION_TYPES); |
| 1054 | assert(bsize == BLOCK_8X8); |
| 1055 | assert(pw * num_4x4_w == bw && ph * num_4x4_h == bh); |
| 1056 | for (y = 0; y < num_4x4_h; ++y) |
| 1057 | for (x = 0; x < num_4x4_w; ++x) |
| 1058 | build_inter_predictors(xd, plane, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1059 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1060 | 0, 0, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1061 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1062 | y * 2 + x, bw, bh, 4 * x, 4 * y, pw, ph, |
| 1063 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1064 | 0, 0, |
| 1065 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1066 | mi_x, mi_y); |
| 1067 | } else { |
| 1068 | build_inter_predictors(xd, plane, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1069 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1070 | 0, 0, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1071 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1072 | 0, bw, bh, 0, 0, bw, bh, |
| 1073 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1074 | 0, 0, |
| 1075 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1076 | mi_x, mi_y); |
| 1077 | } |
| 1078 | } |
| 1079 | } |
| 1080 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1081 | void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1082 | BUFFER_SET *ctx, BLOCK_SIZE bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1083 | build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0); |
| 1084 | #if CONFIG_EXT_INTER |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1085 | if (is_interintra_pred(&xd->mi[0]->mbmi)) { |
| 1086 | BUFFER_SET default_ctx = { { xd->plane[0].dst.buf, NULL, NULL }, |
| 1087 | { xd->plane[0].dst.stride, 0, 0 } }; |
| 1088 | if (!ctx) ctx = &default_ctx; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1089 | av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1090 | xd->plane[0].dst.stride, ctx, bsize); |
| 1091 | } |
| 1092 | #else |
| 1093 | (void)ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1094 | #endif // CONFIG_EXT_INTER |
| 1095 | } |
| 1096 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1097 | void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1098 | BUFFER_SET *ctx, BLOCK_SIZE bsize, |
| 1099 | int plane) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1100 | build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, plane, plane); |
| 1101 | #if CONFIG_EXT_INTER |
| 1102 | if (is_interintra_pred(&xd->mi[0]->mbmi)) { |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1103 | BUFFER_SET default_ctx = { |
| 1104 | { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf }, |
| 1105 | { xd->plane[0].dst.stride, xd->plane[1].dst.stride, |
| 1106 | xd->plane[2].dst.stride } |
| 1107 | }; |
| 1108 | if (!ctx) ctx = &default_ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1109 | if (plane == 0) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1110 | av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1111 | xd->plane[0].dst.stride, ctx, bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1112 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1113 | av1_build_interintra_predictors_sbc(xd, xd->plane[plane].dst.buf, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1114 | xd->plane[plane].dst.stride, ctx, |
| 1115 | plane, bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1116 | } |
| 1117 | } |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1118 | #else |
| 1119 | (void)ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1120 | #endif // CONFIG_EXT_INTER |
| 1121 | } |
| 1122 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1123 | void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1124 | BUFFER_SET *ctx, BLOCK_SIZE bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1125 | build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1, |
| 1126 | MAX_MB_PLANE - 1); |
| 1127 | #if CONFIG_EXT_INTER |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1128 | if (is_interintra_pred(&xd->mi[0]->mbmi)) { |
| 1129 | BUFFER_SET default_ctx = { |
| 1130 | { NULL, xd->plane[1].dst.buf, xd->plane[2].dst.buf }, |
| 1131 | { 0, xd->plane[1].dst.stride, xd->plane[2].dst.stride } |
| 1132 | }; |
| 1133 | if (!ctx) ctx = &default_ctx; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1134 | av1_build_interintra_predictors_sbuv( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1135 | xd, xd->plane[1].dst.buf, xd->plane[2].dst.buf, xd->plane[1].dst.stride, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1136 | xd->plane[2].dst.stride, ctx, bsize); |
| 1137 | } |
| 1138 | #else |
| 1139 | (void)ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1140 | #endif // CONFIG_EXT_INTER |
| 1141 | } |
| 1142 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1143 | void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1144 | BUFFER_SET *ctx, BLOCK_SIZE bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1145 | build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, |
| 1146 | MAX_MB_PLANE - 1); |
| 1147 | #if CONFIG_EXT_INTER |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1148 | if (is_interintra_pred(&xd->mi[0]->mbmi)) { |
| 1149 | BUFFER_SET default_ctx = { |
| 1150 | { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf }, |
| 1151 | { xd->plane[0].dst.stride, xd->plane[1].dst.stride, |
| 1152 | xd->plane[2].dst.stride } |
| 1153 | }; |
| 1154 | if (!ctx) ctx = &default_ctx; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1155 | av1_build_interintra_predictors( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1156 | xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf, |
| 1157 | xd->plane[0].dst.stride, xd->plane[1].dst.stride, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1158 | xd->plane[2].dst.stride, ctx, bsize); |
| 1159 | } |
| 1160 | #else |
| 1161 | (void)ctx; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1162 | #endif // CONFIG_EXT_INTER |
| 1163 | } |
| 1164 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1165 | void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE], |
| 1166 | const YV12_BUFFER_CONFIG *src, int mi_row, |
| 1167 | int mi_col) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1168 | uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer, |
| 1169 | src->v_buffer }; |
| 1170 | const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width, |
| 1171 | src->uv_crop_width }; |
| 1172 | const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height, |
| 1173 | src->uv_crop_height }; |
| 1174 | const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, |
| 1175 | src->uv_stride }; |
| 1176 | int i; |
| 1177 | |
| 1178 | for (i = 0; i < MAX_MB_PLANE; ++i) { |
| 1179 | struct macroblockd_plane *const pd = &planes[i]; |
| 1180 | setup_pred_plane(&pd->dst, buffers[i], widths[i], heights[i], strides[i], |
| 1181 | mi_row, mi_col, NULL, pd->subsampling_x, |
| 1182 | pd->subsampling_y); |
| 1183 | } |
| 1184 | } |
| 1185 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1186 | void av1_setup_pre_planes(MACROBLOCKD *xd, int idx, |
| 1187 | const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col, |
| 1188 | const struct scale_factors *sf) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1189 | if (src != NULL) { |
| 1190 | int i; |
| 1191 | uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer, |
| 1192 | src->v_buffer }; |
| 1193 | const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width, |
| 1194 | src->uv_crop_width }; |
| 1195 | const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height, |
| 1196 | src->uv_crop_height }; |
| 1197 | const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride, |
| 1198 | src->uv_stride }; |
| 1199 | for (i = 0; i < MAX_MB_PLANE; ++i) { |
| 1200 | struct macroblockd_plane *const pd = &xd->plane[i]; |
| 1201 | setup_pred_plane(&pd->pre[idx], buffers[i], widths[i], heights[i], |
| 1202 | strides[i], mi_row, mi_col, sf, pd->subsampling_x, |
| 1203 | pd->subsampling_y); |
| 1204 | } |
| 1205 | } |
| 1206 | } |
| 1207 | |
| 1208 | #if CONFIG_SUPERTX |
Jingning Han | feb517c | 2016-12-21 16:02:07 -0800 | [diff] [blame] | 1209 | #if CONFIG_CB4X4 |
Jingning Han | 9e0976a | 2016-12-27 17:52:42 -0800 | [diff] [blame] | 1210 | static const uint8_t mask_4[4] = { 64, 52, 12, 0 }; |
| 1211 | static const uint8_t mask_4_uv[4] = { 64, 52, 12, 0 }; |
Jingning Han | feb517c | 2016-12-21 16:02:07 -0800 | [diff] [blame] | 1212 | #endif // CONFIG_CB4X4 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1213 | static const uint8_t mask_8[8] = { 64, 64, 62, 52, 12, 2, 0, 0 }; |
| 1214 | |
| 1215 | static const uint8_t mask_16[16] = { 63, 62, 60, 58, 55, 50, 43, 36, |
| 1216 | 28, 21, 14, 9, 6, 4, 2, 1 }; |
| 1217 | |
| 1218 | static const uint8_t mask_32[32] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, |
| 1219 | 61, 57, 52, 45, 36, 28, 19, 12, 7, 3, 1, |
| 1220 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1221 | |
| 1222 | static const uint8_t mask_8_uv[8] = { 64, 64, 62, 52, 12, 2, 0, 0 }; |
| 1223 | |
| 1224 | static const uint8_t mask_16_uv[16] = { 64, 64, 64, 64, 61, 53, 45, 36, |
| 1225 | 28, 19, 11, 3, 0, 0, 0, 0 }; |
| 1226 | |
| 1227 | static const uint8_t mask_32_uv[32] = { 64, 64, 64, 64, 64, 64, 64, 64, |
| 1228 | 64, 64, 64, 64, 60, 54, 46, 36, |
| 1229 | 28, 18, 10, 4, 0, 0, 0, 0, |
| 1230 | 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 1231 | |
| 1232 | static const uint8_t *get_supertx_mask(int length, int plane) { |
| 1233 | switch (length) { |
Jingning Han | feb517c | 2016-12-21 16:02:07 -0800 | [diff] [blame] | 1234 | #if CONFIG_CB4X4 |
| 1235 | case 4: return plane ? mask_4_uv : mask_4; |
| 1236 | #endif // CONFIG_CB4X4 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1237 | case 8: return plane ? mask_8_uv : mask_8; |
| 1238 | case 16: return plane ? mask_16_uv : mask_16; |
| 1239 | case 32: return plane ? mask_32_uv : mask_32; |
| 1240 | default: assert(0); |
| 1241 | } |
| 1242 | return NULL; |
| 1243 | } |
| 1244 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1245 | void av1_build_masked_inter_predictor_complex( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1246 | MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre, |
| 1247 | int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori, |
| 1248 | BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition, |
| 1249 | int plane) { |
| 1250 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
| 1251 | const int ssx = pd->subsampling_x; |
| 1252 | const int ssy = pd->subsampling_y; |
Jingning Han | 9353124 | 2016-12-20 11:54:36 -0800 | [diff] [blame] | 1253 | const int top_w = block_size_wide[top_bsize] >> ssx; |
| 1254 | const int top_h = block_size_high[top_bsize] >> ssy; |
| 1255 | const int w = block_size_wide[bsize] >> ssx; |
| 1256 | const int h = block_size_high[bsize] >> ssy; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1257 | const int w_offset = ((mi_col - mi_col_ori) * MI_SIZE) >> ssx; |
| 1258 | const int h_offset = ((mi_row - mi_row_ori) * MI_SIZE) >> ssy; |
| 1259 | |
| 1260 | int w_remain, h_remain; |
| 1261 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1262 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1263 | const int is_hdb = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1264 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1265 | |
| 1266 | assert(bsize <= BLOCK_32X32); |
| 1267 | assert(IMPLIES(plane == 0, ssx == 0)); |
| 1268 | assert(IMPLIES(plane == 0, ssy == 0)); |
| 1269 | |
| 1270 | switch (partition) { |
| 1271 | case PARTITION_HORZ: { |
| 1272 | const uint8_t *const mask = get_supertx_mask(h, ssy); |
| 1273 | |
| 1274 | w_remain = top_w; |
| 1275 | h_remain = top_h - h_offset - h; |
| 1276 | dst += h_offset * dst_stride; |
| 1277 | pre += h_offset * pre_stride; |
| 1278 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1279 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1280 | if (is_hdb) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1281 | aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1282 | pre_stride, mask, h, top_w, xd->bd); |
| 1283 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1284 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1285 | aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre, pre_stride, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1286 | mask, h, top_w); |
| 1287 | |
| 1288 | dst += h * dst_stride; |
| 1289 | pre += h * pre_stride; |
| 1290 | break; |
| 1291 | } |
| 1292 | case PARTITION_VERT: { |
| 1293 | const uint8_t *const mask = get_supertx_mask(w, ssx); |
| 1294 | |
| 1295 | w_remain = top_w - w_offset - w; |
| 1296 | h_remain = top_h; |
| 1297 | dst += w_offset; |
| 1298 | pre += w_offset; |
| 1299 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1300 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1301 | if (is_hdb) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1302 | aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1303 | pre_stride, mask, top_h, w, xd->bd); |
| 1304 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1305 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1306 | aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre, pre_stride, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1307 | mask, top_h, w); |
| 1308 | |
| 1309 | dst += w; |
| 1310 | pre += w; |
| 1311 | break; |
| 1312 | } |
| 1313 | default: { |
| 1314 | assert(0); |
| 1315 | return; |
| 1316 | } |
| 1317 | } |
| 1318 | |
| 1319 | if (w_remain == 0 || h_remain == 0) { |
| 1320 | return; |
| 1321 | } |
| 1322 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1323 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1324 | if (is_hdb) { |
| 1325 | dst = (uint8_t *)CONVERT_TO_SHORTPTR(dst); |
| 1326 | pre = (const uint8_t *)CONVERT_TO_SHORTPTR(pre); |
| 1327 | dst_stride *= 2; |
| 1328 | pre_stride *= 2; |
| 1329 | w_remain *= 2; |
| 1330 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1331 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1332 | |
| 1333 | do { |
| 1334 | memcpy(dst, pre, w_remain * sizeof(uint8_t)); |
| 1335 | dst += dst_stride; |
| 1336 | pre += pre_stride; |
| 1337 | } while (--h_remain); |
| 1338 | } |
| 1339 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1340 | void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1341 | #if CONFIG_EXT_INTER |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1342 | int mi_row_ori, int mi_col_ori, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1343 | #endif // CONFIG_EXT_INTER |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1344 | int mi_row, int mi_col, |
| 1345 | BLOCK_SIZE bsize, int block) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1346 | // Prediction function used in supertx: |
| 1347 | // Use the mv at current block (which is less than 8x8) |
| 1348 | // to get prediction of a block located at (mi_row, mi_col) at size of bsize |
| 1349 | // bsize can be larger than 8x8. |
| 1350 | // block (0-3): the sub8x8 location of current block |
| 1351 | int plane; |
| 1352 | const int mi_x = mi_col * MI_SIZE; |
| 1353 | const int mi_y = mi_row * MI_SIZE; |
| 1354 | #if CONFIG_EXT_INTER |
| 1355 | const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE; |
| 1356 | const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE; |
| 1357 | #endif // CONFIG_EXT_INTER |
| 1358 | |
| 1359 | // For sub8x8 uv: |
| 1360 | // Skip uv prediction in supertx except the first block (block = 0) |
| 1361 | int max_plane = block ? 1 : MAX_MB_PLANE; |
| 1362 | |
| 1363 | for (plane = 0; plane < max_plane; plane++) { |
| 1364 | const BLOCK_SIZE plane_bsize = |
| 1365 | get_plane_block_size(bsize, &xd->plane[plane]); |
| 1366 | const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; |
| 1367 | const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; |
| 1368 | const int bw = 4 * num_4x4_w; |
| 1369 | const int bh = 4 * num_4x4_h; |
| 1370 | |
| 1371 | build_inter_predictors(xd, plane, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1372 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1373 | 0, 0, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1374 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1375 | block, bw, bh, 0, 0, bw, bh, |
| 1376 | #if CONFIG_EXT_INTER |
| 1377 | wedge_offset_x, wedge_offset_y, |
| 1378 | #endif // CONFIG_EXT_INTER |
| 1379 | mi_x, mi_y); |
| 1380 | } |
| 1381 | #if CONFIG_EXT_INTER |
Yaowu Xu | f4c904c | 2016-12-07 11:18:27 -0800 | [diff] [blame] | 1382 | if (is_interintra_pred(&xd->mi[0]->mbmi)) { |
| 1383 | BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf, |
| 1384 | xd->plane[2].dst.buf }, |
| 1385 | { xd->plane[0].dst.stride, xd->plane[1].dst.stride, |
| 1386 | xd->plane[2].dst.stride } }; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1387 | av1_build_interintra_predictors( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1388 | xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf, |
| 1389 | xd->plane[0].dst.stride, xd->plane[1].dst.stride, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 1390 | xd->plane[2].dst.stride, &ctx, bsize); |
Yaowu Xu | f4c904c | 2016-12-07 11:18:27 -0800 | [diff] [blame] | 1391 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1392 | #endif // CONFIG_EXT_INTER |
| 1393 | } |
| 1394 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1395 | void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1396 | #if CONFIG_EXT_INTER |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1397 | int mi_row_ori, int mi_col_ori, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1398 | #endif // CONFIG_EXT_INTER |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1399 | int mi_row, int mi_col, |
| 1400 | BLOCK_SIZE bsize) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1401 | int plane; |
| 1402 | const int mi_x = mi_col * MI_SIZE; |
| 1403 | const int mi_y = mi_row * MI_SIZE; |
| 1404 | #if CONFIG_EXT_INTER |
| 1405 | const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE; |
| 1406 | const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE; |
| 1407 | #endif // CONFIG_EXT_INTER |
| 1408 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
| 1409 | const BLOCK_SIZE plane_bsize = |
| 1410 | get_plane_block_size(bsize, &xd->plane[plane]); |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 1411 | const int bw = block_size_wide[plane_bsize]; |
| 1412 | const int bh = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1413 | |
Jingning Han | 002c814 | 2016-12-20 15:07:58 -0800 | [diff] [blame] | 1414 | build_inter_predictors(xd, plane, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1415 | #if CONFIG_MOTION_VAR |
Jingning Han | 002c814 | 2016-12-20 15:07:58 -0800 | [diff] [blame] | 1416 | 0, 0, |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1417 | #endif // CONFIG_MOTION_VAR |
Jingning Han | 002c814 | 2016-12-20 15:07:58 -0800 | [diff] [blame] | 1418 | 0, bw, bh, 0, 0, bw, bh, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1419 | #if CONFIG_EXT_INTER |
Jingning Han | 002c814 | 2016-12-20 15:07:58 -0800 | [diff] [blame] | 1420 | wedge_offset_x, wedge_offset_y, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1421 | #endif // CONFIG_EXT_INTER |
Jingning Han | 002c814 | 2016-12-20 15:07:58 -0800 | [diff] [blame] | 1422 | mi_x, mi_y); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1423 | } |
| 1424 | } |
| 1425 | #endif // CONFIG_SUPERTX |
| 1426 | |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 1427 | #if CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1428 | // obmc_mask_N[overlap_position] |
| 1429 | static const uint8_t obmc_mask_1[1] = { 55 }; |
| 1430 | |
| 1431 | static const uint8_t obmc_mask_2[2] = { 45, 62 }; |
| 1432 | |
| 1433 | static const uint8_t obmc_mask_4[4] = { 39, 50, 59, 64 }; |
| 1434 | |
| 1435 | static const uint8_t obmc_mask_8[8] = { 36, 42, 48, 53, 57, 61, 63, 64 }; |
| 1436 | |
| 1437 | static const uint8_t obmc_mask_16[16] = { 34, 37, 40, 43, 46, 49, 52, 54, |
| 1438 | 56, 58, 60, 61, 63, 64, 64, 64 }; |
| 1439 | |
| 1440 | static const uint8_t obmc_mask_32[32] = { 33, 35, 36, 38, 40, 41, 43, 44, |
| 1441 | 45, 47, 48, 50, 51, 52, 53, 55, |
| 1442 | 56, 57, 58, 59, 60, 60, 61, 62, |
| 1443 | 62, 63, 63, 64, 64, 64, 64, 64 }; |
| 1444 | |
| 1445 | #if CONFIG_EXT_PARTITION |
| 1446 | static const uint8_t obmc_mask_64[64] = { |
| 1447 | 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 44, |
| 1448 | 45, 46, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 53, 54, 55, 56, |
| 1449 | 56, 56, 57, 57, 58, 58, 59, 60, 60, 60, 60, 60, 61, 62, 62, 62, |
| 1450 | 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, |
| 1451 | }; |
| 1452 | #endif // CONFIG_EXT_PARTITION |
| 1453 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1454 | const uint8_t *av1_get_obmc_mask(int length) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1455 | switch (length) { |
| 1456 | case 1: return obmc_mask_1; |
| 1457 | case 2: return obmc_mask_2; |
| 1458 | case 4: return obmc_mask_4; |
| 1459 | case 8: return obmc_mask_8; |
| 1460 | case 16: return obmc_mask_16; |
| 1461 | case 32: return obmc_mask_32; |
| 1462 | #if CONFIG_EXT_PARTITION |
| 1463 | case 64: return obmc_mask_64; |
| 1464 | #endif // CONFIG_EXT_PARTITION |
| 1465 | default: assert(0); return NULL; |
| 1466 | } |
| 1467 | } |
| 1468 | |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 1469 | #if CONFIG_NCOBMC |
| 1470 | // obmc_mask_flipN[overlap_position] |
| 1471 | static const uint8_t obmc_mask_flip1[1] = { 55 }; |
| 1472 | |
| 1473 | static const uint8_t obmc_mask_flip2[2] = { 62, 45 }; |
| 1474 | |
| 1475 | static const uint8_t obmc_mask_flip4[4] = { 64, 59, 50, 39 }; |
| 1476 | |
| 1477 | static const uint8_t obmc_mask_flip8[8] = { 64, 63, 61, 57, 53, 48, 42, 36 }; |
| 1478 | |
| 1479 | static const uint8_t obmc_mask_flip16[16] = { 64, 64, 64, 63, 61, 60, 58, 56, |
| 1480 | 54, 52, 49, 46, 43, 40, 37, 34 }; |
| 1481 | |
| 1482 | static const uint8_t obmc_mask_flip32[32] = { 64, 64, 64, 64, 64, 63, 63, 62, |
| 1483 | 62, 61, 60, 60, 59, 58, 57, 56, |
| 1484 | 55, 53, 52, 51, 50, 48, 47, 45, |
| 1485 | 44, 43, 41, 40, 38, 36, 35, 33 }; |
| 1486 | |
| 1487 | #if CONFIG_EXT_PARTITION |
| 1488 | static const uint8_t obmc_mask_flip64[64] = { |
| 1489 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 63, 62, 62, |
| 1490 | 62, 62, 62, 61, 60, 60, 60, 60, 60, 59, 58, 58, 57, 57, 56, 56, |
| 1491 | 56, 55, 54, 53, 52, 52, 51, 51, 51, 50, 49, 48, 47, 47, 46, 45, |
| 1492 | 44, 44, 44, 43, 42, 41, 40, 40, 39, 38, 37, 36, 35, 35, 34, 33, |
| 1493 | }; |
| 1494 | #endif // CONFIG_EXT_PARTITION |
| 1495 | |
| 1496 | const uint8_t *av1_get_obmc_mask_flipped(int length) { |
| 1497 | switch (length) { |
| 1498 | case 1: return obmc_mask_flip1; |
| 1499 | case 2: return obmc_mask_flip2; |
| 1500 | case 4: return obmc_mask_flip4; |
| 1501 | case 8: return obmc_mask_flip8; |
| 1502 | case 16: return obmc_mask_flip16; |
| 1503 | case 32: return obmc_mask_flip32; |
| 1504 | #if CONFIG_EXT_PARTITION |
| 1505 | case 64: return obmc_mask_flip64; |
| 1506 | #endif // CONFIG_EXT_PARTITION |
| 1507 | default: assert(0); return NULL; |
| 1508 | } |
| 1509 | } |
| 1510 | #endif // CONFIG_NCOBMC |
| 1511 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1512 | // This function combines motion compensated predictions that is generated by |
| 1513 | // top/left neighboring blocks' inter predictors with the regular inter |
| 1514 | // prediction. We assume the original prediction (bmc) is stored in |
| 1515 | // xd->plane[].dst.buf |
Urvang Joshi | 5264844 | 2016-10-13 17:27:51 -0700 | [diff] [blame] | 1516 | void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1517 | int mi_row, int mi_col, |
| 1518 | uint8_t *above[MAX_MB_PLANE], |
| 1519 | int above_stride[MAX_MB_PLANE], |
| 1520 | uint8_t *left[MAX_MB_PLANE], |
| 1521 | int left_stride[MAX_MB_PLANE]) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1522 | const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 1523 | int plane, i; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1524 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1525 | const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1526 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1527 | |
| 1528 | // handle above row |
| 1529 | if (xd->up_available) { |
| 1530 | const int overlap = num_4x4_blocks_high_lookup[bsize] * 2; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1531 | const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1532 | const int mi_row_offset = -1; |
| 1533 | |
| 1534 | assert(miw > 0); |
| 1535 | |
| 1536 | i = 0; |
| 1537 | do { // for each mi in the above row |
| 1538 | const int mi_col_offset = i; |
| 1539 | const MB_MODE_INFO *const above_mbmi = |
| 1540 | &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi; |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1541 | const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[above_mbmi->sb_type]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1542 | |
| 1543 | if (is_neighbor_overlappable(above_mbmi)) { |
| 1544 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
| 1545 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
| 1546 | const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x; |
| 1547 | const int bh = overlap >> pd->subsampling_y; |
| 1548 | const int dst_stride = pd->dst.stride; |
| 1549 | uint8_t *const dst = &pd->dst.buf[(i * MI_SIZE) >> pd->subsampling_x]; |
| 1550 | const int tmp_stride = above_stride[plane]; |
| 1551 | const uint8_t *const tmp = |
| 1552 | &above[plane][(i * MI_SIZE) >> pd->subsampling_x]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1553 | const uint8_t *const mask = av1_get_obmc_mask(bh); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1554 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1555 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1556 | if (is_hbd) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1557 | aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1558 | tmp_stride, mask, bh, bw, xd->bd); |
| 1559 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1560 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1561 | aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1562 | tmp_stride, mask, bh, bw); |
| 1563 | } |
| 1564 | } |
| 1565 | i += mi_step; |
| 1566 | } while (i < miw); |
| 1567 | } |
| 1568 | |
| 1569 | // handle left column |
| 1570 | if (xd->left_available) { |
| 1571 | const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1572 | const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1573 | const int mi_col_offset = -1; |
| 1574 | |
| 1575 | assert(mih > 0); |
| 1576 | |
| 1577 | i = 0; |
| 1578 | do { // for each mi in the left column |
| 1579 | const int mi_row_offset = i; |
| 1580 | const MB_MODE_INFO *const left_mbmi = |
| 1581 | &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi; |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1582 | const int mi_step = AOMMIN(xd->n8_h, mi_size_high[left_mbmi->sb_type]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1583 | |
| 1584 | if (is_neighbor_overlappable(left_mbmi)) { |
| 1585 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
| 1586 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
| 1587 | const int bw = overlap >> pd->subsampling_x; |
| 1588 | const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y; |
| 1589 | const int dst_stride = pd->dst.stride; |
| 1590 | uint8_t *const dst = |
| 1591 | &pd->dst.buf[(i * MI_SIZE * dst_stride) >> pd->subsampling_y]; |
| 1592 | const int tmp_stride = left_stride[plane]; |
| 1593 | const uint8_t *const tmp = |
| 1594 | &left[plane][(i * MI_SIZE * tmp_stride) >> pd->subsampling_y]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1595 | const uint8_t *const mask = av1_get_obmc_mask(bw); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1596 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1597 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1598 | if (is_hbd) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1599 | aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1600 | tmp_stride, mask, bh, bw, xd->bd); |
| 1601 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1602 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1603 | aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1604 | tmp_stride, mask, bh, bw); |
| 1605 | } |
| 1606 | } |
| 1607 | i += mi_step; |
| 1608 | } while (i < mih); |
| 1609 | } |
| 1610 | } |
| 1611 | |
| 1612 | #if CONFIG_EXT_INTER |
| 1613 | void modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi) { |
| 1614 | if (is_interintra_pred(mbmi)) { |
Emil Keyder | 01770b3 | 2017-01-20 18:03:11 -0500 | [diff] [blame] | 1615 | mbmi->ref_frame[1] = NONE_FRAME; |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 1616 | } else if (has_second_ref(mbmi) && |
| 1617 | is_masked_compound_type(mbmi->interinter_compound_data.type)) { |
| 1618 | mbmi->interinter_compound_data.type = COMPOUND_AVERAGE; |
Emil Keyder | 01770b3 | 2017-01-20 18:03:11 -0500 | [diff] [blame] | 1619 | mbmi->ref_frame[1] = NONE_FRAME; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1620 | } |
| 1621 | return; |
| 1622 | } |
| 1623 | #endif // CONFIG_EXT_INTER |
| 1624 | |
Urvang Joshi | 5264844 | 2016-10-13 17:27:51 -0700 | [diff] [blame] | 1625 | void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1626 | int mi_row, int mi_col, |
| 1627 | uint8_t *tmp_buf[MAX_MB_PLANE], |
| 1628 | int tmp_width[MAX_MB_PLANE], |
| 1629 | int tmp_height[MAX_MB_PLANE], |
| 1630 | int tmp_stride[MAX_MB_PLANE]) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1631 | const TileInfo *const tile = &xd->tile; |
| 1632 | BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 1633 | int i, j, mi_step, ref; |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1634 | int mb_to_right_edge_base = xd->mb_to_right_edge; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1635 | |
| 1636 | if (mi_row <= tile->mi_row_start) return; |
| 1637 | |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1638 | xd->mb_to_bottom_edge += xd->n8_h * 32; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1639 | for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1640 | int mi_row_offset = -1; |
| 1641 | int mi_col_offset = i; |
| 1642 | int mi_x, mi_y, bw, bh; |
| 1643 | MODE_INFO *above_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 1644 | MB_MODE_INFO *above_mbmi = &above_mi->mbmi; |
| 1645 | #if CONFIG_EXT_INTER |
| 1646 | MB_MODE_INFO backup_mbmi; |
| 1647 | #endif // CONFIG_EXT_INTER |
| 1648 | |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1649 | mi_step = AOMMIN(xd->n8_w, mi_size_wide[above_mbmi->sb_type]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1650 | |
| 1651 | if (!is_neighbor_overlappable(above_mbmi)) continue; |
| 1652 | |
| 1653 | #if CONFIG_EXT_INTER |
| 1654 | backup_mbmi = *above_mbmi; |
| 1655 | modify_neighbor_predictor_for_obmc(above_mbmi); |
| 1656 | #endif // CONFIG_EXT_INTER |
| 1657 | |
| 1658 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1659 | struct macroblockd_plane *const pd = &xd->plane[j]; |
| 1660 | setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j], |
| 1661 | tmp_stride[j], 0, i, NULL, pd->subsampling_x, |
| 1662 | pd->subsampling_y); |
| 1663 | } |
| 1664 | for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) { |
Urvang Joshi | 5264844 | 2016-10-13 17:27:51 -0700 | [diff] [blame] | 1665 | const MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref]; |
| 1666 | const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1667 | |
| 1668 | xd->block_refs[ref] = ref_buf; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1669 | if ((!av1_is_valid_scale(&ref_buf->sf))) |
| 1670 | aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1671 | "Reference frame has invalid dimensions"); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1672 | av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i, |
| 1673 | &ref_buf->sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1674 | } |
| 1675 | |
| 1676 | xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8); |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1677 | xd->mb_to_right_edge = |
| 1678 | mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1679 | mi_x = (mi_col + i) << MI_SIZE_LOG2; |
| 1680 | mi_y = mi_row << MI_SIZE_LOG2; |
| 1681 | |
| 1682 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1683 | const struct macroblockd_plane *pd = &xd->plane[j]; |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1684 | bw = (mi_step * MI_SIZE) >> pd->subsampling_x; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1685 | bh = AOMMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1686 | 4); |
| 1687 | |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1688 | if (above_mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1689 | const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type; |
| 1690 | const int have_vsplit = bp != PARTITION_HORZ; |
| 1691 | const int have_hsplit = bp != PARTITION_VERT; |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1692 | const int num_4x4_w = 2 >> !have_vsplit; |
| 1693 | const int num_4x4_h = 2 >> !have_hsplit; |
| 1694 | const int pw = 8 >> (have_vsplit + pd->subsampling_x); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1695 | int x, y; |
| 1696 | |
| 1697 | for (y = 0; y < num_4x4_h; ++y) |
| 1698 | for (x = 0; x < num_4x4_w; ++x) { |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1699 | if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y == 0) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1700 | continue; |
| 1701 | |
| 1702 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1703 | y * 2 + x, bw, bh, |
| 1704 | (4 * x) >> pd->subsampling_x, 0, pw, bh, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1705 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1706 | 0, 0, |
| 1707 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1708 | mi_x, mi_y); |
| 1709 | } |
| 1710 | } else { |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1711 | #if CONFIG_WARPED_MOTION |
| 1712 | if (above_mbmi->motion_mode == WARPED_CAUSAL) { |
| 1713 | av1_warp_plane(&above_mbmi->wm_params[0], |
| 1714 | #if CONFIG_AOM_HIGHBITDEPTH |
| 1715 | xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, |
| 1716 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1717 | pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height, |
| 1718 | pd->pre[0].stride, pd->dst.buf, |
| 1719 | (((mi_col + i) * MI_SIZE) >> pd->subsampling_x), |
| 1720 | ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh, |
| 1721 | pd->dst.stride, pd->subsampling_x, pd->subsampling_y, |
| 1722 | 16, 16, 0); |
| 1723 | |
| 1724 | } else { |
| 1725 | #endif // CONFIG_WARPED_MOTION |
| 1726 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, |
| 1727 | 0, 0, bw, bh, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1728 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1729 | 0, 0, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1730 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1731 | mi_x, mi_y); |
| 1732 | #if CONFIG_WARPED_MOTION |
| 1733 | } |
| 1734 | #endif // CONFIG_WARPED_MOTION |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1735 | } |
| 1736 | } |
| 1737 | #if CONFIG_EXT_INTER |
| 1738 | *above_mbmi = backup_mbmi; |
| 1739 | #endif // CONFIG_EXT_INTER |
| 1740 | } |
| 1741 | xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1742 | xd->mb_to_right_edge = mb_to_right_edge_base; |
| 1743 | xd->mb_to_bottom_edge -= xd->n8_h * 32; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1744 | } |
| 1745 | |
Urvang Joshi | 5264844 | 2016-10-13 17:27:51 -0700 | [diff] [blame] | 1746 | void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1747 | int mi_row, int mi_col, |
| 1748 | uint8_t *tmp_buf[MAX_MB_PLANE], |
| 1749 | int tmp_width[MAX_MB_PLANE], |
| 1750 | int tmp_height[MAX_MB_PLANE], |
| 1751 | int tmp_stride[MAX_MB_PLANE]) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1752 | const TileInfo *const tile = &xd->tile; |
| 1753 | BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 1754 | int i, j, mi_step, ref; |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1755 | int mb_to_bottom_edge_base = xd->mb_to_bottom_edge; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1756 | |
| 1757 | if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start)) return; |
| 1758 | |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1759 | xd->mb_to_right_edge += xd->n8_w * 32; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1760 | for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1761 | int mi_row_offset = i; |
| 1762 | int mi_col_offset = -1; |
| 1763 | int mi_x, mi_y, bw, bh; |
| 1764 | MODE_INFO *left_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 1765 | MB_MODE_INFO *left_mbmi = &left_mi->mbmi; |
| 1766 | #if CONFIG_EXT_INTER |
| 1767 | MB_MODE_INFO backup_mbmi; |
| 1768 | #endif // CONFIG_EXT_INTER |
| 1769 | |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1770 | mi_step = AOMMIN(xd->n8_h, mi_size_high[left_mbmi->sb_type]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1771 | |
| 1772 | if (!is_neighbor_overlappable(left_mbmi)) continue; |
| 1773 | |
| 1774 | #if CONFIG_EXT_INTER |
| 1775 | backup_mbmi = *left_mbmi; |
| 1776 | modify_neighbor_predictor_for_obmc(left_mbmi); |
| 1777 | #endif // CONFIG_EXT_INTER |
| 1778 | |
| 1779 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1780 | struct macroblockd_plane *const pd = &xd->plane[j]; |
| 1781 | setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j], |
| 1782 | tmp_stride[j], i, 0, NULL, pd->subsampling_x, |
| 1783 | pd->subsampling_y); |
| 1784 | } |
| 1785 | for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) { |
Urvang Joshi | 5264844 | 2016-10-13 17:27:51 -0700 | [diff] [blame] | 1786 | const MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref]; |
| 1787 | const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1788 | |
| 1789 | xd->block_refs[ref] = ref_buf; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1790 | if ((!av1_is_valid_scale(&ref_buf->sf))) |
| 1791 | aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1792 | "Reference frame has invalid dimensions"); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1793 | av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col, |
| 1794 | &ref_buf->sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1795 | } |
| 1796 | |
| 1797 | xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8); |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1798 | xd->mb_to_bottom_edge = |
| 1799 | mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1800 | mi_x = mi_col << MI_SIZE_LOG2; |
| 1801 | mi_y = (mi_row + i) << MI_SIZE_LOG2; |
| 1802 | |
| 1803 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1804 | const struct macroblockd_plane *pd = &xd->plane[j]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1805 | bw = AOMMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1806 | 4); |
| 1807 | bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y; |
| 1808 | |
Jingning Han | 51ec505 | 2017-01-18 16:27:57 -0800 | [diff] [blame] | 1809 | if (left_mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1810 | const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type; |
| 1811 | const int have_vsplit = bp != PARTITION_HORZ; |
| 1812 | const int have_hsplit = bp != PARTITION_VERT; |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1813 | const int num_4x4_w = 2 >> !have_vsplit; |
| 1814 | const int num_4x4_h = 2 >> !have_hsplit; |
| 1815 | const int ph = 8 >> (have_hsplit + pd->subsampling_y); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1816 | int x, y; |
| 1817 | |
| 1818 | for (y = 0; y < num_4x4_h; ++y) |
| 1819 | for (x = 0; x < num_4x4_w; ++x) { |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1820 | if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x == 0) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1821 | continue; |
| 1822 | |
| 1823 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1824 | y * 2 + x, bw, bh, 0, |
| 1825 | (4 * y) >> pd->subsampling_y, bw, ph, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1826 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1827 | 0, 0, |
| 1828 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1829 | mi_x, mi_y); |
| 1830 | } |
| 1831 | } else { |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1832 | #if CONFIG_WARPED_MOTION |
| 1833 | if (left_mbmi->motion_mode == WARPED_CAUSAL) { |
| 1834 | av1_warp_plane(&left_mbmi->wm_params[0], |
| 1835 | #if CONFIG_AOM_HIGHBITDEPTH |
| 1836 | xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, |
| 1837 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1838 | pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height, |
| 1839 | pd->pre[0].stride, pd->dst.buf, |
| 1840 | ((mi_col * MI_SIZE) >> pd->subsampling_x), |
| 1841 | (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw, |
| 1842 | bh, pd->dst.stride, pd->subsampling_x, |
| 1843 | pd->subsampling_y, 16, 16, 0); |
| 1844 | |
| 1845 | } else { |
| 1846 | #endif // CONFIG_WARPED_MOTION |
| 1847 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, |
| 1848 | 0, 0, bw, bh, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1849 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1850 | 0, 0, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1851 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
Yue Chen | 69f18e1 | 2016-09-08 14:48:15 -0700 | [diff] [blame] | 1852 | mi_x, mi_y); |
| 1853 | #if CONFIG_WARPED_MOTION |
| 1854 | } |
| 1855 | #endif // CONFIG_WARPED_MOTION |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1856 | } |
| 1857 | } |
| 1858 | #if CONFIG_EXT_INTER |
| 1859 | *left_mbmi = backup_mbmi; |
| 1860 | #endif // CONFIG_EXT_INTER |
| 1861 | } |
| 1862 | xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); |
Yue Chen | 894fcce | 2016-10-21 16:50:52 -0700 | [diff] [blame] | 1863 | xd->mb_to_bottom_edge = mb_to_bottom_edge_base; |
| 1864 | xd->mb_to_right_edge -= xd->n8_w * 32; |
| 1865 | } |
| 1866 | |
| 1867 | void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 1868 | int mi_row, int mi_col) { |
| 1869 | #if CONFIG_AOM_HIGHBITDEPTH |
| 1870 | DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 1871 | DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 1872 | #else |
| 1873 | DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 1874 | DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 1875 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1876 | uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE]; |
| 1877 | int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1878 | int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1879 | int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1880 | int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1881 | int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1882 | int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 1883 | |
| 1884 | #if CONFIG_AOM_HIGHBITDEPTH |
| 1885 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
| 1886 | int len = sizeof(uint16_t); |
| 1887 | dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1); |
| 1888 | dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len); |
| 1889 | dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len); |
| 1890 | dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2); |
| 1891 | dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len); |
| 1892 | dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len); |
| 1893 | } else { |
| 1894 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1895 | dst_buf1[0] = tmp_buf1; |
| 1896 | dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE; |
| 1897 | dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2; |
| 1898 | dst_buf2[0] = tmp_buf2; |
| 1899 | dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE; |
| 1900 | dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2; |
| 1901 | #if CONFIG_AOM_HIGHBITDEPTH |
| 1902 | } |
| 1903 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 1904 | av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1, |
| 1905 | dst_width1, dst_height1, dst_stride1); |
| 1906 | av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2, |
| 1907 | dst_width2, dst_height2, dst_stride2); |
| 1908 | av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); |
| 1909 | av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1, |
| 1910 | dst_buf2, dst_stride2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1911 | } |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 1912 | |
| 1913 | #if CONFIG_NCOBMC |
| 1914 | void av1_build_prediction_by_bottom_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 1915 | int mi_row, int mi_col, |
| 1916 | uint8_t *tmp_buf[MAX_MB_PLANE], |
| 1917 | int tmp_width[MAX_MB_PLANE], |
| 1918 | int tmp_height[MAX_MB_PLANE], |
| 1919 | int tmp_stride[MAX_MB_PLANE]) { |
| 1920 | const TileInfo *const tile = &xd->tile; |
| 1921 | BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 1922 | int i, j, mi_step, ref; |
| 1923 | int mb_to_right_edge_base = xd->mb_to_right_edge; |
| 1924 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 1925 | if (mi_row + xd->n8_h >= tile->mi_row_end || |
| 1926 | (mi_row + xd->n8_h) % MI_SIZE == 0 || (mi_row + xd->n8_h) >= cm->mi_rows) |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 1927 | return; |
| 1928 | assert(bsize >= BLOCK_8X8); |
| 1929 | |
| 1930 | xd->mb_to_top_edge -= xd->n8_h * 32; |
| 1931 | for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) { |
| 1932 | int mi_row_offset = xd->n8_h; |
| 1933 | int mi_col_offset = i; |
| 1934 | int mi_x, mi_y, bw, bh; |
| 1935 | MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 1936 | MB_MODE_INFO *mbmi = &mi->mbmi; |
| 1937 | #if CONFIG_EXT_INTER |
| 1938 | MB_MODE_INFO backup_mbmi; |
| 1939 | #endif // CONFIG_EXT_INTER |
| 1940 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 1941 | mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]); |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 1942 | |
| 1943 | if (!is_neighbor_overlappable(mbmi)) continue; |
| 1944 | |
| 1945 | #if CONFIG_EXT_INTER |
| 1946 | backup_mbmi = *mbmi; |
| 1947 | modify_neighbor_predictor_for_obmc(mbmi); |
| 1948 | #endif // CONFIG_EXT_INTER |
| 1949 | |
| 1950 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1951 | struct macroblockd_plane *const pd = &xd->plane[j]; |
| 1952 | setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j], |
| 1953 | tmp_stride[j], (xd->n8_h >> 1), i, NULL, |
| 1954 | pd->subsampling_x, pd->subsampling_y); |
| 1955 | } |
| 1956 | for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) { |
| 1957 | const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref]; |
| 1958 | const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME]; |
| 1959 | |
| 1960 | xd->block_refs[ref] = ref_buf; |
| 1961 | if ((!av1_is_valid_scale(&ref_buf->sf))) |
| 1962 | aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, |
| 1963 | "Reference frame has invalid dimensions"); |
| 1964 | av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + (xd->n8_h >> 1), |
| 1965 | mi_col + i, &ref_buf->sf); |
| 1966 | } |
| 1967 | |
| 1968 | xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8); |
| 1969 | xd->mb_to_right_edge = |
| 1970 | mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64; |
| 1971 | mi_x = (mi_col + i) << MI_SIZE_LOG2; |
| 1972 | mi_y = (mi_row << MI_SIZE_LOG2) + xd->n8_h * 4; |
| 1973 | |
| 1974 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 1975 | const struct macroblockd_plane *pd = &xd->plane[j]; |
| 1976 | bw = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_x; |
| 1977 | bh = (num_4x4_blocks_high_lookup[bsize] << 1) >> pd->subsampling_y; |
| 1978 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 1979 | if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 1980 | const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type; |
| 1981 | const int have_vsplit = bp != PARTITION_HORZ; |
| 1982 | const int have_hsplit = bp != PARTITION_VERT; |
| 1983 | const int num_4x4_w = 2 >> (!have_vsplit); |
| 1984 | const int num_4x4_h = 2 >> (!have_hsplit); |
| 1985 | const int pw = 8 >> (have_vsplit + pd->subsampling_x); |
| 1986 | int x, y; |
| 1987 | |
| 1988 | for (y = 0; y < num_4x4_h; ++y) |
| 1989 | for (x = 0; x < num_4x4_w; ++x) { |
| 1990 | if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y != 0) |
| 1991 | continue; |
| 1992 | |
| 1993 | build_inter_predictors( |
| 1994 | xd, j, mi_col_offset, mi_row_offset, y * 2 + x, bw, bh, |
| 1995 | (4 * x) >> pd->subsampling_x, |
| 1996 | xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, pw, bh, |
| 1997 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 1998 | 0, 0, |
| 1999 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2000 | mi_x, mi_y); |
| 2001 | } |
| 2002 | } else { |
| 2003 | #if CONFIG_WARPED_MOTION |
| 2004 | if (mbmi->motion_mode == WARPED_CAUSAL) { |
| 2005 | av1_warp_plane(&mbmi->wm_params[0], |
| 2006 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2007 | xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, |
| 2008 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2009 | pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height, |
| 2010 | pd->pre[0].stride, pd->dst.buf, |
| 2011 | (((mi_col + i) * MI_SIZE) >> pd->subsampling_x), |
| 2012 | ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh, |
| 2013 | pd->dst.stride, pd->subsampling_x, pd->subsampling_y, |
| 2014 | 16, 16, 0); |
| 2015 | |
| 2016 | } else { |
| 2017 | #endif // CONFIG_WARPED_MOTION |
| 2018 | build_inter_predictors( |
| 2019 | xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, 0, |
| 2020 | xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, bw, bh, |
| 2021 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2022 | 0, 0, |
| 2023 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2024 | mi_x, mi_y); |
| 2025 | #if CONFIG_WARPED_MOTION |
| 2026 | } |
| 2027 | #endif // CONFIG_WARPED_MOTION |
| 2028 | } |
| 2029 | } |
| 2030 | #if CONFIG_EXT_INTER |
| 2031 | *mbmi = backup_mbmi; |
| 2032 | #endif // CONFIG_EXT_INTER |
| 2033 | } |
| 2034 | xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); |
| 2035 | xd->mb_to_right_edge = mb_to_right_edge_base; |
| 2036 | xd->mb_to_top_edge += xd->n8_h * 32; |
| 2037 | } |
| 2038 | |
| 2039 | void av1_build_prediction_by_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 2040 | int mi_row, int mi_col, |
| 2041 | uint8_t *tmp_buf[MAX_MB_PLANE], |
| 2042 | int tmp_width[MAX_MB_PLANE], |
| 2043 | int tmp_height[MAX_MB_PLANE], |
| 2044 | const int tmp_stride[MAX_MB_PLANE]) { |
| 2045 | const TileInfo *const tile = &xd->tile; |
| 2046 | BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 2047 | int i, j, mi_step, ref; |
| 2048 | int mb_to_bottom_edge_base = xd->mb_to_bottom_edge; |
| 2049 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2050 | if (mi_col + xd->n8_w >= tile->mi_col_end || |
| 2051 | (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols) |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2052 | return; |
| 2053 | |
| 2054 | xd->mb_to_left_edge -= xd->n8_w * 32; |
| 2055 | for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) { |
| 2056 | int mi_row_offset = i; |
| 2057 | int mi_col_offset = xd->n8_w; |
| 2058 | int mi_x, mi_y, bw, bh; |
| 2059 | MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 2060 | MB_MODE_INFO *mbmi = &mi->mbmi; |
| 2061 | #if CONFIG_EXT_INTER |
| 2062 | MB_MODE_INFO backup_mbmi; |
| 2063 | #endif // CONFIG_EXT_INTER |
| 2064 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2065 | mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]); |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2066 | |
| 2067 | if (!is_neighbor_overlappable(mbmi)) continue; |
| 2068 | |
| 2069 | #if CONFIG_EXT_INTER |
| 2070 | backup_mbmi = *mbmi; |
| 2071 | modify_neighbor_predictor_for_obmc(mbmi); |
| 2072 | #endif // CONFIG_EXT_INTER |
| 2073 | |
| 2074 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 2075 | struct macroblockd_plane *const pd = &xd->plane[j]; |
| 2076 | setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j], |
| 2077 | tmp_stride[j], i, xd->n8_w >> 1, NULL, pd->subsampling_x, |
| 2078 | pd->subsampling_y); |
| 2079 | } |
| 2080 | for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) { |
| 2081 | const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref]; |
| 2082 | const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME]; |
| 2083 | |
| 2084 | xd->block_refs[ref] = ref_buf; |
| 2085 | if ((!av1_is_valid_scale(&ref_buf->sf))) |
| 2086 | aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM, |
| 2087 | "Reference frame has invalid dimensions"); |
| 2088 | av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, |
| 2089 | mi_col + (xd->n8_w >> 1), &ref_buf->sf); |
| 2090 | } |
| 2091 | |
| 2092 | xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8); |
| 2093 | xd->mb_to_bottom_edge = |
| 2094 | mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64; |
| 2095 | mi_x = (mi_col << MI_SIZE_LOG2) + xd->n8_w * 4; |
| 2096 | mi_y = (mi_row + i) << MI_SIZE_LOG2; |
| 2097 | |
| 2098 | for (j = 0; j < MAX_MB_PLANE; ++j) { |
| 2099 | const struct macroblockd_plane *pd = &xd->plane[j]; |
| 2100 | bw = (num_4x4_blocks_wide_lookup[bsize] << 1) >> pd->subsampling_x; |
| 2101 | bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y; |
| 2102 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2103 | if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2104 | const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type; |
| 2105 | const int have_vsplit = bp != PARTITION_HORZ; |
| 2106 | const int have_hsplit = bp != PARTITION_VERT; |
| 2107 | const int num_4x4_w = 2 >> (!have_vsplit); |
| 2108 | const int num_4x4_h = 2 >> (!have_hsplit); |
| 2109 | const int ph = 8 >> (have_hsplit + pd->subsampling_y); |
| 2110 | int x, y; |
| 2111 | |
| 2112 | for (y = 0; y < num_4x4_h; ++y) |
| 2113 | for (x = 0; x < num_4x4_w; ++x) { |
| 2114 | if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x != 0) |
| 2115 | continue; |
| 2116 | |
| 2117 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, |
| 2118 | y * 2 + x, bw, bh, |
| 2119 | xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0, |
| 2120 | (4 * y) >> pd->subsampling_y, bw, ph, |
| 2121 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2122 | 0, 0, |
| 2123 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2124 | mi_x, mi_y); |
| 2125 | } |
| 2126 | } else { |
| 2127 | #if CONFIG_WARPED_MOTION |
| 2128 | if (mbmi->motion_mode == WARPED_CAUSAL) { |
| 2129 | av1_warp_plane(&mbmi->wm_params[0], |
| 2130 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2131 | xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd, |
| 2132 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2133 | pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height, |
| 2134 | pd->pre[0].stride, pd->dst.buf, |
| 2135 | ((mi_col * MI_SIZE) >> pd->subsampling_x), |
| 2136 | (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw, |
| 2137 | bh, pd->dst.stride, pd->subsampling_x, |
| 2138 | pd->subsampling_y, 16, 16, 0); |
| 2139 | |
| 2140 | } else { |
| 2141 | #endif // CONFIG_WARPED_MOTION |
| 2142 | build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, |
| 2143 | xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0, 0, |
| 2144 | bw, bh, |
| 2145 | #if CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2146 | 0, 0, |
| 2147 | #endif // CONFIG_SUPERTX && CONFIG_EXT_INTER |
| 2148 | mi_x, mi_y); |
| 2149 | #if CONFIG_WARPED_MOTION |
| 2150 | } |
| 2151 | #endif // CONFIG_WARPED_MOTION |
| 2152 | } |
| 2153 | } |
| 2154 | #if CONFIG_EXT_INTER |
| 2155 | *mbmi = backup_mbmi; |
| 2156 | #endif // CONFIG_EXT_INTER |
| 2157 | } |
| 2158 | xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); |
| 2159 | xd->mb_to_bottom_edge = mb_to_bottom_edge_base; |
| 2160 | xd->mb_to_left_edge += xd->n8_w * 32; |
| 2161 | } |
| 2162 | |
| 2163 | // This function combines motion compensated predictions that is generated by |
| 2164 | // bottom/right neighboring blocks' inter predictors with prediction in dst |
| 2165 | // buffer. |
| 2166 | void av1_merge_dst_bottom_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 2167 | int mi_row, int mi_col, |
| 2168 | uint8_t *bottom[MAX_MB_PLANE], |
| 2169 | const int bottom_stride[MAX_MB_PLANE], |
| 2170 | uint8_t *right[MAX_MB_PLANE], |
| 2171 | const int right_stride[MAX_MB_PLANE]) { |
| 2172 | const TileInfo *const tile = &xd->tile; |
| 2173 | BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type; |
| 2174 | int plane, i, mi_step; |
| 2175 | const int bottom_available = mi_row + xd->n8_h < tile->mi_row_end && |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2176 | (mi_row + xd->n8_h) % MI_SIZE != 0 && |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2177 | (mi_row + xd->n8_h) < cm->mi_rows; |
| 2178 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2179 | int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0; |
| 2180 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2181 | |
| 2182 | // handle bottom row |
| 2183 | for (i = 0; bottom_available && i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); |
| 2184 | i += mi_step) { |
| 2185 | int mi_row_offset = xd->n8_h; |
| 2186 | int mi_col_offset = i; |
| 2187 | MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 2188 | MB_MODE_INFO *mbmi = &mi->mbmi; |
| 2189 | int overlap; |
| 2190 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2191 | mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]); |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2192 | |
| 2193 | if (!is_neighbor_overlappable(mbmi)) continue; |
| 2194 | |
| 2195 | overlap = num_4x4_blocks_high_lookup[bsize] << 1; |
| 2196 | |
| 2197 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
| 2198 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
| 2199 | const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x; |
| 2200 | const int bh = overlap >> pd->subsampling_y; |
| 2201 | const int dst_stride = pd->dst.stride; |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2202 | uint8_t *dst = |
| 2203 | &pd->dst.buf[((i * MI_SIZE) >> pd->subsampling_x) + |
| 2204 | (((xd->n8_h * MI_SIZE - overlap) * dst_stride) >> |
| 2205 | pd->subsampling_y)]; |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2206 | const int tmp_stride = bottom_stride[plane]; |
| 2207 | const uint8_t *const tmp = |
| 2208 | &bottom[plane][((i * MI_SIZE) >> pd->subsampling_x) + |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2209 | (((xd->n8_h * MI_SIZE - overlap) * tmp_stride) >> |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2210 | pd->subsampling_y)]; |
| 2211 | const uint8_t *const mask = av1_get_obmc_mask_flipped(bh); |
| 2212 | |
| 2213 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2214 | if (is_hbd) |
| 2215 | aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, |
| 2216 | tmp_stride, mask, bh, bw, xd->bd); |
| 2217 | else |
| 2218 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2219 | aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride, |
| 2220 | mask, bh, bw); |
| 2221 | } |
| 2222 | } // each mi in the bottom row |
| 2223 | |
| 2224 | // handle right column |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2225 | if (mi_col + xd->n8_w >= tile->mi_col_end || |
| 2226 | (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols) |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2227 | return; |
| 2228 | |
| 2229 | for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) { |
| 2230 | int mi_row_offset = i; |
| 2231 | int mi_col_offset = xd->n8_w; |
| 2232 | int overlap; |
| 2233 | MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]; |
| 2234 | MB_MODE_INFO *mbmi = &mi->mbmi; |
| 2235 | |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2236 | mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]); |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2237 | |
| 2238 | if (!is_neighbor_overlappable(mbmi)) continue; |
| 2239 | |
| 2240 | overlap = num_4x4_blocks_wide_lookup[bsize] << 1; |
| 2241 | |
| 2242 | for (plane = 0; plane < MAX_MB_PLANE; ++plane) { |
| 2243 | const struct macroblockd_plane *pd = &xd->plane[plane]; |
| 2244 | const int bw = overlap >> pd->subsampling_x; |
| 2245 | const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y; |
| 2246 | const int dst_stride = pd->dst.stride; |
| 2247 | uint8_t *dst = |
| 2248 | &pd->dst.buf[((i * MI_SIZE * dst_stride) >> pd->subsampling_y) + |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2249 | ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)]; |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2250 | const int tmp_stride = right_stride[plane]; |
| 2251 | const uint8_t *const tmp = |
| 2252 | &right[plane][((i * MI_SIZE * tmp_stride) >> pd->subsampling_y) + |
Jingning Han | 91f01fd | 2017-01-18 17:16:40 -0800 | [diff] [blame] | 2253 | ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)]; |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2254 | const uint8_t *const mask = av1_get_obmc_mask_flipped(bw); |
| 2255 | |
| 2256 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2257 | if (is_hbd) |
| 2258 | aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, |
| 2259 | tmp_stride, mask, bh, bw, xd->bd); |
| 2260 | else |
| 2261 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2262 | aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride, |
| 2263 | mask, bh, bw); |
| 2264 | } |
| 2265 | } // each mi in the right column |
| 2266 | } |
| 2267 | |
| 2268 | // This function generates 4 sided obmc. (1) Prediction blocks generated by |
| 2269 | // bottom and right motion vectors are calculated. (2) Combine them with the |
| 2270 | // original prediction block (which should be pre-stored in xd->plane[].dst.buf |
| 2271 | // before calling this function). The results is updated in xd->plane[].dst.buf |
| 2272 | // (3) Call causal obmc prediction function, which will generate left and above |
| 2273 | // preds, and then merge them and xd->plane[].dst.buf. |
| 2274 | void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, |
| 2275 | int mi_row, int mi_col) { |
| 2276 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2277 | DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 2278 | DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 2279 | #else |
| 2280 | DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 2281 | DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]); |
| 2282 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2283 | uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE]; |
| 2284 | int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2285 | int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2286 | int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2287 | int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2288 | int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2289 | int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; |
| 2290 | |
| 2291 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2292 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
| 2293 | int len = sizeof(uint16_t); |
| 2294 | dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1); |
| 2295 | dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len); |
| 2296 | dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len); |
| 2297 | dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2); |
| 2298 | dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len); |
| 2299 | dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len); |
| 2300 | } else { |
| 2301 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2302 | dst_buf1[0] = tmp_buf1; |
| 2303 | dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE; |
| 2304 | dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2; |
| 2305 | dst_buf2[0] = tmp_buf2; |
| 2306 | dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE; |
| 2307 | dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2; |
| 2308 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2309 | } |
| 2310 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2311 | |
Yue Chen | 86ae7b1 | 2017-01-11 17:04:29 -0800 | [diff] [blame] | 2312 | av1_build_prediction_by_bottom_preds(cm, xd, mi_row, mi_col, dst_buf1, |
| 2313 | dst_width1, dst_height1, dst_stride1); |
| 2314 | av1_build_prediction_by_right_preds(cm, xd, mi_row, mi_col, dst_buf2, |
| 2315 | dst_width2, dst_height2, dst_stride2); |
| 2316 | av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); |
| 2317 | av1_merge_dst_bottom_right_preds(cm, xd, mi_row, mi_col, dst_buf1, |
| 2318 | dst_stride1, dst_buf2, dst_stride2); |
| 2319 | av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); |
| 2320 | av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col); |
| 2321 | av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col); |
| 2322 | } |
| 2323 | #endif // CONFIG_NCOBMC |
Yue Chen | cb60b18 | 2016-10-13 15:18:22 -0700 | [diff] [blame] | 2324 | #endif // CONFIG_MOTION_VAR |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2325 | |
| 2326 | #if CONFIG_EXT_INTER |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2327 | /* clang-format off */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2328 | #if CONFIG_EXT_PARTITION |
| 2329 | static const int ii_weights1d[MAX_SB_SIZE] = { |
| 2330 | 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71, 69, 68, 67, |
| 2331 | 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52, 51, 50, 49, 48, 47, 47, |
| 2332 | 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36, |
| 2333 | 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 32, 31, 31, |
| 2334 | 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 28, |
| 2335 | 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27, |
| 2336 | 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, |
| 2337 | }; |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2338 | static int ii_size_scales[BLOCK_SIZES] = { |
| 2339 | #if CONFIG_CB4X4 |
| 2340 | 32, 32, 32, |
| 2341 | #endif |
| 2342 | 32, 16, 16, 16, 8, 8, 8, 4, |
| 2343 | 4, 4, 2, 2, 2, 1, 1, 1, |
| 2344 | }; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2345 | #else |
| 2346 | static const int ii_weights1d[MAX_SB_SIZE] = { |
| 2347 | 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71, |
| 2348 | 69, 68, 67, 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52, |
| 2349 | 51, 50, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, |
| 2350 | 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34, |
| 2351 | }; |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2352 | static int ii_size_scales[BLOCK_SIZES] = { |
| 2353 | #if CONFIG_CB4X4 |
| 2354 | 16, 16, 16, |
| 2355 | #endif |
| 2356 | 16, 8, 8, 8, 4, 4, 4, |
| 2357 | 2, 2, 2, 1, 1, 1, |
| 2358 | }; |
| 2359 | /* clang-format on */ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2360 | #endif // CONFIG_EXT_PARTITION |
| 2361 | |
| 2362 | static void combine_interintra(INTERINTRA_MODE mode, int use_wedge_interintra, |
| 2363 | int wedge_index, int wedge_sign, |
| 2364 | BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize, |
| 2365 | uint8_t *comppred, int compstride, |
| 2366 | const uint8_t *interpred, int interstride, |
| 2367 | const uint8_t *intrapred, int intrastride) { |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 2368 | const int bw = block_size_wide[plane_bsize]; |
| 2369 | const int bh = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2370 | const int size_scale = ii_size_scales[plane_bsize]; |
| 2371 | int i, j; |
| 2372 | |
| 2373 | if (use_wedge_interintra) { |
| 2374 | if (is_interintra_wedge_used(bsize)) { |
| 2375 | const uint8_t *mask = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2376 | av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2377 | const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw; |
| 2378 | const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh; |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 2379 | aom_blend_a64_mask(comppred, compstride, intrapred, intrastride, |
| 2380 | interpred, interstride, mask, block_size_wide[bsize], |
| 2381 | bh, bw, subh, subw); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2382 | } |
| 2383 | return; |
| 2384 | } |
| 2385 | |
| 2386 | switch (mode) { |
| 2387 | case II_V_PRED: |
| 2388 | for (i = 0; i < bh; ++i) { |
| 2389 | for (j = 0; j < bw; ++j) { |
| 2390 | int scale = ii_weights1d[i * size_scale]; |
| 2391 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2392 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2393 | interpred[i * interstride + j]); |
| 2394 | } |
| 2395 | } |
| 2396 | break; |
| 2397 | |
| 2398 | case II_H_PRED: |
| 2399 | for (i = 0; i < bh; ++i) { |
| 2400 | for (j = 0; j < bw; ++j) { |
| 2401 | int scale = ii_weights1d[j * size_scale]; |
| 2402 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2403 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2404 | interpred[i * interstride + j]); |
| 2405 | } |
| 2406 | } |
| 2407 | break; |
| 2408 | |
| 2409 | case II_D63_PRED: |
| 2410 | case II_D117_PRED: |
| 2411 | for (i = 0; i < bh; ++i) { |
| 2412 | for (j = 0; j < bw; ++j) { |
| 2413 | int scale = (ii_weights1d[i * size_scale] * 3 + |
| 2414 | ii_weights1d[j * size_scale]) >> |
| 2415 | 2; |
| 2416 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2417 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2418 | interpred[i * interstride + j]); |
| 2419 | } |
| 2420 | } |
| 2421 | break; |
| 2422 | |
| 2423 | case II_D207_PRED: |
| 2424 | case II_D153_PRED: |
| 2425 | for (i = 0; i < bh; ++i) { |
| 2426 | for (j = 0; j < bw; ++j) { |
| 2427 | int scale = (ii_weights1d[j * size_scale] * 3 + |
| 2428 | ii_weights1d[i * size_scale]) >> |
| 2429 | 2; |
| 2430 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2431 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2432 | interpred[i * interstride + j]); |
| 2433 | } |
| 2434 | } |
| 2435 | break; |
| 2436 | |
| 2437 | case II_D135_PRED: |
| 2438 | for (i = 0; i < bh; ++i) { |
| 2439 | for (j = 0; j < bw; ++j) { |
| 2440 | int scale = ii_weights1d[(i < j ? i : j) * size_scale]; |
| 2441 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2442 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2443 | interpred[i * interstride + j]); |
| 2444 | } |
| 2445 | } |
| 2446 | break; |
| 2447 | |
| 2448 | case II_D45_PRED: |
| 2449 | for (i = 0; i < bh; ++i) { |
| 2450 | for (j = 0; j < bw; ++j) { |
| 2451 | int scale = |
| 2452 | (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >> |
| 2453 | 1; |
| 2454 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2455 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2456 | interpred[i * interstride + j]); |
| 2457 | } |
| 2458 | } |
| 2459 | break; |
| 2460 | |
| 2461 | case II_TM_PRED: |
| 2462 | case II_DC_PRED: |
| 2463 | default: |
| 2464 | for (i = 0; i < bh; ++i) { |
| 2465 | for (j = 0; j < bw; ++j) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2466 | comppred[i * compstride + j] = AOM_BLEND_AVG( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2467 | intrapred[i * intrastride + j], interpred[i * interstride + j]); |
| 2468 | } |
| 2469 | } |
| 2470 | break; |
| 2471 | } |
| 2472 | } |
| 2473 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2474 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2475 | static void combine_interintra_highbd( |
| 2476 | INTERINTRA_MODE mode, int use_wedge_interintra, int wedge_index, |
| 2477 | int wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize, |
| 2478 | uint8_t *comppred8, int compstride, const uint8_t *interpred8, |
| 2479 | int interstride, const uint8_t *intrapred8, int intrastride, int bd) { |
Jingning Han | ae5cfde | 2016-11-30 12:01:44 -0800 | [diff] [blame] | 2480 | const int bw = block_size_wide[plane_bsize]; |
| 2481 | const int bh = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2482 | const int size_scale = ii_size_scales[plane_bsize]; |
| 2483 | int i, j; |
| 2484 | |
| 2485 | uint16_t *comppred = CONVERT_TO_SHORTPTR(comppred8); |
| 2486 | const uint16_t *interpred = CONVERT_TO_SHORTPTR(interpred8); |
| 2487 | const uint16_t *intrapred = CONVERT_TO_SHORTPTR(intrapred8); |
| 2488 | |
| 2489 | if (use_wedge_interintra) { |
| 2490 | if (is_interintra_wedge_used(bsize)) { |
| 2491 | const uint8_t *mask = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2492 | av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2493 | const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh; |
| 2494 | const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2495 | aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2496 | interpred8, interstride, mask, bw, bh, bw, subh, |
| 2497 | subw, bd); |
| 2498 | } |
| 2499 | return; |
| 2500 | } |
| 2501 | |
| 2502 | switch (mode) { |
| 2503 | case II_V_PRED: |
| 2504 | for (i = 0; i < bh; ++i) { |
| 2505 | for (j = 0; j < bw; ++j) { |
| 2506 | int scale = ii_weights1d[i * size_scale]; |
| 2507 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2508 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2509 | interpred[i * interstride + j]); |
| 2510 | } |
| 2511 | } |
| 2512 | break; |
| 2513 | |
| 2514 | case II_H_PRED: |
| 2515 | for (i = 0; i < bh; ++i) { |
| 2516 | for (j = 0; j < bw; ++j) { |
| 2517 | int scale = ii_weights1d[j * size_scale]; |
| 2518 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2519 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2520 | interpred[i * interstride + j]); |
| 2521 | } |
| 2522 | } |
| 2523 | break; |
| 2524 | |
| 2525 | case II_D63_PRED: |
| 2526 | case II_D117_PRED: |
| 2527 | for (i = 0; i < bh; ++i) { |
| 2528 | for (j = 0; j < bw; ++j) { |
| 2529 | int scale = (ii_weights1d[i * size_scale] * 3 + |
| 2530 | ii_weights1d[j * size_scale]) >> |
| 2531 | 2; |
| 2532 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2533 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2534 | interpred[i * interstride + j]); |
| 2535 | } |
| 2536 | } |
| 2537 | break; |
| 2538 | |
| 2539 | case II_D207_PRED: |
| 2540 | case II_D153_PRED: |
| 2541 | for (i = 0; i < bh; ++i) { |
| 2542 | for (j = 0; j < bw; ++j) { |
| 2543 | int scale = (ii_weights1d[j * size_scale] * 3 + |
| 2544 | ii_weights1d[i * size_scale]) >> |
| 2545 | 2; |
| 2546 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2547 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2548 | interpred[i * interstride + j]); |
| 2549 | } |
| 2550 | } |
| 2551 | break; |
| 2552 | |
| 2553 | case II_D135_PRED: |
| 2554 | for (i = 0; i < bh; ++i) { |
| 2555 | for (j = 0; j < bw; ++j) { |
| 2556 | int scale = ii_weights1d[(i < j ? i : j) * size_scale]; |
| 2557 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2558 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2559 | interpred[i * interstride + j]); |
| 2560 | } |
| 2561 | } |
| 2562 | break; |
| 2563 | |
| 2564 | case II_D45_PRED: |
| 2565 | for (i = 0; i < bh; ++i) { |
| 2566 | for (j = 0; j < bw; ++j) { |
| 2567 | int scale = |
| 2568 | (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >> |
| 2569 | 1; |
| 2570 | comppred[i * compstride + j] = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2571 | AOM_BLEND_A256(scale, intrapred[i * intrastride + j], |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2572 | interpred[i * interstride + j]); |
| 2573 | } |
| 2574 | } |
| 2575 | break; |
| 2576 | |
| 2577 | case II_TM_PRED: |
| 2578 | case II_DC_PRED: |
| 2579 | default: |
| 2580 | for (i = 0; i < bh; ++i) { |
| 2581 | for (j = 0; j < bw; ++j) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2582 | comppred[i * compstride + j] = AOM_BLEND_AVG( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2583 | interpred[i * interstride + j], intrapred[i * intrastride + j]); |
| 2584 | } |
| 2585 | } |
| 2586 | break; |
| 2587 | } |
| 2588 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2589 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2590 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2591 | void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd, |
| 2592 | BLOCK_SIZE bsize, int plane, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2593 | BUFFER_SET *ctx, uint8_t *dst, |
| 2594 | int dst_stride) { |
David Barker | 839467f | 2017-01-19 11:06:15 +0000 | [diff] [blame^] | 2595 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 2596 | BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]); |
| 2597 | PREDICTION_MODE mode = |
| 2598 | interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode]; |
| 2599 | |
| 2600 | av1_predict_intra_block(xd, pd->width, pd->height, plane_bsize, mode, |
| 2601 | ctx->plane[plane], ctx->stride[plane], dst, |
| 2602 | dst_stride, 0, 0, plane); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2603 | } |
| 2604 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2605 | void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane, |
| 2606 | const uint8_t *inter_pred, int inter_stride, |
| 2607 | const uint8_t *intra_pred, int intra_stride) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2608 | const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2609 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2610 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
| 2611 | combine_interintra_highbd( |
| 2612 | xd->mi[0]->mbmi.interintra_mode, xd->mi[0]->mbmi.use_wedge_interintra, |
| 2613 | xd->mi[0]->mbmi.interintra_wedge_index, |
| 2614 | xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize, |
| 2615 | xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, inter_pred, |
| 2616 | inter_stride, intra_pred, intra_stride, xd->bd); |
| 2617 | return; |
| 2618 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2619 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2620 | combine_interintra(xd->mi[0]->mbmi.interintra_mode, |
| 2621 | xd->mi[0]->mbmi.use_wedge_interintra, |
| 2622 | xd->mi[0]->mbmi.interintra_wedge_index, |
| 2623 | xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize, |
| 2624 | xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, |
| 2625 | inter_pred, inter_stride, intra_pred, intra_stride); |
| 2626 | } |
| 2627 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2628 | void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2629 | int ystride, BUFFER_SET *ctx, |
| 2630 | BLOCK_SIZE bsize) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2631 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2632 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
| 2633 | DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2634 | av1_build_intra_predictors_for_interintra( |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2635 | xd, bsize, 0, ctx, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2636 | av1_combine_interintra(xd, bsize, 0, ypred, ystride, |
| 2637 | CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2638 | return; |
| 2639 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2640 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2641 | { |
| 2642 | DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]); |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2643 | av1_build_intra_predictors_for_interintra(xd, bsize, 0, ctx, intrapredictor, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2644 | MAX_SB_SIZE); |
| 2645 | av1_combine_interintra(xd, bsize, 0, ypred, ystride, intrapredictor, |
| 2646 | MAX_SB_SIZE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2647 | } |
| 2648 | } |
| 2649 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2650 | void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2651 | int ustride, BUFFER_SET *ctx, |
| 2652 | int plane, BLOCK_SIZE bsize) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2653 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2654 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { |
| 2655 | DECLARE_ALIGNED(16, uint16_t, uintrapredictor[MAX_SB_SQUARE]); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2656 | av1_build_intra_predictors_for_interintra( |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2657 | xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(uintrapredictor), |
| 2658 | MAX_SB_SIZE); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2659 | av1_combine_interintra(xd, bsize, plane, upred, ustride, |
| 2660 | CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2661 | return; |
| 2662 | } |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2663 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2664 | { |
| 2665 | DECLARE_ALIGNED(16, uint8_t, uintrapredictor[MAX_SB_SQUARE]); |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2666 | av1_build_intra_predictors_for_interintra(xd, bsize, plane, ctx, |
| 2667 | uintrapredictor, MAX_SB_SIZE); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2668 | av1_combine_interintra(xd, bsize, plane, upred, ustride, uintrapredictor, |
| 2669 | MAX_SB_SIZE); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2670 | } |
| 2671 | } |
| 2672 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2673 | void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred, |
| 2674 | uint8_t *vpred, int ustride, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2675 | int vstride, BUFFER_SET *ctx, |
| 2676 | BLOCK_SIZE bsize) { |
| 2677 | av1_build_interintra_predictors_sbc(xd, upred, ustride, ctx, 1, bsize); |
| 2678 | av1_build_interintra_predictors_sbc(xd, vpred, vstride, ctx, 2, bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2679 | } |
| 2680 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2681 | void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred, |
| 2682 | uint8_t *upred, uint8_t *vpred, |
| 2683 | int ystride, int ustride, int vstride, |
David Barker | ac37fa3 | 2016-12-02 12:30:21 +0000 | [diff] [blame] | 2684 | BUFFER_SET *ctx, BLOCK_SIZE bsize) { |
| 2685 | av1_build_interintra_predictors_sby(xd, ypred, ystride, ctx, bsize); |
| 2686 | av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride, ctx, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2687 | bsize); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2688 | } |
| 2689 | |
| 2690 | // Builds the inter-predictor for the single ref case |
| 2691 | // for use in the encoder to search the wedges efficiently. |
| 2692 | static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane, |
| 2693 | int block, int bw, int bh, int x, |
| 2694 | int y, int w, int h, int mi_x, |
| 2695 | int mi_y, int ref, |
| 2696 | uint8_t *const ext_dst, |
| 2697 | int ext_dst_stride) { |
| 2698 | struct macroblockd_plane *const pd = &xd->plane[plane]; |
| 2699 | const MODE_INFO *mi = xd->mi[0]; |
| 2700 | |
| 2701 | const struct scale_factors *const sf = &xd->block_refs[ref]->sf; |
| 2702 | struct buf_2d *const pre_buf = &pd->pre[ref]; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2703 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2704 | uint8_t *const dst = |
| 2705 | (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? CONVERT_TO_BYTEPTR(ext_dst) |
| 2706 | : ext_dst) + |
| 2707 | ext_dst_stride * y + x; |
| 2708 | #else |
| 2709 | uint8_t *const dst = ext_dst + ext_dst_stride * y + x; |
| 2710 | #endif |
| 2711 | const MV mv = mi->mbmi.sb_type < BLOCK_8X8 |
| 2712 | ? average_split_mvs(pd, mi, ref, block) |
| 2713 | : mi->mbmi.mv[ref].as_mv; |
| 2714 | |
| 2715 | // TODO(jkoleszar): This clamping is done in the incorrect place for the |
| 2716 | // scaling case. It needs to be done on the scaled MV, not the pre-scaling |
| 2717 | // MV. Note however that it performs the subsampling aware scaling so |
| 2718 | // that the result is always q4. |
| 2719 | // mv_precision precision is MV_PRECISION_Q4. |
| 2720 | const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh, pd->subsampling_x, |
| 2721 | pd->subsampling_y); |
| 2722 | |
| 2723 | uint8_t *pre; |
| 2724 | MV32 scaled_mv; |
| 2725 | int xs, ys, subpel_x, subpel_y; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2726 | const int is_scaled = av1_is_scaled(sf); |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 2727 | ConvolveParams conv_params = get_conv_params(0); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2728 | |
| 2729 | if (is_scaled) { |
| 2730 | pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2731 | scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2732 | xs = sf->x_step_q4; |
| 2733 | ys = sf->y_step_q4; |
| 2734 | } else { |
| 2735 | pre = pre_buf->buf + (y * pre_buf->stride + x); |
| 2736 | scaled_mv.row = mv_q4.row; |
| 2737 | scaled_mv.col = mv_q4.col; |
| 2738 | xs = ys = 16; |
| 2739 | } |
| 2740 | |
| 2741 | subpel_x = scaled_mv.col & SUBPEL_MASK; |
| 2742 | subpel_y = scaled_mv.row & SUBPEL_MASK; |
| 2743 | pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride + |
| 2744 | (scaled_mv.col >> SUBPEL_BITS); |
| 2745 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2746 | av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride, subpel_x, |
Angie Chiang | 9f45bc4 | 2017-01-13 16:27:54 -0800 | [diff] [blame] | 2747 | subpel_y, sf, w, h, &conv_params, |
| 2748 | mi->mbmi.interp_filter, xs, ys, xd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2749 | } |
| 2750 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2751 | void av1_build_inter_predictors_for_planes_single_buf( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2752 | MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row, |
| 2753 | int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]) { |
| 2754 | int plane; |
| 2755 | const int mi_x = mi_col * MI_SIZE; |
| 2756 | const int mi_y = mi_row * MI_SIZE; |
| 2757 | for (plane = plane_from; plane <= plane_to; ++plane) { |
| 2758 | const BLOCK_SIZE plane_bsize = |
| 2759 | get_plane_block_size(bsize, &xd->plane[plane]); |
| 2760 | const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; |
| 2761 | const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; |
Jingning Han | 691a690 | 2016-11-30 14:53:44 -0800 | [diff] [blame] | 2762 | const int bw = block_size_wide[plane_bsize]; |
| 2763 | const int bh = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2764 | |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2765 | if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2766 | int x, y; |
| 2767 | assert(bsize == BLOCK_8X8); |
| 2768 | for (y = 0; y < num_4x4_h; ++y) |
| 2769 | for (x = 0; x < num_4x4_w; ++x) |
| 2770 | build_inter_predictors_single_buf( |
| 2771 | xd, plane, y * 2 + x, bw, bh, 4 * x, 4 * y, 4, 4, mi_x, mi_y, ref, |
| 2772 | ext_dst[plane], ext_dst_stride[plane]); |
| 2773 | } else { |
| 2774 | build_inter_predictors_single_buf(xd, plane, 0, bw, bh, 0, 0, bw, bh, |
| 2775 | mi_x, mi_y, ref, ext_dst[plane], |
| 2776 | ext_dst_stride[plane]); |
| 2777 | } |
| 2778 | } |
| 2779 | } |
| 2780 | |
| 2781 | static void build_wedge_inter_predictor_from_buf( |
| 2782 | MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0, |
| 2783 | int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) { |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2784 | MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2785 | const int is_compound = has_second_ref(mbmi); |
| 2786 | MACROBLOCKD_PLANE *const pd = &xd->plane[plane]; |
| 2787 | struct buf_2d *const dst_buf = &pd->dst; |
| 2788 | uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2789 | INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2790 | |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 2791 | if (is_compound && |
| 2792 | is_masked_compound_type(mbmi->interinter_compound_data.type)) { |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2793 | #if CONFIG_COMPOUND_SEGMENT |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 2794 | #if CONFIG_AOM_HIGHBITDEPTH |
| 2795 | if (!plane && comp_data->type == COMPOUND_SEG) { |
| 2796 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
| 2797 | build_compound_seg_mask_highbd( |
| 2798 | comp_data->seg_mask, comp_data->mask_type, |
| 2799 | CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, |
| 2800 | CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, mbmi->sb_type, h, w, |
| 2801 | xd->bd); |
| 2802 | else |
| 2803 | build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, |
| 2804 | ext_dst0, ext_dst_stride0, ext_dst1, |
| 2805 | ext_dst_stride1, mbmi->sb_type, h, w); |
| 2806 | } |
| 2807 | #else |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2808 | if (!plane && comp_data->type == COMPOUND_SEG) |
Sarah Parker | b9f757c | 2017-01-06 17:12:24 -0800 | [diff] [blame] | 2809 | build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, |
| 2810 | ext_dst0, ext_dst_stride0, ext_dst1, |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2811 | ext_dst_stride1, mbmi->sb_type, h, w); |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 2812 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Sarah Parker | 569edda | 2016-12-14 14:57:38 -0800 | [diff] [blame] | 2813 | #endif // CONFIG_COMPOUND_SEGMENT |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2814 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2815 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 2816 | build_masked_compound_highbd( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2817 | dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, |
Debargha Mukherjee | 1edf9a3 | 2017-01-07 18:54:20 -0800 | [diff] [blame] | 2818 | CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data, |
| 2819 | mbmi->sb_type, h, w, xd->bd); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2820 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2821 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Sarah Parker | 6fdc853 | 2016-11-16 17:47:13 -0800 | [diff] [blame] | 2822 | build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0, |
| 2823 | ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type, |
| 2824 | h, w); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2825 | } else { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2826 | #if CONFIG_AOM_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2827 | if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2828 | aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2829 | dst, dst_buf->stride, NULL, 0, NULL, 0, w, h, |
| 2830 | xd->bd); |
| 2831 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2832 | #endif // CONFIG_AOM_HIGHBITDEPTH |
| 2833 | aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2834 | 0, NULL, 0, w, h); |
| 2835 | } |
| 2836 | } |
| 2837 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 2838 | void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize, |
| 2839 | int plane_from, int plane_to, |
| 2840 | uint8_t *ext_dst0[3], |
| 2841 | int ext_dst_stride0[3], |
| 2842 | uint8_t *ext_dst1[3], |
| 2843 | int ext_dst_stride1[3]) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2844 | int plane; |
| 2845 | for (plane = plane_from; plane <= plane_to; ++plane) { |
| 2846 | const BLOCK_SIZE plane_bsize = |
| 2847 | get_plane_block_size(bsize, &xd->plane[plane]); |
| 2848 | const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize]; |
| 2849 | const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize]; |
| 2850 | |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2851 | if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2852 | int x, y; |
| 2853 | assert(bsize == BLOCK_8X8); |
| 2854 | for (y = 0; y < num_4x4_h; ++y) |
| 2855 | for (x = 0; x < num_4x4_w; ++x) |
| 2856 | build_wedge_inter_predictor_from_buf( |
| 2857 | xd, plane, 4 * x, 4 * y, 4, 4, ext_dst0[plane], |
| 2858 | ext_dst_stride0[plane], ext_dst1[plane], ext_dst_stride1[plane]); |
| 2859 | } else { |
Jingning Han | 61418bb | 2017-01-23 17:12:48 -0800 | [diff] [blame] | 2860 | const int bw = block_size_wide[plane_bsize]; |
| 2861 | const int bh = block_size_high[plane_bsize]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 2862 | build_wedge_inter_predictor_from_buf( |
| 2863 | xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane], |
| 2864 | ext_dst1[plane], ext_dst_stride1[plane]); |
| 2865 | } |
| 2866 | } |
| 2867 | } |
| 2868 | #endif // CONFIG_EXT_INTER |