<HTML><HEAD>
<META content="text/html; charset=utf-8" http-equiv=Content-Type></HEAD>
<BODY>
<DIV>
<DIV style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif">Hey.<BR>It would be very useful to add a protocol handler to VLC mac/pc/linuxGNU   :)<BR><BR>Cheers<BR><BR>Konrad<BR><BR><BR>Konrad Iturbe<BR>http://chernowii.com</DIV></DIV>
<DIV dir=ltr>
<HR>
<SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif; FONT-WEIGHT: bold">From: </SPAN><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif"><A href="mailto:martin@martin.st">Martin Storsjö</A></SPAN><BR><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif; FONT-WEIGHT: bold">Sent: </SPAN><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif">‎01/‎10/‎2013 22:05</SPAN><BR><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif; FONT-WEIGHT: bold">To: </SPAN><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif"><A href="mailto:vlc-devel@videolan.org">vlc-devel@videolan.org</A></SPAN><BR><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif; FONT-WEIGHT: bold">Subject: </SPAN><SPAN style="FONT-SIZE: 11pt; FONT-FAMILY: Calibri,sans-serif">[vlc-devel] [PATCH] arm_neon: Add an optimized routine for NV12/21to I420/YV12</SPAN><BR><BR></DIV>This avoids hitting swscale for this conversion, for hw decoders<BR>that return NV12/21 in combination with the android vout in YUV<BR>mode.<BR>---<BR>Avoiding multiplications in the memcpy loop as suggested by Denis,<BR>avoiding duplicate filter definitions, renamed the asm and filter<BR>functions and reusing registers more cleverly as suggested by Rémi<BR>(clobbering 3 fewer registers than before).<BR>---<BR>modules/arm_neon/Makefile.am         |    1 +<BR>modules/arm_neon/chroma_neon.h       |    5 +++<BR>modules/arm_neon/chroma_yuv.c        |   65 ++++++++++++++++++++++++++++++++++<BR>modules/arm_neon/semiplanar_planar.S |   64 +++++++++++++++++++++++++++++++++<BR>4 files changed, 135 insertions(+)<BR>create mode 100644 modules/arm_neon/semiplanar_planar.S<BR><BR>diff --git a/modules/arm_neon/Makefile.am b/modules/arm_neon/Makefile.am<BR>index 212605f..c375c10 100644<BR>--- a/modules/arm_neon/Makefile.am<BR>+++ b/modules/arm_neon/Makefile.am<BR>@@ -9,6 +9,7 @@ libsimple_channel_mixer_neon_plugin_LIBTOOLFLAGS = --tag=CC<BR>libchroma_yuv_neon_plugin_la_SOURCES = \<BR>arm_neon/i420_yuyv.S \<BR>arm_neon/i422_yuyv.S \<BR>+ arm_neon/semiplanar_planar.S \<BR>arm_neon/yuyv_i422.S \<BR>arm_neon/chroma_yuv.c arm_neon/chroma_neon.h<BR>libchroma_yuv_neon_plugin_la_CFLAGS = $(AM_CFLAGS)<BR>diff --git a/modules/arm_neon/chroma_neon.h b/modules/arm_neon/chroma_neon.h<BR>index 865315a..a5ce775 100644<BR>--- a/modules/arm_neon/chroma_neon.h<BR>+++ b/modules/arm_neon/chroma_neon.h<BR>@@ -67,6 +67,11 @@ void uyvy_i422_neon (struct yuv_planes *const out,<BR>                      const struct yuv_pack *const in,<BR>                      int width, int height) asm("uyvy_i422_neon");<BR><BR>+/* Semiplanar to planar conversion. */<BR>+void semiplanar_planar_neon (struct yuv_planes *const out,<BR>+                             const struct yuv_planes *const in,<BR>+                             int width, int height) asm("semiplanar_planar_neon");<BR>+<BR>/* I420 to RGBA conversion. */<BR>void i420_rgb_neon (struct yuv_pack *const out,<BR>                     const struct yuv_planes *const in,<BR>diff --git a/modules/arm_neon/chroma_yuv.c b/modules/arm_neon/chroma_yuv.c<BR>index b54732e..0129c30 100644<BR>--- a/modules/arm_neon/chroma_yuv.c<BR>+++ b/modules/arm_neon/chroma_yuv.c<BR>@@ -83,6 +83,42 @@ static void I420_VYUY (filter_t *filter, picture_t *src, picture_t *dst)<BR>VIDEO_FILTER_WRAPPER (I420_VYUY)<BR><BR><BR>+/* Semiplanar NV12/21 to planar I420/YV12 */<BR>+static void copy_y_plane(filter_t *filter, picture_t *src, picture_t *dst)<BR>+{<BR>+    uint8_t *src_y = src->Y_PIXELS;<BR>+    uint8_t *dst_y = dst->Y_PIXELS;<BR>+    if (src->Y_PITCH == dst->Y_PITCH) {<BR>+        memcpy(dst_y, src_y, dst->Y_PITCH * filter->fmt_in.video.i_height);<BR>+    } else {<BR>+        for (unsigned y = 0; y < filter->fmt_in.video.i_height;<BR>+                y++, dst_y += dst->Y_PITCH, src_y += src->Y_PITCH)<BR>+            memcpy(dst_y, src_y, filter->fmt_in.video.i_width);<BR>+    }<BR>+}<BR>+<BR>+static void Semiplanar_Planar (filter_t *filter, picture_t *src, picture_t *dst)<BR>+{<BR>+    DEFINE_PLANES(out, dst);<BR>+    DEFINE_PLANES(in, src);<BR>+    copy_y_plane (filter, src, dst);<BR>+    semiplanar_planar_neon (&out, &in, filter->fmt_in.video.i_width,<BR>+                            filter->fmt_in.video.i_height);<BR>+}<BR>+VIDEO_FILTER_WRAPPER (Semiplanar_Planar)<BR>+<BR>+static void Semiplanar_Planar_Swap (filter_t *filter, picture_t *src,<BR>+                                    picture_t *dst)<BR>+{<BR>+    DEFINE_PLANES_SWAP(out, dst);<BR>+    DEFINE_PLANES(in, src);<BR>+    copy_y_plane (filter, src, dst);<BR>+    semiplanar_planar_neon (&out, &in, filter->fmt_in.video.i_width,<BR>+                            filter->fmt_in.video.i_height);<BR>+}<BR>+VIDEO_FILTER_WRAPPER (Semiplanar_Planar_Swap)<BR>+<BR>+<BR>/* Planar YUV422 to packed YUV422 */<BR>static void I422_YUYV (filter_t *filter, picture_t *src, picture_t *dst)<BR>{<BR>@@ -231,6 +267,35 @@ static int Open (vlc_object_t *obj)<BR>             }<BR>             break;<BR><BR>+        /* Semiplanar to planar */<BR>+        case VLC_CODEC_NV12:<BR>+            switch (filter->fmt_out.video.i_chroma)<BR>+            {<BR>+                case VLC_CODEC_I420:<BR>+                    filter->pf_video_filter = Semiplanar_Planar_Filter;<BR>+                    break;<BR>+                case VLC_CODEC_YV12:<BR>+                    filter->pf_video_filter = Semiplanar_Planar_Swap_Filter;<BR>+                    break;<BR>+                default:<BR>+                    return VLC_EGENERIC;<BR>+            }<BR>+            break;<BR>+<BR>+        case VLC_CODEC_NV21:<BR>+            switch (filter->fmt_out.video.i_chroma)<BR>+            {<BR>+                case VLC_CODEC_I420:<BR>+                    filter->pf_video_filter = Semiplanar_Planar_Swap_Filter;<BR>+                    break;<BR>+                case VLC_CODEC_YV12:<BR>+                    filter->pf_video_filter = Semiplanar_Planar_Filter;<BR>+                    break;<BR>+                default:<BR>+                    return VLC_EGENERIC;<BR>+            }<BR>+            break;<BR>+<BR>         /* Packed to planar */<BR>         case VLC_CODEC_YUYV:<BR>             switch (filter->fmt_out.video.i_chroma)<BR>diff --git a/modules/arm_neon/semiplanar_planar.S b/modules/arm_neon/semiplanar_planar.S<BR>new file mode 100644<BR>index 0000000..d099add<BR>--- /dev/null<BR>+++ b/modules/arm_neon/semiplanar_planar.S<BR>@@ -0,0 +1,64 @@<BR>+ @*****************************************************************************<BR>+ @ nv12_i420.S : ARM NEONv1 NV12 to I420 chroma conversion<BR>+ @*****************************************************************************<BR>+ @ Copyright (C) 2009-2011 Rémi Denis-Courmont<BR>+ @ Copyright (C) 2013 Martin Storsjö<BR>+ @<BR>+ @ This program is free software; you can redistribute it and/or modify<BR>+ @ it under the terms of the GNU Lesser General Public License as published by<BR>+ @ the Free Software Foundation; either version 2.1 of the License, or<BR>+ @ (at your option) any later version.<BR>+ @<BR>+ @ This program is distributed in the hope that it will be useful,<BR>+ @ but WITHOUT ANY WARRANTY; without even the implied warranty of<BR>+ @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<BR>+ @ GNU Lesser General Public License for more details.<BR>+ @<BR>+ @ You should have received a copy of the GNU Lesser General Public License<BR>+ @ along with this program; if not, write to the Free Software Foundation,<BR>+ @ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.<BR>+ @****************************************************************************/<BR>+<BR>+ .syntax unified<BR>+ .fpu neon<BR>+ .text<BR>+<BR>+#define IPITCH r0<BR>+#define IPAD r0<BR>+#define COUNT r1<BR>+#define WIDTH r2<BR>+#define HEIGHT r3<BR>+#define UV r4<BR>+#define U r5<BR>+#define V r6<BR>+#define OPITCH lr<BR>+#define OPAD lr<BR>+<BR>+ .align 2<BR>+ .global semiplanar_planar_neon<BR>+ .type semiplanar_planar_neon, %function<BR>+semiplanar_planar_neon:<BR>+ push {r4-r6,lr}<BR>+ add r0, r0, #4 @ first plane is unused<BR>+ ldmia r0, {U, V, OPITCH}<BR>+ ldr UV, [r1, #4] @ only need the second plane<BR>+ ldr IPITCH, [r1, #12]<BR>+ cmp HEIGHT, #0<BR>+ sub IPAD, IPITCH, WIDTH<BR>+ sub OPAD, OPITCH, WIDTH<BR>+1:<BR>+ movsgt COUNT, WIDTH<BR>+ pople {r4-r6,pc}<BR>+2:<BR>+ pld [UV, #64]<BR>+ vld2.u8 {d0, d1}, [UV,:128]!<BR>+ subs COUNT, COUNT, #16<BR>+ vst1.u8 {d0}, [U,:64]!<BR>+ vst1.u8 {d1}, [V,:64]!<BR>+ bgt 2b<BR>+<BR>+ subs HEIGHT, #2<BR>+ add UV, UV, IPAD<BR>+ add U, U, OPAD, lsr #1<BR>+ add V, V, OPAD, lsr #1<BR>+ b 1b<BR>-- <BR>1.7.9.4<BR><BR>_______________________________________________<BR>vlc-devel mailing list<BR>To unsubscribe or modify your subscription options:<BR>https://mailman.videolan.org/listinfo/vlc-devel<BR></BODY></HTML>