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