]> git.sesse.net Git - vlc/blob - modules/arm_neon/nv21_rgb.S
enable the macosx GUI to handle negative stop-time
[vlc] / modules / arm_neon / nv21_rgb.S
1  @*****************************************************************************
2  @ nv21_rgb.S : ARM NEONv1 NV21 to RGB chroma conversion
3  @*****************************************************************************
4  @ Copyright (C) 2011 Sébastien Toque
5  @                    Rémi Denis-Courmont
6  @
7  @ This program is free software; you can redistribute it and/or modify it
8  @ under the terms of the GNU Lesser General Public License as published by
9  @ the Free Software Foundation; either version 2.1 of the License, or
10  @ (at your option) any later version.
11  @
12  @ This program is distributed in the hope that it will be useful,
13  @ but WITHOUT ANY WARRANTY; without even the implied warranty of
14  @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  @ GNU Lesser General Public License for more details.
16  @
17  @ You should have received a copy of the GNU Lesser General Public License
18  @ along with this program; if not, write to the Free Software Foundation,
19  @ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  @****************************************************************************/
21
22         .syntax unified
23         .fpu neon
24         .text
25
26 /* ARM */
27 #define O1      r0
28 #define O2      r1
29 #define WIDTH   r2
30 #define HEIGHT  r3
31 #define Y1      r4
32 #define Y2      r5
33 #define U       r6
34 #define V       r7
35 #define YPITCH  r8
36 #define OPAD    r10
37 #define YPAD    r11
38 #define COUNT   ip
39 #define OPITCH  lr
40
41 /* NEON */
42 #define coefY   D0
43 #define coefRV  D1
44 #define coefGU  D2
45 #define coefGV  D3
46 #define coefBU  D4
47 #define Rc      Q3
48 #define Gc      Q4
49 #define Bc      Q5
50
51 #define u       D24
52 #define v       D25
53 #define y1      D28
54 #define y2      D29
55
56 #define chro_r  Q6
57 #define chro_g  Q7
58 #define chro_b  Q8
59 #define red             Q9
60 #define green   Q10
61 #define blue    Q11
62 #define lumi    Q15
63
64 #define red1    D24
65 #define green1  D25
66 #define blue1   D26
67 #define alpha1  D27
68 #define red2    D28
69 #define green2  D29
70 #define blue2   D30
71 #define alpha2  D31
72
73 coefficients:
74     .short  -15872
75     .short    4992
76     .short  -18432
77
78         .align 2
79         .global nv21_rgb_neon
80         .type   nv21_rgb_neon, %function
81 nv21_rgb_neon:
82         push            {r4-r8,r10-r11,lr}
83         vpush           {q4-q7}
84
85         /* load arguments */
86         ldmia           r0,     {O1, OPITCH}
87         ldmia           r1,     {Y1, U, V, YPITCH}
88
89         /* round the width to be a multiple of 16 */
90         ands            OPAD, WIDTH, #15
91         sub                     WIDTH, WIDTH, OPAD
92         addne           WIDTH, WIDTH, #16
93
94         /* init constants (scale value by 64) */
95         vmov.u8         coefY, #74
96         vmov.u8         coefRV, #115
97         vmov.u8         coefGU, #14
98         vmov.u8         coefGV, #34
99         vmov.u8         coefBU, #135
100         adr                     OPAD, coefficients
101         vld1.s16        {d6[], d7[]}, [OPAD]!
102         vld1.s16        {d8[], d9[]}, [OPAD]!
103         vld1.s16        {d10[], d11[]}, [OPAD]!
104         vmov.u8         alpha1, #255
105
106         /* init padding */
107         cmp                     HEIGHT, #0
108         sub                     OPAD,   OPITCH, WIDTH, lsl #2
109         sub                     YPAD,   YPITCH, WIDTH
110
111 loop_row:
112         movsgt  COUNT,  WIDTH
113         add             O2,     O1,     OPITCH
114         add             Y2,     Y1,     YPITCH
115         /* exit if all rows have been processed */
116         vpople  {q4-q7}
117         pople   {r4-r8,r10-r11,pc}
118
119 loop_col:
120
121         /* Common U & V */
122
123         vld2.u8 {u,v}, [U,:128]!
124
125         vmull.u8        chro_r, u, coefRV
126         vmull.u8        chro_g, v, coefGU
127         vmlal.u8        chro_g, u, coefGV
128         vmull.u8        chro_b, v, coefBU
129
130         vadd.s16        chro_r, Rc, chro_r
131         vsub.s16        chro_g, Gc, chro_g
132         vadd.s16        chro_b, Bc, chro_b
133
134         pld     [U]
135
136         /* Y Top Row */
137         vld2.u8 {y1,y2}, [Y1,:128]!
138
139         /* y1 : chrominance + luminance, then clamp (divide by 64) */
140         vmull.u8        lumi, y1, coefY
141         vqadd.s16       red, lumi, chro_r
142         vqadd.s16       green, lumi, chro_g
143         vqadd.s16       blue, lumi, chro_b
144         vqrshrun.s16    red1, red, #6
145         vqrshrun.s16    green1, green, #6
146         vqrshrun.s16    blue1, blue, #6
147
148         /* y2 : chrominance + luminance, then clamp (divide by 64) */
149         vmull.u8        lumi, y2, coefY
150         vqadd.s16       red, lumi, chro_r
151         vqadd.s16       green, lumi, chro_g
152         vqadd.s16       blue, lumi, chro_b
153         vqrshrun.s16    red2, red, #6
154         vqrshrun.s16    green2, green, #6
155         vqrshrun.s16    blue2, blue, #6
156
157         pld     [Y1]
158
159         vmov.u8 alpha2, #255
160         vzip.u8 red1, red2
161         vzip.u8 green1, green2
162         vzip.u8 blue1, blue2
163
164         vst4.u8         {red1,green1,blue1,alpha1}, [O1,:128]!
165         vst4.u8         {red2,green2,blue2,alpha2}, [O1,:128]!
166
167         /* Y Bottom Row */
168         vld2.u8 {y1,y2}, [Y2,:128]!
169
170         /* y1 : chrominance + luminance, then clamp (divide by 64) */
171         vmull.u8        lumi, y1, coefY
172         vqadd.s16       red, lumi, chro_r
173         vqadd.s16       green, lumi, chro_g
174         vqadd.s16       blue, lumi, chro_b
175         vqrshrun.s16    red1, red, #6
176         vqrshrun.s16    green1, green, #6
177         vqrshrun.s16    blue1, blue, #6
178
179         /* y2 : chrominance + luminance, then clamp (divide by 64) */
180         vmull.u8        lumi, y2, coefY
181         vqadd.s16       red, lumi, chro_r
182         vqadd.s16       green, lumi, chro_g
183         vqadd.s16       blue, lumi, chro_b
184         vqrshrun.s16    red2, red, #6
185         vqrshrun.s16    green2, green, #6
186         vqrshrun.s16    blue2, blue, #6
187
188         pld     [Y2]
189
190         vmov.u8 alpha2, #255
191         vzip.u8 red1, red2
192         vzip.u8 green1, green2
193         vzip.u8 blue1, blue2
194
195         vst4.u8         {red1,green1,blue1,alpha1}, [O2,:128]!
196         vst4.u8         {red2,green2,blue2,alpha2}, [O2,:128]!
197
198         /* next columns (x16) */
199         subs    COUNT,  COUNT,  #16
200         bgt             loop_col
201
202         /* next rows (x2) */
203         subs    HEIGHT, #2
204         add             O1,     O2,     OPAD
205         add             Y1,     Y2,     YPAD
206         add             U,      U,      YPAD
207         b               loop_row