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