OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include <arm_neon.h> |
| 12 |
| 13 #include "./vpx_config.h" |
| 14 |
| 15 static INLINE void vp9_mbloop_filter_neon( |
| 16 uint8x8_t dblimit, // mblimit |
| 17 uint8x8_t dlimit, // limit |
| 18 uint8x8_t dthresh, // thresh |
| 19 uint8x8_t d3u8, // p2 |
| 20 uint8x8_t d4u8, // p2 |
| 21 uint8x8_t d5u8, // p1 |
| 22 uint8x8_t d6u8, // p0 |
| 23 uint8x8_t d7u8, // q0 |
| 24 uint8x8_t d16u8, // q1 |
| 25 uint8x8_t d17u8, // q2 |
| 26 uint8x8_t d18u8, // q3 |
| 27 uint8x8_t *d0ru8, // p1 |
| 28 uint8x8_t *d1ru8, // p1 |
| 29 uint8x8_t *d2ru8, // p0 |
| 30 uint8x8_t *d3ru8, // q0 |
| 31 uint8x8_t *d4ru8, // q1 |
| 32 uint8x8_t *d5ru8) { // q1 |
| 33 uint32_t flat; |
| 34 uint8x8_t d0u8, d1u8, d2u8, d19u8, d20u8, d21u8, d22u8, d23u8, d24u8; |
| 35 uint8x8_t d25u8, d26u8, d27u8, d28u8, d29u8, d30u8, d31u8; |
| 36 int16x8_t q15s16; |
| 37 uint16x8_t q10u16, q14u16; |
| 38 int8x8_t d21s8, d24s8, d25s8, d26s8, d28s8, d29s8, d30s8; |
| 39 |
| 40 d19u8 = vabd_u8(d3u8, d4u8); |
| 41 d20u8 = vabd_u8(d4u8, d5u8); |
| 42 d21u8 = vabd_u8(d5u8, d6u8); |
| 43 d22u8 = vabd_u8(d16u8, d7u8); |
| 44 d23u8 = vabd_u8(d17u8, d16u8); |
| 45 d24u8 = vabd_u8(d18u8, d17u8); |
| 46 |
| 47 d19u8 = vmax_u8(d19u8, d20u8); |
| 48 d20u8 = vmax_u8(d21u8, d22u8); |
| 49 |
| 50 d25u8 = vabd_u8(d6u8, d4u8); |
| 51 |
| 52 d23u8 = vmax_u8(d23u8, d24u8); |
| 53 |
| 54 d26u8 = vabd_u8(d7u8, d17u8); |
| 55 |
| 56 d19u8 = vmax_u8(d19u8, d20u8); |
| 57 |
| 58 d24u8 = vabd_u8(d6u8, d7u8); |
| 59 d27u8 = vabd_u8(d3u8, d6u8); |
| 60 d28u8 = vabd_u8(d18u8, d7u8); |
| 61 |
| 62 d19u8 = vmax_u8(d19u8, d23u8); |
| 63 |
| 64 d23u8 = vabd_u8(d5u8, d16u8); |
| 65 d24u8 = vqadd_u8(d24u8, d24u8); |
| 66 |
| 67 |
| 68 d19u8 = vcge_u8(dlimit, d19u8); |
| 69 |
| 70 |
| 71 d25u8 = vmax_u8(d25u8, d26u8); |
| 72 d26u8 = vmax_u8(d27u8, d28u8); |
| 73 |
| 74 d23u8 = vshr_n_u8(d23u8, 1); |
| 75 |
| 76 d25u8 = vmax_u8(d25u8, d26u8); |
| 77 |
| 78 d24u8 = vqadd_u8(d24u8, d23u8); |
| 79 |
| 80 d20u8 = vmax_u8(d20u8, d25u8); |
| 81 |
| 82 d23u8 = vdup_n_u8(1); |
| 83 d24u8 = vcge_u8(dblimit, d24u8); |
| 84 |
| 85 d21u8 = vcgt_u8(d21u8, dthresh); |
| 86 |
| 87 d20u8 = vcge_u8(d23u8, d20u8); |
| 88 |
| 89 d19u8 = vand_u8(d19u8, d24u8); |
| 90 |
| 91 d23u8 = vcgt_u8(d22u8, dthresh); |
| 92 |
| 93 d20u8 = vand_u8(d20u8, d19u8); |
| 94 |
| 95 d22u8 = vdup_n_u8(0x80); |
| 96 |
| 97 d23u8 = vorr_u8(d21u8, d23u8); |
| 98 |
| 99 q10u16 = vcombine_u16(vreinterpret_u16_u8(d20u8), |
| 100 vreinterpret_u16_u8(d21u8)); |
| 101 |
| 102 d30u8 = vshrn_n_u16(q10u16, 4); |
| 103 flat = vget_lane_u32(vreinterpret_u32_u8(d30u8), 0); |
| 104 |
| 105 if (flat == 0xffffffff) { // Check for all 1's, power_branch_only |
| 106 d27u8 = vdup_n_u8(3); |
| 107 d21u8 = vdup_n_u8(2); |
| 108 q14u16 = vaddl_u8(d6u8, d7u8); |
| 109 q14u16 = vmlal_u8(q14u16, d3u8, d27u8); |
| 110 q14u16 = vmlal_u8(q14u16, d4u8, d21u8); |
| 111 q14u16 = vaddw_u8(q14u16, d5u8); |
| 112 *d0ru8 = vqrshrn_n_u16(q14u16, 3); |
| 113 |
| 114 q14u16 = vsubw_u8(q14u16, d3u8); |
| 115 q14u16 = vsubw_u8(q14u16, d4u8); |
| 116 q14u16 = vaddw_u8(q14u16, d5u8); |
| 117 q14u16 = vaddw_u8(q14u16, d16u8); |
| 118 *d1ru8 = vqrshrn_n_u16(q14u16, 3); |
| 119 |
| 120 q14u16 = vsubw_u8(q14u16, d3u8); |
| 121 q14u16 = vsubw_u8(q14u16, d5u8); |
| 122 q14u16 = vaddw_u8(q14u16, d6u8); |
| 123 q14u16 = vaddw_u8(q14u16, d17u8); |
| 124 *d2ru8 = vqrshrn_n_u16(q14u16, 3); |
| 125 |
| 126 q14u16 = vsubw_u8(q14u16, d3u8); |
| 127 q14u16 = vsubw_u8(q14u16, d6u8); |
| 128 q14u16 = vaddw_u8(q14u16, d7u8); |
| 129 q14u16 = vaddw_u8(q14u16, d18u8); |
| 130 *d3ru8 = vqrshrn_n_u16(q14u16, 3); |
| 131 |
| 132 q14u16 = vsubw_u8(q14u16, d4u8); |
| 133 q14u16 = vsubw_u8(q14u16, d7u8); |
| 134 q14u16 = vaddw_u8(q14u16, d16u8); |
| 135 q14u16 = vaddw_u8(q14u16, d18u8); |
| 136 *d4ru8 = vqrshrn_n_u16(q14u16, 3); |
| 137 |
| 138 q14u16 = vsubw_u8(q14u16, d5u8); |
| 139 q14u16 = vsubw_u8(q14u16, d16u8); |
| 140 q14u16 = vaddw_u8(q14u16, d17u8); |
| 141 q14u16 = vaddw_u8(q14u16, d18u8); |
| 142 *d5ru8 = vqrshrn_n_u16(q14u16, 3); |
| 143 } else { |
| 144 d21u8 = veor_u8(d7u8, d22u8); |
| 145 d24u8 = veor_u8(d6u8, d22u8); |
| 146 d25u8 = veor_u8(d5u8, d22u8); |
| 147 d26u8 = veor_u8(d16u8, d22u8); |
| 148 |
| 149 d27u8 = vdup_n_u8(3); |
| 150 |
| 151 d28s8 = vsub_s8(vreinterpret_s8_u8(d21u8), vreinterpret_s8_u8(d24u8)); |
| 152 d29s8 = vqsub_s8(vreinterpret_s8_u8(d25u8), vreinterpret_s8_u8(d26u8)); |
| 153 |
| 154 q15s16 = vmull_s8(d28s8, vreinterpret_s8_u8(d27u8)); |
| 155 |
| 156 d29s8 = vand_s8(d29s8, vreinterpret_s8_u8(d23u8)); |
| 157 |
| 158 q15s16 = vaddw_s8(q15s16, d29s8); |
| 159 |
| 160 d29u8 = vdup_n_u8(4); |
| 161 |
| 162 d28s8 = vqmovn_s16(q15s16); |
| 163 |
| 164 d28s8 = vand_s8(d28s8, vreinterpret_s8_u8(d19u8)); |
| 165 |
| 166 d30s8 = vqadd_s8(d28s8, vreinterpret_s8_u8(d27u8)); |
| 167 d29s8 = vqadd_s8(d28s8, vreinterpret_s8_u8(d29u8)); |
| 168 d30s8 = vshr_n_s8(d30s8, 3); |
| 169 d29s8 = vshr_n_s8(d29s8, 3); |
| 170 |
| 171 d24s8 = vqadd_s8(vreinterpret_s8_u8(d24u8), d30s8); |
| 172 d21s8 = vqsub_s8(vreinterpret_s8_u8(d21u8), d29s8); |
| 173 |
| 174 d29s8 = vrshr_n_s8(d29s8, 1); |
| 175 d29s8 = vbic_s8(d29s8, vreinterpret_s8_u8(d23u8)); |
| 176 |
| 177 d25s8 = vqadd_s8(vreinterpret_s8_u8(d25u8), d29s8); |
| 178 d26s8 = vqsub_s8(vreinterpret_s8_u8(d26u8), d29s8); |
| 179 |
| 180 if (flat == 0) { // filter_branch_only |
| 181 *d0ru8 = d4u8; |
| 182 *d1ru8 = veor_u8(vreinterpret_u8_s8(d25s8), d22u8); |
| 183 *d2ru8 = veor_u8(vreinterpret_u8_s8(d24s8), d22u8); |
| 184 *d3ru8 = veor_u8(vreinterpret_u8_s8(d21s8), d22u8); |
| 185 *d4ru8 = veor_u8(vreinterpret_u8_s8(d26s8), d22u8); |
| 186 *d5ru8 = d17u8; |
| 187 return; |
| 188 } |
| 189 |
| 190 d21u8 = veor_u8(vreinterpret_u8_s8(d21s8), d22u8); |
| 191 d24u8 = veor_u8(vreinterpret_u8_s8(d24s8), d22u8); |
| 192 d25u8 = veor_u8(vreinterpret_u8_s8(d25s8), d22u8); |
| 193 d26u8 = veor_u8(vreinterpret_u8_s8(d26s8), d22u8); |
| 194 |
| 195 d23u8 = vdup_n_u8(2); |
| 196 q14u16 = vaddl_u8(d6u8, d7u8); |
| 197 q14u16 = vmlal_u8(q14u16, d3u8, d27u8); |
| 198 q14u16 = vmlal_u8(q14u16, d4u8, d23u8); |
| 199 |
| 200 d0u8 = vbsl_u8(d20u8, dblimit, d4u8); |
| 201 |
| 202 q14u16 = vaddw_u8(q14u16, d5u8); |
| 203 |
| 204 d1u8 = vbsl_u8(d20u8, dlimit, d25u8); |
| 205 |
| 206 d30u8 = vqrshrn_n_u16(q14u16, 3); |
| 207 |
| 208 q14u16 = vsubw_u8(q14u16, d3u8); |
| 209 q14u16 = vsubw_u8(q14u16, d4u8); |
| 210 q14u16 = vaddw_u8(q14u16, d5u8); |
| 211 q14u16 = vaddw_u8(q14u16, d16u8); |
| 212 |
| 213 d2u8 = vbsl_u8(d20u8, dthresh, d24u8); |
| 214 |
| 215 d31u8 = vqrshrn_n_u16(q14u16, 3); |
| 216 |
| 217 q14u16 = vsubw_u8(q14u16, d3u8); |
| 218 q14u16 = vsubw_u8(q14u16, d5u8); |
| 219 q14u16 = vaddw_u8(q14u16, d6u8); |
| 220 q14u16 = vaddw_u8(q14u16, d17u8); |
| 221 |
| 222 *d0ru8 = vbsl_u8(d20u8, d30u8, d0u8); |
| 223 |
| 224 d23u8 = vqrshrn_n_u16(q14u16, 3); |
| 225 |
| 226 q14u16 = vsubw_u8(q14u16, d3u8); |
| 227 q14u16 = vsubw_u8(q14u16, d6u8); |
| 228 q14u16 = vaddw_u8(q14u16, d7u8); |
| 229 |
| 230 *d1ru8 = vbsl_u8(d20u8, d31u8, d1u8); |
| 231 |
| 232 q14u16 = vaddw_u8(q14u16, d18u8); |
| 233 |
| 234 *d2ru8 = vbsl_u8(d20u8, d23u8, d2u8); |
| 235 |
| 236 d22u8 = vqrshrn_n_u16(q14u16, 3); |
| 237 |
| 238 q14u16 = vsubw_u8(q14u16, d4u8); |
| 239 q14u16 = vsubw_u8(q14u16, d7u8); |
| 240 q14u16 = vaddw_u8(q14u16, d16u8); |
| 241 |
| 242 d3u8 = vbsl_u8(d20u8, d3u8, d21u8); |
| 243 |
| 244 q14u16 = vaddw_u8(q14u16, d18u8); |
| 245 |
| 246 d4u8 = vbsl_u8(d20u8, d4u8, d26u8); |
| 247 |
| 248 d6u8 = vqrshrn_n_u16(q14u16, 3); |
| 249 |
| 250 q14u16 = vsubw_u8(q14u16, d5u8); |
| 251 q14u16 = vsubw_u8(q14u16, d16u8); |
| 252 q14u16 = vaddw_u8(q14u16, d17u8); |
| 253 q14u16 = vaddw_u8(q14u16, d18u8); |
| 254 |
| 255 d5u8 = vbsl_u8(d20u8, d5u8, d17u8); |
| 256 |
| 257 d7u8 = vqrshrn_n_u16(q14u16, 3); |
| 258 |
| 259 *d3ru8 = vbsl_u8(d20u8, d22u8, d3u8); |
| 260 *d4ru8 = vbsl_u8(d20u8, d6u8, d4u8); |
| 261 *d5ru8 = vbsl_u8(d20u8, d7u8, d5u8); |
| 262 } |
| 263 return; |
| 264 } |
| 265 |
| 266 void vp9_lpf_horizontal_8_neon( |
| 267 unsigned char *src, |
| 268 int pitch, |
| 269 unsigned char *blimit, |
| 270 unsigned char *limit, |
| 271 unsigned char *thresh, |
| 272 int count) { |
| 273 int i; |
| 274 uint8_t *s, *psrc; |
| 275 uint8x8_t dblimit, dlimit, dthresh; |
| 276 uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8; |
| 277 uint8x8_t d16u8, d17u8, d18u8; |
| 278 |
| 279 if (count == 0) // end_vp9_mblf_h_edge |
| 280 return; |
| 281 |
| 282 dblimit = vld1_u8(blimit); |
| 283 dlimit = vld1_u8(limit); |
| 284 dthresh = vld1_u8(thresh); |
| 285 |
| 286 psrc = src - (pitch << 2); |
| 287 for (i = 0; i < count; i++) { |
| 288 s = psrc + i * 8; |
| 289 |
| 290 d3u8 = vld1_u8(s); |
| 291 s += pitch; |
| 292 d4u8 = vld1_u8(s); |
| 293 s += pitch; |
| 294 d5u8 = vld1_u8(s); |
| 295 s += pitch; |
| 296 d6u8 = vld1_u8(s); |
| 297 s += pitch; |
| 298 d7u8 = vld1_u8(s); |
| 299 s += pitch; |
| 300 d16u8 = vld1_u8(s); |
| 301 s += pitch; |
| 302 d17u8 = vld1_u8(s); |
| 303 s += pitch; |
| 304 d18u8 = vld1_u8(s); |
| 305 |
| 306 vp9_mbloop_filter_neon(dblimit, dlimit, dthresh, |
| 307 d3u8, d4u8, d5u8, d6u8, d7u8, d16u8, d17u8, d18u8, |
| 308 &d0u8, &d1u8, &d2u8, &d3u8, &d4u8, &d5u8); |
| 309 |
| 310 s -= (pitch * 6); |
| 311 vst1_u8(s, d0u8); |
| 312 s += pitch; |
| 313 vst1_u8(s, d1u8); |
| 314 s += pitch; |
| 315 vst1_u8(s, d2u8); |
| 316 s += pitch; |
| 317 vst1_u8(s, d3u8); |
| 318 s += pitch; |
| 319 vst1_u8(s, d4u8); |
| 320 s += pitch; |
| 321 vst1_u8(s, d5u8); |
| 322 } |
| 323 return; |
| 324 } |
| 325 |
| 326 void vp9_lpf_vertical_8_neon( |
| 327 unsigned char *src, |
| 328 int pitch, |
| 329 unsigned char *blimit, |
| 330 unsigned char *limit, |
| 331 unsigned char *thresh, |
| 332 int count) { |
| 333 int i; |
| 334 uint8_t *s; |
| 335 uint8x8_t dblimit, dlimit, dthresh; |
| 336 uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8; |
| 337 uint8x8_t d16u8, d17u8, d18u8; |
| 338 uint32x2x2_t d2tmp0, d2tmp1, d2tmp2, d2tmp3; |
| 339 uint16x4x2_t d2tmp4, d2tmp5, d2tmp6, d2tmp7; |
| 340 uint8x8x2_t d2tmp8, d2tmp9, d2tmp10, d2tmp11; |
| 341 uint8x8x4_t d4Result; |
| 342 uint8x8x2_t d2Result; |
| 343 |
| 344 if (count == 0) |
| 345 return; |
| 346 |
| 347 dblimit = vld1_u8(blimit); |
| 348 dlimit = vld1_u8(limit); |
| 349 dthresh = vld1_u8(thresh); |
| 350 |
| 351 for (i = 0; i < count; i++) { |
| 352 s = src + (i * (pitch << 3)) - 4; |
| 353 |
| 354 d3u8 = vld1_u8(s); |
| 355 s += pitch; |
| 356 d4u8 = vld1_u8(s); |
| 357 s += pitch; |
| 358 d5u8 = vld1_u8(s); |
| 359 s += pitch; |
| 360 d6u8 = vld1_u8(s); |
| 361 s += pitch; |
| 362 d7u8 = vld1_u8(s); |
| 363 s += pitch; |
| 364 d16u8 = vld1_u8(s); |
| 365 s += pitch; |
| 366 d17u8 = vld1_u8(s); |
| 367 s += pitch; |
| 368 d18u8 = vld1_u8(s); |
| 369 |
| 370 d2tmp0 = vtrn_u32(vreinterpret_u32_u8(d3u8), |
| 371 vreinterpret_u32_u8(d7u8)); |
| 372 d2tmp1 = vtrn_u32(vreinterpret_u32_u8(d4u8), |
| 373 vreinterpret_u32_u8(d16u8)); |
| 374 d2tmp2 = vtrn_u32(vreinterpret_u32_u8(d5u8), |
| 375 vreinterpret_u32_u8(d17u8)); |
| 376 d2tmp3 = vtrn_u32(vreinterpret_u32_u8(d6u8), |
| 377 vreinterpret_u32_u8(d18u8)); |
| 378 |
| 379 d2tmp4 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[0]), |
| 380 vreinterpret_u16_u32(d2tmp2.val[0])); |
| 381 d2tmp5 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[0]), |
| 382 vreinterpret_u16_u32(d2tmp3.val[0])); |
| 383 d2tmp6 = vtrn_u16(vreinterpret_u16_u32(d2tmp0.val[1]), |
| 384 vreinterpret_u16_u32(d2tmp2.val[1])); |
| 385 d2tmp7 = vtrn_u16(vreinterpret_u16_u32(d2tmp1.val[1]), |
| 386 vreinterpret_u16_u32(d2tmp3.val[1])); |
| 387 |
| 388 d2tmp8 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[0]), |
| 389 vreinterpret_u8_u16(d2tmp5.val[0])); |
| 390 d2tmp9 = vtrn_u8(vreinterpret_u8_u16(d2tmp4.val[1]), |
| 391 vreinterpret_u8_u16(d2tmp5.val[1])); |
| 392 d2tmp10 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[0]), |
| 393 vreinterpret_u8_u16(d2tmp7.val[0])); |
| 394 d2tmp11 = vtrn_u8(vreinterpret_u8_u16(d2tmp6.val[1]), |
| 395 vreinterpret_u8_u16(d2tmp7.val[1])); |
| 396 |
| 397 d3u8 = d2tmp8.val[0]; |
| 398 d4u8 = d2tmp8.val[1]; |
| 399 d5u8 = d2tmp9.val[0]; |
| 400 d6u8 = d2tmp9.val[1]; |
| 401 d7u8 = d2tmp10.val[0]; |
| 402 d16u8 = d2tmp10.val[1]; |
| 403 d17u8 = d2tmp11.val[0]; |
| 404 d18u8 = d2tmp11.val[1]; |
| 405 |
| 406 vp9_mbloop_filter_neon(dblimit, dlimit, dthresh, |
| 407 d3u8, d4u8, d5u8, d6u8, d7u8, d16u8, d17u8, d18u8, |
| 408 &d0u8, &d1u8, &d2u8, &d3u8, &d4u8, &d5u8); |
| 409 |
| 410 d4Result.val[0] = d0u8; |
| 411 d4Result.val[1] = d1u8; |
| 412 d4Result.val[2] = d2u8; |
| 413 d4Result.val[3] = d3u8; |
| 414 |
| 415 d2Result.val[0] = d4u8; |
| 416 d2Result.val[1] = d5u8; |
| 417 |
| 418 s = src - 3; |
| 419 vst4_lane_u8(s, d4Result, 0); |
| 420 s += pitch; |
| 421 vst4_lane_u8(s, d4Result, 1); |
| 422 s += pitch; |
| 423 vst4_lane_u8(s, d4Result, 2); |
| 424 s += pitch; |
| 425 vst4_lane_u8(s, d4Result, 3); |
| 426 s += pitch; |
| 427 vst4_lane_u8(s, d4Result, 4); |
| 428 s += pitch; |
| 429 vst4_lane_u8(s, d4Result, 5); |
| 430 s += pitch; |
| 431 vst4_lane_u8(s, d4Result, 6); |
| 432 s += pitch; |
| 433 vst4_lane_u8(s, d4Result, 7); |
| 434 |
| 435 s = src + 1; |
| 436 vst2_lane_u8(s, d2Result, 0); |
| 437 s += pitch; |
| 438 vst2_lane_u8(s, d2Result, 1); |
| 439 s += pitch; |
| 440 vst2_lane_u8(s, d2Result, 2); |
| 441 s += pitch; |
| 442 vst2_lane_u8(s, d2Result, 3); |
| 443 s += pitch; |
| 444 vst2_lane_u8(s, d2Result, 4); |
| 445 s += pitch; |
| 446 vst2_lane_u8(s, d2Result, 5); |
| 447 s += pitch; |
| 448 vst2_lane_u8(s, d2Result, 6); |
| 449 s += pitch; |
| 450 vst2_lane_u8(s, d2Result, 7); |
| 451 } |
| 452 return; |
| 453 } |
OLD | NEW |