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