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