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
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.
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.
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 *****************************************************************************/
25 #include <vlc_common.h>
26 #include <vlc_plugin.h>
27 #include <vlc_filter.h>
29 #include "chroma_neon.h"
31 static int Open (vlc_object_t *);
34 set_description (N_("ARM NEON video chroma conversions"))
35 set_capability ("video filter2", 250)
36 set_callbacks (Open, NULL)
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 }
48 /* Planar YUV420 to packed YUV422 */
49 static void I420_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
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);
56 VIDEO_FILTER_WRAPPER (I420_YUYV)
58 static void I420_YVYU (filter_t *filter, picture_t *src, picture_t *dst)
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);
65 VIDEO_FILTER_WRAPPER (I420_YVYU)
67 static void I420_UYVY (filter_t *filter, picture_t *src, picture_t *dst)
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);
74 VIDEO_FILTER_WRAPPER (I420_UYVY)
76 static void I420_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
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);
83 VIDEO_FILTER_WRAPPER (I420_VYUY)
86 /* Planar YUV422 to packed YUV422 */
87 static void I422_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
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);
94 VIDEO_FILTER_WRAPPER (I422_YUYV)
96 static void I422_YVYU (filter_t *filter, picture_t *src, picture_t *dst)
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);
103 VIDEO_FILTER_WRAPPER (I422_YVYU)
105 static void I422_UYVY (filter_t *filter, picture_t *src, picture_t *dst)
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);
112 VIDEO_FILTER_WRAPPER (I422_UYVY)
114 static void I422_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
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);
121 VIDEO_FILTER_WRAPPER (I422_VYUY)
124 /* Packedr YUV422 to planar YUV422 */
125 static void YUYV_I422 (filter_t *filter, picture_t *src, picture_t *dst)
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);
132 VIDEO_FILTER_WRAPPER (YUYV_I422)
134 static void YVYU_I422 (filter_t *filter, picture_t *src, picture_t *dst)
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);
141 VIDEO_FILTER_WRAPPER (YVYU_I422)
143 static void UYVY_I422 (filter_t *filter, picture_t *src, picture_t *dst)
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);
150 VIDEO_FILTER_WRAPPER (UYVY_I422)
152 static void VYUY_I422 (filter_t *filter, picture_t *src, picture_t *dst)
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);
159 VIDEO_FILTER_WRAPPER (VYUY_I422)
161 static int Open (vlc_object_t *obj)
163 filter_t *filter = (filter_t *)obj;
165 if (!vlc_CPU_ARM_NEON())
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))
171 switch (filter->fmt_in.video.i_chroma)
173 /* Planar to packed */
175 switch (filter->fmt_out.video.i_chroma)
178 filter->pf_video_filter = I420_YUYV_Filter;
181 filter->pf_video_filter = I420_UYVY_Filter;
184 filter->pf_video_filter = I420_YVYU_Filter;
187 filter->pf_video_filter = I420_VYUY_Filter;
195 switch (filter->fmt_out.video.i_chroma)
198 filter->pf_video_filter = I420_YVYU_Filter;
201 filter->pf_video_filter = I420_VYUY_Filter;
204 filter->pf_video_filter = I420_YUYV_Filter;
207 filter->pf_video_filter = I420_UYVY_Filter;
215 switch (filter->fmt_out.video.i_chroma)
218 filter->pf_video_filter = I422_YUYV_Filter;
221 filter->pf_video_filter = I422_UYVY_Filter;
224 filter->pf_video_filter = I422_YVYU_Filter;
227 filter->pf_video_filter = I422_VYUY_Filter;
234 /* Packed to planar */
236 switch (filter->fmt_out.video.i_chroma)
239 filter->pf_video_filter = YUYV_I422_Filter;
246 switch (filter->fmt_out.video.i_chroma)
249 filter->pf_video_filter = UYVY_I422_Filter;
256 switch (filter->fmt_out.video.i_chroma)
259 filter->pf_video_filter = YVYU_I422_Filter;
267 switch (filter->fmt_out.video.i_chroma)
270 filter->pf_video_filter = VYUY_I422_Filter;