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 #include <string.h> 13 #include "./vpx_config.h" 14 #include "vpx_dsp/arm/mem_neon.h" 15 16 static const uint8_t bifilter4_coeff[8][2] = { { 128, 0 }, { 112, 16 }, 17 { 96, 32 }, { 80, 48 }, 18 { 64, 64 }, { 48, 80 }, 19 { 32, 96 }, { 16, 112 } }; 20 21 static INLINE uint8x8_t load_and_shift(const unsigned char *a) { 22 return vreinterpret_u8_u64(vshl_n_u64(vreinterpret_u64_u8(vld1_u8(a)), 32)); 23 } 24 25 void vp8_bilinear_predict4x4_neon(unsigned char *src_ptr, 26 int src_pixels_per_line, int xoffset, 27 int yoffset, unsigned char *dst_ptr, 28 int dst_pitch) { 29 uint8x8_t e0, e1, e2; 30 31 if (xoffset == 0) { // skip_1stpass_filter 32 uint8x8_t a0, a1, a2, a3, a4; 33 34 a0 = load_and_shift(src_ptr); 35 src_ptr += src_pixels_per_line; 36 a1 = vld1_u8(src_ptr); 37 src_ptr += src_pixels_per_line; 38 a2 = load_and_shift(src_ptr); 39 src_ptr += src_pixels_per_line; 40 a3 = vld1_u8(src_ptr); 41 src_ptr += src_pixels_per_line; 42 a4 = vld1_u8(src_ptr); 43 44 e0 = vext_u8(a0, a1, 4); 45 e1 = vext_u8(a2, a3, 4); 46 e2 = a4; 47 } else { 48 uint8x8_t a0, a1, a2, a3, a4, b4; 49 uint8x16_t a01, a23; 50 uint8x16_t b01, b23; 51 uint32x2x2_t c0, c1, c2, c3; 52 uint16x8_t d0, d1, d2; 53 const uint8x8_t filter0 = vdup_n_u8(bifilter4_coeff[xoffset][0]); 54 const uint8x8_t filter1 = vdup_n_u8(bifilter4_coeff[xoffset][1]); 55 56 a0 = vld1_u8(src_ptr); 57 src_ptr += src_pixels_per_line; 58 a1 = vld1_u8(src_ptr); 59 src_ptr += src_pixels_per_line; 60 a2 = vld1_u8(src_ptr); 61 src_ptr += src_pixels_per_line; 62 a3 = vld1_u8(src_ptr); 63 src_ptr += src_pixels_per_line; 64 a4 = vld1_u8(src_ptr); 65 66 a01 = vcombine_u8(a0, a1); 67 a23 = vcombine_u8(a2, a3); 68 69 b01 = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(a01), 8)); 70 b23 = vreinterpretq_u8_u64(vshrq_n_u64(vreinterpretq_u64_u8(a23), 8)); 71 b4 = vreinterpret_u8_u64(vshr_n_u64(vreinterpret_u64_u8(a4), 8)); 72 73 c0 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a01)), 74 vreinterpret_u32_u8(vget_high_u8(a01))); 75 c1 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(a23)), 76 vreinterpret_u32_u8(vget_high_u8(a23))); 77 c2 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b01)), 78 vreinterpret_u32_u8(vget_high_u8(b01))); 79 c3 = vzip_u32(vreinterpret_u32_u8(vget_low_u8(b23)), 80 vreinterpret_u32_u8(vget_high_u8(b23))); 81 82 d0 = vmull_u8(vreinterpret_u8_u32(c0.val[0]), filter0); 83 d1 = vmull_u8(vreinterpret_u8_u32(c1.val[0]), filter0); 84 d2 = vmull_u8(a4, filter0); 85 86 d0 = vmlal_u8(d0, vreinterpret_u8_u32(c2.val[0]), filter1); 87 d1 = vmlal_u8(d1, vreinterpret_u8_u32(c3.val[0]), filter1); 88 d2 = vmlal_u8(d2, b4, filter1); 89 90 e0 = vqrshrn_n_u16(d0, 7); 91 e1 = vqrshrn_n_u16(d1, 7); 92 e2 = vqrshrn_n_u16(d2, 7); 93 } 94 95 // secondpass_filter 96 if (yoffset == 0) { // skip_2ndpass_filter 97 store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(e0, e1)); 98 } else { 99 uint8x8_t f0, f1; 100 const uint8x8_t filter0 = vdup_n_u8(bifilter4_coeff[yoffset][0]); 101 const uint8x8_t filter1 = vdup_n_u8(bifilter4_coeff[yoffset][1]); 102 103 uint16x8_t b0 = vmull_u8(e0, filter0); 104 uint16x8_t b1 = vmull_u8(e1, filter0); 105 106 const uint8x8_t a0 = vext_u8(e0, e1, 4); 107 const uint8x8_t a1 = vext_u8(e1, e2, 4); 108 109 b0 = vmlal_u8(b0, a0, filter1); 110 b1 = vmlal_u8(b1, a1, filter1); 111 112 f0 = vqrshrn_n_u16(b0, 7); 113 f1 = vqrshrn_n_u16(b1, 7); 114 115 store_unaligned_u8q(dst_ptr, dst_pitch, vcombine_u8(f0, f1)); 116 } 117 } 118 119 void vp8_bilinear_predict8x4_neon(unsigned char *src_ptr, 120 int src_pixels_per_line, int xoffset, 121 int yoffset, unsigned char *dst_ptr, 122 int dst_pitch) { 123 uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8; 124 uint8x8_t d7u8, d9u8, d11u8, d22u8, d23u8, d24u8, d25u8, d26u8; 125 uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8; 126 uint16x8_t q1u16, q2u16, q3u16, q4u16; 127 uint16x8_t q6u16, q7u16, q8u16, q9u16, q10u16; 128 129 if (xoffset == 0) { // skip_1stpass_filter 130 d22u8 = vld1_u8(src_ptr); 131 src_ptr += src_pixels_per_line; 132 d23u8 = vld1_u8(src_ptr); 133 src_ptr += src_pixels_per_line; 134 d24u8 = vld1_u8(src_ptr); 135 src_ptr += src_pixels_per_line; 136 d25u8 = vld1_u8(src_ptr); 137 src_ptr += src_pixels_per_line; 138 d26u8 = vld1_u8(src_ptr); 139 } else { 140 q1u8 = vld1q_u8(src_ptr); 141 src_ptr += src_pixels_per_line; 142 q2u8 = vld1q_u8(src_ptr); 143 src_ptr += src_pixels_per_line; 144 q3u8 = vld1q_u8(src_ptr); 145 src_ptr += src_pixels_per_line; 146 q4u8 = vld1q_u8(src_ptr); 147 src_ptr += src_pixels_per_line; 148 q5u8 = vld1q_u8(src_ptr); 149 150 d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); 151 d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); 152 153 q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); 154 q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); 155 q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); 156 q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); 157 q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); 158 159 d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); 160 d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); 161 d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); 162 d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); 163 d11u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); 164 165 q6u16 = vmlal_u8(q6u16, d3u8, d1u8); 166 q7u16 = vmlal_u8(q7u16, d5u8, d1u8); 167 q8u16 = vmlal_u8(q8u16, d7u8, d1u8); 168 q9u16 = vmlal_u8(q9u16, d9u8, d1u8); 169 q10u16 = vmlal_u8(q10u16, d11u8, d1u8); 170 171 d22u8 = vqrshrn_n_u16(q6u16, 7); 172 d23u8 = vqrshrn_n_u16(q7u16, 7); 173 d24u8 = vqrshrn_n_u16(q8u16, 7); 174 d25u8 = vqrshrn_n_u16(q9u16, 7); 175 d26u8 = vqrshrn_n_u16(q10u16, 7); 176 } 177 178 // secondpass_filter 179 if (yoffset == 0) { // skip_2ndpass_filter 180 vst1_u8((uint8_t *)dst_ptr, d22u8); 181 dst_ptr += dst_pitch; 182 vst1_u8((uint8_t *)dst_ptr, d23u8); 183 dst_ptr += dst_pitch; 184 vst1_u8((uint8_t *)dst_ptr, d24u8); 185 dst_ptr += dst_pitch; 186 vst1_u8((uint8_t *)dst_ptr, d25u8); 187 } else { 188 d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); 189 d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); 190 191 q1u16 = vmull_u8(d22u8, d0u8); 192 q2u16 = vmull_u8(d23u8, d0u8); 193 q3u16 = vmull_u8(d24u8, d0u8); 194 q4u16 = vmull_u8(d25u8, d0u8); 195 196 q1u16 = vmlal_u8(q1u16, d23u8, d1u8); 197 q2u16 = vmlal_u8(q2u16, d24u8, d1u8); 198 q3u16 = vmlal_u8(q3u16, d25u8, d1u8); 199 q4u16 = vmlal_u8(q4u16, d26u8, d1u8); 200 201 d2u8 = vqrshrn_n_u16(q1u16, 7); 202 d3u8 = vqrshrn_n_u16(q2u16, 7); 203 d4u8 = vqrshrn_n_u16(q3u16, 7); 204 d5u8 = vqrshrn_n_u16(q4u16, 7); 205 206 vst1_u8((uint8_t *)dst_ptr, d2u8); 207 dst_ptr += dst_pitch; 208 vst1_u8((uint8_t *)dst_ptr, d3u8); 209 dst_ptr += dst_pitch; 210 vst1_u8((uint8_t *)dst_ptr, d4u8); 211 dst_ptr += dst_pitch; 212 vst1_u8((uint8_t *)dst_ptr, d5u8); 213 } 214 return; 215 } 216 217 void vp8_bilinear_predict8x8_neon(unsigned char *src_ptr, 218 int src_pixels_per_line, int xoffset, 219 int yoffset, unsigned char *dst_ptr, 220 int dst_pitch) { 221 uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8, d11u8; 222 uint8x8_t d22u8, d23u8, d24u8, d25u8, d26u8, d27u8, d28u8, d29u8, d30u8; 223 uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8; 224 uint16x8_t q1u16, q2u16, q3u16, q4u16, q5u16; 225 uint16x8_t q6u16, q7u16, q8u16, q9u16, q10u16; 226 227 if (xoffset == 0) { // skip_1stpass_filter 228 d22u8 = vld1_u8(src_ptr); 229 src_ptr += src_pixels_per_line; 230 d23u8 = vld1_u8(src_ptr); 231 src_ptr += src_pixels_per_line; 232 d24u8 = vld1_u8(src_ptr); 233 src_ptr += src_pixels_per_line; 234 d25u8 = vld1_u8(src_ptr); 235 src_ptr += src_pixels_per_line; 236 d26u8 = vld1_u8(src_ptr); 237 src_ptr += src_pixels_per_line; 238 d27u8 = vld1_u8(src_ptr); 239 src_ptr += src_pixels_per_line; 240 d28u8 = vld1_u8(src_ptr); 241 src_ptr += src_pixels_per_line; 242 d29u8 = vld1_u8(src_ptr); 243 src_ptr += src_pixels_per_line; 244 d30u8 = vld1_u8(src_ptr); 245 } else { 246 q1u8 = vld1q_u8(src_ptr); 247 src_ptr += src_pixels_per_line; 248 q2u8 = vld1q_u8(src_ptr); 249 src_ptr += src_pixels_per_line; 250 q3u8 = vld1q_u8(src_ptr); 251 src_ptr += src_pixels_per_line; 252 q4u8 = vld1q_u8(src_ptr); 253 src_ptr += src_pixels_per_line; 254 255 d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); 256 d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); 257 258 q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); 259 q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); 260 q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); 261 q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); 262 263 d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); 264 d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); 265 d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); 266 d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); 267 268 q6u16 = vmlal_u8(q6u16, d3u8, d1u8); 269 q7u16 = vmlal_u8(q7u16, d5u8, d1u8); 270 q8u16 = vmlal_u8(q8u16, d7u8, d1u8); 271 q9u16 = vmlal_u8(q9u16, d9u8, d1u8); 272 273 d22u8 = vqrshrn_n_u16(q6u16, 7); 274 d23u8 = vqrshrn_n_u16(q7u16, 7); 275 d24u8 = vqrshrn_n_u16(q8u16, 7); 276 d25u8 = vqrshrn_n_u16(q9u16, 7); 277 278 // first_pass filtering on the rest 5-line data 279 q1u8 = vld1q_u8(src_ptr); 280 src_ptr += src_pixels_per_line; 281 q2u8 = vld1q_u8(src_ptr); 282 src_ptr += src_pixels_per_line; 283 q3u8 = vld1q_u8(src_ptr); 284 src_ptr += src_pixels_per_line; 285 q4u8 = vld1q_u8(src_ptr); 286 src_ptr += src_pixels_per_line; 287 q5u8 = vld1q_u8(src_ptr); 288 289 q6u16 = vmull_u8(vget_low_u8(q1u8), d0u8); 290 q7u16 = vmull_u8(vget_low_u8(q2u8), d0u8); 291 q8u16 = vmull_u8(vget_low_u8(q3u8), d0u8); 292 q9u16 = vmull_u8(vget_low_u8(q4u8), d0u8); 293 q10u16 = vmull_u8(vget_low_u8(q5u8), d0u8); 294 295 d3u8 = vext_u8(vget_low_u8(q1u8), vget_high_u8(q1u8), 1); 296 d5u8 = vext_u8(vget_low_u8(q2u8), vget_high_u8(q2u8), 1); 297 d7u8 = vext_u8(vget_low_u8(q3u8), vget_high_u8(q3u8), 1); 298 d9u8 = vext_u8(vget_low_u8(q4u8), vget_high_u8(q4u8), 1); 299 d11u8 = vext_u8(vget_low_u8(q5u8), vget_high_u8(q5u8), 1); 300 301 q6u16 = vmlal_u8(q6u16, d3u8, d1u8); 302 q7u16 = vmlal_u8(q7u16, d5u8, d1u8); 303 q8u16 = vmlal_u8(q8u16, d7u8, d1u8); 304 q9u16 = vmlal_u8(q9u16, d9u8, d1u8); 305 q10u16 = vmlal_u8(q10u16, d11u8, d1u8); 306 307 d26u8 = vqrshrn_n_u16(q6u16, 7); 308 d27u8 = vqrshrn_n_u16(q7u16, 7); 309 d28u8 = vqrshrn_n_u16(q8u16, 7); 310 d29u8 = vqrshrn_n_u16(q9u16, 7); 311 d30u8 = vqrshrn_n_u16(q10u16, 7); 312 } 313 314 // secondpass_filter 315 if (yoffset == 0) { // skip_2ndpass_filter 316 vst1_u8((uint8_t *)dst_ptr, d22u8); 317 dst_ptr += dst_pitch; 318 vst1_u8((uint8_t *)dst_ptr, d23u8); 319 dst_ptr += dst_pitch; 320 vst1_u8((uint8_t *)dst_ptr, d24u8); 321 dst_ptr += dst_pitch; 322 vst1_u8((uint8_t *)dst_ptr, d25u8); 323 dst_ptr += dst_pitch; 324 vst1_u8((uint8_t *)dst_ptr, d26u8); 325 dst_ptr += dst_pitch; 326 vst1_u8((uint8_t *)dst_ptr, d27u8); 327 dst_ptr += dst_pitch; 328 vst1_u8((uint8_t *)dst_ptr, d28u8); 329 dst_ptr += dst_pitch; 330 vst1_u8((uint8_t *)dst_ptr, d29u8); 331 } else { 332 d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); 333 d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); 334 335 q1u16 = vmull_u8(d22u8, d0u8); 336 q2u16 = vmull_u8(d23u8, d0u8); 337 q3u16 = vmull_u8(d24u8, d0u8); 338 q4u16 = vmull_u8(d25u8, d0u8); 339 q5u16 = vmull_u8(d26u8, d0u8); 340 q6u16 = vmull_u8(d27u8, d0u8); 341 q7u16 = vmull_u8(d28u8, d0u8); 342 q8u16 = vmull_u8(d29u8, d0u8); 343 344 q1u16 = vmlal_u8(q1u16, d23u8, d1u8); 345 q2u16 = vmlal_u8(q2u16, d24u8, d1u8); 346 q3u16 = vmlal_u8(q3u16, d25u8, d1u8); 347 q4u16 = vmlal_u8(q4u16, d26u8, d1u8); 348 q5u16 = vmlal_u8(q5u16, d27u8, d1u8); 349 q6u16 = vmlal_u8(q6u16, d28u8, d1u8); 350 q7u16 = vmlal_u8(q7u16, d29u8, d1u8); 351 q8u16 = vmlal_u8(q8u16, d30u8, d1u8); 352 353 d2u8 = vqrshrn_n_u16(q1u16, 7); 354 d3u8 = vqrshrn_n_u16(q2u16, 7); 355 d4u8 = vqrshrn_n_u16(q3u16, 7); 356 d5u8 = vqrshrn_n_u16(q4u16, 7); 357 d6u8 = vqrshrn_n_u16(q5u16, 7); 358 d7u8 = vqrshrn_n_u16(q6u16, 7); 359 d8u8 = vqrshrn_n_u16(q7u16, 7); 360 d9u8 = vqrshrn_n_u16(q8u16, 7); 361 362 vst1_u8((uint8_t *)dst_ptr, d2u8); 363 dst_ptr += dst_pitch; 364 vst1_u8((uint8_t *)dst_ptr, d3u8); 365 dst_ptr += dst_pitch; 366 vst1_u8((uint8_t *)dst_ptr, d4u8); 367 dst_ptr += dst_pitch; 368 vst1_u8((uint8_t *)dst_ptr, d5u8); 369 dst_ptr += dst_pitch; 370 vst1_u8((uint8_t *)dst_ptr, d6u8); 371 dst_ptr += dst_pitch; 372 vst1_u8((uint8_t *)dst_ptr, d7u8); 373 dst_ptr += dst_pitch; 374 vst1_u8((uint8_t *)dst_ptr, d8u8); 375 dst_ptr += dst_pitch; 376 vst1_u8((uint8_t *)dst_ptr, d9u8); 377 } 378 return; 379 } 380 381 void vp8_bilinear_predict16x16_neon(unsigned char *src_ptr, 382 int src_pixels_per_line, int xoffset, 383 int yoffset, unsigned char *dst_ptr, 384 int dst_pitch) { 385 int i; 386 unsigned char tmp[272]; 387 unsigned char *tmpp; 388 uint8x8_t d0u8, d1u8, d2u8, d3u8, d4u8, d5u8, d6u8, d7u8, d8u8, d9u8; 389 uint8x8_t d10u8, d11u8, d12u8, d13u8, d14u8, d15u8, d16u8, d17u8, d18u8; 390 uint8x8_t d19u8, d20u8, d21u8; 391 uint8x16_t q1u8, q2u8, q3u8, q4u8, q5u8, q6u8, q7u8, q8u8, q9u8, q10u8; 392 uint8x16_t q11u8, q12u8, q13u8, q14u8, q15u8; 393 uint16x8_t q1u16, q2u16, q3u16, q4u16, q5u16, q6u16, q7u16, q8u16; 394 uint16x8_t q9u16, q10u16, q11u16, q12u16, q13u16, q14u16; 395 396 if (xoffset == 0) { // secondpass_bfilter16x16_only 397 d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); 398 d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); 399 400 q11u8 = vld1q_u8(src_ptr); 401 src_ptr += src_pixels_per_line; 402 for (i = 4; i > 0; i--) { 403 q12u8 = vld1q_u8(src_ptr); 404 src_ptr += src_pixels_per_line; 405 q13u8 = vld1q_u8(src_ptr); 406 src_ptr += src_pixels_per_line; 407 q14u8 = vld1q_u8(src_ptr); 408 src_ptr += src_pixels_per_line; 409 q15u8 = vld1q_u8(src_ptr); 410 src_ptr += src_pixels_per_line; 411 412 q1u16 = vmull_u8(vget_low_u8(q11u8), d0u8); 413 q2u16 = vmull_u8(vget_high_u8(q11u8), d0u8); 414 q3u16 = vmull_u8(vget_low_u8(q12u8), d0u8); 415 q4u16 = vmull_u8(vget_high_u8(q12u8), d0u8); 416 q5u16 = vmull_u8(vget_low_u8(q13u8), d0u8); 417 q6u16 = vmull_u8(vget_high_u8(q13u8), d0u8); 418 q7u16 = vmull_u8(vget_low_u8(q14u8), d0u8); 419 q8u16 = vmull_u8(vget_high_u8(q14u8), d0u8); 420 421 q1u16 = vmlal_u8(q1u16, vget_low_u8(q12u8), d1u8); 422 q2u16 = vmlal_u8(q2u16, vget_high_u8(q12u8), d1u8); 423 q3u16 = vmlal_u8(q3u16, vget_low_u8(q13u8), d1u8); 424 q4u16 = vmlal_u8(q4u16, vget_high_u8(q13u8), d1u8); 425 q5u16 = vmlal_u8(q5u16, vget_low_u8(q14u8), d1u8); 426 q6u16 = vmlal_u8(q6u16, vget_high_u8(q14u8), d1u8); 427 q7u16 = vmlal_u8(q7u16, vget_low_u8(q15u8), d1u8); 428 q8u16 = vmlal_u8(q8u16, vget_high_u8(q15u8), d1u8); 429 430 d2u8 = vqrshrn_n_u16(q1u16, 7); 431 d3u8 = vqrshrn_n_u16(q2u16, 7); 432 d4u8 = vqrshrn_n_u16(q3u16, 7); 433 d5u8 = vqrshrn_n_u16(q4u16, 7); 434 d6u8 = vqrshrn_n_u16(q5u16, 7); 435 d7u8 = vqrshrn_n_u16(q6u16, 7); 436 d8u8 = vqrshrn_n_u16(q7u16, 7); 437 d9u8 = vqrshrn_n_u16(q8u16, 7); 438 439 q1u8 = vcombine_u8(d2u8, d3u8); 440 q2u8 = vcombine_u8(d4u8, d5u8); 441 q3u8 = vcombine_u8(d6u8, d7u8); 442 q4u8 = vcombine_u8(d8u8, d9u8); 443 444 q11u8 = q15u8; 445 446 vst1q_u8((uint8_t *)dst_ptr, q1u8); 447 dst_ptr += dst_pitch; 448 vst1q_u8((uint8_t *)dst_ptr, q2u8); 449 dst_ptr += dst_pitch; 450 vst1q_u8((uint8_t *)dst_ptr, q3u8); 451 dst_ptr += dst_pitch; 452 vst1q_u8((uint8_t *)dst_ptr, q4u8); 453 dst_ptr += dst_pitch; 454 } 455 return; 456 } 457 458 if (yoffset == 0) { // firstpass_bfilter16x16_only 459 d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); 460 d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); 461 462 for (i = 4; i > 0; i--) { 463 d2u8 = vld1_u8(src_ptr); 464 d3u8 = vld1_u8(src_ptr + 8); 465 d4u8 = vld1_u8(src_ptr + 16); 466 src_ptr += src_pixels_per_line; 467 d5u8 = vld1_u8(src_ptr); 468 d6u8 = vld1_u8(src_ptr + 8); 469 d7u8 = vld1_u8(src_ptr + 16); 470 src_ptr += src_pixels_per_line; 471 d8u8 = vld1_u8(src_ptr); 472 d9u8 = vld1_u8(src_ptr + 8); 473 d10u8 = vld1_u8(src_ptr + 16); 474 src_ptr += src_pixels_per_line; 475 d11u8 = vld1_u8(src_ptr); 476 d12u8 = vld1_u8(src_ptr + 8); 477 d13u8 = vld1_u8(src_ptr + 16); 478 src_ptr += src_pixels_per_line; 479 480 q7u16 = vmull_u8(d2u8, d0u8); 481 q8u16 = vmull_u8(d3u8, d0u8); 482 q9u16 = vmull_u8(d5u8, d0u8); 483 q10u16 = vmull_u8(d6u8, d0u8); 484 q11u16 = vmull_u8(d8u8, d0u8); 485 q12u16 = vmull_u8(d9u8, d0u8); 486 q13u16 = vmull_u8(d11u8, d0u8); 487 q14u16 = vmull_u8(d12u8, d0u8); 488 489 d2u8 = vext_u8(d2u8, d3u8, 1); 490 d5u8 = vext_u8(d5u8, d6u8, 1); 491 d8u8 = vext_u8(d8u8, d9u8, 1); 492 d11u8 = vext_u8(d11u8, d12u8, 1); 493 494 q7u16 = vmlal_u8(q7u16, d2u8, d1u8); 495 q9u16 = vmlal_u8(q9u16, d5u8, d1u8); 496 q11u16 = vmlal_u8(q11u16, d8u8, d1u8); 497 q13u16 = vmlal_u8(q13u16, d11u8, d1u8); 498 499 d3u8 = vext_u8(d3u8, d4u8, 1); 500 d6u8 = vext_u8(d6u8, d7u8, 1); 501 d9u8 = vext_u8(d9u8, d10u8, 1); 502 d12u8 = vext_u8(d12u8, d13u8, 1); 503 504 q8u16 = vmlal_u8(q8u16, d3u8, d1u8); 505 q10u16 = vmlal_u8(q10u16, d6u8, d1u8); 506 q12u16 = vmlal_u8(q12u16, d9u8, d1u8); 507 q14u16 = vmlal_u8(q14u16, d12u8, d1u8); 508 509 d14u8 = vqrshrn_n_u16(q7u16, 7); 510 d15u8 = vqrshrn_n_u16(q8u16, 7); 511 d16u8 = vqrshrn_n_u16(q9u16, 7); 512 d17u8 = vqrshrn_n_u16(q10u16, 7); 513 d18u8 = vqrshrn_n_u16(q11u16, 7); 514 d19u8 = vqrshrn_n_u16(q12u16, 7); 515 d20u8 = vqrshrn_n_u16(q13u16, 7); 516 d21u8 = vqrshrn_n_u16(q14u16, 7); 517 518 q7u8 = vcombine_u8(d14u8, d15u8); 519 q8u8 = vcombine_u8(d16u8, d17u8); 520 q9u8 = vcombine_u8(d18u8, d19u8); 521 q10u8 = vcombine_u8(d20u8, d21u8); 522 523 vst1q_u8((uint8_t *)dst_ptr, q7u8); 524 dst_ptr += dst_pitch; 525 vst1q_u8((uint8_t *)dst_ptr, q8u8); 526 dst_ptr += dst_pitch; 527 vst1q_u8((uint8_t *)dst_ptr, q9u8); 528 dst_ptr += dst_pitch; 529 vst1q_u8((uint8_t *)dst_ptr, q10u8); 530 dst_ptr += dst_pitch; 531 } 532 return; 533 } 534 535 d0u8 = vdup_n_u8(bifilter4_coeff[xoffset][0]); 536 d1u8 = vdup_n_u8(bifilter4_coeff[xoffset][1]); 537 538 d2u8 = vld1_u8(src_ptr); 539 d3u8 = vld1_u8(src_ptr + 8); 540 d4u8 = vld1_u8(src_ptr + 16); 541 src_ptr += src_pixels_per_line; 542 d5u8 = vld1_u8(src_ptr); 543 d6u8 = vld1_u8(src_ptr + 8); 544 d7u8 = vld1_u8(src_ptr + 16); 545 src_ptr += src_pixels_per_line; 546 d8u8 = vld1_u8(src_ptr); 547 d9u8 = vld1_u8(src_ptr + 8); 548 d10u8 = vld1_u8(src_ptr + 16); 549 src_ptr += src_pixels_per_line; 550 d11u8 = vld1_u8(src_ptr); 551 d12u8 = vld1_u8(src_ptr + 8); 552 d13u8 = vld1_u8(src_ptr + 16); 553 src_ptr += src_pixels_per_line; 554 555 // First Pass: output_height lines x output_width columns (17x16) 556 tmpp = tmp; 557 for (i = 3; i > 0; i--) { 558 q7u16 = vmull_u8(d2u8, d0u8); 559 q8u16 = vmull_u8(d3u8, d0u8); 560 q9u16 = vmull_u8(d5u8, d0u8); 561 q10u16 = vmull_u8(d6u8, d0u8); 562 q11u16 = vmull_u8(d8u8, d0u8); 563 q12u16 = vmull_u8(d9u8, d0u8); 564 q13u16 = vmull_u8(d11u8, d0u8); 565 q14u16 = vmull_u8(d12u8, d0u8); 566 567 d2u8 = vext_u8(d2u8, d3u8, 1); 568 d5u8 = vext_u8(d5u8, d6u8, 1); 569 d8u8 = vext_u8(d8u8, d9u8, 1); 570 d11u8 = vext_u8(d11u8, d12u8, 1); 571 572 q7u16 = vmlal_u8(q7u16, d2u8, d1u8); 573 q9u16 = vmlal_u8(q9u16, d5u8, d1u8); 574 q11u16 = vmlal_u8(q11u16, d8u8, d1u8); 575 q13u16 = vmlal_u8(q13u16, d11u8, d1u8); 576 577 d3u8 = vext_u8(d3u8, d4u8, 1); 578 d6u8 = vext_u8(d6u8, d7u8, 1); 579 d9u8 = vext_u8(d9u8, d10u8, 1); 580 d12u8 = vext_u8(d12u8, d13u8, 1); 581 582 q8u16 = vmlal_u8(q8u16, d3u8, d1u8); 583 q10u16 = vmlal_u8(q10u16, d6u8, d1u8); 584 q12u16 = vmlal_u8(q12u16, d9u8, d1u8); 585 q14u16 = vmlal_u8(q14u16, d12u8, d1u8); 586 587 d14u8 = vqrshrn_n_u16(q7u16, 7); 588 d15u8 = vqrshrn_n_u16(q8u16, 7); 589 d16u8 = vqrshrn_n_u16(q9u16, 7); 590 d17u8 = vqrshrn_n_u16(q10u16, 7); 591 d18u8 = vqrshrn_n_u16(q11u16, 7); 592 d19u8 = vqrshrn_n_u16(q12u16, 7); 593 d20u8 = vqrshrn_n_u16(q13u16, 7); 594 d21u8 = vqrshrn_n_u16(q14u16, 7); 595 596 d2u8 = vld1_u8(src_ptr); 597 d3u8 = vld1_u8(src_ptr + 8); 598 d4u8 = vld1_u8(src_ptr + 16); 599 src_ptr += src_pixels_per_line; 600 d5u8 = vld1_u8(src_ptr); 601 d6u8 = vld1_u8(src_ptr + 8); 602 d7u8 = vld1_u8(src_ptr + 16); 603 src_ptr += src_pixels_per_line; 604 d8u8 = vld1_u8(src_ptr); 605 d9u8 = vld1_u8(src_ptr + 8); 606 d10u8 = vld1_u8(src_ptr + 16); 607 src_ptr += src_pixels_per_line; 608 d11u8 = vld1_u8(src_ptr); 609 d12u8 = vld1_u8(src_ptr + 8); 610 d13u8 = vld1_u8(src_ptr + 16); 611 src_ptr += src_pixels_per_line; 612 613 q7u8 = vcombine_u8(d14u8, d15u8); 614 q8u8 = vcombine_u8(d16u8, d17u8); 615 q9u8 = vcombine_u8(d18u8, d19u8); 616 q10u8 = vcombine_u8(d20u8, d21u8); 617 618 vst1q_u8((uint8_t *)tmpp, q7u8); 619 tmpp += 16; 620 vst1q_u8((uint8_t *)tmpp, q8u8); 621 tmpp += 16; 622 vst1q_u8((uint8_t *)tmpp, q9u8); 623 tmpp += 16; 624 vst1q_u8((uint8_t *)tmpp, q10u8); 625 tmpp += 16; 626 } 627 628 // First-pass filtering for rest 5 lines 629 d14u8 = vld1_u8(src_ptr); 630 d15u8 = vld1_u8(src_ptr + 8); 631 d16u8 = vld1_u8(src_ptr + 16); 632 src_ptr += src_pixels_per_line; 633 634 q9u16 = vmull_u8(d2u8, d0u8); 635 q10u16 = vmull_u8(d3u8, d0u8); 636 q11u16 = vmull_u8(d5u8, d0u8); 637 q12u16 = vmull_u8(d6u8, d0u8); 638 q13u16 = vmull_u8(d8u8, d0u8); 639 q14u16 = vmull_u8(d9u8, d0u8); 640 641 d2u8 = vext_u8(d2u8, d3u8, 1); 642 d5u8 = vext_u8(d5u8, d6u8, 1); 643 d8u8 = vext_u8(d8u8, d9u8, 1); 644 645 q9u16 = vmlal_u8(q9u16, d2u8, d1u8); 646 q11u16 = vmlal_u8(q11u16, d5u8, d1u8); 647 q13u16 = vmlal_u8(q13u16, d8u8, d1u8); 648 649 d3u8 = vext_u8(d3u8, d4u8, 1); 650 d6u8 = vext_u8(d6u8, d7u8, 1); 651 d9u8 = vext_u8(d9u8, d10u8, 1); 652 653 q10u16 = vmlal_u8(q10u16, d3u8, d1u8); 654 q12u16 = vmlal_u8(q12u16, d6u8, d1u8); 655 q14u16 = vmlal_u8(q14u16, d9u8, d1u8); 656 657 q1u16 = vmull_u8(d11u8, d0u8); 658 q2u16 = vmull_u8(d12u8, d0u8); 659 q3u16 = vmull_u8(d14u8, d0u8); 660 q4u16 = vmull_u8(d15u8, d0u8); 661 662 d11u8 = vext_u8(d11u8, d12u8, 1); 663 d14u8 = vext_u8(d14u8, d15u8, 1); 664 665 q1u16 = vmlal_u8(q1u16, d11u8, d1u8); 666 q3u16 = vmlal_u8(q3u16, d14u8, d1u8); 667 668 d12u8 = vext_u8(d12u8, d13u8, 1); 669 d15u8 = vext_u8(d15u8, d16u8, 1); 670 671 q2u16 = vmlal_u8(q2u16, d12u8, d1u8); 672 q4u16 = vmlal_u8(q4u16, d15u8, d1u8); 673 674 d10u8 = vqrshrn_n_u16(q9u16, 7); 675 d11u8 = vqrshrn_n_u16(q10u16, 7); 676 d12u8 = vqrshrn_n_u16(q11u16, 7); 677 d13u8 = vqrshrn_n_u16(q12u16, 7); 678 d14u8 = vqrshrn_n_u16(q13u16, 7); 679 d15u8 = vqrshrn_n_u16(q14u16, 7); 680 d16u8 = vqrshrn_n_u16(q1u16, 7); 681 d17u8 = vqrshrn_n_u16(q2u16, 7); 682 d18u8 = vqrshrn_n_u16(q3u16, 7); 683 d19u8 = vqrshrn_n_u16(q4u16, 7); 684 685 q5u8 = vcombine_u8(d10u8, d11u8); 686 q6u8 = vcombine_u8(d12u8, d13u8); 687 q7u8 = vcombine_u8(d14u8, d15u8); 688 q8u8 = vcombine_u8(d16u8, d17u8); 689 q9u8 = vcombine_u8(d18u8, d19u8); 690 691 vst1q_u8((uint8_t *)tmpp, q5u8); 692 tmpp += 16; 693 vst1q_u8((uint8_t *)tmpp, q6u8); 694 tmpp += 16; 695 vst1q_u8((uint8_t *)tmpp, q7u8); 696 tmpp += 16; 697 vst1q_u8((uint8_t *)tmpp, q8u8); 698 tmpp += 16; 699 vst1q_u8((uint8_t *)tmpp, q9u8); 700 701 // secondpass_filter 702 d0u8 = vdup_n_u8(bifilter4_coeff[yoffset][0]); 703 d1u8 = vdup_n_u8(bifilter4_coeff[yoffset][1]); 704 705 tmpp = tmp; 706 q11u8 = vld1q_u8(tmpp); 707 tmpp += 16; 708 for (i = 4; i > 0; i--) { 709 q12u8 = vld1q_u8(tmpp); 710 tmpp += 16; 711 q13u8 = vld1q_u8(tmpp); 712 tmpp += 16; 713 q14u8 = vld1q_u8(tmpp); 714 tmpp += 16; 715 q15u8 = vld1q_u8(tmpp); 716 tmpp += 16; 717 718 q1u16 = vmull_u8(vget_low_u8(q11u8), d0u8); 719 q2u16 = vmull_u8(vget_high_u8(q11u8), d0u8); 720 q3u16 = vmull_u8(vget_low_u8(q12u8), d0u8); 721 q4u16 = vmull_u8(vget_high_u8(q12u8), d0u8); 722 q5u16 = vmull_u8(vget_low_u8(q13u8), d0u8); 723 q6u16 = vmull_u8(vget_high_u8(q13u8), d0u8); 724 q7u16 = vmull_u8(vget_low_u8(q14u8), d0u8); 725 q8u16 = vmull_u8(vget_high_u8(q14u8), d0u8); 726 727 q1u16 = vmlal_u8(q1u16, vget_low_u8(q12u8), d1u8); 728 q2u16 = vmlal_u8(q2u16, vget_high_u8(q12u8), d1u8); 729 q3u16 = vmlal_u8(q3u16, vget_low_u8(q13u8), d1u8); 730 q4u16 = vmlal_u8(q4u16, vget_high_u8(q13u8), d1u8); 731 q5u16 = vmlal_u8(q5u16, vget_low_u8(q14u8), d1u8); 732 q6u16 = vmlal_u8(q6u16, vget_high_u8(q14u8), d1u8); 733 q7u16 = vmlal_u8(q7u16, vget_low_u8(q15u8), d1u8); 734 q8u16 = vmlal_u8(q8u16, vget_high_u8(q15u8), d1u8); 735 736 d2u8 = vqrshrn_n_u16(q1u16, 7); 737 d3u8 = vqrshrn_n_u16(q2u16, 7); 738 d4u8 = vqrshrn_n_u16(q3u16, 7); 739 d5u8 = vqrshrn_n_u16(q4u16, 7); 740 d6u8 = vqrshrn_n_u16(q5u16, 7); 741 d7u8 = vqrshrn_n_u16(q6u16, 7); 742 d8u8 = vqrshrn_n_u16(q7u16, 7); 743 d9u8 = vqrshrn_n_u16(q8u16, 7); 744 745 q1u8 = vcombine_u8(d2u8, d3u8); 746 q2u8 = vcombine_u8(d4u8, d5u8); 747 q3u8 = vcombine_u8(d6u8, d7u8); 748 q4u8 = vcombine_u8(d8u8, d9u8); 749 750 q11u8 = q15u8; 751 752 vst1q_u8((uint8_t *)dst_ptr, q1u8); 753 dst_ptr += dst_pitch; 754 vst1q_u8((uint8_t *)dst_ptr, q2u8); 755 dst_ptr += dst_pitch; 756 vst1q_u8((uint8_t *)dst_ptr, q3u8); 757 dst_ptr += dst_pitch; 758 vst1q_u8((uint8_t *)dst_ptr, q4u8); 759 dst_ptr += dst_pitch; 760 } 761 return; 762 } 763