Subversion Repositories shark

Rev

Rev 1049 | Go to most recent revision | 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
}