[PATCH] add sn9c20x-i420 decoder to libv4l-0.5.7
Vasily Khoruzhick <[email protected]> Thu, 8 Jan 2009 22:56:17 +0200
| Newsgroups | gmane.linux.drivers.spca50x.devel |
|---|---|
| Message-ID | <[email protected]> |
--===============3183349066270622764== Content-Type: multipart/signed; boundary="nextPart1506573.8Pyuxi00LT"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit --nextPart1506573.8Pyuxi00LT Content-Type: multipart/mixed; boundary="Boundary-01=_xhmZJNl/IrCbrIw" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_xhmZJNl/IrCbrIw Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi, Hans Recent sn9c20x driver written by microdia project=20 (http://groups.goolge.com/group/microdia) introduce new output format -=20 sn9c20x-i420. This format is actually scrambled yuv420, so it's very easy a= nd=20 fast to convert it to yuv420. This patch adds sn9c20x-i420 decoder to the=20 libv4l-0.5.7 This decoder is much faster than jpeg one (sn9c20x supports JPEG too):=20 sn9c20x-i420 decoder eats only 10% of 1GHz CPU at 640x480x25fps vs 40% of=20 1GHz CPU in jpeg at same frame size/rate. This format should be preffered for sn9c20x, because sn9c20x driver support= s=20 SBGGR8 too, so it should go before SBGGR8 in supported_src_pixfmts. Regards Vasily P.S. sn9c20x-i420 decoder code was originally written by myself and license= d=20 under GPLv2 license, I grant you permission to relicense it under LGPLv2 or= =20 later. --Boundary-01=_xhmZJNl/IrCbrIw Content-Type: text/x-diff; charset="iso 8859-15"; name="0001-Added-sn9c20x-i420-decoder.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Added-sn9c20x-i420-decoder.patch" =46rom 00c284bd74c19c3f9ef8858a8ca92d17e81b2d80 Mon Sep 17 00:00:00 2001 =46rom: Vasily Khoruzhick <[email protected]> Date: Thu, 8 Jan 2009 00:33:21 +0200 Subject: [PATCH] Added sn9c20x i420 decoder Signed-off-by: Vasily Khoruzhick <[email protected]> =2D-- libv4lconvert/Makefile | 2 +- libv4lconvert/libv4lconvert-priv.h | 7 ++ libv4lconvert/libv4lconvert.c | 5 ++ libv4lconvert/sn9c20x.c | 137 ++++++++++++++++++++++++++++++++= ++++ 4 files changed, 150 insertions(+), 1 deletions(-) create mode 100644 libv4lconvert/sn9c20x.c diff --git a/libv4lconvert/Makefile b/libv4lconvert/Makefile index 65748bb..011949b 100644 =2D-- a/libv4lconvert/Makefile +++ b/libv4lconvert/Makefile @@ -10,7 +10,7 @@ CONVERT_LIB =3D libv4lconvert.so override CPPFLAGS +=3D -fPIC endif =20 =2DCONVERT_OBJS =3D libv4lconvert.o tinyjpeg.o sn9c10x.o pac207.o flip.o c= rop.o \ +CONVERT_OBJS =3D libv4lconvert.o tinyjpeg.o sn9c10x.o sn9c20x.o pac207.o = flip.o crop.o \ jidctflt.o spca561-decompress.o rgbyuv.o spca501.o bayer.o TARGETS =3D $(CONVERT_LIB) libv4lconvert.pc INCLUDES =3D ../include/libv4lconvert.h diff --git a/libv4lconvert/libv4lconvert-priv.h b/libv4lconvert/libv4lconve= rt-priv.h index 55a5b49..f34036d 100644 =2D-- a/libv4lconvert/libv4lconvert-priv.h +++ b/libv4lconvert/libv4lconvert-priv.h @@ -63,6 +63,10 @@ #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') #endif =20 +#ifndef V4L2_PIX_FMT_SN9C20X_I420 +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') +#endif + #define V4LCONVERT_ERROR_MSG_SIZE 256 #define V4LCONVERT_MAX_FRAMESIZES 16 =20 @@ -147,6 +151,9 @@ void v4lconvert_spca505_to_yuv420(const unsigned char *= src, unsigned char *dst, void v4lconvert_spca508_to_yuv420(const unsigned char *src, unsigned char = *dst, int width, int height, int yvu); =20 +void v4lconvert_sn9c20x_to_yuv420(const unsigned char *src, unsigned char = *dst, + int width, int height, int yvu); + void v4lconvert_decode_spca561(const unsigned char *src, unsigned char *ds= t, int width, int height); =20 diff --git a/libv4lconvert/libv4lconvert.c b/libv4lconvert/libv4lconvert.c index b3487b6..e123d7b 100644 =2D-- a/libv4lconvert/libv4lconvert.c +++ b/libv4lconvert/libv4lconvert.c @@ -44,6 +44,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfm= ts[] =3D { SUPPORTED_DST_PIXFMTS, { V4L2_PIX_FMT_YUYV, 0 }, { V4L2_PIX_FMT_YVYU, 0 }, + { V4L2_PIX_FMT_SN9C20X_I420, 0 }, { V4L2_PIX_FMT_SBGGR8, 0 }, { V4L2_PIX_FMT_SGBRG8, 0 }, { V4L2_PIX_FMT_SGRBG8, 0 }, @@ -538,6 +539,7 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_= data *data, case V4L2_PIX_FMT_SPCA501: case V4L2_PIX_FMT_SPCA505: case V4L2_PIX_FMT_SPCA508: + case V4L2_PIX_FMT_SN9C20X_I420: { unsigned char *d; int yvu =3D 0; @@ -564,6 +566,9 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_= data *data, case V4L2_PIX_FMT_SPCA508: v4lconvert_spca508_to_yuv420(src, d, width, height, yvu); break; + case V4L2_PIX_FMT_SN9C20X_I420: + v4lconvert_sn9c20x_to_yuv420(src, d, width, height, yvu); + break; } =20 switch (dest_pix_fmt) { diff --git a/libv4lconvert/sn9c20x.c b/libv4lconvert/sn9c20x.c new file mode 100644 index 0000000..4817079 =2D-- /dev/null +++ b/libv4lconvert/sn9c20x.c @@ -0,0 +1,137 @@ +/* + * Sonix SN9C20X decoder + * Vasily Khoruzhick, (C) 2008-2009 + * Algorithm based on Java code written by Jens on microdia google group + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as publishe= d 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 Lesser 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U= SA + * + * Note this code was originally licensed under the GNU GPL instead of the + * GNU LGPL, its license has been changed by its author. + */ + +#include "libv4lconvert-priv.h" + +#define DO_SANITY_CHECKS 0 + +static const int UVTranslate[32] =3D {0, 1, 2, 3,=20 + 8, 9, 10, 11,=20 + 16, 17, 18, 19,=20 + 24, 25, 26, 27,=20 + 4, 5, 6, 7, + 12, 13, 14, 15, + 20, 21, 22, 23, + 28, 29, 30, 31}; + +static const int Y_coords_624x[128][2] =3D { +{ 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7,= 0}, +{ 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7,= 1}, +{ 0, 2}, { 1, 2}, { 2, 2}, { 3, 2}, { 4, 2}, { 5, 2}, { 6, 2}, { 7,= 2}, +{ 0, 3}, { 1, 3}, { 2, 3}, { 3, 3}, { 4, 3}, { 5, 3}, { 6, 3}, { 7,= 3}, + +{ 0, 4}, { 1, 4}, { 2, 4}, { 3, 4}, { 4, 4}, { 5, 4}, { 6, 4}, { 7,= 4}, +{ 0, 5}, { 1, 5}, { 2, 5}, { 3, 5}, { 4, 5}, { 5, 5}, { 6, 5}, { 7,= 5}, +{ 0, 6}, { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6}, { 7,= 6}, +{ 0, 7}, { 1, 7}, { 2, 7}, { 3, 7}, { 4, 7}, { 5, 7}, { 6, 7}, { 7,= 7}, + +{ 8, 0}, { 9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15,= 0}, +{ 8, 1}, { 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15,= 1}, +{ 8, 2}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15,= 2}, +{ 8, 3}, { 9, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15,= 3}, + +{ 8, 4}, { 9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15,= 4}, +{ 8, 5}, { 9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15,= 5}, +{ 8, 6}, { 9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15,= 6}, +{ 8, 7}, { 9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15,= 7} +}; + +static void do_write_u(const unsigned char *buf, unsigned char *ptr, + int i, int j) +{ + *ptr =3D buf[i + 128 + j]; +} + +static void do_write_v(const unsigned char *buf, unsigned char *ptr, + int i, int j) +{ + *ptr =3D buf[i + 160 + j]; +} + +void v4lconvert_sn9c20x_to_yuv420(const unsigned char *raw, unsigned char = *i420, + int width, int height, int yvu) +{ + int i =3D 0, x =3D 0, y =3D 0, j, relX, relY, x_div2, y_div2; + const unsigned char *buf =3D raw; + unsigned char *ptr; + int frame_size =3D width * height; + int frame_size_div2 =3D frame_size >> 1; + int frame_size_div4 =3D frame_size >> 2; + int width_div2 =3D width >> 1; + int height_div2 =3D height >> 1; + void (*do_write_uv1)(const unsigned char *buf, unsigned char *ptr, int i, + int j) =3D NULL; + void (*do_write_uv2)(const unsigned char *buf, unsigned char *ptr, int i, + int j) =3D NULL; + + if (yvu) { + do_write_uv1 =3D do_write_v; + do_write_uv2 =3D do_write_u; + } + else { + do_write_uv1 =3D do_write_u; + do_write_uv2 =3D do_write_v; + } + + while (i < (frame_size + frame_size_div2)) { + for (j =3D 0; j < 128; j++) { + relX =3D x + Y_coords_624x[j][0]; + relY =3D y + Y_coords_624x[j][1]; + +#if (DO_SANITY_CHECKS=3D=3D1) + if ((relX < width) && (relY < height)) { +#endif + ptr =3D i420 + relY * width + relX; + *ptr =3D buf[i + j]; +#if (DO_SANITY_CHECKS=3D=3D1) + } +#endif + + } + x_div2 =3D x >> 1; + y_div2 =3D y >> 1; + for (j =3D 0; j < 32; j++) { + relX =3D (x_div2) + (j & 0x07); + relY =3D (y_div2) + (j >> 3); + +#if (DO_SANITY_CHECKS=3D=3D1) + if ((relX < width_div2) && (relY < height_div2)) { +#endif + ptr =3D i420 + frame_size + + relY * width_div2 + relX; + do_write_uv1(buf, ptr, i, j); + ptr +=3D frame_size_div4; + do_write_uv2(buf, ptr, i, j); +#if (DO_SANITY_CHECKS=3D=3D1) + } +#endif + } + + i +=3D 192; + x +=3D 16; + if (x >=3D width) { + x =3D 0; + y +=3D 8; + } + } +} =2D-=20 1.6.0.6 --Boundary-01=_xhmZJNl/IrCbrIw-- --nextPart1506573.8Pyuxi00LT Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEYEABECAAYFAklmaIQACgkQRM6pQpltKE7HUgCdFdIM1hcHj4AflaKT2qleQN0i 8UoAnA278E9e8brPOzEWfVzDypt8Oktk =6/Nw -----END PGP SIGNATURE----- --nextPart1506573.8Pyuxi00LT-- --===============3183349066270622764== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------------ Check out the new SourceForge.net Marketplace. It is the best place to buy or sell services for just about anything Open Source. http://p.sf.net/sfu/Xq1LFB --===============3183349066270622764== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Spca50x-devs mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/spca50x-devs --===============3183349066270622764==--