Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: source/libvpx/vp9/common/arm/neon/vp9_reconintra_neon.c

Issue 1217053002: libvpx: Pull from upstream (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libvpx.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <arm_neon.h> 11 #include <arm_neon.h>
12 12
13 #include "./vp9_rtcd.h" 13 #include "./vp9_rtcd.h"
14 #include "./vpx_config.h" 14 #include "./vpx_config.h"
15 #include "vpx/vpx_integer.h" 15 #include "vpx/vpx_integer.h"
16 16
17 //------------------------------------------------------------------------------ 17 //------------------------------------------------------------------------------
18 // DC 4x4
19
20 // 'do_above' and 'do_left' facilitate branch removal when inlined.
21 static INLINE void dc_4x4(uint8_t *dst, ptrdiff_t stride,
22 const uint8_t *above, const uint8_t *left,
23 int do_above, int do_left) {
24 uint16x8_t sum_top;
25 uint16x8_t sum_left;
26 uint8x8_t dc0;
27
28 if (do_above) {
29 const uint8x8_t A = vld1_u8(above); // top row
30 const uint16x4_t p0 = vpaddl_u8(A); // cascading summation of the top
31 const uint16x4_t p1 = vpadd_u16(p0, p0);
32 sum_top = vcombine_u16(p1, p1);
33 }
34
35 if (do_left) {
36 const uint8x8_t L = vld1_u8(left); // left border
37 const uint16x4_t p0 = vpaddl_u8(L); // cascading summation of the left
38 const uint16x4_t p1 = vpadd_u16(p0, p0);
39 sum_left = vcombine_u16(p1, p1);
40 }
41
42 if (do_above && do_left) {
43 const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
44 dc0 = vrshrn_n_u16(sum, 3);
45 } else if (do_above) {
46 dc0 = vrshrn_n_u16(sum_top, 2);
47 } else if (do_left) {
48 dc0 = vrshrn_n_u16(sum_left, 2);
49 } else {
50 dc0 = vdup_n_u8(0x80);
51 }
52
53 {
54 const uint8x8_t dc = vdup_lane_u8(dc0, 0);
55 int i;
56 for (i = 0; i < 4; ++i) {
57 vst1_lane_u32((uint32_t*)(dst + i * stride), vreinterpret_u32_u8(dc), 0);
58 }
59 }
60 }
61
62 void vp9_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
63 const uint8_t *above, const uint8_t *left) {
64 dc_4x4(dst, stride, above, left, 1, 1);
65 }
66
67 void vp9_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
68 const uint8_t *above, const uint8_t *left) {
69 (void)above;
70 dc_4x4(dst, stride, NULL, left, 0, 1);
71 }
72
73 void vp9_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
74 const uint8_t *above, const uint8_t *left) {
75 (void)left;
76 dc_4x4(dst, stride, above, NULL, 1, 0);
77 }
78
79 void vp9_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
80 const uint8_t *above, const uint8_t *left) {
81 (void)above;
82 (void)left;
83 dc_4x4(dst, stride, NULL, NULL, 0, 0);
84 }
85
86 //------------------------------------------------------------------------------
18 // DC 8x8 87 // DC 8x8
19 88
20 // 'do_above' and 'do_left' facilitate branch removal when inlined. 89 // 'do_above' and 'do_left' facilitate branch removal when inlined.
21 static INLINE void dc_8x8(uint8_t *dst, ptrdiff_t stride, 90 static INLINE void dc_8x8(uint8_t *dst, ptrdiff_t stride,
22 const uint8_t *above, const uint8_t *left, 91 const uint8_t *above, const uint8_t *left,
23 int do_above, int do_left) { 92 int do_above, int do_left) {
24 uint16x8_t sum_top; 93 uint16x8_t sum_top;
25 uint16x8_t sum_left; 94 uint16x8_t sum_left;
26 uint8x8_t dc0; 95 uint8x8_t dc0;
27 96
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 } 223 }
155 224
156 void vp9_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride, 225 void vp9_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
157 const uint8_t *above, 226 const uint8_t *above,
158 const uint8_t *left) { 227 const uint8_t *left) {
159 (void)above; 228 (void)above;
160 (void)left; 229 (void)left;
161 dc_16x16(dst, stride, NULL, NULL, 0, 0); 230 dc_16x16(dst, stride, NULL, NULL, 0, 0);
162 } 231 }
163 232
233 //------------------------------------------------------------------------------
234 // DC 32x32
235
236 // 'do_above' and 'do_left' facilitate branch removal when inlined.
237 static INLINE void dc_32x32(uint8_t *dst, ptrdiff_t stride,
238 const uint8_t *above, const uint8_t *left,
239 int do_above, int do_left) {
240 uint16x8_t sum_top;
241 uint16x8_t sum_left;
242 uint8x8_t dc0;
243
244 if (do_above) {
245 const uint8x16_t A0 = vld1q_u8(above); // top row
246 const uint8x16_t A1 = vld1q_u8(above + 16);
247 const uint16x8_t p0 = vpaddlq_u8(A0); // cascading summation of the top
248 const uint16x8_t p1 = vpaddlq_u8(A1);
249 const uint16x8_t p2 = vaddq_u16(p0, p1);
250 const uint16x4_t p3 = vadd_u16(vget_low_u16(p2), vget_high_u16(p2));
251 const uint16x4_t p4 = vpadd_u16(p3, p3);
252 const uint16x4_t p5 = vpadd_u16(p4, p4);
253 sum_top = vcombine_u16(p5, p5);
254 }
255
256 if (do_left) {
257 const uint8x16_t L0 = vld1q_u8(left); // left row
258 const uint8x16_t L1 = vld1q_u8(left + 16);
259 const uint16x8_t p0 = vpaddlq_u8(L0); // cascading summation of the left
260 const uint16x8_t p1 = vpaddlq_u8(L1);
261 const uint16x8_t p2 = vaddq_u16(p0, p1);
262 const uint16x4_t p3 = vadd_u16(vget_low_u16(p2), vget_high_u16(p2));
263 const uint16x4_t p4 = vpadd_u16(p3, p3);
264 const uint16x4_t p5 = vpadd_u16(p4, p4);
265 sum_left = vcombine_u16(p5, p5);
266 }
267
268 if (do_above && do_left) {
269 const uint16x8_t sum = vaddq_u16(sum_left, sum_top);
270 dc0 = vrshrn_n_u16(sum, 6);
271 } else if (do_above) {
272 dc0 = vrshrn_n_u16(sum_top, 5);
273 } else if (do_left) {
274 dc0 = vrshrn_n_u16(sum_left, 5);
275 } else {
276 dc0 = vdup_n_u8(0x80);
277 }
278
279 {
280 const uint8x16_t dc = vdupq_lane_u8(dc0, 0);
281 int i;
282 for (i = 0; i < 32; ++i) {
283 vst1q_u8(dst + i * stride, dc);
284 vst1q_u8(dst + i * stride + 16, dc);
285 }
286 }
287 }
288
289 void vp9_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
290 const uint8_t *above, const uint8_t *left) {
291 dc_32x32(dst, stride, above, left, 1, 1);
292 }
293
294 void vp9_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
295 const uint8_t *above,
296 const uint8_t *left) {
297 (void)above;
298 dc_32x32(dst, stride, NULL, left, 0, 1);
299 }
300
301 void vp9_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
302 const uint8_t *above,
303 const uint8_t *left) {
304 (void)left;
305 dc_32x32(dst, stride, above, NULL, 1, 0);
306 }
307
308 void vp9_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t stride,
309 const uint8_t *above,
310 const uint8_t *left) {
311 (void)above;
312 (void)left;
313 dc_32x32(dst, stride, NULL, NULL, 0, 0);
314 }
315
316 // -----------------------------------------------------------------------------
317
318 void vp9_d45_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
319 const uint8_t *above, const uint8_t *left) {
320 const uint64x1_t A0 = vreinterpret_u64_u8(vld1_u8(above)); // top row
321 const uint64x1_t A1 = vshr_n_u64(A0, 8);
322 const uint64x1_t A2 = vshr_n_u64(A0, 16);
323 const uint8x8_t ABCDEFGH = vreinterpret_u8_u64(A0);
324 const uint8x8_t BCDEFGH0 = vreinterpret_u8_u64(A1);
325 const uint8x8_t CDEFGH00 = vreinterpret_u8_u64(A2);
326 const uint8x8_t avg1 = vhadd_u8(ABCDEFGH, CDEFGH00);
327 const uint8x8_t avg2 = vrhadd_u8(avg1, BCDEFGH0);
328 const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
329 const uint32x2_t r0 = vreinterpret_u32_u8(avg2);
330 const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
331 const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
332 const uint32x2_t r3 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
333 (void)left;
334 vst1_lane_u32((uint32_t *)(dst + 0 * stride), r0, 0);
335 vst1_lane_u32((uint32_t *)(dst + 1 * stride), r1, 0);
336 vst1_lane_u32((uint32_t *)(dst + 2 * stride), r2, 0);
337 vst1_lane_u32((uint32_t *)(dst + 3 * stride), r3, 0);
338 dst[3 * stride + 3] = above[7];
339 }
340
341 void vp9_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t stride,
342 const uint8_t *above, const uint8_t *left) {
343 static const uint8_t shuffle1[8] = { 1, 2, 3, 4, 5, 6, 7, 7 };
344 static const uint8_t shuffle2[8] = { 2, 3, 4, 5, 6, 7, 7, 7 };
345 const uint8x8_t sh_12345677 = vld1_u8(shuffle1);
346 const uint8x8_t sh_23456777 = vld1_u8(shuffle2);
347 const uint8x8_t A0 = vld1_u8(above); // top row
348 const uint8x8_t A1 = vtbl1_u8(A0, sh_12345677);
349 const uint8x8_t A2 = vtbl1_u8(A0, sh_23456777);
350 const uint8x8_t avg1 = vhadd_u8(A0, A2);
351 uint8x8_t row = vrhadd_u8(avg1, A1);
352 int i;
353 (void)left;
354 for (i = 0; i < 7; ++i) {
355 vst1_u8(dst + i * stride, row);
356 row = vtbl1_u8(row, sh_12345677);
357 }
358 vst1_u8(dst + i * stride, row);
359 }
360
361 void vp9_d45_predictor_16x16_neon(uint8_t *dst, ptrdiff_t stride,
362 const uint8_t *above, const uint8_t *left) {
363 const uint8x16_t A0 = vld1q_u8(above); // top row
364 const uint8x16_t above_right = vld1q_dup_u8(above + 15);
365 const uint8x16_t A1 = vextq_u8(A0, above_right, 1);
366 const uint8x16_t A2 = vextq_u8(A0, above_right, 2);
367 const uint8x16_t avg1 = vhaddq_u8(A0, A2);
368 uint8x16_t row = vrhaddq_u8(avg1, A1);
369 int i;
370 (void)left;
371 for (i = 0; i < 15; ++i) {
372 vst1q_u8(dst + i * stride, row);
373 row = vextq_u8(row, above_right, 1);
374 }
375 vst1q_u8(dst + i * stride, row);
376 }
377
378 // -----------------------------------------------------------------------------
379
380 void vp9_d135_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
381 const uint8_t *above, const uint8_t *left) {
382 const uint8x8_t XABCD_u8 = vld1_u8(above - 1);
383 const uint64x1_t XABCD = vreinterpret_u64_u8(XABCD_u8);
384 const uint64x1_t ____XABC = vshl_n_u64(XABCD, 32);
385 const uint32x2_t zero = vdup_n_u32(0);
386 const uint32x2_t IJKL = vld1_lane_u32((const uint32_t *)left, zero, 0);
387 const uint8x8_t IJKL_u8 = vreinterpret_u8_u32(IJKL);
388 const uint64x1_t LKJI____ = vreinterpret_u64_u8(vrev32_u8(IJKL_u8));
389 const uint64x1_t LKJIXABC = vorr_u64(LKJI____, ____XABC);
390 const uint8x8_t KJIXABC_ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 8));
391 const uint8x8_t JIXABC__ = vreinterpret_u8_u64(vshr_n_u64(LKJIXABC, 16));
392 const uint8_t D = vget_lane_u8(XABCD_u8, 4);
393 const uint8x8_t JIXABCD_ = vset_lane_u8(D, JIXABC__, 6);
394 const uint8x8_t LKJIXABC_u8 = vreinterpret_u8_u64(LKJIXABC);
395 const uint8x8_t avg1 = vhadd_u8(JIXABCD_, LKJIXABC_u8);
396 const uint8x8_t avg2 = vrhadd_u8(avg1, KJIXABC_);
397 const uint64x1_t avg2_u64 = vreinterpret_u64_u8(avg2);
398 const uint32x2_t r3 = vreinterpret_u32_u8(avg2);
399 const uint32x2_t r2 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 8));
400 const uint32x2_t r1 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 16));
401 const uint32x2_t r0 = vreinterpret_u32_u64(vshr_n_u64(avg2_u64, 24));
402 vst1_lane_u32((uint32_t *)(dst + 0 * stride), r0, 0);
403 vst1_lane_u32((uint32_t *)(dst + 1 * stride), r1, 0);
404 vst1_lane_u32((uint32_t *)(dst + 2 * stride), r2, 0);
405 vst1_lane_u32((uint32_t *)(dst + 3 * stride), r3, 0);
406 }
407
164 #if !HAVE_NEON_ASM 408 #if !HAVE_NEON_ASM
165 409
166 void vp9_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride, 410 void vp9_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t stride,
167 const uint8_t *above, const uint8_t *left) { 411 const uint8_t *above, const uint8_t *left) {
168 int i; 412 int i;
169 uint32x2_t d0u32 = vdup_n_u32(0); 413 uint32x2_t d0u32 = vdup_n_u32(0);
170 (void)left; 414 (void)left;
171 415
172 d0u32 = vld1_lane_u32((const uint32_t *)above, d0u32, 0); 416 d0u32 = vld1_lane_u32((const uint32_t *)above, d0u32, 0);
173 for (i = 0; i < 4; i++, dst += stride) 417 for (i = 0; i < 4; i++, dst += stride)
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 d3u8 = vqmovun_s16(q15s16); 813 d3u8 = vqmovun_s16(q15s16);
570 q0u8 = vcombine_u8(d0u8, d1u8); 814 q0u8 = vcombine_u8(d0u8, d1u8);
571 q1u8 = vcombine_u8(d2u8, d3u8); 815 q1u8 = vcombine_u8(d2u8, d3u8);
572 vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8)); 816 vst1q_u64((uint64_t *)dst, vreinterpretq_u64_u8(q0u8));
573 vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8)); 817 vst1q_u64((uint64_t *)(dst + 16), vreinterpretq_u64_u8(q1u8));
574 dst += stride; 818 dst += stride;
575 } 819 }
576 } 820 }
577 } 821 }
578 #endif // !HAVE_NEON_ASM 822 #endif // !HAVE_NEON_ASM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698