Mercurial > mplayer.hg
comparison vidix/ivtv_vid.c @ 25276:334d55a31174
sync ivtv driver with vidix.sf.net (multiple revisions)
author | ben |
---|---|
date | Tue, 04 Dec 2007 22:37:58 +0000 |
parents | 17fcd644f32e |
children | 9feba3abc178 |
comparison
equal
deleted
inserted
replaced
25275:d4fda3892e5b | 25276:334d55a31174 |
---|---|
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | 21 |
22 09.05.2007 Lutz Koschorreck | 22 09.05.2007 Lutz Koschorreck |
23 First version: Tested with ivtv-0.10.1, xine-ui-0.99.5, xine-lib-1.1.6 | 23 First version: Tested with ivtv-0.10.1, xine-ui-0.99.5, xine-lib-1.1.6 |
24 | 24 20.05.2007 Lutz Koschorreck |
25 Some Scaling and zooming problems fixed. By default the vidix driver now | |
26 controlls the setting of alphablending. So there is no need to use | |
27 ivtvfbctl anymore. To disable this feature set the following environment | |
28 variable:VIDIXIVTVALPHA=disable. Special thanx to Ian Armstrong. | |
29 23.07.2007 Lutz Koschorreck | |
30 Support for 2.6.22 kernel added. PCI scan added. | |
31 07.10.2007 Lutz Koschorreck | |
32 Restore old alpha value correctly. Fix capability struct values. | |
25 **/ | 33 **/ |
26 | 34 |
27 #include <errno.h> | 35 #include <errno.h> |
28 #include <stdio.h> | 36 #include <stdio.h> |
29 #include <stdlib.h> | 37 #include <stdlib.h> |
32 #include <math.h> | 40 #include <math.h> |
33 #include <inttypes.h> | 41 #include <inttypes.h> |
34 #include <fcntl.h> | 42 #include <fcntl.h> |
35 #include <sys/ioctl.h> | 43 #include <sys/ioctl.h> |
36 #include <linux/types.h> | 44 #include <linux/types.h> |
45 #include <linux/version.h> | |
46 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) | |
47 #include <linux/videodev2.h> | |
48 #endif | |
37 #include <linux/ivtv.h> | 49 #include <linux/ivtv.h> |
50 #include <linux/fb.h> | |
38 | 51 |
39 #include "vidix.h" | 52 #include "vidix.h" |
40 #include "vidixlib.h" | 53 #include "vidixlib.h" |
41 #include "fourcc.h" | 54 #include "fourcc.h" |
42 #include "dha.h" | 55 #include "dha.h" |
48 #define IVTV_MSG "[ivtv-vid] " | 61 #define IVTV_MSG "[ivtv-vid] " |
49 #define MAXLINE 128 | 62 #define MAXLINE 128 |
50 #define IVTVMAXWIDTH 720 | 63 #define IVTVMAXWIDTH 720 |
51 #define IVTVMAXHEIGHT 576 | 64 #define IVTVMAXHEIGHT 576 |
52 | 65 |
53 static int yuvdev = 0; | 66 static int fbdev = -1; |
54 static void *memBase = 0; | 67 static int yuvdev = -1; |
68 static void *memBase = NULL; | |
55 static int frameSize = 0; | 69 static int frameSize = 0; |
56 static int probed = 0; | 70 static int probed = 0; |
57 static int ivtv_verbose; | 71 static int ivtv_verbose; |
58 static vidix_rect_t destVideo; | 72 static vidix_rect_t destVideo; |
59 static vidix_rect_t srcVideo; | 73 static vidix_rect_t srcVideo; |
60 static unsigned char *outbuf = NULL; | 74 static unsigned char *outbuf = NULL; |
75 double fb_width; | |
76 double fb_height; | |
77 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) | |
78 static struct ivtvfb_ioctl_state_info fb_state_old; | |
79 static struct ivtvfb_ioctl_state_info fb_state_hide; | |
80 #else | |
81 struct v4l2_format format_old, format_hide; | |
82 #endif | |
83 int alpha_disable = 0; | |
61 | 84 |
62 /* VIDIX exports */ | 85 /* VIDIX exports */ |
63 | 86 |
64 static vidix_capability_t ivtv_cap = | 87 static vidix_capability_t ivtv_cap = |
65 { | 88 { |
66 "Hauppauge PVR 350 YUV Video", | 89 "Hauppauge PVR 350 YUV Video", |
67 "Lutz Koschorreck", | 90 "Lutz Koschorreck", |
68 TYPE_OUTPUT, | 91 TYPE_OUTPUT, |
69 { 0, 0, 0, 0 }, | 92 { 0, 0, 0, 0 }, |
70 IVTVMAXHEIGHT, | 93 IVTVMAXWIDTH, |
71 IVTVMAXWIDTH, | 94 IVTVMAXHEIGHT, |
72 4, | 95 4, |
73 4, | 96 4, |
74 -1, | 97 -1, |
75 FLAG_UPSCALER|FLAG_DOWNSCALER, | 98 FLAG_UPSCALER|FLAG_DOWNSCALER, |
76 -1, | 99 -1, |
77 -1, | 100 -1, |
78 { 0, 0, 0, 0 } | 101 { 0, 0, 0, 0 } |
79 }; | 102 }; |
80 | 103 |
81 static void de_macro_y (unsigned char *src, unsigned char *dst, | 104 static void de_macro_y(unsigned char *src, unsigned char *dst, |
82 unsigned int w, unsigned int h, | 105 unsigned int w, unsigned int h, int src_x, int src_y, int height __attribute__ ((unused)), int width) |
83 int src_x, int src_y, | 106 { |
84 int height __attribute__ ((unused)), int width) | 107 unsigned int x, y, i; |
85 { | 108 unsigned char *dst_2; |
86 unsigned int x, y, i; | 109 unsigned int h_tail, w_tail; |
87 unsigned char *dst_2; | 110 unsigned int h_size, w_size; |
88 unsigned int h_tail, w_tail; | 111 |
89 unsigned int h_size, w_size; | 112 // Always round the origin, but compensate by increasing the size |
90 | 113 if (src_x & 15) { |
91 // Always round the origin, but compensate by increasing the size | 114 w += src_x & 15; |
92 if (src_x & 15) | 115 src_x &= ~15; |
93 { | 116 } |
94 w += src_x & 15; | 117 |
95 src_x &= ~15; | 118 if (src_y & 15) { |
96 } | 119 h += src_y & 15; |
97 | 120 src_y &= ~15; |
98 if (src_y & 15) | 121 } |
99 { | 122 |
100 h += src_y & 15; | 123 // The right / bottom edge might not be a multiple of 16 |
101 src_y &= ~15; | 124 h_tail = h & 15; |
102 } | 125 w_tail = w & 15; |
103 | 126 |
104 // The right / bottom edge might not be a multiple of 16 | 127 // One block is 16 pixels high |
105 h_tail = h & 15; | 128 h_size = 16; |
106 w_tail = w & 15; | 129 |
107 | 130 // descramble Y plane |
108 // One block is 16 pixels high | 131 for (y = 0; y < h; y += 16) { |
109 h_size = 16; | 132 |
110 | 133 // Clip if we've reached the bottom & the size isn't a multiple of 16 |
111 // descramble Y plane | 134 if (y + 16 > h) h_size = h_tail; |
112 for (y = 0; y < h; y += 16) | 135 |
113 { | 136 for (x = 0; x < w; x += 16) { |
114 // Clip if we've reached the bottom & the size isn't a multiple of 16 | 137 if (x + 16 > w) |
115 if (y + 16 > h) h_size = h_tail; | 138 w_size = w_tail; |
116 | 139 else |
117 for (x = 0; x < w; x += 16) | 140 w_size = 16; |
118 { | 141 |
119 if (x + 16 > w) | 142 dst_2 = dst + (720 * y) + (720 * src_y) + (256 * (src_x>>4)) + (x * 16); |
120 w_size = w_tail; | 143 |
121 else | 144 for (i = 0; i < h_size; i++) { |
122 w_size = 16; | 145 memcpy(dst_2, src + src_x + x + (y + i) * width + (src_y * width), w_size); |
123 | 146 dst_2 += 16; |
124 dst_2 = dst + (720 * y) + (720 * src_y) + (256 * (src_x>>4)) + (x * 16); | 147 } |
125 | 148 } |
126 for (i = 0; i < h_size; i++) | 149 } |
127 { | 150 } |
128 memcpy (dst_2, src + src_x + x + (y + i) * width + (src_y * width), | 151 |
129 w_size); | 152 static void de_macro_uv(unsigned char *srcu, unsigned char *srcv, |
130 dst_2 += 16; | 153 unsigned char *dst, unsigned int w, unsigned int h, int src_x, int src_y, |
131 } | 154 int height, int width) |
132 } | 155 { |
133 } | 156 unsigned int x, y, i, f; |
134 } | 157 unsigned char *dst_2; |
135 | 158 unsigned int h_tail, w_tail; |
136 static void de_macro_uv (unsigned char *srcu, unsigned char *srcv, | 159 unsigned int h_size; |
137 unsigned char *dst, unsigned int w, unsigned int h, | 160 |
138 int src_x, int src_y, int height, int width) | 161 // The uv plane is half the size of the y plane, so 'correct' all dimensions. |
139 { | 162 w /= 2; |
140 unsigned int x, y, i, f; | 163 h /= 2; |
141 unsigned char *dst_2; | 164 src_x /= 2; |
142 unsigned int h_tail, w_tail; | 165 src_y /= 2; |
143 unsigned int h_size; | 166 height /= 2; |
144 | 167 width /= 2; |
145 /* The uv plane is half the size of the y plane, | 168 |
146 so 'correct' all dimensions. */ | 169 // Always round the origin, but compensate by increasing the size |
147 w /= 2; | 170 if (src_x & 7) { |
148 h /= 2; | 171 w += src_x & 7; |
149 src_x /= 2; | 172 src_x &= ~7; |
150 src_y /= 2; | 173 } |
151 height /= 2; | 174 |
152 width /= 2; | 175 if (src_y & 15) { |
153 | 176 h += src_y & 15; |
154 // Always round the origin, but compensate by increasing the size | 177 src_y &= ~15; |
155 if (src_x & 7) | 178 } |
156 { | 179 |
157 w += src_x & 7; | 180 // The right / bottom edge may not be a multiple of 16 |
158 src_x &= ~7; | 181 h_tail = h & 15; |
159 } | 182 w_tail = w & 7; |
160 | 183 |
161 if (src_y & 15) | 184 h_size = 16; |
162 { | 185 |
163 h += src_y & 15; | 186 // descramble U/V plane |
164 src_y &= ~15; | 187 for (y = 0; y < h; y += 16) { |
165 } | 188 if ( y + 16 > h ) h_size = h_tail; |
166 | 189 for (x = 0; x < w; x += 8) { |
167 // The right / bottom edge may not be a multiple of 16 | 190 dst_2 = dst + (720 * y) + (720 * src_y) + (256 * (src_x>>3)) + (x * 32); |
168 h_tail = h & 15; | 191 if (x + 8 <= w) { |
169 w_tail = w & 7; | 192 for (i = 0; i < h_size; i++) { |
170 | 193 int idx = src_x + x + ((y + i) * width) + (src_y * width); |
171 h_size = 16; | 194 dst_2[0] = srcu[idx + 0]; |
172 | 195 dst_2[1] = srcv[idx + 0]; |
173 // descramble U/V plane | 196 dst_2[2] = srcu[idx + 1]; |
174 for (y = 0; y < h; y += 16) | 197 dst_2[3] = srcv[idx + 1]; |
175 { | 198 dst_2[4] = srcu[idx + 2]; |
176 if (y + 16 > h) | 199 dst_2[5] = srcv[idx + 2]; |
177 h_size = h_tail; | 200 dst_2[6] = srcu[idx + 3]; |
178 | 201 dst_2[7] = srcv[idx + 3]; |
179 for (x = 0; x < w; x += 8) | 202 dst_2[8] = srcu[idx + 4]; |
180 { | 203 dst_2[9] = srcv[idx + 4]; |
181 dst_2 = dst + (720 * y) + (720 * src_y) + (256 * (src_x>>3)) + (x * 32); | 204 dst_2[10] = srcu[idx + 5]; |
182 if (x + 8 <= w) | 205 dst_2[11] = srcv[idx + 5]; |
183 { | 206 dst_2[12] = srcu[idx + 6]; |
184 for (i = 0; i < h_size; i++) | 207 dst_2[13] = srcv[idx + 6]; |
185 { | 208 dst_2[14] = srcu[idx + 7]; |
186 int idx = src_x + x + ((y + i) * width) + (src_y * width); | 209 dst_2[15] = srcv[idx + 7]; |
187 dst_2[0] = srcu[idx + 0]; | 210 dst_2 += 16; |
188 dst_2[1] = srcv[idx + 0]; | 211 } |
189 dst_2[2] = srcu[idx + 1]; | 212 } |
190 dst_2[3] = srcv[idx + 1]; | 213 else { |
191 dst_2[4] = srcu[idx + 2]; | 214 for (i = 0; i < h_size; i ++) { |
192 dst_2[5] = srcv[idx + 2]; | 215 int idx = src_x + x + ((y + i) * width) + (src_y * width); |
193 dst_2[6] = srcu[idx + 3]; | 216 for (f = 0; f < w_tail; f++) { |
194 dst_2[7] = srcv[idx + 3]; | 217 dst_2[0] = srcu[idx + f]; |
195 dst_2[8] = srcu[idx + 4]; | 218 dst_2[1] = srcv[idx + f]; |
196 dst_2[9] = srcv[idx + 4]; | 219 dst_2 += 2; |
197 dst_2[10] = srcu[idx + 5]; | 220 } |
198 dst_2[11] = srcv[idx + 5]; | 221 /* |
199 dst_2[12] = srcu[idx + 6]; | 222 // Used for testing edge cutoff. Sets colour to Green |
200 dst_2[13] = srcv[idx + 6]; | 223 for (f = w_tail;f < 8;f ++) { |
201 dst_2[14] = srcu[idx + 7]; | 224 dst_2[0] = 0; |
202 dst_2[15] = srcv[idx + 7]; | 225 dst_2[1] = 0; |
203 dst_2 += 16; | 226 dst_2 += 2; |
204 } | 227 } |
205 } | 228 */ |
206 else | 229 dst_2 += 16 - (w_tail << 1); |
207 { | 230 } |
208 for (i = 0; i < h_size; i ++) | 231 } |
209 { | 232 } |
210 int idx = src_x + x + ((y + i) * width) + (src_y * width); | 233 } |
211 for (f = 0; f < w_tail; f++) | 234 } |
212 { | 235 |
213 dst_2[0] = srcu[idx + f]; | 236 int ivtv_probe(int verbose,int force __attribute__ ((unused))) |
214 dst_2[1] = srcv[idx + f]; | 237 { |
215 dst_2 += 2; | 238 unsigned char fb_number = 0; |
216 } | 239 char *device_name = NULL; |
217 | 240 char *alpha = NULL; |
218 dst_2 += 16 - (w_tail << 1); | 241 struct fb_var_screeninfo vinfo; |
219 } | 242 char fb_dev_name[] = "/dev/fb0\0"; |
220 } | 243 pciinfo_t lst[MAX_PCI_DEVICES]; |
221 } | 244 int err = 0; |
222 } | 245 unsigned int i, num_pci = 0; |
223 } | 246 |
224 | 247 if(verbose) |
225 static int ivtv_probe (int verbose, int force __attribute__ ((unused))) | 248 printf(IVTV_MSG"probe\n"); |
226 { | 249 |
227 pciinfo_t lst[MAX_PCI_DEVICES]; | 250 ivtv_verbose = verbose; |
228 unsigned int i, num_pci; | 251 |
229 int err; | 252 err = pci_scan(lst, &num_pci); |
230 FILE *procFb; | 253 if(err) { |
231 unsigned char fb_number = 0; | 254 printf(IVTV_MSG"Error occured during pci scan: %s\n", strerror(err)); |
232 unsigned char yuv_device_number, yuv_device; | 255 return err; |
233 char yuv_device_name[] = "/dev/videoXXX\0"; | 256 } |
234 | 257 |
235 if (verbose) | 258 if(ivtv_verbose) |
236 printf (IVTV_MSG"probe\n"); | 259 printf(IVTV_MSG"Found %d pci devices\n", num_pci); |
237 | 260 |
238 ivtv_verbose = verbose; | 261 for(i = 0; i < num_pci; i++) { |
239 | 262 if(2 == ivtv_verbose) |
240 err = pci_scan (lst, &num_pci); | 263 printf(IVTV_MSG"Found chip [%04X:%04X] '%s' '%s'\n" |
241 if (err) | 264 ,lst[i].vendor |
242 { | 265 ,lst[i].device |
243 printf (IVTV_MSG"Error occured during pci scan: %s\n", strerror (err)); | 266 ,pci_vendor_name(lst[i].vendor) |
244 return err; | 267 ,pci_device_name(lst[i].vendor,lst[i].device)); |
245 } | 268 if(VENDOR_INTERNEXT == lst[i].vendor) { |
246 | 269 switch(lst[i].device) |
247 if (ivtv_verbose) | 270 { |
248 printf (IVTV_MSG"Found %d pci devices\n", num_pci); | 271 case DEVICE_INTERNEXT_ITVC15_MPEG_2_ENCODER: |
249 | 272 if(ivtv_verbose) |
250 for (i = 0; i < num_pci; i++) | 273 printf(IVTV_MSG"Found PVR 350\n"); |
251 { | 274 goto card_found; |
252 if (ivtv_verbose == 2) | 275 } |
253 printf (IVTV_MSG"Found chip [%04X:%04X] '%s' '%s'\n", | 276 } |
254 lst[i].vendor, lst[i].device, pci_vendor_name (lst[i].vendor), | 277 } |
255 pci_device_name(lst[i].vendor,lst[i].device)); | 278 |
256 | 279 if(ivtv_verbose) |
257 if (VENDOR_INTERNEXT == lst[i].vendor) | 280 printf(IVTV_MSG"Can't find chip\n"); |
258 { | 281 return(ENXIO); |
259 switch (lst[i].device) | 282 |
260 { | 283 card_found: |
261 case DEVICE_INTERNEXT_ITVC15_MPEG_2_ENCODER: | 284 |
262 if (ivtv_verbose) | 285 device_name = getenv("FRAMEBUFFER"); |
263 printf (IVTV_MSG"Found PVR 350\n"); | 286 if(NULL == device_name) { |
264 goto card_found; | 287 device_name = fb_dev_name; |
265 } | 288 } |
266 } | 289 |
267 } | 290 fb_number = atoi(device_name+strlen("/dev/fb")); |
268 | 291 |
269 if (ivtv_verbose) | 292 fbdev = open(device_name, O_RDWR); |
270 printf (IVTV_MSG"Can't find chip\n"); | 293 if(-1 != fbdev) { |
271 | 294 if(ioctl(fbdev, FBIOGET_VSCREENINFO, &vinfo) < 0) { |
272 return (ENXIO); | 295 printf(IVTV_MSG"Unable to read screen info\n"); |
273 | 296 close(fbdev); |
274 card_found: | 297 return(ENXIO); |
275 | 298 } else { |
276 /* Try to find framebuffer device */ | 299 fb_width = vinfo.xres; |
277 procFb = fopen ("/proc/fb", "r"); | 300 fb_height = vinfo.yres; |
278 if (procFb) | 301 if(2 == ivtv_verbose) { |
279 { | 302 printf(IVTV_MSG"framebuffer width : %3.0f\n",fb_width); |
280 char procEntry[MAXLINE] = {0}; | 303 printf(IVTV_MSG"framebuffer height: %3.0f\n",fb_height); |
281 while (NULL != fgets(procEntry, MAXLINE, procFb)) | 304 } |
282 { | 305 } |
283 char *pos = NULL; | 306 if(NULL != (alpha = getenv("VIDIXIVTVALPHA"))) { |
284 if (ivtv_verbose) | 307 if(0 == strcmp(alpha, "disable")) { |
285 printf (IVTV_MSG" %s", procEntry); | 308 alpha_disable = 1; |
286 | 309 } |
287 if (NULL != (pos = strstr(procEntry, " cx23415 TV out"))) | 310 } |
288 { | 311 } else { |
289 *pos = '\0'; | 312 printf(IVTV_MSG"Failed to open /dev/fb%u\n", fb_number); |
290 fb_number = atoi (procEntry); | 313 return(ENXIO); |
291 if (ivtv_verbose) | 314 } |
292 printf (IVTV_MSG"Framebuffer found #%u\n", fb_number); | 315 |
293 goto fb_found; | 316 /* Try to find YUV device */ |
294 } | 317 unsigned char yuv_device_number = 48, yuv_device = 48 + fb_number; |
295 } | 318 char yuv_device_name[] = "/dev/videoXXX\0"; |
296 } | 319 |
297 else | 320 do { |
298 { | 321 sprintf(yuv_device_name, "/dev/video%u", yuv_device); |
299 if (ivtv_verbose) | 322 yuvdev = open(yuv_device_name, O_RDWR); |
300 printf (IVTV_MSG"Framebuffer device not found\n"); | 323 if(-1 != yuvdev) { |
301 return (ENXIO); | 324 if(ivtv_verbose) |
302 } | 325 printf(IVTV_MSG"YUV device found /dev/video%u\n", yuv_device); |
303 | 326 goto yuv_found; |
304 fb_found: | 327 } else { |
305 fclose (procFb); | 328 if(ivtv_verbose) |
306 | 329 printf(IVTV_MSG"YUV device not found: /dev/video%u\n", yuv_device); |
307 /* Try to find YUV device */ | 330 } |
308 yuv_device_number = 48; | 331 } while(yuv_device-- > yuv_device_number); |
309 yuv_device = 48 + fb_number; | 332 return(ENXIO); |
310 | 333 |
311 do { | 334 yuv_found: |
312 sprintf (yuv_device_name, "/dev/video%u", yuv_device); | 335 if(0 == alpha_disable) { |
313 yuvdev = open (yuv_device_name, O_RDWR); | 336 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
314 if (-1 != yuvdev) | 337 if(ioctl(fbdev, IVTVFB_IOCTL_GET_STATE, &fb_state_old) < 0) { |
315 { | 338 printf(IVTV_MSG"Unable to read fb state\n"); |
316 if (ivtv_verbose) | 339 close(yuvdev); |
317 printf (IVTV_MSG"YUV device found /dev/video%u\n", yuv_device); | 340 close(fbdev); |
318 goto yuv_found; | 341 return(ENXIO); |
319 } | 342 } else { |
320 else | 343 if(ivtv_verbose) { |
321 { | 344 printf(IVTV_MSG"old alpha : %ld\n",fb_state_old.alpha); |
322 if (ivtv_verbose) | 345 printf(IVTV_MSG"old status: 0x%lx\n",fb_state_old.status); |
323 printf (IVTV_MSG"YUV device not found: /dev/video%u\n", yuv_device); | 346 } |
324 } | 347 fb_state_hide.alpha = 0; |
325 } while (yuv_device-- > yuv_device_number); | 348 fb_state_hide.status = fb_state_old.status | IVTVFB_STATUS_GLOBAL_ALPHA; |
326 | 349 } |
327 return (ENXIO); | 350 #else |
328 | 351 memset(&format_old, 0, sizeof(format_old)); |
329 yuv_found: | 352 format_old.type = format_hide.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; |
330 probed = 1; | 353 if(ioctl(yuvdev, VIDIOC_G_FMT , &format_old) < 0) { |
331 return 0; | 354 printf(IVTV_MSG"Unable to read fb state\n"); |
332 } | 355 close(yuvdev); |
333 | 356 close(fbdev); |
334 static int ivtv_init (void) | 357 return(ENXIO); |
335 { | 358 } else { |
336 if (ivtv_verbose) | 359 if(ivtv_verbose) { |
337 printf (IVTV_MSG"init\n"); | 360 printf(IVTV_MSG"old alpha : %d\n",format_old.fmt.win.global_alpha); |
338 | 361 } |
339 if (!probed) | 362 memcpy(&format_hide, &format_old, sizeof(format_old)); |
340 { | 363 format_hide.fmt.win.global_alpha = 0; |
341 if (ivtv_verbose) | 364 } |
342 printf (IVTV_MSG"Driver was not probed but is being initialized\n"); | 365 #endif |
343 | 366 } |
344 return (EINTR); | 367 probed = 1; |
345 } | 368 return(0); |
346 | 369 } |
347 outbuf = malloc ((IVTVMAXHEIGHT * IVTVMAXWIDTH) | 370 |
348 + (IVTVMAXHEIGHT * IVTVMAXWIDTH / 2)); | 371 int ivtv_init(const char *args __attribute__ ((unused))) |
349 | 372 { |
350 if (!outbuf) | 373 if(ivtv_verbose) |
351 { | 374 printf(IVTV_MSG"init\n"); |
352 if (ivtv_verbose) | 375 |
353 printf (IVTV_MSG"Not enough memory availabe!\n"); | 376 if (!probed) { |
354 return (EINTR); | 377 if(ivtv_verbose) |
355 } | 378 printf(IVTV_MSG"Driver was not probed but is being initialized\n"); |
356 | 379 return(EINTR); |
357 return 0; | 380 } |
358 } | 381 outbuf = malloc((IVTVMAXHEIGHT * IVTVMAXWIDTH) + (IVTVMAXHEIGHT * IVTVMAXWIDTH / 2)); |
359 | 382 if(NULL == outbuf) { |
360 static void ivtv_destroy (void) | 383 if(ivtv_verbose) |
361 { | 384 printf(IVTV_MSG"Not enough memory availabe!\n"); |
362 if (ivtv_verbose) | 385 return(EINTR); |
363 printf (IVTV_MSG"destory\n"); | 386 } |
364 close (yuvdev); | 387 return(0); |
365 free (outbuf); | 388 } |
366 } | 389 |
367 | 390 void ivtv_destroy(void) |
368 static int ivtv_get_caps (vidix_capability_t *to) | 391 { |
369 { | 392 if(ivtv_verbose) |
370 if (ivtv_verbose) | 393 printf(IVTV_MSG"destroy\n"); |
371 printf (IVTV_MSG"GetCap\n"); | 394 if(-1 != yuvdev) |
372 memcpy (to, &ivtv_cap, sizeof (vidix_capability_t)); | 395 close(yuvdev); |
373 | 396 if(-1 != fbdev) |
374 return 0; | 397 close(fbdev); |
375 } | 398 if(NULL != outbuf) |
376 | 399 free(outbuf); |
377 static int ivtv_query_fourcc (vidix_fourcc_t *to) | 400 if(NULL != memBase) |
378 { | 401 free(memBase); |
379 int supports = 0; | 402 } |
380 | 403 |
381 if (ivtv_verbose) | 404 int ivtv_get_caps(vidix_capability_t *to) |
382 printf (IVTV_MSG"query fourcc (%x)\n", to->fourcc); | 405 { |
383 | 406 if(ivtv_verbose) |
384 switch (to->fourcc) | 407 printf(IVTV_MSG"GetCap\n"); |
385 { | 408 memcpy(to, &ivtv_cap, sizeof(vidix_capability_t)); |
386 case IMGFMT_YV12: | 409 return(0); |
387 supports = 1; | 410 } |
388 break; | 411 |
389 default: | 412 int ivtv_query_fourcc(vidix_fourcc_t *to) |
390 supports = 0; | 413 { |
391 } | 414 if(ivtv_verbose) |
392 | 415 printf(IVTV_MSG"query fourcc (%x)\n", to->fourcc); |
393 if (!supports) | 416 |
394 { | 417 int supports = 0; |
395 to->depth = to->flags = 0; | 418 switch(to->fourcc) |
396 return (ENOTSUP); | 419 { |
397 } | 420 case IMGFMT_YV12: |
398 | 421 supports = 1; |
399 to->depth = VID_DEPTH_12BPP | | 422 break; |
400 VID_DEPTH_15BPP | VID_DEPTH_16BPP | | 423 default: |
401 VID_DEPTH_24BPP | VID_DEPTH_32BPP; | 424 supports = 0; |
402 to->flags = 0; | 425 } |
403 | 426 |
404 return 0; | 427 if(!supports) { |
405 } | 428 to->depth = to->flags = 0; |
406 | 429 return(ENOTSUP); |
407 static int ivtv_config_playback (vidix_playback_t *info) | 430 } |
408 { | 431 to->depth = VID_DEPTH_12BPP | |
409 if (ivtv_verbose) | 432 VID_DEPTH_15BPP | VID_DEPTH_16BPP | |
410 printf (IVTV_MSG"config playback\n"); | 433 VID_DEPTH_24BPP | VID_DEPTH_32BPP; |
411 | 434 to->flags = 0; |
412 if (2 == ivtv_verbose) | 435 return(0); |
413 { | 436 } |
414 printf (IVTV_MSG"src : x:%d y:%d w:%d h:%d\n", | 437 |
415 info->src.x, info->src.y, info->src.w, info->src.h); | 438 int ivtv_config_playback(vidix_playback_t *info) |
416 printf (IVTV_MSG"dest: x:%d y:%d w:%d h:%d\n", | 439 { |
417 info->dest.x, info->dest.y, info->dest.w, info->dest.h); | 440 if(ivtv_verbose) |
418 } | 441 printf(IVTV_MSG"config playback\n"); |
419 | 442 |
420 memcpy (&destVideo, &info->dest, sizeof (vidix_rect_t)); | 443 if(2 == ivtv_verbose){ |
421 memcpy (&srcVideo, &info->src, sizeof (vidix_rect_t)); | 444 printf(IVTV_MSG"src : x:%d y:%d w:%d h:%d\n", |
422 | 445 info->src.x, info->src.y, info->src.w, info->src.h); |
423 info->num_frames = 2; | 446 printf(IVTV_MSG"dest: x:%d y:%d w:%d h:%d\n", |
424 info->frame_size = frameSize = | 447 info->dest.x, info->dest.y, info->dest.w, info->dest.h); |
425 info->src.w*info->src.h+(info->src.w*info->src.h)/2; | 448 } |
426 info->dest.pitch.y = 16; | 449 |
427 info->dest.pitch.u = info->dest.pitch.v = 16; | 450 memcpy(&destVideo, &info->dest, sizeof(vidix_rect_t)); |
428 info->offsets[0] = 0; | 451 memcpy(&srcVideo, &info->src, sizeof(vidix_rect_t)); |
429 info->offsets[1] = info->frame_size; | 452 |
430 info->offset.y = 0; | 453 info->num_frames = 2; |
431 info->offset.u = IVTVMAXWIDTH * IVTVMAXHEIGHT; | 454 info->frame_size = frameSize = info->src.w*info->src.h+(info->src.w*info->src.h)/2; |
432 info->offset.v = IVTVMAXWIDTH * IVTVMAXHEIGHT | 455 info->dest.pitch.y = 1; |
433 + (IVTVMAXWIDTH / 2) * (IVTVMAXHEIGHT / 2); | 456 info->dest.pitch.u = info->dest.pitch.v = 2; |
434 | 457 info->offsets[0] = 0; |
435 info->dga_addr = memBase = malloc (info->num_frames*info->frame_size); | 458 info->offsets[1] = info->frame_size; |
436 | 459 info->offset.y = 0; |
437 if (ivtv_verbose) | 460 info->offset.u = info->src.w * info->src.h; |
438 printf (IVTV_MSG"frame_size: %d, dga_addr: %p\n", | 461 info->offset.v = info->offset.u + ((info->src.w * info->src.h)/4); |
439 info->frame_size, info->dga_addr); | 462 info->dga_addr = memBase = malloc(info->num_frames*info->frame_size); |
440 | 463 if(ivtv_verbose) |
441 return 0; | 464 printf(IVTV_MSG"frame_size: %d, dga_addr: %p\n", |
442 } | 465 info->frame_size, info->dga_addr); |
443 | 466 return(0); |
444 static int ivtv_playback_on (void) | 467 } |
445 { | 468 |
446 if (ivtv_verbose) | 469 int ivtv_playback_on(void) |
447 printf (IVTV_MSG"playback on\n"); | 470 { |
448 | 471 if(ivtv_verbose) |
449 return 0; | 472 printf(IVTV_MSG"playback on\n"); |
450 } | 473 |
451 | 474 if(0 == alpha_disable) { |
452 static int ivtv_playback_off (void) | 475 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
453 { | 476 if (-1 != fbdev) { |
454 if (ivtv_verbose) | 477 if (ioctl(fbdev, IVTVFB_IOCTL_SET_STATE, &fb_state_hide) < 0) |
455 printf (IVTV_MSG"playback off\n"); | 478 printf (IVTV_MSG"Failed to set fb state\n"); |
456 | 479 } |
457 return 0; | 480 #else |
458 } | 481 if (-1 != yuvdev) { |
459 | 482 if (ioctl(yuvdev, VIDIOC_S_FMT, &format_hide) < 0) |
460 static int ivtv_frame_sel (unsigned int frame) | 483 printf (IVTV_MSG"Failed to set fb state\n"); |
461 { | 484 } |
462 struct ivtvyuv_ioctl_dma_host_to_ivtv_args args; | 485 #endif |
463 | 486 } |
464 de_macro_y ((memBase + (frame * frameSize)), | 487 return(0); |
465 outbuf, srcVideo.w, srcVideo.h, | 488 } |
466 srcVideo.x, srcVideo.y, destVideo.h, destVideo.w); | 489 |
467 | 490 int ivtv_playback_off(void) |
468 de_macro_uv ((memBase + (frame * frameSize)) | 491 { |
469 + (srcVideo.w * srcVideo.h) + srcVideo.w * srcVideo.h / 4, | 492 if(ivtv_verbose) |
470 (memBase + (frame * frameSize)) + (srcVideo.w * srcVideo.h), | 493 printf(IVTV_MSG"playback off\n"); |
471 outbuf + IVTVMAXWIDTH * IVTVMAXHEIGHT, | 494 |
472 srcVideo.w, srcVideo.h, srcVideo.x, srcVideo.y, | 495 if(0 == alpha_disable) { |
473 destVideo.h, destVideo.w); | 496 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
474 | 497 if (-1 != fbdev) { |
475 args.y_source = outbuf; | 498 if (ioctl(fbdev, IVTVFB_IOCTL_SET_STATE, &fb_state_old) < 0) |
476 args.uv_source = outbuf + (IVTVMAXWIDTH * IVTVMAXHEIGHT); | 499 printf (IVTV_MSG"Failed to restore fb state\n"); |
477 args.src_x = srcVideo.x; | 500 } |
478 args.src_y = srcVideo.y; | 501 #else |
479 args.dst_x = destVideo.x; | 502 if (-1 != yuvdev) { |
480 args.dst_y = destVideo.y; | 503 if (ioctl(yuvdev, VIDIOC_S_FMT, &format_old) < 0) |
481 args.src_w = srcVideo.w; | 504 printf (IVTV_MSG"Failed to restore fb state\n"); |
482 args.dst_w = destVideo.w; | 505 } |
483 args.srcBuf_width = srcVideo.w; | 506 #endif |
484 args.src_h = srcVideo.h; | 507 } |
485 args.dst_h = destVideo.h; | 508 return(0); |
486 args.srcBuf_height = srcVideo.h; | 509 } |
487 args.yuv_type = 0; | 510 |
488 | 511 int ivtv_frame_sel(unsigned int frame) |
489 if(ioctl(yuvdev, IVTV_IOC_PREP_FRAME_YUV, &args) == -1) | 512 { |
490 printf ("Ioctl IVTV_IOC_PREP_FRAME_YUV returned failed Error\n"); | 513 |
491 | 514 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
492 return 0; | 515 struct ivtvyuv_ioctl_dma_host_to_ivtv_args args; |
516 #else | |
517 struct ivtv_dma_frame args; | |
518 #endif | |
519 unsigned char *curMemBase = (unsigned char *)memBase + (frame * frameSize); | |
520 | |
521 de_macro_y(curMemBase, outbuf, srcVideo.w, srcVideo.h, srcVideo.x, srcVideo.y, srcVideo.h, srcVideo.w); | |
522 de_macro_uv(curMemBase + (srcVideo.w * srcVideo.h) + srcVideo.w * srcVideo.h / 4, | |
523 curMemBase + (srcVideo.w * srcVideo.h), outbuf + (IVTVMAXHEIGHT * IVTVMAXWIDTH), | |
524 srcVideo.w, srcVideo.h, srcVideo.x, srcVideo.y, srcVideo.h, srcVideo.w); | |
525 | |
526 args.y_source = outbuf; | |
527 args.uv_source = outbuf + (IVTVMAXHEIGHT * IVTVMAXWIDTH); | |
528 | |
529 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) | |
530 args.src_x = srcVideo.x; | |
531 args.src_y = srcVideo.y; | |
532 args.dst_x = destVideo.x; | |
533 args.dst_y = destVideo.y; | |
534 args.src_w = srcVideo.w; | |
535 args.dst_w = destVideo.w; | |
536 args.srcBuf_width = srcVideo.w; | |
537 args.src_h = srcVideo.h; | |
538 args.dst_h = destVideo.h; | |
539 args.srcBuf_height = srcVideo.h; | |
540 args.yuv_type = 0; | |
541 #else | |
542 args.src.left = srcVideo.x; | |
543 args.src.top = srcVideo.y; | |
544 args.dst.left = destVideo.x; | |
545 args.dst.top = destVideo.y; | |
546 args.src.width = srcVideo.w; | |
547 args.dst.width = destVideo.w; | |
548 args.src_width = srcVideo.w; | |
549 args.src.height = srcVideo.h; | |
550 args.dst.height = destVideo.h; | |
551 args.src_height = srcVideo.h; | |
552 args.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; | |
553 #endif | |
554 | |
555 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) | |
556 if(ioctl(yuvdev, IVTV_IOC_PREP_FRAME_YUV, &args) == -1) { | |
557 #else | |
558 if(ioctl(yuvdev, IVTV_IOC_DMA_FRAME, &args) == -1) { | |
559 #endif | |
560 printf("Ioctl IVTV_IOC_DMA_FRAME returned failed Error\n"); | |
561 } | |
562 return(0); | |
493 } | 563 } |
494 | 564 |
495 VDXDriver ivtv_drv = { | 565 VDXDriver ivtv_drv = { |
496 "ivtv", | 566 "ivtv", |
497 NULL, | 567 NULL, |
498 .probe = ivtv_probe, | 568 .probe = ivtv_probe, |
499 .get_caps = ivtv_get_caps, | 569 .get_caps = ivtv_get_caps, |
500 .query_fourcc = ivtv_query_fourcc, | 570 .query_fourcc = ivtv_query_fourcc, |
501 .init = ivtv_init, | 571 .init = ivtv_init, |
502 .destroy = ivtv_destroy, | 572 .destroy = ivtv_destroy, |
503 .config_playback = ivtv_config_playback, | 573 .config_playback = ivtv_config_playback, |
504 .playback_on = ivtv_playback_on, | 574 .playback_on = ivtv_playback_on, |
505 .playback_off = ivtv_playback_off, | 575 .playback_off = ivtv_playback_off, |
506 .frame_sel = ivtv_frame_sel, | 576 .frame_sel = ivtv_frame_sel, |
507 }; | 577 }; |