Commit a54dab74 authored by Jean-Baptiste Kempf's avatar Jean-Baptiste Kempf

Update patches for 2.0.0 branch

parent 3fc1410e
From cd075d698fe8b680984b299844a705bca1923785 Mon Sep 17 00:00:00 2001
From eff0203865dc65f6315d77eddf8d6694ede0ca78 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Philippe=20Andr=C3=A9?= <jpeg@videolan.org>
Date: Thu, 2 Jun 2011 15:15:57 +0200
Subject: [PATCH 1/2] Android: add compatibility pthread_cancel
Subject: [PATCH 1/4] Android: add compatibility pthread_cancel
Original-code: c1ee19f63a6c6773400e98a9265b0a7e49fd528c
7884ed8d407647a1523afb8be6a2859477d54fd7
......@@ -15,11 +15,11 @@ Modified and ported-by: Jean-Baptiste Kempf <jb@videolan.org>
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
---
compat/pthread_cancel.c | 291 +++++++++++++++++++++++++++++++++++++++++++++++
configure.ac | 5 +
configure.ac | 4 +
include/vlc_fixups.h | 22 ++++
lib/error.c | 16 +++
src/posix/thread.c | 37 ++++++-
5 files changed, 367 insertions(+), 4 deletions(-)
src/posix/thread.c | 21 ++++
5 files changed, 354 insertions(+), 0 deletions(-)
create mode 100644 compat/pthread_cancel.c
diff --git a/compat/pthread_cancel.c b/compat/pthread_cancel.c
......@@ -320,26 +320,25 @@ index 0000000..8a39f5d
+ return ret;
+}
diff --git a/configure.ac b/configure.ac
index 52d8cf7..e72a05c 100644
index 81a0d3a..c1b7de6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -446,6 +446,11 @@ if test "${SYS}" = "mingw32" ; then
fi
@@ -469,6 +469,10 @@ if test "${SYS}" = "mingw32" ; then
CFLAGS="${CFLAGS_save}"; CXXFLAGS="${CXXFLAGS_save}"
fi
+if test "${HAVE_ANDROID}" = "1"; then
+ AC_REPLACE_FUNCS([pthread_cancel])
+ VLC_ADD_LIBS([libvlccore],[-llog])
+fi
+
dnl
dnl Buggy glibc prevention. Purposedly not cached.
dnl See sourceware.org bugs 5058 and 5443.
diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h
index b5884f4..227658a 100644
index e0152fc..0d63194 100644
--- a/include/vlc_fixups.h
+++ b/include/vlc_fixups.h
@@ -338,6 +338,28 @@ long nrand48 (unsigned short subi[3]);
@@ -339,6 +339,28 @@ long nrand48 (unsigned short subi[3]);
# undef __cplusplus
# endif
char *tempnam(const char *, const char *);
......@@ -410,54 +409,10 @@ index ef2ecdc..441953c 100644
vlc_mutex_unlock (&lock);
}
diff --git a/src/posix/thread.c b/src/posix/thread.c
index 7c4860e..94b1a73 100644
index 122e201..9d9c771 100644
--- a/src/posix/thread.c
+++ b/src/posix/thread.c
@@ -136,6 +136,14 @@ static struct timespec mtime_to_ts (mtime_t date)
return ts;
}
+#if defined(__ANDROID__) && !defined(NDEBUG)
+# include <android/log.h>
+# define LOG_TAG "VLC/pthread"
+# define FATAL(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#else
+# define FATAL(...) fprintf(stderr, __VA_ARGS__)
+#endif
+
/**
* Print a backtrace to the standard error for debugging purpose.
*/
@@ -176,8 +184,8 @@ vlc_thread_fatal (const char *action, int error,
const char *function, const char *file, unsigned line)
{
int canc = vlc_savecancel ();
- fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ",
- action, error, vlc_threadid ());
+ FATAL ("LibVLC fatal error %s (%d) in thread %lu ",
+ action, error, vlc_threadid ());
vlc_trace (function, file, line);
/* Sometimes strerror_r() crashes too, so make sure we print an error
@@ -185,7 +193,7 @@ vlc_thread_fatal (const char *action, int error,
#ifdef __GLIBC__
/* Avoid the strerror_r() prototype brain damage in glibc */
errno = error;
- fprintf (stderr, " Error message: %m\n");
+ FATAL (" Error message: %m\n");
#else
char buf[1000];
const char *msg;
@@ -202,7 +210,7 @@ vlc_thread_fatal (const char *action, int error,
msg = "unknown (invalid error number)";
break;
}
- fprintf (stderr, " Error message: %s\n", msg);
+ FATAL (" Error message: %s\n", msg);
#endif
fflush (stderr);
@@ -435,7 +443,11 @@ void vlc_cond_broadcast (vlc_cond_t *p_condvar)
@@ -435,7 +435,11 @@ void vlc_cond_broadcast (vlc_cond_t *p_condvar)
*/
void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
{
......@@ -469,9 +424,9 @@ index 7c4860e..94b1a73 100644
VLC_THREAD_ASSERT ("waiting on condition");
}
@@ -458,7 +470,12 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
mtime_t deadline)
{
@@ -472,7 +476,12 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
#endif
struct timespec ts = mtime_to_ts (deadline);
+
+#ifdef __ANDROID__
......@@ -482,7 +437,7 @@ index 7c4860e..94b1a73 100644
if (val != ETIMEDOUT)
VLC_THREAD_ASSERT ("timed-waiting on condition");
return val;
@@ -497,6 +514,14 @@ void vlc_sem_destroy (vlc_sem_t *sem)
@@ -511,6 +520,14 @@ void vlc_sem_destroy (vlc_sem_t *sem)
val = errno;
#endif
......@@ -497,7 +452,7 @@ index 7c4860e..94b1a73 100644
VLC_THREAD_ASSERT ("destroying semaphore");
}
@@ -727,7 +752,11 @@ static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr,
@@ -741,7 +758,11 @@ static int vlc_clone_attr (vlc_thread_t *th, pthread_attr_t *attr,
assert (ret == 0); /* fails iif VLC_STACKSIZE is invalid */
#endif
......@@ -510,5 +465,5 @@ index 7c4860e..94b1a73 100644
pthread_attr_destroy (attr);
return ret;
--
1.7.8.3
1.7.8.4
From a00dc86ddff76c50791962b8c1981140ff0b8bac Mon Sep 17 00:00:00 2001
From 1b9b62e8bd39d752d867a2ad273b5e546dd001b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Duraffort?= <ivoire@videolan.org>
Date: Sun, 7 Nov 2010 19:11:51 +0100
Subject: [PATCH 2/2] Implement rw_locks, needed for Android 2.2 and below
Subject: [PATCH 2/4] Implement rw_locks, needed for Android 2.2 and below
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
---
include/vlc_threads.h | 22 ++++++++++++++
src/posix/thread.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -44,10 +45,10 @@ index 7a6c6af..181f273 100644
typedef struct vlc_timer *vlc_timer_t;
diff --git a/src/posix/thread.c b/src/posix/thread.c
index 94b1a73..d7438a4 100644
index 9d9c771..031dcc2 100644
--- a/src/posix/thread.c
+++ b/src/posix/thread.c
@@ -573,6 +573,7 @@ void vlc_sem_wait (vlc_sem_t *sem)
@@ -579,6 +579,7 @@ void vlc_sem_wait (vlc_sem_t *sem)
VLC_THREAD_ASSERT ("locking semaphore");
}
......@@ -55,7 +56,7 @@ index 94b1a73..d7438a4 100644
/**
* Initializes a read/write lock.
*/
@@ -617,6 +618,81 @@ void vlc_rwlock_unlock (vlc_rwlock_t *lock)
@@ -623,6 +624,81 @@ void vlc_rwlock_unlock (vlc_rwlock_t *lock)
int val = pthread_rwlock_unlock (lock);
VLC_THREAD_ASSERT ("releasing R/W lock");
}
......@@ -138,5 +139,5 @@ index 94b1a73..d7438a4 100644
/**
* Allocates a thread-specific variable.
--
1.7.8.3
1.7.8.4
From b3337dea60851df32e659ddbc576d9cdd78ee23d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Toque?= <xilasz@gmail.com>
Date: Tue, 4 Oct 2011 22:38:36 +0200
Subject: [PATCH 3/4] YUV->RGB convertor in NEON
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Rafaël Carré <funman@videolan.org>
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
---
modules/arm_neon/Modules.am | 10 ++
modules/arm_neon/chroma_neon.h | 12 +++
modules/arm_neon/i420_rgb.S | 209 ++++++++++++++++++++++++++++++++++++++++
modules/arm_neon/nv12_rgb.S | 206 +++++++++++++++++++++++++++++++++++++++
modules/arm_neon/nv21_rgb.S | 206 +++++++++++++++++++++++++++++++++++++++
modules/arm_neon/yuv_rgb.c | 179 ++++++++++++++++++++++++++++++++++
6 files changed, 822 insertions(+), 0 deletions(-)
create mode 100644 modules/arm_neon/i420_rgb.S
create mode 100644 modules/arm_neon/nv12_rgb.S
create mode 100644 modules/arm_neon/nv21_rgb.S
create mode 100644 modules/arm_neon/yuv_rgb.c
diff --git a/modules/arm_neon/Modules.am b/modules/arm_neon/Modules.am
index 83576eb..9dfd4ab 100644
--- a/modules/arm_neon/Modules.am
+++ b/modules/arm_neon/Modules.am
@@ -18,7 +18,17 @@ libchroma_yuv_neon_plugin_la_CFLAGS = $(AM_CFLAGS)
libchroma_yuv_neon_plugin_la_LIBADD = $(AM_LIBADD)
libchroma_yuv_neon_plugin_la_DEPENDENCIES =
+libyuv_rgb_neon_plugin_la_SOURCES = \
+ i420_rgb.S \
+ nv21_rgb.S \
+ nv12_rgb.S \
+ yuv_rgb.c
+libyuv_rgb_neon_plugin_la_CFLAGS = $(AM_CFLAGS)
+libyuv_rgb_neon_plugin_la_LIBADD = $(AM_LIBADD)
+libyuv_rgb_neon_plugin_la_DEPENDENCIES =
+
libvlc_LTLIBRARIES += \
libaudio_format_neon_plugin.la \
libchroma_yuv_neon_plugin.la \
+ libyuv_rgb_neon_plugin.la \
$(NULL)
diff --git a/modules/arm_neon/chroma_neon.h b/modules/arm_neon/chroma_neon.h
index 204c5f1..3e867e3 100644
--- a/modules/arm_neon/chroma_neon.h
+++ b/modules/arm_neon/chroma_neon.h
@@ -64,3 +64,15 @@ void yuyv_i422_neon (struct yuv_planes *const out,
/* UYVY to I422 conversion. */
void uyvy_i422_neon (struct yuv_planes *const out,
const struct yuv_pack *const in, int width, int height);
+
+/* I420 to RGBA conversion. */
+void i420_rgb_neon (struct yuv_pack *const out,
+ const struct yuv_planes *const in, int width, int height);
+
+/* NV21 to RGBA conversion. */
+void nv21_rgb_neon (struct yuv_pack *const out,
+ const struct yuv_planes *const in, int width, int height);
+
+/* NV12 to RGBA conversion. */
+void nv12_rgb_neon (struct yuv_pack *const out,
+ const struct yuv_planes *const in, int width, int height);
diff --git a/modules/arm_neon/i420_rgb.S b/modules/arm_neon/i420_rgb.S
new file mode 100644
index 0000000..b31dd92
--- /dev/null
+++ b/modules/arm_neon/i420_rgb.S
@@ -0,0 +1,209 @@
+ @*****************************************************************************
+ @ i420_rgb.S : ARM NEONv1 I420 to RGB chroma conversion
+ @*****************************************************************************
+ @ Copyright (C) 2011 Sébastien Toque
+ @ Rémi Denis-Courmont
+ @
+ @ This program is free software; you can redistribute it and/or modify
+ @ it under the terms of the GNU General Public License as published by
+ @ the Free Software Foundation; either version 2 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 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
+
+/* ARM */
+#define O1 r0
+#define O2 r1
+#define WIDTH r2
+#define HEIGHT r3
+#define Y1 r4
+#define Y2 r5
+#define U r6
+#define V r7
+#define YPITCH r8
+#define OPAD r10
+#define YPAD r11
+#define COUNT ip
+#define OPITCH lr
+
+/* NEON */
+#define coefY D0
+#define coefRV D1
+#define coefGU D2
+#define coefGV D3
+#define coefBU D4
+#define Rc Q3
+#define Gc Q4
+#define Bc Q5
+
+#define u D24
+#define v D25
+#define y1 D28
+#define y2 D29
+
+#define chro_r Q6
+#define chro_g Q7
+#define chro_b Q8
+#define red Q9
+#define green Q10
+#define blue Q11
+#define lumi Q15
+
+#define red1 D24
+#define green1 D25
+#define blue1 D26
+#define alpha1 D27
+#define red2 D28
+#define green2 D29
+#define blue2 D30
+#define alpha2 D31
+
+coefficients:
+ .short -15872
+ .short 4992
+ .short -18432
+
+ .align
+ .global i420_rgb_neon
+ .type i420_rgb_neon, %function
+i420_rgb_neon:
+ push {r4-r8,r10-r11,lr}
+ vpush {q4-q7}
+
+ /* load arguments */
+ ldmia r0, {O1, OPITCH}
+ ldmia r1, {Y1, U, V, YPITCH}
+
+ /* round the width to be a multiple of 16 */
+ ands OPAD, WIDTH, #15
+ sub WIDTH, WIDTH, OPAD
+ addne WIDTH, WIDTH, #16
+
+ /* init constants (scale value by 64) */
+ vmov.u8 coefY, #74
+ vmov.u8 coefRV, #115
+ vmov.u8 coefGU, #14
+ vmov.u8 coefGV, #34
+ vmov.u8 coefBU, #135
+ adr OPAD, coefficients
+ vld1.s16 {d6[], d7[]}, [OPAD]!
+ vld1.s16 {d8[], d9[]}, [OPAD]!
+ vld1.s16 {d10[], d11[]}, [OPAD]!
+ vmov.u8 alpha1, #255
+
+ /* init padding */
+ cmp HEIGHT, #0
+ sub OPAD, OPITCH, WIDTH, lsl #2
+ sub YPAD, YPITCH, WIDTH
+
+loop_row:
+ movgts COUNT, WIDTH
+ add O2, O1, OPITCH
+ add Y2, Y1, YPITCH
+ /* exit if all rows have been processed */
+ vpople {q4-q7}
+ pople {r4-r8,r10-r11,pc}
+
+loop_col:
+
+ /* Common U & V */
+
+ vld1.u8 {u}, [U,:64]!
+ vld1.u8 {v}, [V,:64]!
+
+ vmull.u8 chro_r, v, coefRV
+ vmull.u8 chro_g, u, coefGU
+ vmlal.u8 chro_g, v, coefGV
+ vmull.u8 chro_b, u, coefBU
+
+ vadd.s16 chro_r, Rc, chro_r
+ vsub.s16 chro_g, Gc, chro_g
+ vadd.s16 chro_b, Bc, chro_b
+
+ PLD [U]
+ PLD [V]
+
+ /* Y Top Row */
+ vld2.u8 {y1,y2}, [Y1,:128]!
+
+ /* y1 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y1, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red1, red, #6
+ vqrshrun.s16 green1, green, #6
+ vqrshrun.s16 blue1, blue, #6
+
+ /* y2 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y2, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red2, red, #6
+ vqrshrun.s16 green2, green, #6
+ vqrshrun.s16 blue2, blue, #6
+
+ PLD [Y1]
+
+ vmov.u8 alpha2, #255
+ vzip.u8 red1, red2
+ vzip.u8 green1, green2
+ vzip.u8 blue1, blue2
+
+ vst4.u8 {red1,green1,blue1,alpha1}, [O1,:128]!
+ vst4.u8 {red2,green2,blue2,alpha2}, [O1,:128]!
+
+ /* Y Bottom Row */
+ vld2.u8 {y1,y2}, [Y2,:128]!
+
+ /* y1 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y1, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red1, red, #6
+ vqrshrun.s16 green1, green, #6
+ vqrshrun.s16 blue1, blue, #6
+
+ /* y2 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y2, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red2, red, #6
+ vqrshrun.s16 green2, green, #6
+ vqrshrun.s16 blue2, blue, #6
+
+ PLD [Y2]
+
+ vmov.u8 alpha2, #255
+ vzip.u8 red1, red2
+ vzip.u8 green1, green2
+ vzip.u8 blue1, blue2
+
+ vst4.u8 {red1,green1,blue1,alpha1}, [O2,:128]!
+ vst4.u8 {red2,green2,blue2,alpha2}, [O2,:128]!
+
+ /* next columns (x16) */
+ subs COUNT, COUNT, #16
+ bgt loop_col
+
+ /* next rows (x2) */
+ subs HEIGHT, #2
+ add O1, O2, OPAD
+ add Y1, Y2, YPAD
+ add U, U, YPAD, lsr #1
+ add V, V, YPAD, lsr #1
+ b loop_row
diff --git a/modules/arm_neon/nv12_rgb.S b/modules/arm_neon/nv12_rgb.S
new file mode 100644
index 0000000..b6276a5
--- /dev/null
+++ b/modules/arm_neon/nv12_rgb.S
@@ -0,0 +1,206 @@
+ @*****************************************************************************
+ @ nv12_rgb.S : ARM NEONv1 NV12 to RGB chroma conversion
+ @*****************************************************************************
+ @ Copyright (C) 2011 Sébastien Toque
+ @ Rémi Denis-Courmont
+ @
+ @ This program is free software; you can redistribute it and/or modify
+ @ it under the terms of the GNU General Public License as published by
+ @ the Free Software Foundation; either version 2 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 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
+
+/* ARM */
+#define O1 r0
+#define O2 r1
+#define WIDTH r2
+#define HEIGHT r3
+#define Y1 r4
+#define Y2 r5
+#define U r6
+#define V r7
+#define YPITCH r8
+#define OPAD r10
+#define YPAD r11
+#define COUNT ip
+#define OPITCH lr
+
+/* NEON */
+#define coefY D0
+#define coefRV D1
+#define coefGU D2
+#define coefGV D3
+#define coefBU D4
+#define Rc Q3
+#define Gc Q4
+#define Bc Q5
+
+#define u D24
+#define v D25
+#define y1 D28
+#define y2 D29
+
+#define chro_r Q6
+#define chro_g Q7
+#define chro_b Q8
+#define red Q9
+#define green Q10
+#define blue Q11
+#define lumi Q15
+
+#define red1 D24
+#define green1 D25
+#define blue1 D26
+#define alpha1 D27
+#define red2 D28
+#define green2 D29
+#define blue2 D30
+#define alpha2 D31
+
+coefficients:
+ .short -15872
+ .short 4992
+ .short -18432
+
+ .align
+ .global nv12_rgb_neon
+ .type nv12_rgb_neon, %function
+nv12_rgb_neon:
+ push {r4-r8,r10-r11,lr}
+ vpush {q4-q7}
+
+ /* load arguments */
+ ldmia r0, {O1, OPITCH}
+ ldmia r1, {Y1, U, V, YPITCH}
+
+ /* round the width to be a multiple of 16 */
+ ands OPAD, WIDTH, #15
+ sub WIDTH, WIDTH, OPAD
+ addne WIDTH, WIDTH, #16
+
+ /* init constants (scale value by 64) */
+ vmov.u8 coefY, #74
+ vmov.u8 coefRV, #115
+ vmov.u8 coefGU, #14
+ vmov.u8 coefGV, #34
+ vmov.u8 coefBU, #135
+ adr OPAD, coefficients
+ vld1.s16 {d6[], d7[]}, [OPAD]!
+ vld1.s16 {d8[], d9[]}, [OPAD]!
+ vld1.s16 {d10[], d11[]}, [OPAD]!
+ vmov.u8 alpha1, #255
+
+ /* init padding */
+ cmp HEIGHT, #0
+ sub OPAD, OPITCH, WIDTH, lsl #2
+ sub YPAD, YPITCH, WIDTH
+
+loop_row:
+ movgts COUNT, WIDTH
+ add O2, O1, OPITCH
+ add Y2, Y1, YPITCH
+ /* exit if all rows have been processed */
+ vpople {q4-q7}
+ pople {r4-r8,r10-r11,pc}
+
+loop_col:
+
+ /* Common U & V */
+
+ vld2.u8 {u,v}, [U,:128]!
+
+ vmull.u8 chro_r, v, coefRV
+ vmull.u8 chro_g, u, coefGU
+ vmlal.u8 chro_g, v, coefGV
+ vmull.u8 chro_b, u, coefBU
+
+ vadd.s16 chro_r, Rc, chro_r
+ vsub.s16 chro_g, Gc, chro_g
+ vadd.s16 chro_b, Bc, chro_b
+
+ PLD [U]
+
+ /* Y Top Row */
+ vld2.u8 {y1,y2}, [Y1,:128]!
+
+ /* y1 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y1, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red1, red, #6
+ vqrshrun.s16 green1, green, #6
+ vqrshrun.s16 blue1, blue, #6
+
+ /* y2 : chrominance + luminance, then clamp (divide by 64) */
+ vmull.u8 lumi, y2, coefY
+ vqadd.s16 red, lumi, chro_r
+ vqadd.s16 green, lumi, chro_g
+ vqadd.s16 blue, lumi, chro_b
+ vqrshrun.s16 red2, red, #6
+ vqrshrun.s16 green2, green, #6
+ vqrshrun.s16 blue2, blue, #6
+
+ PLD [Y1]
+
+ vmov.u8 alpha2, #255
+ vzip.u8 red1, red2
+ vzip.u8 green1, green2