]> git.sesse.net Git - vlc/blob - modules/arm_neon/chroma_yuv.c
chroma_yuv_neon: add planar to packet YUV422 conversions
[vlc] / modules / arm_neon / chroma_yuv.c
1 /*****************************************************************************
2  * i420_yuy2.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
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, 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 "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 static int Open (vlc_object_t *obj)
125 {
126     filter_t *filter = (filter_t *)obj;
127
128     if (!(vlc_CPU() & CPU_CAPABILITY_NEON))
129         return VLC_EGENERIC;
130     if ((filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
131      || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
132         return VLC_EGENERIC;
133
134     switch (filter->fmt_in.video.i_chroma)
135     {
136         case VLC_CODEC_I420:
137             switch (filter->fmt_out.video.i_chroma)
138             {
139                 case VLC_CODEC_YUYV:
140                     filter->pf_video_filter = I420_YUYV_Filter;
141                     break;
142                 case VLC_CODEC_UYVY:
143                     filter->pf_video_filter = I420_UYVY_Filter;
144                     break;
145                 case VLC_CODEC_YVYU:
146                     filter->pf_video_filter = I420_YVYU_Filter;
147                     break;
148                 case VLC_CODEC_VYUY:
149                     filter->pf_video_filter = I420_VYUY_Filter;
150                     break;
151                 default:
152                     return VLC_EGENERIC;
153             }
154             break;
155
156         case VLC_CODEC_YV12:
157             switch (filter->fmt_out.video.i_chroma)
158             {
159                 case VLC_CODEC_YUYV:
160                     filter->pf_video_filter = I420_YVYU_Filter;
161                     break;
162                 case VLC_CODEC_UYVY:
163                     filter->pf_video_filter = I420_VYUY_Filter;
164                     break;
165                 case VLC_CODEC_YVYU:
166                     filter->pf_video_filter = I420_YUYV_Filter;
167                     break;
168                 case VLC_CODEC_VYUY:
169                     filter->pf_video_filter = I420_UYVY_Filter;
170                     break;
171                 default:
172                     return VLC_EGENERIC;
173             }
174             break;
175
176         case VLC_CODEC_I422:
177             switch (filter->fmt_out.video.i_chroma)
178             {
179                 case VLC_CODEC_YUYV:
180                     filter->pf_video_filter = I422_YUYV_Filter;
181                     break;
182                 case VLC_CODEC_UYVY:
183                     filter->pf_video_filter = I422_UYVY_Filter;
184                     break;
185                 case VLC_CODEC_YVYU:
186                     filter->pf_video_filter = I422_YVYU_Filter;
187                     break;
188                 case VLC_CODEC_VYUY:
189                     filter->pf_video_filter = I422_VYUY_Filter;
190                     break;
191                 default:
192                     return VLC_EGENERIC;
193             }
194             break;
195
196         default:
197             return VLC_EGENERIC;
198     }
199     return VLC_SUCCESS;
200 }