Rev 1063 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1063 | tullio | 1 | |
2 | /* |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
16 | * |
||
17 | */ |
||
18 | |||
1049 | mauro | 19 | #include <linuxcomp.h> |
20 | |||
21 | #include <linux/config.h> |
||
22 | #include <linux/types.h> |
||
23 | #include <linux/major.h> |
||
24 | #include <linux/errno.h> |
||
25 | #include <linux/signal.h> |
||
26 | |||
27 | #include "media/pwc-ioctl.h" |
||
28 | #include <linux/videodev.h> |
||
29 | #include <drivers/shark_pwc26.h> |
||
30 | |||
31 | /* |
||
32 | * shark lowlevel wrapper |
||
33 | */ |
||
34 | |||
35 | struct PWC_data { |
||
36 | struct file* file; |
||
37 | struct pwc_imagesize RealSize; |
||
38 | struct pwc_coord m_ViewSize, m_RealSize; |
||
39 | struct pwc_coord m_Offset; |
||
40 | struct video_capability Capability; |
||
41 | struct pwc_probe Probe; |
||
42 | struct video_picture Picture; |
||
43 | struct video_window Window; |
||
44 | struct pwc_video_command VideoCmd; |
||
45 | void *m_pPWCXBuffer, *m_pInputBuffer, *m_pImageBuffer; |
||
46 | int m_Frames, len, m_UseRaw, m_ImageSize, m_ImageLen; |
||
47 | int m_Type, m_Bandlength, m_Bayer; |
||
48 | int m_InputLen; |
||
49 | }; |
||
50 | |||
51 | |||
52 | extern int usb_pwc_init(); |
||
53 | extern void* malloc(size_t size); |
||
54 | |||
55 | extern int pwc_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg); |
||
56 | extern int pwc_video_open(struct inode *inode, struct file *file); |
||
57 | extern int pwc_video_close(struct inode *inode, struct file *file); |
||
58 | extern ssize_t pwc_video_read(struct file *file, char *buf, size_t count, loff_t *ppos); |
||
59 | extern int pwc_video_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg); |
||
60 | |||
61 | void shark_PWC_init() |
||
62 | { |
||
63 | usb_pwc_init(); |
||
64 | } |
||
65 | |||
66 | int shark_PWC_open(struct PWC26_DEVICE *pwc26, int width, int height, int fps, int quality, int webcamnr) |
||
67 | { |
||
68 | int err; |
||
69 | struct PWC_data *pwc_data; |
||
70 | struct file *file; |
||
71 | struct inode *inode; |
||
72 | |||
73 | pwc_data = malloc(sizeof(struct PWC_data)); |
||
74 | pwc26->private_data = (void*)pwc_data; |
||
75 | |||
76 | if (!pwc_data) |
||
77 | return -ENOMEM; |
||
78 | |||
79 | memset(pwc_data, 0, sizeof(struct PWC_data)); |
||
80 | file = malloc(sizeof(struct file)); |
||
81 | if (!file) |
||
82 | return -ENOMEM; |
||
83 | |||
84 | file->f_dentry= malloc(sizeof(struct dentry)); |
||
85 | if (!file->f_dentry) |
||
86 | return -ENOMEM; |
||
87 | |||
88 | file->f_dentry->d_inode = malloc(sizeof(struct inode)); |
||
89 | if (!file->f_dentry->d_inode) |
||
90 | return -ENOMEM; |
||
91 | |||
92 | file->f_dentry->d_inode->i_rdev = webcamnr; |
||
93 | inode = file->f_dentry->d_inode; |
||
94 | |||
95 | pwc_data->file = file; |
||
96 | pwc_data->m_ViewSize.x = width; |
||
97 | pwc_data->m_ViewSize.y = height; |
||
98 | pwc_data->m_Frames = fps; |
||
99 | |||
100 | pwc_data->m_RealSize = pwc_data->m_ViewSize; |
||
101 | |||
102 | pwc_data->m_Offset.x = 0; |
||
103 | pwc_data->m_Offset.y = 0; |
||
104 | pwc_data->m_UseRaw = TRUE; |
||
105 | pwc_data->m_Bayer = FALSE; |
||
106 | pwc_data->m_pInputBuffer = NULL; |
||
107 | pwc_data->m_InputLen = 0; |
||
108 | pwc_data->m_pImageBuffer = NULL; |
||
109 | pwc_data->m_ImageLen = NULL; |
||
110 | pwc_data->m_Type = NULL; |
||
111 | |||
112 | pwc_data->m_pPWCXBuffer = malloc(60000); // large enoug for all cams |
||
113 | if (!pwc_data->m_pPWCXBuffer) |
||
114 | return -ENOMEM; |
||
115 | |||
116 | err=pwc_video_open(inode, file); |
||
117 | if (err <0) |
||
118 | return err; |
||
119 | |||
120 | pwc_video_do_ioctl(inode, file, VIDIOCGCAP, &pwc_data->Capability); |
||
121 | |||
122 | printk(KERN_INFO "Capability->type= %d\n", pwc_data->Capability.type); |
||
123 | printk(KERN_INFO "Capability->channels =%d\n",pwc_data->Capability.channels); |
||
124 | printk(KERN_INFO "Capability->audios=%d\n",pwc_data->Capability.audios); |
||
125 | printk(KERN_INFO "Capability->minwidth=%d\n",pwc_data->Capability.minwidth); |
||
126 | printk(KERN_INFO "Capability->minheight=%d\n",pwc_data->Capability.minheight); |
||
127 | printk(KERN_INFO "Capability->maxwidth=%d\n",pwc_data->Capability.maxwidth); |
||
128 | printk(KERN_INFO "Capability->maxheight=%d\n",pwc_data->Capability.maxheight); |
||
129 | |||
130 | memset(&pwc_data->Probe, 0, sizeof(pwc_data->Probe)); |
||
131 | pwc_video_do_ioctl(inode, file, VIDIOCPWCPROBE, &pwc_data->Probe); |
||
132 | pwc_video_do_ioctl(inode, file, VIDIOCGPICT, &pwc_data->Picture); |
||
133 | |||
134 | if (pwc_data->m_UseRaw) |
||
135 | pwc_data->Picture.palette = VIDEO_PALETTE_RAW; |
||
136 | else |
||
137 | pwc_data->Picture.palette = VIDEO_PALETTE_YUV420P; |
||
138 | |||
139 | pwc_video_do_ioctl(inode, file, VIDIOCSPICT, &pwc_data->Picture); |
||
140 | pwc_video_do_ioctl(inode, file, VIDIOCGWIN, &pwc_data->Window); |
||
141 | |||
142 | /* unavailable in pwc 10.x */ |
||
143 | if (pwc_data->m_Bayer) |
||
144 | { |
||
145 | // special raw Bayer mode |
||
146 | pwc_data->m_ViewSize.x = 640; |
||
147 | pwc_data->m_ViewSize.y = 480; |
||
148 | pwc_data->m_Frames = 5; |
||
149 | pwc_data->m_RealSize = pwc_data->m_ViewSize; |
||
150 | } |
||
151 | |||
152 | pwc_data->Window.width = pwc_data->m_ViewSize.x; |
||
153 | pwc_data->Window.height = pwc_data->m_ViewSize.y; |
||
154 | pwc_data->Window.flags = (pwc_data->m_Frames << PWC_FPS_SHIFT); |
||
155 | |||
156 | if (pwc_data->m_Bayer) |
||
157 | pwc_data->Window.flags |= PWC_FPS_SNAPSHOT; |
||
158 | |||
159 | pwc_video_do_ioctl(inode, file, VIDIOCSWIN, &pwc_data->Window); |
||
160 | |||
161 | if (pwc_data->m_UseRaw) |
||
162 | { |
||
163 | pwc_video_do_ioctl(inode, file, VIDIOCPWCGVIDCMD, &pwc_data->VideoCmd); |
||
164 | |||
165 | pwc_data->m_Type = pwc_data->VideoCmd.type; |
||
166 | pwc_data->m_InputLen = pwc_data->VideoCmd.frame_size; |
||
167 | pwc_data->m_Bandlength = pwc_data->VideoCmd.bandlength; |
||
168 | |||
169 | if (pwc_data->m_Bandlength > 0) |
||
170 | { |
||
171 | switch(pwc_data->m_Type) |
||
172 | { |
||
173 | case 645: |
||
174 | case 646: |
||
175 | pwcx_init_decompress_Nala(pwc_data->m_Type, pwc_data->VideoCmd.release, &pwc_data->VideoCmd.command_buf, pwc_data->m_pPWCXBuffer); |
||
176 | break; |
||
177 | |||
178 | case 675: |
||
179 | case 680: |
||
180 | case 690: |
||
181 | pwcx_init_decompress_Timon(pwc_data->m_Type, pwc_data->VideoCmd.release, &pwc_data->VideoCmd.command_buf, pwc_data->m_pPWCXBuffer); |
||
182 | break; |
||
183 | |||
184 | case 720: |
||
185 | case 730: |
||
186 | case 740: |
||
187 | case 750: |
||
188 | pwcx_init_decompress_Kiara(pwc_data->m_Type, pwc_data->VideoCmd.release, &pwc_data->VideoCmd.command_buf, pwc_data->m_pPWCXBuffer); |
||
189 | break; |
||
190 | |||
191 | default: |
||
192 | // qDebug("Unknown type of camera (%d)!", VideoCmd.type); |
||
193 | break; |
||
194 | } // ..switch |
||
195 | } // ..m_Bandlength > 0 |
||
196 | |||
197 | if (pwc_video_do_ioctl(inode, file, VIDIOCPWCGREALSIZE, &pwc_data->RealSize) == 0) |
||
198 | { |
||
199 | pwc_data->m_Offset.x = (pwc_data->m_ViewSize.x - pwc_data->RealSize.width) / 2; |
||
200 | pwc_data->m_Offset.y = (pwc_data->m_ViewSize.y - pwc_data->RealSize.height) / 2; |
||
201 | } |
||
202 | } |
||
203 | |||
204 | pwc_data->m_ImageLen = pwc_data->m_ViewSize.x * pwc_data->m_ViewSize.y * 3; |
||
205 | pwc_data->m_pImageBuffer = malloc (pwc_data->m_ImageLen); |
||
206 | |||
207 | if (pwc_data->m_UseRaw) |
||
208 | { |
||
209 | pwc_data->m_pInputBuffer = malloc(pwc_data->m_InputLen); |
||
210 | } |
||
211 | else |
||
212 | { |
||
213 | if (pwc_data->m_pImageBuffer != 0) |
||
214 | { |
||
215 | pwc_data->m_pInputBuffer = pwc_data->m_pImageBuffer; |
||
216 | pwc_data->m_InputLen = pwc_data->m_ImageLen; |
||
217 | } |
||
218 | } |
||
219 | |||
220 | pwc26->width=pwc_data->m_ViewSize.x ; |
||
221 | pwc26->height=pwc_data->m_ViewSize.y ; |
||
222 | pwc26->imgptr=(BYTE*)pwc_data->m_pImageBuffer; |
||
223 | |||
224 | return 0; |
||
225 | } |
||
226 | |||
227 | int shark_PWC_read(struct PWC26_DEVICE *pwc26) |
||
228 | { |
||
229 | int len; |
||
230 | struct PWC_data *pwc_data = (struct PWC_data*)pwc26->private_data; |
||
231 | |||
232 | if (pwc_data->m_pInputBuffer == 0 || pwc_data->m_pImageBuffer == 0) |
||
233 | return -666; |
||
234 | |||
235 | len = pwc_video_read(pwc_data->file, pwc_data->m_pInputBuffer, pwc_data->m_InputLen, 0); |
||
236 | |||
237 | if (len > 0 && pwc_data->m_Bandlength > 0) |
||
238 | { |
||
239 | switch(pwc_data->m_Type) |
||
240 | { |
||
241 | case 645: |
||
242 | case 646: |
||
243 | pwcx_decompress_Nala(&pwc_data->m_RealSize, &pwc_data->m_ViewSize, &pwc_data->m_Offset, \ |
||
244 | pwc_data->m_pInputBuffer, pwc_data->m_pImageBuffer, \ |
||
245 | PWCX_FLAG_PLANAR, \ |
||
246 | pwc_data->m_pPWCXBuffer, pwc_data->m_Bandlength); |
||
247 | break; |
||
248 | |||
249 | case 675: |
||
250 | case 680: |
||
251 | case 690: |
||
252 | pwcx_decompress_Timon(&pwc_data->m_RealSize, &pwc_data->m_ViewSize, &pwc_data->m_Offset, \ |
||
253 | pwc_data->m_pInputBuffer, pwc_data->m_pImageBuffer, \ |
||
254 | PWCX_FLAG_PLANAR, \ |
||
255 | pwc_data->m_pPWCXBuffer, pwc_data->m_Bandlength); |
||
256 | break; |
||
257 | |||
258 | case 720: |
||
259 | case 730: |
||
260 | case 740: |
||
261 | case 750: |
||
262 | pwcx_decompress_Kiara(&pwc_data->m_RealSize, &pwc_data->m_ViewSize, &pwc_data->m_Offset, \ |
||
263 | pwc_data->m_pInputBuffer, pwc_data->m_pImageBuffer, \ |
||
264 | PWCX_FLAG_PLANAR | (pwc_data->m_Bayer ? PWCX_FLAG_BAYER : 0), \ |
||
265 | pwc_data->m_pPWCXBuffer, pwc_data->m_Bandlength); |
||
266 | break; |
||
267 | } |
||
268 | } |
||
269 | return len; |
||
270 | } |
||
271 | |||
272 | void shark_PWC_close(struct PWC26_DEVICE *pwc26) |
||
273 | { |
||
274 | struct file *file; |
||
275 | struct inode *inode; |
||
276 | struct PWC_data *pwc_data = (struct PWC_data*)pwc26->private_data; |
||
277 | |||
278 | if (!pwc_data) |
||
279 | return; |
||
280 | |||
281 | free(pwc_data->m_pPWCXBuffer); |
||
282 | |||
283 | file = pwc_data->file; |
||
284 | inode = file->f_dentry->d_inode; |
||
285 | // pwc_video_close(inode, file); |
||
286 | |||
287 | free(inode); |
||
288 | free(file->f_dentry); |
||
289 | free(file); |
||
290 | free(pwc_data); |
||
291 | } |