Statistics
| Branch: | Revision:

ffmpeg / libavcodec / arm / vp3dsp_neon.S @ 2912e87a

History | View | Annotate | Download (13.8 KB)

1
/*
2
 * Copyright (c) 2009 David Conrad
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav 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
 * Libav 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 Libav; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

    
21
#include "asm.S"
22

    
23
.section .rodata
24
.align 4
25

    
26
vp3_idct_constants:
27
.short 64277, 60547, 54491, 46341, 36410, 25080, 12785
28

    
29
#define xC1S7 d0[0]
30
#define xC2S6 d0[1]
31
#define xC3S5 d0[2]
32
#define xC4S4 d0[3]
33
#define xC5S3 d1[0]
34
#define xC6S2 d1[1]
35
#define xC7S1 d1[2]
36

    
37
.text
38

    
39
.macro vp3_loop_filter
40
    vsubl.u8        q3,  d18, d17
41
    vsubl.u8        q2,  d16, d19
42
    vadd.i16        q1,  q3,  q3
43
    vadd.i16        q2,  q2,  q3
44
    vadd.i16        q0,  q1,  q2
45
    vrshr.s16       q0,  q0,  #3
46
    vmovl.u8        q9,  d18
47
    vdup.u16        q15, r2
48

    
49
    vabs.s16        q1,  q0
50
    vshr.s16        q0,  q0,  #15
51
    vqsub.u16       q2,  q15, q1
52
    vqsub.u16       q3,  q2,  q1
53
    vsub.i16        q1,  q2,  q3
54
    veor            q1,  q1,  q0
55
    vsub.i16        q0,  q1,  q0
56

    
57
    vaddw.u8        q2,  q0,  d17
58
    vsub.i16        q3,  q9,  q0
59
    vqmovun.s16     d0,  q2
60
    vqmovun.s16     d1,  q3
61
.endm
62

    
63
function ff_vp3_v_loop_filter_neon, export=1
64
    sub             ip,  r0,  r1
65
    sub             r0,  r0,  r1,  lsl #1
66
    vld1.64         {d16}, [r0,:64], r1
67
    vld1.64         {d17}, [r0,:64], r1
68
    vld1.64         {d18}, [r0,:64], r1
69
    vld1.64         {d19}, [r0,:64], r1
70
    ldrb            r2,    [r2, #129*4]
71

    
72
    vp3_loop_filter
73

    
74
    vst1.64         {d0},  [ip,:64], r1
75
    vst1.64         {d1},  [ip,:64], r1
76
    bx              lr
77
endfunc
78

    
79
function ff_vp3_h_loop_filter_neon, export=1
80
    sub             ip,  r0,  #1
81
    sub             r0,  r0,  #2
82
    vld1.32         {d16[]},  [r0], r1
83
    vld1.32         {d17[]},  [r0], r1
84
    vld1.32         {d18[]},  [r0], r1
85
    vld1.32         {d19[]},  [r0], r1
86
    vld1.32         {d16[1]}, [r0], r1
87
    vld1.32         {d17[1]}, [r0], r1
88
    vld1.32         {d18[1]}, [r0], r1
89
    vld1.32         {d19[1]}, [r0], r1
90
    ldrb            r2,  [r2, #129*4]
91

    
92
    vtrn.8          d16, d17
93
    vtrn.8          d18, d19
94
    vtrn.16         d16, d18
95
    vtrn.16         d17, d19
96

    
97
    vp3_loop_filter
98

    
99
    vtrn.8          d0,  d1
100

    
101
    vst1.16         {d0[0]}, [ip], r1
102
    vst1.16         {d1[0]}, [ip], r1
103
    vst1.16         {d0[1]}, [ip], r1
104
    vst1.16         {d1[1]}, [ip], r1
105
    vst1.16         {d0[2]}, [ip], r1
106
    vst1.16         {d1[2]}, [ip], r1
107
    vst1.16         {d0[3]}, [ip], r1
108
    vst1.16         {d1[3]}, [ip], r1
109
    bx              lr
110
endfunc
111

    
112

    
113
function vp3_idct_start_neon
114
    vpush           {d8-d15}
115
    movrel          r3,  vp3_idct_constants
116
    vld1.64         {d0-d1},   [r3,:128]
117
    vld1.64         {d16-d19}, [r2,:128]!
118
    vld1.64         {d20-d23}, [r2,:128]!
119
    vld1.64         {d24-d27}, [r2,:128]!
120
    vadd.s16        q1,  q8,  q12
121
    vsub.s16        q8,  q8,  q12
122
    vld1.64         {d28-d31}, [r2,:128]!
123
endfunc
124

    
125
function vp3_idct_core_neon
126
    vmull.s16       q2,  d18, xC1S7     // (ip[1] * C1) << 16
127
    vmull.s16       q3,  d19, xC1S7
128
    vmull.s16       q4,  d2,  xC4S4     // ((ip[0] + ip[4]) * C4) << 16
129
    vmull.s16       q5,  d3,  xC4S4
130
    vmull.s16       q6,  d16, xC4S4     // ((ip[0] - ip[4]) * C4) << 16
131
    vmull.s16       q7,  d17, xC4S4
132
    vshrn.s32       d4,  q2,  #16
133
    vshrn.s32       d5,  q3,  #16
134
    vshrn.s32       d6,  q4,  #16
135
    vshrn.s32       d7,  q5,  #16
136
    vshrn.s32       d8,  q6,  #16
137
    vshrn.s32       d9,  q7,  #16
138
    vadd.s16        q12, q1,  q3        // E = (ip[0] + ip[4]) * C4
139
    vadd.s16        q8,  q8,  q4        // F = (ip[0] - ip[4]) * C4
140
    vadd.s16        q1,  q2,  q9        // ip[1] * C1
141

    
142
    vmull.s16       q2,  d30, xC1S7     // (ip[7] * C1) << 16
143
    vmull.s16       q3,  d31, xC1S7
144
    vmull.s16       q4,  d30, xC7S1     // (ip[7] * C7) << 16
145
    vmull.s16       q5,  d31, xC7S1
146
    vmull.s16       q6,  d18, xC7S1     // (ip[1] * C7) << 16
147
    vmull.s16       q7,  d19, xC7S1
148
    vshrn.s32       d4,  q2,  #16
149
    vshrn.s32       d5,  q3,  #16
150
    vshrn.s32       d6,  q4,  #16       // ip[7] * C7
151
    vshrn.s32       d7,  q5,  #16
152
    vshrn.s32       d8,  q6,  #16       // ip[1] * C7
153
    vshrn.s32       d9,  q7,  #16
154
    vadd.s16        q2,  q2,  q15       // ip[7] * C1
155
    vadd.s16        q9,  q1,  q3        // A = ip[1] * C1 + ip[7] * C7
156
    vsub.s16        q15, q4,  q2        // B = ip[1] * C7 - ip[7] * C1
157

    
158
    vmull.s16       q2,  d22, xC5S3     // (ip[3] * C5) << 16
159
    vmull.s16       q3,  d23, xC5S3
160
    vmull.s16       q4,  d22, xC3S5     // (ip[3] * C3) << 16
161
    vmull.s16       q5,  d23, xC3S5
162
    vmull.s16       q6,  d26, xC5S3     // (ip[5] * C5) << 16
163
    vmull.s16       q7,  d27, xC5S3
164
    vshrn.s32       d4,  q2,  #16
165
    vshrn.s32       d5,  q3,  #16
166
    vshrn.s32       d6,  q4,  #16
167
    vshrn.s32       d7,  q5,  #16
168
    vshrn.s32       d8,  q6,  #16
169
    vshrn.s32       d9,  q7,  #16
170
    vadd.s16        q3,  q3,  q11       // ip[3] * C3
171
    vadd.s16        q4,  q4,  q13       // ip[5] * C5
172
    vadd.s16        q1,  q2,  q11       // ip[3] * C5
173
    vadd.s16        q11, q3,  q4        // C = ip[3] * C3 + ip[5] * C5
174

    
175
    vmull.s16       q2,  d26, xC3S5     // (ip[5] * C3) << 16
176
    vmull.s16       q3,  d27, xC3S5
177
    vmull.s16       q4,  d20, xC2S6     // (ip[2] * C2) << 16
178
    vmull.s16       q5,  d21, xC2S6
179
    vmull.s16       q6,  d28, xC6S2     // (ip[6] * C6) << 16
180
    vmull.s16       q7,  d29, xC6S2
181
    vshrn.s32       d4,  q2,  #16
182
    vshrn.s32       d5,  q3,  #16
183
    vshrn.s32       d6,  q4,  #16
184
    vshrn.s32       d7,  q5,  #16
185
    vshrn.s32       d8,  q6,  #16       // ip[6] * C6
186
    vshrn.s32       d9,  q7,  #16
187
    vadd.s16        q2,  q2,  q13       // ip[5] * C3
188
    vadd.s16        q3,  q3,  q10       // ip[2] * C2
189
    vsub.s16        q13, q2,  q1        // D = ip[5] * C3 - ip[3] * C5
190
    vsub.s16        q1,  q9,  q11       // (A - C)
191
    vadd.s16        q11, q9,  q11       // Cd = A + C
192
    vsub.s16        q9,  q15, q13       // (B - D)
193
    vadd.s16        q13, q15, q13       // Dd = B + D
194
    vadd.s16        q15, q3,  q4        // G = ip[2] * C2 + ip[6] * C6
195

    
196
    vmull.s16       q2,  d2,  xC4S4     // ((A - C) * C4) << 16
197
    vmull.s16       q3,  d3,  xC4S4
198
    vmull.s16       q4,  d28, xC2S6     // (ip[6] * C2) << 16
199
    vmull.s16       q5,  d29, xC2S6
200
    vmull.s16       q6,  d20, xC6S2     // (ip[2] * C6) << 16
201
    vmull.s16       q7,  d21, xC6S2
202
    vshrn.s32       d4,  q2,  #16
203
    vshrn.s32       d5,  q3,  #16
204
    vshrn.s32       d6,  q4,  #16
205
    vshrn.s32       d7,  q5,  #16
206
    vshrn.s32       d8,  q6,  #16       // ip[2] * C6
207
    vmull.s16       q5,  d18, xC4S4     // ((B - D) * C4) << 16
208
    vmull.s16       q6,  d19, xC4S4
209
    vshrn.s32       d9,  q7,  #16
210
    vadd.s16        q3,  q3,  q14       // ip[6] * C2
211
    vadd.s16        q10, q1,  q2        // Ad = (A - C) * C4
212
    vsub.s16        q14, q4,  q3        // H = ip[2] * C6 - ip[6] * C2
213
    bx              lr
214
endfunc
215

    
216
.macro VP3_IDCT_END type
217
function vp3_idct_end_\type\()_neon
218
.ifc \type, col
219
    vdup.16         q0,  r3
220
    vadd.s16        q12, q12, q0
221
    vadd.s16        q8,  q8,  q0
222
.endif
223

    
224
    vshrn.s32       d2,  q5,  #16
225
    vshrn.s32       d3,  q6,  #16
226
    vadd.s16        q2,  q12, q15       // Gd  = E + G
227
    vadd.s16        q9,  q1,  q9        // (B - D) * C4
228
    vsub.s16        q12, q12, q15       // Ed  = E - G
229
    vsub.s16        q3,  q8,  q10       // Fd  = F - Ad
230
    vadd.s16        q10, q8,  q10       // Add = F + Ad
231
    vadd.s16        q4,  q9,  q14       // Hd  = Bd + H
232
    vsub.s16        q14, q9,  q14       // Bdd = Bd - H
233
    vadd.s16        q8,  q2,  q11       // [0] = Gd + Cd
234
    vsub.s16        q15, q2,  q11       // [7] = Gd - Cd
235
    vadd.s16        q9,  q10, q4        // [1] = Add + Hd
236
    vsub.s16        q10, q10, q4        // [2] = Add - Hd
237
    vadd.s16        q11, q12, q13       // [3] = Ed + Dd
238
    vsub.s16        q12, q12, q13       // [4] = Ed - Dd
239
.ifc \type, row
240
    vtrn.16         q8,  q9
241
.endif
242
    vadd.s16        q13, q3,  q14       // [5] = Fd + Bdd
243
    vsub.s16        q14, q3,  q14       // [6] = Fd - Bdd
244

    
245
.ifc \type, row
246
    // 8x8 transpose
247
    vtrn.16         q10, q11
248
    vtrn.16         q12, q13
249
    vtrn.16         q14, q15
250
    vtrn.32         q8,  q10
251
    vtrn.32         q9,  q11
252
    vtrn.32         q12, q14
253
    vtrn.32         q13, q15
254
    vswp            d17, d24
255
    vswp            d19, d26
256
    vadd.s16        q1,  q8,  q12
257
    vswp            d21, d28
258
    vsub.s16        q8,  q8,  q12
259
    vswp            d23, d30
260
.endif
261
    bx              lr
262
endfunc
263
.endm
264

    
265
VP3_IDCT_END row
266
VP3_IDCT_END col
267

    
268
function ff_vp3_idct_neon, export=1
269
    mov             ip,  lr
270
    mov             r2,  r0
271
    bl              vp3_idct_start_neon
272
    bl              vp3_idct_end_row_neon
273
    mov             r3,  #8
274
    bl              vp3_idct_core_neon
275
    bl              vp3_idct_end_col_neon
276
    mov             lr,  ip
277
    vpop            {d8-d15}
278

    
279
    vshr.s16        q8,  q8,  #4
280
    vshr.s16        q9,  q9,  #4
281
    vshr.s16        q10, q10, #4
282
    vshr.s16        q11, q11, #4
283
    vshr.s16        q12, q12, #4
284
    vst1.64         {d16-d19}, [r0,:128]!
285
    vshr.s16        q13, q13, #4
286
    vshr.s16        q14, q14, #4
287
    vst1.64         {d20-d23}, [r0,:128]!
288
    vshr.s16        q15, q15, #4
289
    vst1.64         {d24-d27}, [r0,:128]!
290
    vst1.64         {d28-d31}, [r0,:128]!
291
    bx              lr
292
endfunc
293

    
294
function ff_vp3_idct_put_neon, export=1
295
    mov             ip,  lr
296
    bl              vp3_idct_start_neon
297
    bl              vp3_idct_end_row_neon
298
    mov             r3,  #8
299
    add             r3,  r3,  #2048         // convert signed pixel to unsigned
300
    bl              vp3_idct_core_neon
301
    bl              vp3_idct_end_col_neon
302
    mov             lr,  ip
303
    vpop            {d8-d15}
304

    
305
    vqshrun.s16     d0,  q8,  #4
306
    vqshrun.s16     d1,  q9,  #4
307
    vqshrun.s16     d2,  q10, #4
308
    vqshrun.s16     d3,  q11, #4
309
    vst1.64         {d0}, [r0,:64], r1
310
    vqshrun.s16     d4,  q12, #4
311
    vst1.64         {d1}, [r0,:64], r1
312
    vqshrun.s16     d5,  q13, #4
313
    vst1.64         {d2}, [r0,:64], r1
314
    vqshrun.s16     d6,  q14, #4
315
    vst1.64         {d3}, [r0,:64], r1
316
    vqshrun.s16     d7,  q15, #4
317
    vst1.64         {d4}, [r0,:64], r1
318
    vst1.64         {d5}, [r0,:64], r1
319
    vst1.64         {d6}, [r0,:64], r1
320
    vst1.64         {d7}, [r0,:64], r1
321
    bx              lr
322
endfunc
323

    
324
function ff_vp3_idct_add_neon, export=1
325
    mov             ip,  lr
326
    bl              vp3_idct_start_neon
327
    bl              vp3_idct_end_row_neon
328
    mov             r3,  #8
329
    bl              vp3_idct_core_neon
330
    bl              vp3_idct_end_col_neon
331
    mov             lr,  ip
332
    vpop            {d8-d15}
333
    mov             r2,  r0
334

    
335
    vld1.64         {d0}, [r0,:64], r1
336
    vshr.s16        q8,  q8,  #4
337
    vld1.64         {d1}, [r0,:64], r1
338
    vshr.s16        q9,  q9,  #4
339
    vld1.64         {d2}, [r0,:64], r1
340
    vaddw.u8        q8,  q8,  d0
341
    vld1.64         {d3}, [r0,:64], r1
342
    vaddw.u8        q9,  q9,  d1
343
    vld1.64         {d4}, [r0,:64], r1
344
    vshr.s16        q10, q10, #4
345
    vld1.64         {d5}, [r0,:64], r1
346
    vshr.s16        q11, q11, #4
347
    vld1.64         {d6}, [r0,:64], r1
348
    vqmovun.s16     d0,  q8
349
    vld1.64         {d7}, [r0,:64], r1
350
    vqmovun.s16     d1,  q9
351
    vaddw.u8        q10, q10, d2
352
    vaddw.u8        q11, q11, d3
353
    vshr.s16        q12, q12, #4
354
    vshr.s16        q13, q13, #4
355
    vqmovun.s16     d2,  q10
356
    vqmovun.s16     d3,  q11
357
    vaddw.u8        q12, q12, d4
358
    vaddw.u8        q13, q13, d5
359
    vshr.s16        q14, q14, #4
360
    vshr.s16        q15, q15, #4
361
    vst1.64         {d0}, [r2,:64], r1
362
    vqmovun.s16     d4,  q12
363
    vst1.64         {d1}, [r2,:64], r1
364
    vqmovun.s16     d5,  q13
365
    vst1.64         {d2}, [r2,:64], r1
366
    vaddw.u8        q14, q14, d6
367
    vst1.64         {d3}, [r2,:64], r1
368
    vaddw.u8        q15, q15, d7
369
    vst1.64         {d4}, [r2,:64], r1
370
    vqmovun.s16     d6,  q14
371
    vst1.64         {d5}, [r2,:64], r1
372
    vqmovun.s16     d7,  q15
373
    vst1.64         {d6}, [r2,:64], r1
374
    vst1.64         {d7}, [r2,:64], r1
375
    bx              lr
376
endfunc
377

    
378
function ff_vp3_idct_dc_add_neon, export=1
379
    ldrsh           r2,  [r2]
380
    mov             r3,  r0
381
    add             r2,  r2,  #15
382
    vdup.16         q15, r2
383
    vshr.s16        q15, q15, #5
384

    
385
    vld1.8          {d0}, [r0,:64], r1
386
    vld1.8          {d1}, [r0,:64], r1
387
    vld1.8          {d2}, [r0,:64], r1
388
    vaddw.u8        q8,  q15, d0
389
    vld1.8          {d3}, [r0,:64], r1
390
    vaddw.u8        q9,  q15, d1
391
    vld1.8          {d4}, [r0,:64], r1
392
    vaddw.u8        q10, q15, d2
393
    vld1.8          {d5}, [r0,:64], r1
394
    vaddw.u8        q11, q15, d3
395
    vld1.8          {d6}, [r0,:64], r1
396
    vaddw.u8        q12, q15, d4
397
    vld1.8          {d7}, [r0,:64], r1
398
    vaddw.u8        q13, q15, d5
399
    vqmovun.s16     d0,  q8
400
    vaddw.u8        q14, q15, d6
401
    vqmovun.s16     d1,  q9
402
    vaddw.u8        q15, q15, d7
403
    vqmovun.s16     d2,  q10
404
    vst1.8          {d0}, [r3,:64], r1
405
    vqmovun.s16     d3,  q11
406
    vst1.8          {d1}, [r3,:64], r1
407
    vqmovun.s16     d4,  q12
408
    vst1.8          {d2}, [r3,:64], r1
409
    vqmovun.s16     d5,  q13
410
    vst1.8          {d3}, [r3,:64], r1
411
    vqmovun.s16     d6,  q14
412
    vst1.8          {d4}, [r3,:64], r1
413
    vqmovun.s16     d7,  q15
414
    vst1.8          {d5}, [r3,:64], r1
415
    vst1.8          {d6}, [r3,:64], r1
416
    vst1.8          {d7}, [r3,:64], r1
417
    bx              lr
418
endfunc