[vlc-commits] chroma_yuv_neon: add planar to packet YUV422 conversions

Rémi Denis-Courmont git at videolan.org
Thu Jul 7 20:26:50 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Jul  7 21:21:34 2011 +0300| [5b4d6cf447eeebf88c4e70fa219d822c65831388] | committer: Rémi Denis-Courmont

chroma_yuv_neon: add planar to packet YUV422 conversions

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5b4d6cf447eeebf88c4e70fa219d822c65831388
---

 modules/arm_neon/chroma_neon.h |   10 ++++
 modules/arm_neon/chroma_yuv.c  |   63 +++++++++++++++++++++++++-
 modules/arm_neon/i422_yuyv.S   |   97 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 168 insertions(+), 2 deletions(-)

diff --git a/modules/arm_neon/chroma_neon.h b/modules/arm_neon/chroma_neon.h
index 40bfbcc..df8730e 100644
--- a/modules/arm_neon/chroma_neon.h
+++ b/modules/arm_neon/chroma_neon.h
@@ -46,3 +46,13 @@ void i420_yuyv_neon (struct yuv_pack *const out,
 void i420_uyvy_neon (struct yuv_pack *const out,
                      const struct yuv_planes *const in,
                      int width, int height);
+
+/* I422 to YUYV conversion. */
+void i422_yuyv_neon (struct yuv_pack *const out,
+                     const struct yuv_planes *const in,
+                     int width, int height);
+
+/* I422 to UYVY conversion. */
+void i422_uyvy_neon (struct yuv_pack *const out,
+                     const struct yuv_planes *const in,
+                     int width, int height);
diff --git a/modules/arm_neon/chroma_yuv.c b/modules/arm_neon/chroma_yuv.c
index 8372c90..3ac30fb 100644
--- a/modules/arm_neon/chroma_yuv.c
+++ b/modules/arm_neon/chroma_yuv.c
@@ -45,6 +45,7 @@ vlc_module_end ()
     struct yuv_planes planes = { \
         (pict)->Y_PIXELS, (pict)->V_PIXELS, (pict)->U_PIXELS, (pict)->Y_PITCH }
 
+/* Planar YUV420 to packed YUV422 */
 static void I420_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
 {
     DEFINE_PACK(out, dst);
@@ -81,14 +82,52 @@ static void I420_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
 }
 VIDEO_FILTER_WRAPPER (I420_VYUY)
 
+
+/* Planar YUV422 to packed YUV422 */
+static void I422_YUYV (filter_t *filter, picture_t *src, picture_t *dst)
+{
+    DEFINE_PACK(out, dst);
+    DEFINE_PLANES(in, src);
+    i422_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
+                    filter->fmt_in.video.i_height);
+}
+VIDEO_FILTER_WRAPPER (I422_YUYV)
+
+static void I422_YVYU (filter_t *filter, picture_t *src, picture_t *dst)
+{
+    DEFINE_PACK(out, dst);
+    DEFINE_PLANES_SWAP(in, src);
+    i422_yuyv_neon (&out, &in, filter->fmt_in.video.i_width,
+                    filter->fmt_in.video.i_height);
+}
+VIDEO_FILTER_WRAPPER (I422_YVYU)
+
+static void I422_UYVY (filter_t *filter, picture_t *src, picture_t *dst)
+{
+    DEFINE_PACK(out, dst);
+    DEFINE_PLANES(in, src);
+    i422_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
+                    filter->fmt_in.video.i_height);
+}
+VIDEO_FILTER_WRAPPER (I422_UYVY)
+
+static void I422_VYUY (filter_t *filter, picture_t *src, picture_t *dst)
+{
+    DEFINE_PACK(out, dst);
+    DEFINE_PLANES_SWAP(in, src);
+    i422_uyvy_neon (&out, &in, filter->fmt_in.video.i_width,
+                    filter->fmt_in.video.i_height);
+}
+VIDEO_FILTER_WRAPPER (I422_VYUY)
+
+
 static int Open (vlc_object_t *obj)
 {
     filter_t *filter = (filter_t *)obj;
 
     if (!(vlc_CPU() & CPU_CAPABILITY_NEON))
         return VLC_EGENERIC;
-    if (((filter->fmt_in.video.i_width | filter->fmt_in.video.i_height) & 1)
-     || (filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
+    if ((filter->fmt_in.video.i_width != filter->fmt_out.video.i_width)
      || (filter->fmt_in.video.i_height != filter->fmt_out.video.i_height))
         return VLC_EGENERIC;
 
@@ -134,6 +173,26 @@ static int Open (vlc_object_t *obj)
             }
             break;
 
+        case VLC_CODEC_I422:
+            switch (filter->fmt_out.video.i_chroma)
+            {
+                case VLC_CODEC_YUYV:
+                    filter->pf_video_filter = I422_YUYV_Filter;
+                    break;
+                case VLC_CODEC_UYVY:
+                    filter->pf_video_filter = I422_UYVY_Filter;
+                    break;
+                case VLC_CODEC_YVYU:
+                    filter->pf_video_filter = I422_YVYU_Filter;
+                    break;
+                case VLC_CODEC_VYUY:
+                    filter->pf_video_filter = I422_VYUY_Filter;
+                    break;
+                default:
+                    return VLC_EGENERIC;
+            }
+            break;
+
         default:
             return VLC_EGENERIC;
     }
diff --git a/modules/arm_neon/i422_yuyv.S b/modules/arm_neon/i422_yuyv.S
new file mode 100644
index 0000000..5561e44
--- /dev/null
+++ b/modules/arm_neon/i422_yuyv.S
@@ -0,0 +1,97 @@
+ @*****************************************************************************
+ @ i422_yuyv_neon.S : ARM NEONv1 I422 to YUYV chroma conversion
+ @*****************************************************************************
+ @ Copyright (C) 2011 Rémi Denis-Courmont
+ @
+ @ This program is free software; you can redistribute it and/or modify
+ @ it under the terms of the GNU Lesser General Public License as published by
+ @ the Free Software Foundation; either version 2.1 of the License, or
+ @ (at your option) any later version.
+ @
+ @ This program is distributed in the hope that it will be useful,
+ @ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ @ GNU General Public License for more details.
+ @
+ @ You should have received a copy of the GNU Lesser General Public License
+ @ along with this program; if not, write to the Free Software Foundation,
+ @ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ @****************************************************************************/
+
+	.fpu neon
+	.text
+
+#define O	r0
+#define OPAD	r1
+#define WIDTH	r2
+#define HEIGHT	r3
+#define Y	r4
+#define U	r5
+#define V	r6
+#define COUNT	ip
+#define YPAD	lr
+
+	.align
+	.global i422_yuyv_neon
+	.type	i422_yuyv_neon, %function
+i422_yuyv_neon:
+	push		{r4-r6,lr}
+	ldmia		r1,	{Y, U, V, YPAD}
+	ldmia		r0,	{O, OPAD}
+	cmp		HEIGHT,	#0
+	sub		OPAD,	OPAD,	WIDTH,	lsl #1
+	sub		YPAD,	YPAD,	WIDTH
+1:
+	movgts		COUNT,	WIDTH
+	pople		{r4-r6,pc}
+2:
+	pld		[U, #64]
+	vld1.u8		{d2},		[U,:64]!
+	pld		[V, #64]
+	vld1.u8		{d3},		[V,:64]!
+	pld		[Y, #64]
+	vzip.u8		d2,	d3
+	subs		COUNT,	COUNT,	#16
+	vld1.u8		{q0},		[Y,:128]!
+	vzip.u8		q0,	q1
+	vst1.u8		{q0-q1},	[O,:128]!
+	bgt		2b
+
+	subs		HEIGHT,	#1
+	add		U,	U,	YPAD,	lsr #1
+	add		V,	V,	YPAD,	lsr #1
+	add		Y,	Y,	YPAD
+	add		O,	O,	OPAD
+	b		1b
+
+	.global i422_uyvy_neon
+	.type	i422_uyvy_neon, %function
+i422_uyvy_neon:
+	push		{r4-r6,lr}
+	ldmia		r1,	{Y, U, V, YPAD}
+	ldmia		r0,	{O, OPAD}
+	cmp		HEIGHT,	#0
+	sub		OPAD,	OPAD,	WIDTH,	lsl #1
+	sub		YPAD,	YPAD,	WIDTH
+1:
+	movgts		COUNT,	WIDTH
+	pople		{r4-r6,pc}
+2:
+	pld		[U, #64]
+	vld1.u8		{d0},		[U,:64]!
+	pld		[V, #64]
+	vld1.u8		{d1},		[V,:64]!
+	pld		[Y, #64]
+	vzip.u8		d0,	d1
+	subs		COUNT,	COUNT,	#16
+	vld1.u8		{q1},		[Y,:128]!
+	vzip.u8		q0,	q1
+	vst1.u8		{q0-q1},	[O,:128]!
+	bgt		2b
+
+	subs		HEIGHT,	#1
+	add		U,	U,	YPAD,	lsr #1
+	add		V,	V,	YPAD,	lsr #1
+	add		Y,	Y,	YPAD
+	add		O,	O,	OPAD
+	b		1b



More information about the vlc-commits mailing list