From 2b455db6d456ef2d44808a8377fd3bc832e08317 Mon Sep 17 00:00:00 2001 From: Luc Saillard Date: Mon, 24 Apr 2006 10:29:46 -0300 Subject: V4L/DVB (3835): [PATCH] update pwc driver Add v4l2 compatibility Include the decompressor (legal problem has been resolv by Alan Cox) Faster decoder and easier to maintain, optimize, ... Can export to userland compressed stream Support more cameras, lot of bugs are fixed. Signed-off-by: Luc Saillard Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-uncompress.c | 154 +++++++++++++++---------------- 1 file changed, 73 insertions(+), 81 deletions(-) (limited to 'drivers/media/video/pwc/pwc-uncompress.c') diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index b37a89a163f9..5d82028ef942 100644 --- a/drivers/media/video/pwc/pwc-uncompress.c +++ b/drivers/media/video/pwc/pwc-uncompress.c @@ -1,7 +1,7 @@ /* Linux driver for Philips webcam Decompression frontend. (C) 1999-2003 Nemosoft Unv. - (C) 2004 Luc Saillard (luc@saillard.org) + (C) 2004-2006 Luc Saillard (luc@saillard.org) NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx driver and thus may have bugs that are not present in the original version. @@ -22,6 +22,8 @@ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + vim: set ts=8: */ #include @@ -29,6 +31,8 @@ #include "pwc.h" #include "pwc-uncompress.h" +#include "pwc-dec1.h" +#include "pwc-dec23.h" int pwc_decompress(struct pwc_device *pdev) { @@ -40,107 +44,95 @@ int pwc_decompress(struct pwc_device *pdev) if (pdev == NULL) return -EFAULT; -#if defined(__KERNEL__) && defined(PWC_MAGIC) - if (pdev->magic != PWC_MAGIC) { - Err("pwc_decompress(): magic failed.\n"); - return -EFAULT; - } -#endif fbuf = pdev->read_frame; if (fbuf == NULL) return -EFAULT; - image = pdev->image_ptr[pdev->fill_image]; - if (!image) - return -EFAULT; + image = pdev->image_data; + image += pdev->images[pdev->fill_image].offset; yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ /* Raw format; that's easy... */ if (pdev->vpalette == VIDEO_PALETTE_RAW) { - memcpy(image, yuv, pdev->frame_size); + struct pwc_raw_frame *raw_frame = image; + raw_frame->type = cpu_to_le16(pdev->type); + raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength); + /* cmd_buf is always 4 bytes, but sometimes, only the + * first 3 bytes is filled (Nala case). We can + * determine this using the type of the webcam */ + memcpy(raw_frame->cmd, pdev->cmd_buf, 4); + memcpy(raw_frame+1, yuv, pdev->frame_size); return 0; } if (pdev->vbandlength == 0) { - /* Uncompressed mode. We copy the data into the output buffer, - using the viewport size (which may be larger than the image - size). Unfortunately we have to do a bit of byte stuffing - to get the desired output format/size. + /* Uncompressed mode. + * We copy the data into the output buffer, using the viewport + * size (which may be larger than the image size). + * Unfortunately we have to do a bit of byte stuffing to get + * the desired output format/size. + * + * We do some byte shuffling here to go from the + * native format to YUV420P. */ - /* - * We do some byte shuffling here to go from the - * native format to YUV420P. - */ - src = (u16 *)yuv; - n = pdev->view.x * pdev->view.y; - - /* offset in Y plane */ - stride = pdev->view.x * pdev->offset.y + pdev->offset.x; - dsty = (u16 *)(image + stride); - - /* offsets in U/V planes */ - stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; - dstu = (u16 *)(image + n + stride); - dstv = (u16 *)(image + n + n / 4 + stride); - - /* increment after each line */ - stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ - - for (line = 0; line < pdev->image.y; line++) { - for (col = 0; col < pdev->image.x; col += 4) { - *dsty++ = *src++; - *dsty++ = *src++; - if (line & 1) - *dstv++ = *src++; - else - *dstu++ = *src++; - } - dsty += stride; + src = (u16 *)yuv; + n = pdev->view.x * pdev->view.y; + + /* offset in Y plane */ + stride = pdev->view.x * pdev->offset.y + pdev->offset.x; + dsty = (u16 *)(image + stride); + + /* offsets in U/V planes */ + stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; + dstu = (u16 *)(image + n + stride); + dstv = (u16 *)(image + n + n / 4 + stride); + + /* increment after each line */ + stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ + + for (line = 0; line < pdev->image.y; line++) { + for (col = 0; col < pdev->image.x; col += 4) { + *dsty++ = *src++; + *dsty++ = *src++; if (line & 1) - dstv += (stride >> 1); + *dstv++ = *src++; else - dstu += (stride >> 1); + *dstu++ = *src++; } + dsty += stride; + if (line & 1) + dstv += (stride >> 1); + else + dstu += (stride >> 1); + } + + return 0; } - else { - /* Compressed; the decompressor routines will write the data - in planar format immediately. - */ - int flags; - - flags = PWCX_FLAG_PLANAR; - if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) - { - printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); - flags |= PWCX_FLAG_BAYER; - return -ENXIO; /* No such device or address: missing decompressor */ - } - -#if 0 - switch (pdev->type) - { - case 675: - case 680: - case 690: - case 720: - case 730: - case 740: - case 750: - pwc_dec23_decompress(&pdev->image, &pdev->view, - &pdev->offset, yuv, image, flags, - pdev->decompress_data, pdev->vbandlength); - break; - case 645: - case 646: - /* TODO & FIXME */ - return -ENXIO; /* Missing decompressor */ - break; - } -#endif + + /* + * Compressed; + * the decompressor routines will write the data in planar format + * immediately. + */ + if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) { + PWC_ERROR("Mode Bayer is not supported for now\n"); + /* flags |= PWCX_FLAG_BAYER; */ + return -ENXIO; /* No such device or address: missing decompressor */ + } + + if (DEVICE_USE_CODEC1(pdev->type)) { + + /* TODO & FIXME */ + PWC_ERROR("This chipset is not supported for now\n"); + return -ENXIO; /* No such device or address: missing decompressor */ + + } else { + pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR); } return 0; } +/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ -- cgit v1.2.1