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