]> git.sesse.net Git - vlc/blob - modules/arm_neon/chroma_yuv.c
arm_neon: remove recursion
[vlc] / modules / arm_neon / chroma_yuv.c
1 /*****************************************************************************
2  * chroma_yuv.c : ARM NEONv1 YUV 4:2:0 to YUV :2:2 chroma conversion for VLC
3  *****************************************************************************
4  * Copyright (C) 2009 RĂ©mi Denis-Courmont
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24
25 #include <vlc_common.h>
26 #include <vlc_plugin.h>
27 #include <vlc_filter.h>
28 #include <vlc_cpu.h>
29 #include "arm_neon/chroma_neon.h"
30
31 static int Open (vlc_object_t *);
32
33 vlc_module_begin ()
34     set_description (N_("ARM NEON video chroma conversions"))
35     set_capability ("video filter2", 250)
36     set_callbacks (Open, NULL)
37 vlc_module_end ()
38
39 #define DEFINE_PACK(pack, pict) \
40     struct yuv_pack pack = { (pict)->Y_PIXELS, (pict)->Y_PITCH }
41 #define DEFINE_PLANES(planes, pict) \
42     struct yuv_planes planes = { \
43         (pict)->Y_PIXELS, (pict)->U_PIXELS, (pict)->V_PIXELS, (pict)->Y_PITCH }
44 #define DEFINE_PLANES_SWAP(planes, pict) \
45     struct yuv_planes planes = { \
46         (pict)->Y_PIXELS, (pict)->V_PIXELS, (pict)->U_PIXELS, (pict)->Y_PITCH }
47
48 /* Planar YUV420 to packed YUV422 */
49 static void I420_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
50 {
51     DEFINE_PACK(out, dst);
52     DEFINE_PLANES(in, src);
53     i420_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
54                     filter->fmt_in.video.i_height);
55 }
56 VIDEO_FILTER_WRAPPER (I420_YUYV)
57
58 static void I420_YVYU (filter_t *filter, picture_t *src, picture_t *dst)
59 {
60     DEFINE_PACK(out, dst);
61     DEFINE_PLANES_SWAP(in, src);
62     i420_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
63                     filter->fmt_in.video.i_height);
64 }
65 VIDEO_FILTER_WRAPPER (I420_YVYU)
66
67 static void I420_UYVY (filter_t *filter, picture_t *src, picture_t *dst)
68 {
69     DEFINE_PACK(out, dst);
70     DEFINE_PLANES(in, src);
71     i420_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
72                     filter->fmt_in.video.i_height);
73 }
74 VIDEO_FILTER_WRAPPER (I420_UYVY)
75
76 static void I420_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
77 {
78     DEFINE_PACK(out, dst);
79     DEFINE_PLANES_SWAP(in, src);
80     i420_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
81                     filter->fmt_in.video.i_height);
82 }
83 VIDEO_FILTER_WRAPPER (I420_VYUY)
84
85
86 /* Planar YUV422 to packed YUV422 */
87 static void I422_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
88 {
89     DEFINE_PACK(out, dst);
90     DEFINE_PLANES(in, src);
91     i422_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
92                     filter->fmt_in.video.i_height);
93 }
94 VIDEO_FILTER_WRAPPER (I422_YUYV)
95
96 static void I422_YVYU (filter_t *filter, picture_t *src, picture_t *dst)
97 {
98     DEFINE_PACK(out, dst);
99     DEFINE_PLANES_SWAP(in, src);
100     i422_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
101                     filter->fmt_in.video.i_height);
102 }
103 VIDEO_FILTER_WRAPPER (I422_YVYU)
104
105 static void I422_UYVY (filter_t *filter, picture_t *src, picture_t *dst)
106 {
107     DEFINE_PACK(out, dst);
108     DEFINE_PLANES(in, src);
109     i422_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
110                     filter->fmt_in.video.i_height);
111 }
112 VIDEO_FILTER_WRAPPER (I422_UYVY)
113
114 static void I422_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
115 {
116     DEFINE_PACK(out, dst);
117     DEFINE_PLANES_SWAP(in, src);
118     i422_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
119                     filter->fmt_in.video.i_height);
120 }
121 VIDEO_FILTER_WRAPPER (I422_VYUY)
122
123
124 /* Packedr YUV422 to planar YUV422 */
125 static void YUYV_I422 (filter_t *filter, picture_t *src, picture_t *dst)
126 {
127     DEFINE_PLANES(out, dst);
128     DEFINE_PACK(in, src);
129     yuyv_i422_neon (&out, &in, filter->fmt_in.video.i_width,
130                     filter->fmt_in.video.i_height);
131 }
132 VIDEO_FILTER_WRAPPER (YUYV_I422)
133
134 static void YVYU_I422 (filter_t *filter, picture_t *src, picture_t *dst)
135 {
136     DEFINE_PLANES_SWAP(out, dst);
137     DEFINE_PACK(in, src);
138     yuyv_i422_neon (&out, &in, filter->fmt_in.video.i_width,
139                     filter->fmt_in.video.i_height);
140 }
141 VIDEO_FILTER_WRAPPER (YVYU_I422)
142
143 static void UYVY_I422 (filter_t *filter, picture_t *src, picture_t *dst)
144 {
145     DEFINE_PLANES(out, dst);
146     DEFINE_PACK(in, src);
147     uyvy_i422_neon (&out, &in, filter->fmt_in.video.i_width,
148                     filter->fmt_in.video.i_height);
149 }
150 VIDEO_FILTER_WRAPPER (UYVY_I422)
151
152 static void VYUY_I422 (filter_t *filter, picture_t *src, picture_t *dst)
153 {
154     DEFINE_PLANES_SWAP(out, dst);
155     DEFINE_PACK(in, src);
156     uyvy_i422_neon (&out, &in, filter->fmt_in.video.i_width,
157                     filter->fmt_in.video.i_height);
158 }
159 VIDEO_FILTER_WRAPPER (VYUY_I422)
160
161 static int Open (vlc_object_t *obj)
162 {
163     filter_t *filter = (filter_t *)obj;
164
165     if (!vlc_CPU_ARM_NEON())
166         return VLC_EGENERIC;
167     if ((filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
168      || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
169         return VLC_EGENERIC;
170
171     switch (filter->fmt_in.video.i_chroma)
172     {
173         /* Planar to packed */
174         case VLC_CODEC_I420:
175             switch (filter->fmt_out.video.i_chroma)
176             {
177                 case VLC_CODEC_YUYV:
178                     filter->pf_video_filter = I420_YUYV_Filter;
179                     break;
180                 case VLC_CODEC_UYVY:
181                     filter->pf_video_filter = I420_UYVY_Filter;
182                     break;
183                 case VLC_CODEC_YVYU:
184                     filter->pf_video_filter = I420_YVYU_Filter;
185                     break;
186                 case VLC_CODEC_VYUY:
187                     filter->pf_video_filter = I420_VYUY_Filter;
188                     break;
189                 default:
190                     return VLC_EGENERIC;
191             }
192             break;
193
194         case VLC_CODEC_YV12:
195             switch (filter->fmt_out.video.i_chroma)
196             {
197                 case VLC_CODEC_YUYV:
198                     filter->pf_video_filter = I420_YVYU_Filter;
199                     break;
200                 case VLC_CODEC_UYVY:
201                     filter->pf_video_filter = I420_VYUY_Filter;
202                     break;
203                 case VLC_CODEC_YVYU:
204                     filter->pf_video_filter = I420_YUYV_Filter;
205                     break;
206                 case VLC_CODEC_VYUY:
207                     filter->pf_video_filter = I420_UYVY_Filter;
208                     break;
209                 default:
210                     return VLC_EGENERIC;
211             }
212             break;
213
214         case VLC_CODEC_I422:
215             switch (filter->fmt_out.video.i_chroma)
216             {
217                 case VLC_CODEC_YUYV:
218                     filter->pf_video_filter = I422_YUYV_Filter;
219                     break;
220                 case VLC_CODEC_UYVY:
221                     filter->pf_video_filter = I422_UYVY_Filter;
222                     break;
223                 case VLC_CODEC_YVYU:
224                     filter->pf_video_filter = I422_YVYU_Filter;
225                     break;
226                 case VLC_CODEC_VYUY:
227                     filter->pf_video_filter = I422_VYUY_Filter;
228                     break;
229                 default:
230                     return VLC_EGENERIC;
231             }
232             break;
233
234         /* Packed to planar */
235         case VLC_CODEC_YUYV:
236             switch (filter->fmt_out.video.i_chroma)
237             {
238                 case VLC_CODEC_I422:
239                     filter->pf_video_filter = YUYV_I422_Filter;
240                     break;
241                 default:
242                     return VLC_EGENERIC;
243             }
244
245         case VLC_CODEC_UYVY:
246             switch (filter->fmt_out.video.i_chroma)
247             {
248                 case VLC_CODEC_I422:
249                     filter->pf_video_filter = UYVY_I422_Filter;
250                     break;
251                 default:
252                     return VLC_EGENERIC;
253             }
254
255         case VLC_CODEC_YVYU:
256             switch (filter->fmt_out.video.i_chroma)
257             {
258                 case VLC_CODEC_I422:
259                     filter->pf_video_filter = YVYU_I422_Filter;
260                     break;
261                 default:
262                     return VLC_EGENERIC;
263             }
264
265
266         case VLC_CODEC_VYUY:
267             switch (filter->fmt_out.video.i_chroma)
268             {
269                 case VLC_CODEC_I422:
270                     filter->pf_video_filter = VYUY_I422_Filter;
271                     break;
272                 default:
273                     return VLC_EGENERIC;
274             }
275
276         default:
277             return VLC_EGENERIC;
278     }
279     return VLC_SUCCESS;
280 }