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 };