diff options
Diffstat (limited to 'drivers/media/video/pwc/pwc-uncompress.c')
-rw-r--r-- | drivers/media/video/pwc/pwc-uncompress.c | 154 |
1 files changed, 73 insertions, 81 deletions
diff --git a/drivers/media/video/pwc/pwc-uncompress.c b/drivers/media/video/pwc/pwc-uncompress.c index b37a89a163f..5d82028ef94 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 <asm/current.h> @@ -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: */ |