aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-uncompress.c
diff options
context:
space:
mode:
authorLuc Saillard <luc@saillard.org>2006-04-24 09:29:46 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 00:58:20 -0400
commit2b455db6d456ef2d44808a8377fd3bc832e08317 (patch)
treeb7b7bcabd53f9bb58d7f69eb6d012735dacd31c7 /drivers/media/video/pwc/pwc-uncompress.c
parentd9e12f25cf538d103426946121d214dff332efbb (diff)
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 <luc@saillard.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pwc/pwc-uncompress.c')
-rw-r--r--drivers/media/video/pwc/pwc-uncompress.c154
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 b37a89a163f9..5d82028ef942 100644
--- a/drivers/media/video/pwc/pwc-uncompress.c
+++ b/drivers/media/video/pwc/pwc-uncompress.c
@@ -1,7 +1,7 @@
1/* Linux driver for Philips webcam 1/* Linux driver for Philips webcam
2 Decompression frontend. 2 Decompression frontend.
3 (C) 1999-2003 Nemosoft Unv. 3 (C) 1999-2003 Nemosoft Unv.
4 (C) 2004 Luc Saillard (luc@saillard.org) 4 (C) 2004-2006 Luc Saillard (luc@saillard.org)
5 5
6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx 6 NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx
7 driver and thus may have bugs that are not present in the original version. 7 driver and thus may have bugs that are not present in the original version.
@@ -22,6 +22,8 @@
22 You should have received a copy of the GNU General Public License 22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software 23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 vim: set ts=8:
25*/ 27*/
26 28
27#include <asm/current.h> 29#include <asm/current.h>
@@ -29,6 +31,8 @@
29 31
30#include "pwc.h" 32#include "pwc.h"
31#include "pwc-uncompress.h" 33#include "pwc-uncompress.h"
34#include "pwc-dec1.h"
35#include "pwc-dec23.h"
32 36
33int pwc_decompress(struct pwc_device *pdev) 37int pwc_decompress(struct pwc_device *pdev)
34{ 38{
@@ -40,107 +44,95 @@ int pwc_decompress(struct pwc_device *pdev)
40 44
41 if (pdev == NULL) 45 if (pdev == NULL)
42 return -EFAULT; 46 return -EFAULT;
43#if defined(__KERNEL__) && defined(PWC_MAGIC)
44 if (pdev->magic != PWC_MAGIC) {
45 Err("pwc_decompress(): magic failed.\n");
46 return -EFAULT;
47 }
48#endif
49 47
50 fbuf = pdev->read_frame; 48 fbuf = pdev->read_frame;
51 if (fbuf == NULL) 49 if (fbuf == NULL)
52 return -EFAULT; 50 return -EFAULT;
53 image = pdev->image_ptr[pdev->fill_image]; 51 image = pdev->image_data;
54 if (!image) 52 image += pdev->images[pdev->fill_image].offset;
55 return -EFAULT;
56 53
57 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */ 54 yuv = fbuf->data + pdev->frame_header_size; /* Skip header */
58 55
59 /* Raw format; that's easy... */ 56 /* Raw format; that's easy... */
60 if (pdev->vpalette == VIDEO_PALETTE_RAW) 57 if (pdev->vpalette == VIDEO_PALETTE_RAW)
61 { 58 {
62 memcpy(image, yuv, pdev->frame_size); 59 struct pwc_raw_frame *raw_frame = image;
60 raw_frame->type = cpu_to_le16(pdev->type);
61 raw_frame->vbandlength = cpu_to_le16(pdev->vbandlength);
62 /* cmd_buf is always 4 bytes, but sometimes, only the
63 * first 3 bytes is filled (Nala case). We can
64 * determine this using the type of the webcam */
65 memcpy(raw_frame->cmd, pdev->cmd_buf, 4);
66 memcpy(raw_frame+1, yuv, pdev->frame_size);
63 return 0; 67 return 0;
64 } 68 }
65 69
66 if (pdev->vbandlength == 0) { 70 if (pdev->vbandlength == 0) {
67 /* Uncompressed mode. We copy the data into the output buffer, 71 /* Uncompressed mode.
68 using the viewport size (which may be larger than the image 72 * We copy the data into the output buffer, using the viewport
69 size). Unfortunately we have to do a bit of byte stuffing 73 * size (which may be larger than the image size).
70 to get the desired output format/size. 74 * Unfortunately we have to do a bit of byte stuffing to get
75 * the desired output format/size.
76 *
77 * We do some byte shuffling here to go from the
78 * native format to YUV420P.
71 */ 79 */
72 /* 80 src = (u16 *)yuv;
73 * We do some byte shuffling here to go from the 81 n = pdev->view.x * pdev->view.y;
74 * native format to YUV420P. 82
75 */ 83 /* offset in Y plane */
76 src = (u16 *)yuv; 84 stride = pdev->view.x * pdev->offset.y + pdev->offset.x;
77 n = pdev->view.x * pdev->view.y; 85 dsty = (u16 *)(image + stride);
78 86
79 /* offset in Y plane */ 87 /* offsets in U/V planes */
80 stride = pdev->view.x * pdev->offset.y + pdev->offset.x; 88 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2;
81 dsty = (u16 *)(image + stride); 89 dstu = (u16 *)(image + n + stride);
82 90 dstv = (u16 *)(image + n + n / 4 + stride);
83 /* offsets in U/V planes */ 91
84 stride = pdev->view.x * pdev->offset.y / 4 + pdev->offset.x / 2; 92 /* increment after each line */
85 dstu = (u16 *)(image + n + stride); 93 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */
86 dstv = (u16 *)(image + n + n / 4 + stride); 94
87 95 for (line = 0; line < pdev->image.y; line++) {
88 /* increment after each line */ 96 for (col = 0; col < pdev->image.x; col += 4) {
89 stride = (pdev->view.x - pdev->image.x) / 2; /* u16 is 2 bytes */ 97 *dsty++ = *src++;
90 98 *dsty++ = *src++;
91 for (line = 0; line < pdev->image.y; line++) {
92 for (col = 0; col < pdev->image.x; col += 4) {
93 *dsty++ = *src++;
94 *dsty++ = *src++;
95 if (line & 1)
96 *dstv++ = *src++;
97 else
98 *dstu++ = *src++;
99 }
100 dsty += stride;
101 if (line & 1) 99 if (line & 1)
102 dstv += (stride >> 1); 100 *dstv++ = *src++;
103 else 101 else
104 dstu += (stride >> 1); 102 *dstu++ = *src++;
105 } 103 }
104 dsty += stride;
105 if (line & 1)
106 dstv += (stride >> 1);
107 else
108 dstu += (stride >> 1);
109 }
110
111 return 0;
106 } 112 }
107 else { 113
108 /* Compressed; the decompressor routines will write the data 114 /*
109 in planar format immediately. 115 * Compressed;
110 */ 116 * the decompressor routines will write the data in planar format
111 int flags; 117 * immediately.
112 118 */
113 flags = PWCX_FLAG_PLANAR; 119 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) {
114 if (pdev->vsize == PSZ_VGA && pdev->vframes == 5 && pdev->vsnapshot) 120 PWC_ERROR("Mode Bayer is not supported for now\n");
115 { 121 /* flags |= PWCX_FLAG_BAYER; */
116 printk(KERN_ERR "pwc: Mode Bayer is not supported for now\n"); 122 return -ENXIO; /* No such device or address: missing decompressor */
117 flags |= PWCX_FLAG_BAYER; 123 }
118 return -ENXIO; /* No such device or address: missing decompressor */ 124
119 } 125 if (DEVICE_USE_CODEC1(pdev->type)) {
120 126
121#if 0 127 /* TODO & FIXME */
122 switch (pdev->type) 128 PWC_ERROR("This chipset is not supported for now\n");
123 { 129 return -ENXIO; /* No such device or address: missing decompressor */
124 case 675: 130
125 case 680: 131 } else {
126 case 690: 132 pwc_dec23_decompress(pdev, yuv, image, PWCX_FLAG_PLANAR);
127 case 720:
128 case 730:
129 case 740:
130 case 750:
131 pwc_dec23_decompress(&pdev->image, &pdev->view,
132 &pdev->offset, yuv, image, flags,
133 pdev->decompress_data, pdev->vbandlength);
134 break;
135 case 645:
136 case 646:
137 /* TODO & FIXME */
138 return -ENXIO; /* Missing decompressor */
139 break;
140 }
141#endif
142 } 133 }
143 return 0; 134 return 0;
144} 135}
145 136
146 137
138/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */