diff options
author | Luc Saillard <luc@saillard.org> | 2006-04-24 09:29:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 00:58:20 -0400 |
commit | 2b455db6d456ef2d44808a8377fd3bc832e08317 (patch) | |
tree | b7b7bcabd53f9bb58d7f69eb6d012735dacd31c7 /drivers/media/video/pwc/pwc-uncompress.c | |
parent | d9e12f25cf538d103426946121d214dff332efbb (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.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 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 | ||
33 | int pwc_decompress(struct pwc_device *pdev) | 37 | int 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: */ | ||