• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2009 David Conrad
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavutil/arm/asm.S"
22
23const   vp3_idct_constants, align=4
24.short 64277, 60547, 54491, 46341, 36410, 25080, 12785
25endconst
26
27#define xC1S7 d0[0]
28#define xC2S6 d0[1]
29#define xC3S5 d0[2]
30#define xC4S4 d0[3]
31#define xC5S3 d1[0]
32#define xC6S2 d1[1]
33#define xC7S1 d1[2]
34
35.macro vp3_loop_filter
36    vsubl.u8        q3,  d18, d17
37    vsubl.u8        q2,  d16, d19
38    vadd.i16        q1,  q3,  q3
39    vadd.i16        q2,  q2,  q3
40    vadd.i16        q0,  q1,  q2
41    vrshr.s16       q0,  q0,  #3
42    vmovl.u8        q9,  d18
43    vdup.u16        q15, r2
44
45    vabs.s16        q1,  q0
46    vshr.s16        q0,  q0,  #15
47    vqsub.u16       q2,  q15, q1
48    vqsub.u16       q3,  q2,  q1
49    vsub.i16        q1,  q2,  q3
50    veor            q1,  q1,  q0
51    vsub.i16        q0,  q1,  q0
52
53    vaddw.u8        q2,  q0,  d17
54    vsub.i16        q3,  q9,  q0
55    vqmovun.s16     d0,  q2
56    vqmovun.s16     d1,  q3
57.endm
58
59function ff_vp3_v_loop_filter_neon, export=1
60    sub             ip,  r0,  r1
61    sub             r0,  r0,  r1,  lsl #1
62    vld1.64         {d16}, [r0,:64], r1
63    vld1.64         {d17}, [r0,:64], r1
64    vld1.64         {d18}, [r0,:64], r1
65    vld1.64         {d19}, [r0,:64], r1
66    ldrb            r2,    [r2, #129*4]
67
68    vp3_loop_filter
69
70    vst1.64         {d0},  [ip,:64], r1
71    vst1.64         {d1},  [ip,:64], r1
72    bx              lr
73endfunc
74
75function ff_vp3_h_loop_filter_neon, export=1
76    sub             ip,  r0,  #1
77    sub             r0,  r0,  #2
78    vld1.32         {d16[]},  [r0], r1
79    vld1.32         {d17[]},  [r0], r1
80    vld1.32         {d18[]},  [r0], r1
81    vld1.32         {d19[]},  [r0], r1
82    vld1.32         {d16[1]}, [r0], r1
83    vld1.32         {d17[1]}, [r0], r1
84    vld1.32         {d18[1]}, [r0], r1
85    vld1.32         {d19[1]}, [r0], r1
86    ldrb            r2,  [r2, #129*4]
87
88    vtrn.8          d16, d17
89    vtrn.8          d18, d19
90    vtrn.16         d16, d18
91    vtrn.16         d17, d19
92
93    vp3_loop_filter
94
95    vtrn.8          d0,  d1
96
97    vst1.16         {d0[0]}, [ip], r1
98    vst1.16         {d1[0]}, [ip], r1
99    vst1.16         {d0[1]}, [ip], r1
100    vst1.16         {d1[1]}, [ip], r1
101    vst1.16         {d0[2]}, [ip], r1
102    vst1.16         {d1[2]}, [ip], r1
103    vst1.16         {d0[3]}, [ip], r1
104    vst1.16         {d1[3]}, [ip], r1
105    bx              lr
106endfunc
107
108
109function vp3_idct_start_neon
110    vpush           {d8-d15}
111    vmov.i16        q4,  #0
112    vmov.i16        q5,  #0
113    movrel          r3,  vp3_idct_constants
114    vld1.64         {d0-d1},   [r3,:128]
115    vld1.64         {d16-d19}, [r2,:128]
116    vst1.64         {q4-q5},   [r2,:128]!
117    vld1.64         {d20-d23}, [r2,:128]
118    vst1.64         {q4-q5},   [r2,:128]!
119    vld1.64         {d24-d27}, [r2,:128]
120    vst1.64         {q4-q5},   [r2,:128]!
121    vadd.s16        q1,  q8,  q12
122    vsub.s16        q8,  q8,  q12
123    vld1.64         {d28-d31}, [r2,:128]
124    vst1.64         {q4-q5},   [r2,:128]!
125
126vp3_idct_core_neon:
127    vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
128    vmull.s16       q3,  d19, xC1S7
129    vmull.s16       q4,  d2,  xC4S4     // ((ip[0] + ip[4]) * C4) << 16
130    vmull.s16       q5,  d3,  xC4S4
131    vmull.s16       q6,  d16, xC4S4     // ((ip[0] - ip[4]) * C4) << 16
132    vmull.s16       q7,  d17, xC4S4
133    vshrn.s32       d4,  q2,  #16
134    vshrn.s32       d5,  q3,  #16
135    vshrn.s32       d6,  q4,  #16
136    vshrn.s32       d7,  q5,  #16
137    vshrn.s32       d8,  q6,  #16
138    vshrn.s32       d9,  q7,  #16
139    vadd.s16        q12, q1,  q3        // E = (ip[0] + ip[4]) * C4
140    vadd.s16        q8,  q8,  q4        // F = (ip[0] - ip[4]) * C4
141    vadd.s16        q1,  q2,  q9        // ip[1] * C1
142
143    vmull.s16       q2,  d30, xC1S7     // (ip[7] * C1) << 16
144    vmull.s16       q3,  d31, xC1S7
145    vmull.s16       q4,  d30, xC7S1     // (ip[7] * C7) << 16
146    vmull.s16       q5,  d31, xC7S1
147    vmull.s16       q6,  d18, xC7S1     // (ip[1] * C7) << 16
148    vmull.s16       q7,  d19, xC7S1
149    vshrn.s32       d4,  q2,  #16
150    vshrn.s32       d5,  q3,  #16
151    vshrn.s32       d6,  q4,  #16       // ip[7] * C7
152    vshrn.s32       d7,  q5,  #16
153    vshrn.s32       d8,  q6,  #16       // ip[1] * C7
154    vshrn.s32       d9,  q7,  #16
155    vadd.s16        q2,  q2,  q15       // ip[7] * C1
156    vadd.s16        q9,  q1,  q3        // A = ip[1] * C1 + ip[7] * C7
157    vsub.s16        q15, q4,  q2        // B = ip[1] * C7 - ip[7] * C1
158
159    vmull.s16       q2,  d22, xC5S3     // (ip[3] * C5) << 16
160    vmull.s16       q3,  d23, xC5S3
161    vmull.s16       q4,  d22, xC3S5     // (ip[3] * C3) << 16
162    vmull.s16       q5,  d23, xC3S5
163    vmull.s16       q6,  d26, xC5S3     // (ip[5] * C5) << 16
164    vmull.s16       q7,  d27, xC5S3
165    vshrn.s32       d4,  q2,  #16
166    vshrn.s32       d5,  q3,  #16
167    vshrn.s32       d6,  q4,  #16
168    vshrn.s32       d7,  q5,  #16
169    vshrn.s32       d8,  q6,  #16
170    vshrn.s32       d9,  q7,  #16
171    vadd.s16        q3,  q3,  q11       // ip[3] * C3
172    vadd.s16        q4,  q4,  q13       // ip[5] * C5
173    vadd.s16        q1,  q2,  q11       // ip[3] * C5
174    vadd.s16        q11, q3,  q4        // C = ip[3] * C3 + ip[5] * C5
175
176    vmull.s16       q2,  d26, xC3S5     // (ip[5] * C3) << 16
177    vmull.s16       q3,  d27, xC3S5
178    vmull.s16       q4,  d20, xC2S6     // (ip[2] * C2) << 16
179    vmull.s16       q5,  d21, xC2S6
180    vmull.s16       q6,  d28, xC6S2     // (ip[6] * C6) << 16
181    vmull.s16       q7,  d29, xC6S2
182    vshrn.s32       d4,  q2,  #16
183    vshrn.s32       d5,  q3,  #16
184    vshrn.s32       d6,  q4,  #16
185    vshrn.s32       d7,  q5,  #16
186    vshrn.s32       d8,  q6,  #16       // ip[6] * C6
187    vshrn.s32       d9,  q7,  #16
188    vadd.s16        q2,  q2,  q13       // ip[5] * C3
189    vadd.s16        q3,  q3,  q10       // ip[2] * C2
190    vsub.s16        q13, q2,  q1        // D = ip[5] * C3 - ip[3] * C5
191    vsub.s16        q1,  q9,  q11       // (A - C)
192    vadd.s16        q11, q9,  q11       // Cd = A + C
193    vsub.s16        q9,  q15, q13       // (B - D)
194    vadd.s16        q13, q15, q13       // Dd = B + D
195    vadd.s16        q15, q3,  q4        // G = ip[2] * C2 + ip[6] * C6
196
197    vmull.s16       q2,  d2,  xC4S4     // ((A - C) * C4) << 16
198    vmull.s16       q3,  d3,  xC4S4
199    vmull.s16       q4,  d28, xC2S6     // (ip[6] * C2) << 16
200    vmull.s16       q5,  d29, xC2S6
201    vmull.s16       q6,  d20, xC6S2     // (ip[2] * C6) << 16
202    vmull.s16       q7,  d21, xC6S2
203    vshrn.s32       d4,  q2,  #16
204    vshrn.s32       d5,  q3,  #16
205    vshrn.s32       d6,  q4,  #16
206    vshrn.s32       d7,  q5,  #16
207    vshrn.s32       d8,  q6,  #16       // ip[2] * C6
208    vmull.s16       q5,  d18, xC4S4     // ((B - D) * C4) << 16
209    vmull.s16       q6,  d19, xC4S4
210    vshrn.s32       d9,  q7,  #16
211    vadd.s16        q3,  q3,  q14       // ip[6] * C2
212    vadd.s16        q10, q1,  q2        // Ad = (A - C) * C4
213    vsub.s16        q14, q4,  q3        // H = ip[2] * C6 - ip[6] * C2
214    bx              lr
215endfunc
216
217.macro VP3_IDCT_END type
218function vp3_idct_end_\type\()_neon
219.ifc \type, col
220    vdup.16         q0,  r3
221    vadd.s16        q12, q12, q0
222    vadd.s16        q8,  q8,  q0
223.endif
224
225    vshrn.s32       d2,  q5,  #16
226    vshrn.s32       d3,  q6,  #16
227    vadd.s16        q2,  q12, q15       // Gd  = E + G
228    vadd.s16        q9,  q1,  q9        // (B - D) * C4
229    vsub.s16        q12, q12, q15       // Ed  = E - G
230    vsub.s16        q3,  q8,  q10       // Fd  = F - Ad
231    vadd.s16        q10, q8,  q10       // Add = F + Ad
232    vadd.s16        q4,  q9,  q14       // Hd  = Bd + H
233    vsub.s16        q14, q9,  q14       // Bdd = Bd - H
234    vadd.s16        q8,  q2,  q11       // [0] = Gd + Cd
235    vsub.s16        q15, q2,  q11       // [7] = Gd - Cd
236    vadd.s16        q9,  q10, q4        // [1] = Add + Hd
237    vsub.s16        q10, q10, q4        // [2] = Add - Hd
238    vadd.s16        q11, q12, q13       // [3] = Ed + Dd
239    vsub.s16        q12, q12, q13       // [4] = Ed - Dd
240.ifc \type, row
241    vtrn.16         q8,  q9
242.endif
243    vadd.s16        q13, q3,  q14       // [5] = Fd + Bdd
244    vsub.s16        q14, q3,  q14       // [6] = Fd - Bdd
245
246.ifc \type, row
247    // 8x8 transpose
248    vtrn.16         q10, q11
249    vtrn.16         q12, q13
250    vtrn.16         q14, q15
251    vtrn.32         q8,  q10
252    vtrn.32         q9,  q11
253    vtrn.32         q12, q14
254    vtrn.32         q13, q15
255    vswp            d17, d24
256    vswp            d19, d26
257    vadd.s16        q1,  q8,  q12
258    vswp            d21, d28
259    vsub.s16        q8,  q8,  q12
260    vswp            d23, d30
261.endif
262    bx              lr
263endfunc
264.endm
265
266VP3_IDCT_END row
267VP3_IDCT_END col
268
269function ff_vp3_idct_put_neon, export=1
270    mov             ip,  lr
271    bl              vp3_idct_start_neon
272    bl              vp3_idct_end_row_neon
273    mov             r3,  #8
274    add             r3,  r3,  #2048         // convert signed pixel to unsigned
275    bl              vp3_idct_core_neon
276    bl              vp3_idct_end_col_neon
277    mov             lr,  ip
278    vpop            {d8-d15}
279
280    vqshrun.s16     d0,  q8,  #4
281    vqshrun.s16     d1,  q9,  #4
282    vqshrun.s16     d2,  q10, #4
283    vqshrun.s16     d3,  q11, #4
284    vst1.64         {d0}, [r0,:64], r1
285    vqshrun.s16     d4,  q12, #4
286    vst1.64         {d1}, [r0,:64], r1
287    vqshrun.s16     d5,  q13, #4
288    vst1.64         {d2}, [r0,:64], r1
289    vqshrun.s16     d6,  q14, #4
290    vst1.64         {d3}, [r0,:64], r1
291    vqshrun.s16     d7,  q15, #4
292    vst1.64         {d4}, [r0,:64], r1
293    vst1.64         {d5}, [r0,:64], r1
294    vst1.64         {d6}, [r0,:64], r1
295    vst1.64         {d7}, [r0,:64], r1
296    bx              lr
297endfunc
298
299function ff_vp3_idct_add_neon, export=1
300    mov             ip,  lr
301    bl              vp3_idct_start_neon
302    bl              vp3_idct_end_row_neon
303    mov             r3,  #8
304    bl              vp3_idct_core_neon
305    bl              vp3_idct_end_col_neon
306    mov             lr,  ip
307    vpop            {d8-d15}
308    mov             r2,  r0
309
310    vld1.64         {d0}, [r0,:64], r1
311    vshr.s16        q8,  q8,  #4
312    vld1.64         {d1}, [r0,:64], r1
313    vshr.s16        q9,  q9,  #4
314    vld1.64         {d2}, [r0,:64], r1
315    vaddw.u8        q8,  q8,  d0
316    vld1.64         {d3}, [r0,:64], r1
317    vaddw.u8        q9,  q9,  d1
318    vld1.64         {d4}, [r0,:64], r1
319    vshr.s16        q10, q10, #4
320    vld1.64         {d5}, [r0,:64], r1
321    vshr.s16        q11, q11, #4
322    vld1.64         {d6}, [r0,:64], r1
323    vqmovun.s16     d0,  q8
324    vld1.64         {d7}, [r0,:64], r1
325    vqmovun.s16     d1,  q9
326    vaddw.u8        q10, q10, d2
327    vaddw.u8        q11, q11, d3
328    vshr.s16        q12, q12, #4
329    vshr.s16        q13, q13, #4
330    vqmovun.s16     d2,  q10
331    vqmovun.s16     d3,  q11
332    vaddw.u8        q12, q12, d4
333    vaddw.u8        q13, q13, d5
334    vshr.s16        q14, q14, #4
335    vshr.s16        q15, q15, #4
336    vst1.64         {d0}, [r2,:64], r1
337    vqmovun.s16     d4,  q12
338    vst1.64         {d1}, [r2,:64], r1
339    vqmovun.s16     d5,  q13
340    vst1.64         {d2}, [r2,:64], r1
341    vaddw.u8        q14, q14, d6
342    vst1.64         {d3}, [r2,:64], r1
343    vaddw.u8        q15, q15, d7
344    vst1.64         {d4}, [r2,:64], r1
345    vqmovun.s16     d6,  q14
346    vst1.64         {d5}, [r2,:64], r1
347    vqmovun.s16     d7,  q15
348    vst1.64         {d6}, [r2,:64], r1
349    vst1.64         {d7}, [r2,:64], r1
350    bx              lr
351endfunc
352
353function ff_vp3_idct_dc_add_neon, export=1
354    ldrsh           r12, [r2]
355    mov             r3,  r0
356    add             r12, r12,  #15
357    vdup.16         q15, r12
358    mov             r12, #0
359    strh            r12, [r2]
360    vshr.s16        q15, q15, #5
361
362    vld1.8          {d0}, [r0,:64], r1
363    vld1.8          {d1}, [r0,:64], r1
364    vld1.8          {d2}, [r0,:64], r1
365    vaddw.u8        q8,  q15, d0
366    vld1.8          {d3}, [r0,:64], r1
367    vaddw.u8        q9,  q15, d1
368    vld1.8          {d4}, [r0,:64], r1
369    vaddw.u8        q10, q15, d2
370    vld1.8          {d5}, [r0,:64], r1
371    vaddw.u8        q11, q15, d3
372    vld1.8          {d6}, [r0,:64], r1
373    vaddw.u8        q12, q15, d4
374    vld1.8          {d7}, [r0,:64], r1
375    vaddw.u8        q13, q15, d5
376    vqmovun.s16     d0,  q8
377    vaddw.u8        q14, q15, d6
378    vqmovun.s16     d1,  q9
379    vaddw.u8        q15, q15, d7
380    vqmovun.s16     d2,  q10
381    vst1.8          {d0}, [r3,:64], r1
382    vqmovun.s16     d3,  q11
383    vst1.8          {d1}, [r3,:64], r1
384    vqmovun.s16     d4,  q12
385    vst1.8          {d2}, [r3,:64], r1
386    vqmovun.s16     d5,  q13
387    vst1.8          {d3}, [r3,:64], r1
388    vqmovun.s16     d6,  q14
389    vst1.8          {d4}, [r3,:64], r1
390    vqmovun.s16     d7,  q15
391    vst1.8          {d5}, [r3,:64], r1
392    vst1.8          {d6}, [r3,:64], r1
393    vst1.8          {d7}, [r3,:64], r1
394    bx              lr
395endfunc
396