]> git.sesse.net Git - vlc/blob - modules/arm_neon/i420_rgb.S
DASH: fix URL parsing
[vlc] / modules / arm_neon / i420_rgb.S
1  @*****************************************************************************
2  @ i420_rgb.S : ARM NEONv1 I420 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
8  @ it under the terms of the GNU General Public License as published by
9  @ the Free Software Foundation; either version 2 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 General Public License for more details.
16  @
17  @ You should have received a copy of the GNU 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         .fpu neon
23         .text
24
25 /* ARM */
26 #define O1      r0
27 #define O2      r1
28 #define WIDTH   r2
29 #define HEIGHT  r3
30 #define Y1      r4
31 #define Y2      r5
32 #define U       r6
33 #define V       r7
34 #define YPITCH  r8
35 #define OPAD    r10
36 #define YPAD    r11
37 #define COUNT   ip
38 #define OPITCH  lr
39
40 /* NEON */
41 #define coefY   D0
42 #define coefRV  D1
43 #define coefGU  D2
44 #define coefGV  D3
45 #define coefBU  D4
46 #define Rc      Q3
47 #define Gc      Q4
48 #define Bc      Q5
49
50 #define u       D24
51 #define v       D25
52 #define y1      D28
53 #define y2      D29
54
55 #define chro_r  Q6
56 #define chro_g  Q7
57 #define chro_b  Q8
58 #define red             Q9
59 #define green   Q10
60 #define blue    Q11
61 #define lumi    Q15
62
63 #define red1    D24
64 #define green1  D25
65 #define blue1   D26
66 #define alpha1  D27
67 #define red2    D28
68 #define green2  D29
69 #define blue2   D30
70 #define alpha2  D31
71
72 coefficients:
73     .short  -15872
74     .short    4992
75     .short  -18432
76
77         .align
78         .global i420_rgb_neon
79         .type   i420_rgb_neon, %function
80 i420_rgb_neon:
81         push            {r4-r8,r10-r11,lr}
82         vpush           {q4-q7}
83
84         /* load arguments */
85         ldmia           r0,     {O1, OPITCH}
86         ldmia           r1,     {Y1, U, V, YPITCH}
87
88         /* round the width to be a multiple of 16 */
89         ands            OPAD, WIDTH, #15
90         sub                     WIDTH, WIDTH, OPAD
91         addne           WIDTH, WIDTH, #16
92
93         /* init constants (scale value by 64) */
94         vmov.u8         coefY, #74
95         vmov.u8         coefRV, #115
96         vmov.u8         coefGU, #14
97         vmov.u8         coefGV, #34
98         vmov.u8         coefBU, #135
99         adr                     OPAD, coefficients
100         vld1.s16        {d6[], d7[]}, [OPAD]!
101         vld1.s16        {d8[], d9[]}, [OPAD]!
102         vld1.s16        {d10[], d11[]}, [OPAD]!
103         vmov.u8         alpha1, #255
104
105         /* init padding */
106         cmp                     HEIGHT, #0
107         sub                     OPAD,   OPITCH, WIDTH, lsl #2
108         sub                     YPAD,   YPITCH, WIDTH
109
110 loop_row:
111         movgts  COUNT,  WIDTH
112         add             O2,     O1,     OPITCH
113         add             Y2,     Y1,     YPITCH
114         /* exit if all rows have been processed */
115         vpople  {q4-q7}
116         pople   {r4-r8,r10-r11,pc}
117
118 loop_col:
119
120         /* Common U & V */
121
122         vld1.u8 {u}, [U,:64]!
123         vld1.u8 {v}, [V,:64]!
124
125         vmull.u8        chro_r, v, coefRV
126         vmull.u8        chro_g, u, coefGU
127         vmlal.u8        chro_g, v, coefGV
128         vmull.u8        chro_b, u, 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         PLD     [V]
136
137         /* Y Top Row */
138         vld2.u8 {y1,y2}, [Y1,:128]!
139
140         /* y1 : chrominance + luminance, then clamp (divide by 64) */
141         vmull.u8        lumi, y1, coefY
142         vqadd.s16       red, lumi, chro_r
143         vqadd.s16       green, lumi, chro_g
144         vqadd.s16       blue, lumi, chro_b
145         vqrshrun.s16    red1, red, #6
146         vqrshrun.s16    green1, green, #6
147         vqrshrun.s16    blue1, blue, #6
148
149         /* y2 : chrominance + luminance, then clamp (divide by 64) */
150         vmull.u8        lumi, y2, coefY
151         vqadd.s16       red, lumi, chro_r
152         vqadd.s16       green, lumi, chro_g
153         vqadd.s16       blue, lumi, chro_b
154         vqrshrun.s16    red2, red, #6
155         vqrshrun.s16    green2, green, #6
156         vqrshrun.s16    blue2, blue, #6
157
158         PLD     [Y1]
159
160         vmov.u8 alpha2, #255
161         vzip.u8 red1, red2
162         vzip.u8 green1, green2
163         vzip.u8 blue1, blue2
164
165         vst4.u8         {red1,green1,blue1,alpha1}, [O1,:128]!
166         vst4.u8         {red2,green2,blue2,alpha2}, [O1,:128]!
167
168         /* Y Bottom Row */
169         vld2.u8 {y1,y2}, [Y2,:128]!
170
171         /* y1 : chrominance + luminance, then clamp (divide by 64) */
172         vmull.u8        lumi, y1, coefY
173         vqadd.s16       red, lumi, chro_r
174         vqadd.s16       green, lumi, chro_g
175         vqadd.s16       blue, lumi, chro_b
176         vqrshrun.s16    red1, red, #6
177         vqrshrun.s16    green1, green, #6
178         vqrshrun.s16    blue1, blue, #6
179
180         /* y2 : chrominance + luminance, then clamp (divide by 64) */
181         vmull.u8        lumi, y2, coefY
182         vqadd.s16       red, lumi, chro_r
183         vqadd.s16       green, lumi, chro_g
184         vqadd.s16       blue, lumi, chro_b
185         vqrshrun.s16    red2, red, #6
186         vqrshrun.s16    green2, green, #6
187         vqrshrun.s16    blue2, blue, #6
188
189         PLD     [Y2]
190
191         vmov.u8 alpha2, #255
192         vzip.u8 red1, red2
193         vzip.u8 green1, green2
194         vzip.u8 blue1, blue2
195
196         vst4.u8         {red1,green1,blue1,alpha1}, [O2,:128]!
197         vst4.u8         {red2,green2,blue2,alpha2}, [O2,:128]!
198
199         /* next columns (x16) */
200         subs    COUNT,  COUNT,  #16
201         bgt             loop_col
202
203         /* next rows (x2) */
204         subs    HEIGHT, #2
205         add             O1,     O2,     OPAD
206         add             Y1,     Y2,     YPAD
207         add             U,      U,      YPAD,   lsr #1
208         add             V,      V,      YPAD,   lsr #1
209         b               loop_row