Subversion Repositories shark

Rev

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
}