Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /xawtv-3.94/libng/plugins/drv0-v4l2.c (Version 2.6.11.8) and /xawtv-3.94/libng/plugins/drv0-v4l2.c (Version 2.6.31.13)


  1 /*                                                  1 
  2  * interface to the v4l2 driver                   
  3  *                                                
  4  *   (c) 1998-2002 Gerd Knorr <kraxel@bytesex.    
  5  *                                                
  6  */                                               
  7 #include "config.h"                               
  8                                                   
  9 #include <stdio.h>                                
 10 #include <stdlib.h>                               
 11 #include <unistd.h>                               
 12 #include <math.h>                                 
 13 #include <errno.h>                                
 14 #include <fcntl.h>                                
 15 #include <string.h>                               
 16 #include <signal.h>                               
 17 #include <sys/types.h>                            
 18 #include <sys/time.h>                             
 19 #include <sys/ioctl.h>                            
 20 #include <sys/stat.h>                             
 21 #include <sys/mman.h>                             
 22 #include <pthread.h>                              
 23                                                   
 24 #include <asm/types.h>          /* XXX glibc *    
 25 #include "videodev2.h"                            
 26                                                   
 27 #include "grab-ng.h"                              
 28                                                   
 29 #include "struct-dump.h"                          
 30 #include "struct-v4l2.h"                          
 31                                                   
 32 /* -------------------------------------------    
 33                                                   
 34 /* open+close */                                  
 35 static void*   v4l2_open(char *device);           
 36 static int     v4l2_close(void *handle);          
 37                                                   
 38 /* attributes */                                  
 39 static char*   v4l2_devname(void *handle);        
 40 static int     v4l2_flags(void *handle);          
 41 static struct ng_attribute* v4l2_attrs(void *h    
 42 static int     v4l2_read_attr(struct ng_attrib    
 43 static void    v4l2_write_attr(struct ng_attri    
 44                                                   
 45 /* overlay */                                     
 46 static int   v4l2_setupfb(void *handle, struct    
 47 static int   v4l2_overlay(void *handle, struct    
 48                           struct OVERLAY_CLIP     
 49                                                   
 50 /* capture video */                               
 51 static int v4l2_setformat(void *handle, struct    
 52 static int v4l2_startvideo(void *handle, int f    
 53 static void v4l2_stopvideo(void *handle);         
 54 static struct ng_video_buf* v4l2_nextframe(voi    
 55 static struct ng_video_buf* v4l2_getimage(void    
 56                                                   
 57 /* tuner */                                       
 58 static unsigned long v4l2_getfreq(void *handle    
 59 static void v4l2_setfreq(void *handle, unsigne    
 60 static int v4l2_tuned(void *handle);              
 61                                                   
 62 /* -------------------------------------------    
 63                                                   
 64 #define WANTED_BUFFERS 32                         
 65                                                   
 66 #define MAX_INPUT   16                            
 67 #define MAX_NORM    16                            
 68 #define MAX_FORMAT  32                            
 69 #define MAX_CTRL    32                            
 70                                                   
 71 struct v4l2_handle {                              
 72     int                         fd;               
 73                                                   
 74     /* device descriptions */                     
 75     int                         ninputs,nstds,    
 76     struct v4l2_capability      cap;              
 77     struct v4l2_streamparm      streamparm;       
 78     struct v4l2_input           inp[MAX_INPUT]    
 79     struct v4l2_standard        std[MAX_NORM];    
 80     struct v4l2_fmtdesc         fmt[MAX_FORMAT    
 81     struct v4l2_queryctrl       ctl[MAX_CTRL*2    
 82                                                   
 83     /* attributes */                              
 84     int                         nattr;            
 85     struct ng_attribute         *attr;            
 86                                                   
 87     /* capture */                                 
 88     int                            fps,first;     
 89     long long                      start;         
 90     struct v4l2_format             fmt_v4l2;      
 91     struct ng_video_fmt            fmt_me;        
 92     struct v4l2_requestbuffers     reqbufs;       
 93     struct v4l2_buffer             buf_v4l2[WA    
 94     struct ng_video_buf            buf_me[WANT    
 95     unsigned int                   queue,waito    
 96                                                   
 97     /* overlay */                                 
 98     struct v4l2_framebuffer        ov_fb;         
 99     struct v4l2_format             ov_win;        
100     struct v4l2_clip               ov_clips[25    
101 #if 0                                             
102     enum v4l2_field                ov_fields;     
103 #endif                                            
104     int                            ov_error;      
105     int                            ov_enabled;    
106     int                            ov_on;         
107 };                                                
108                                                   
109 /* -------------------------------------------    
110                                                   
111 struct ng_vid_driver v4l2_driver = {              
112     name:          "v4l2",                        
113     open:          v4l2_open,                     
114     close:         v4l2_close,                    
115                                                   
116     get_devname:   v4l2_devname,                  
117     capabilities:  v4l2_flags,                    
118     list_attrs:    v4l2_attrs,                    
119                                                   
120     setupfb:       v4l2_setupfb,                  
121     overlay:       v4l2_overlay,                  
122                                                   
123     setformat:     v4l2_setformat,                
124     startvideo:    v4l2_startvideo,               
125     stopvideo:     v4l2_stopvideo,                
126     nextframe:     v4l2_nextframe,                
127     getimage:      v4l2_getimage,                 
128                                                   
129     getfreq:       v4l2_getfreq,                  
130     setfreq:       v4l2_setfreq,                  
131     is_tuned:      v4l2_tuned,                    
132 };                                                
133                                                   
134 static __u32 xawtv_pixelformat[VIDEO_FMT_COUNT    
135     [ VIDEO_RGB08 ]    = V4L2_PIX_FMT_HI240,      
136     [ VIDEO_GRAY ]     = V4L2_PIX_FMT_GREY,       
137     [ VIDEO_RGB15_LE ] = V4L2_PIX_FMT_RGB555,     
138     [ VIDEO_RGB16_LE ] = V4L2_PIX_FMT_RGB565,     
139     [ VIDEO_RGB15_BE ] = V4L2_PIX_FMT_RGB555X,    
140     [ VIDEO_RGB16_BE ] = V4L2_PIX_FMT_RGB565X,    
141     [ VIDEO_BGR24 ]    = V4L2_PIX_FMT_BGR24,      
142     [ VIDEO_BGR32 ]    = V4L2_PIX_FMT_BGR32,      
143     [ VIDEO_RGB24 ]    = V4L2_PIX_FMT_RGB24,      
144     [ VIDEO_YUYV ]     = V4L2_PIX_FMT_YUYV,       
145     [ VIDEO_UYVY ]     = V4L2_PIX_FMT_UYVY,       
146     [ VIDEO_YUV422P ]  = V4L2_PIX_FMT_YUV422P,    
147     [ VIDEO_YUV420P ]  = V4L2_PIX_FMT_YUV420,     
148 };                                                
149                                                   
150 static struct STRTAB stereo[] = {                 
151     {  V4L2_TUNER_MODE_MONO,   "mono"    },       
152     {  V4L2_TUNER_MODE_STEREO, "stereo"  },       
153     {  V4L2_TUNER_MODE_LANG1,  "lang1"   },       
154     {  V4L2_TUNER_MODE_LANG2,  "lang2"   },       
155     { -1, NULL },                                 
156 };                                                
157                                                   
158 /* -------------------------------------------    
159 /* debug output                                   
160                                                   
161 #define PREFIX "ioctl: "                          
162                                                   
163 static int                                        
164 xioctl(int fd, int cmd, void *arg, int mayfail    
165 {                                                 
166     int rc;                                       
167                                                   
168     rc = ioctl(fd,cmd,arg);                       
169     if (0 == rc && ng_debug < 2)                  
170         return rc;                                
171     if (mayfail && errno == mayfail && ng_debu    
172         return rc;                                
173     print_ioctl(stderr,ioctls_v4l2,PREFIX,cmd,    
174     fprintf(stderr,": %s\n",(rc == 0) ? "ok" :    
175     return rc;                                    
176 }                                                 
177                                                   
178 static void                                       
179 print_bufinfo(struct v4l2_buffer *buf)            
180 {                                                 
181     static char *type[] = {                       
182         [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video    
183         [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video    
184         [V4L2_BUF_TYPE_VIDEO_OUTPUT]  = "video    
185         [V4L2_BUF_TYPE_VBI_CAPTURE]   = "vbi-c    
186         [V4L2_BUF_TYPE_VBI_OUTPUT]    = "vbi-o    
187     };                                            
188                                                   
189     fprintf(stderr,"v4l2: buf %d: %s 0x%x+%d,     
190             buf->index,                           
191             buf->type < sizeof(type)/sizeof(ch    
192             ? type[buf->type] : "unknown",        
193             buf->m.offset,buf->length,buf->byt    
194 }                                                 
195                                                   
196 /* -------------------------------------------    
197 /* helpers                                        
198                                                   
199 static void                                       
200 get_device_capabilities(struct v4l2_handle *h)    
201 {                                                 
202     int i;                                        
203                                                   
204     for (h->ninputs = 0; h->ninputs < MAX_INPU    
205         h->inp[h->ninputs].index = h->ninputs;    
206         if (-1 == xioctl(h->fd, VIDIOC_ENUMINP    
207             break;                                
208     }                                             
209     for (h->nstds = 0; h->nstds < MAX_NORM; h-    
210         h->std[h->nstds].index = h->nstds;        
211         if (-1 == xioctl(h->fd, VIDIOC_ENUMSTD    
212             break;                                
213     }                                             
214     for (h->nfmts = 0; h->nfmts < MAX_FORMAT;     
215         h->fmt[h->nfmts].index = h->nfmts;        
216         h->fmt[h->nfmts].type  = V4L2_BUF_TYPE    
217         if (-1 == xioctl(h->fd, VIDIOC_ENUM_FM    
218             break;                                
219     }                                             
220                                                   
221     h->streamparm.type = V4L2_BUF_TYPE_VIDEO_C    
222     ioctl(h->fd,VIDIOC_G_PARM,&h->streamparm);    
223                                                   
224     /* controls */                                
225     for (i = 0; i < MAX_CTRL; i++) {              
226         h->ctl[i].id = V4L2_CID_BASE+i;           
227         if (-1 == xioctl(h->fd, VIDIOC_QUERYCT    
228             (h->ctl[i].flags & V4L2_CTRL_FLAG_    
229             h->ctl[i].id = -1;                    
230     }                                             
231     for (i = 0; i < MAX_CTRL; i++) {              
232         h->ctl[i+MAX_CTRL].id = V4L2_CID_PRIVA    
233         if (-1 == xioctl(h->fd, VIDIOC_QUERYCT    
234             (h->ctl[i+MAX_CTRL].flags & V4L2_C    
235             h->ctl[i+MAX_CTRL].id = -1;           
236     }                                             
237 }                                                 
238                                                   
239 static struct STRTAB *                            
240 build_norms(struct v4l2_handle *h)                
241 {                                                 
242     struct STRTAB *norms;                         
243     int i;                                        
244                                                   
245     norms = malloc(sizeof(struct STRTAB) * (h-    
246     for (i = 0; i < h->nstds; i++) {              
247         norms[i].nr  = i;                         
248         norms[i].str = h->std[i].name;            
249     }                                             
250     norms[i].nr  = -1;                            
251     norms[i].str = NULL;                          
252     return norms;                                 
253 }                                                 
254                                                   
255 static struct STRTAB *                            
256 build_inputs(struct v4l2_handle *h)               
257 {                                                 
258     struct STRTAB *inputs;                        
259     int i;                                        
260                                                   
261     inputs = malloc(sizeof(struct STRTAB) * (h    
262     for (i = 0; i < h->ninputs; i++) {            
263         inputs[i].nr  = i;                        
264         inputs[i].str = h->inp[i].name;           
265     }                                             
266     inputs[i].nr  = -1;                           
267     inputs[i].str = NULL;                         
268     return inputs;                                
269 }                                                 
270                                                   
271 /* -------------------------------------------    
272                                                   
273 static struct V4L2_ATTR {                         
274     unsigned int id;                              
275     unsigned int v4l2;                            
276 } v4l2_attr[] = {                                 
277     { ATTR_ID_VOLUME,   V4L2_CID_AUDIO_VOLUME     
278     { ATTR_ID_MUTE,     V4L2_CID_AUDIO_MUTE       
279     { ATTR_ID_COLOR,    V4L2_CID_SATURATION       
280     { ATTR_ID_BRIGHT,   V4L2_CID_BRIGHTNESS       
281     { ATTR_ID_HUE,      V4L2_CID_HUE              
282     { ATTR_ID_CONTRAST, V4L2_CID_CONTRAST         
283 };                                                
284 #define NUM_ATTR (sizeof(v4l2_attr)/sizeof(str    
285                                                   
286 static struct STRTAB*                             
287 v4l2_menu(int fd, const struct v4l2_queryctrl     
288 {                                                 
289     struct STRTAB *menu;                          
290     struct v4l2_querymenu item;                   
291     int i;                                        
292                                                   
293     menu = malloc(sizeof(struct STRTAB) * (ctl    
294     for (i = ctl->minimum; i <= ctl->maximum;     
295         item.id = ctl->id;                        
296         item.index = i;                           
297         if (-1 == xioctl(fd, VIDIOC_QUERYMENU,    
298             free(menu);                           
299             return NULL;                          
300         }                                         
301         menu[i-ctl->minimum].nr  = i;             
302         menu[i-ctl->minimum].str = strdup(item    
303     }                                             
304     menu[i-ctl->minimum].nr  = -1;                
305     menu[i-ctl->minimum].str = NULL;              
306     return menu;                                  
307 }                                                 
308                                                   
309 static void                                       
310 v4l2_add_attr(struct v4l2_handle *h, struct v4    
311               int id, struct STRTAB *choices)     
312 {                                                 
313     static int private_ids = ATTR_ID_COUNT;       
314     unsigned int i;                               
315                                                   
316     h->attr = realloc(h->attr,(h->nattr+2) * s    
317     memset(h->attr+h->nattr,0,sizeof(struct ng    
318     if (ctl) {                                    
319         for (i = 0; i < NUM_ATTR; i++)            
320             if (v4l2_attr[i].v4l2 == ctl->id)     
321                 break;                            
322         if (i != NUM_ATTR) {                      
323             h->attr[h->nattr].id  = v4l2_attr[    
324         } else {                                  
325             h->attr[h->nattr].id  = private_id    
326         }                                         
327         h->attr[h->nattr].name    = ctl->name;    
328         h->attr[h->nattr].priv    = ctl;          
329         h->attr[h->nattr].defval  = ctl->defau    
330         switch (ctl->type) {                      
331         case V4L2_CTRL_TYPE_INTEGER:              
332             h->attr[h->nattr].type    = ATTR_T    
333             h->attr[h->nattr].defval  = ctl->d    
334             h->attr[h->nattr].min     = ctl->m    
335             h->attr[h->nattr].max     = ctl->m    
336             break;                                
337         case V4L2_CTRL_TYPE_BOOLEAN:              
338             h->attr[h->nattr].type    = ATTR_T    
339             break;                                
340         case V4L2_CTRL_TYPE_MENU:                 
341             h->attr[h->nattr].type    = ATTR_T    
342             h->attr[h->nattr].choices = v4l2_m    
343             break;                                
344         default:                                  
345             return;                               
346         }                                         
347     } else {                                      
348         /* for norms + inputs */                  
349         h->attr[h->nattr].id      = id;           
350         if (-1 == h->attr[h->nattr].id)           
351             h->attr[h->nattr].id  = private_id    
352         h->attr[h->nattr].defval  = 0;            
353         h->attr[h->nattr].type    = ATTR_TYPE_    
354         h->attr[h->nattr].choices = choices;      
355     }                                             
356     if (h->attr[h->nattr].id < ATTR_ID_COUNT)     
357         h->attr[h->nattr].name = ng_attr_to_de    
358                                                   
359     h->attr[h->nattr].read    = v4l2_read_attr    
360     h->attr[h->nattr].write   = v4l2_write_att    
361     h->attr[h->nattr].handle  = h;                
362     h->nattr++;                                   
363 }                                                 
364                                                   
365 static int v4l2_read_attr(struct ng_attribute     
366 {                                                 
367     struct v4l2_handle *h = attr->handle;         
368     const struct v4l2_queryctrl *ctl = attr->p    
369     struct v4l2_control c;                        
370     struct v4l2_tuner tuner;                      
371     v4l2_std_id std;                              
372     int value = 0;                                
373     int i;                                        
374                                                   
375     if (NULL != ctl) {                            
376         c.id = ctl->id;                           
377         xioctl(h->fd,VIDIOC_G_CTRL,&c,0);         
378         value = c.value;                          
379                                                   
380     } else if (attr->id == ATTR_ID_NORM) {        
381         value = -1;                               
382         xioctl(h->fd,VIDIOC_G_STD,&std,0);        
383         for (i = 0; i < h->nstds; i++)            
384             if (std & h->std[i].id)               
385                 value = i;                        
386                                                   
387     } else if (attr->id == ATTR_ID_INPUT) {       
388         xioctl(h->fd,VIDIOC_G_INPUT,&value,0);    
389                                                   
390     } else if (attr->id == ATTR_ID_AUDIO_MODE)    
391         memset(&tuner,0,sizeof(tuner));           
392         xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0);    
393         value = tuner.audmode;                    
394 #if 1                                             
395         if (ng_debug) {                           
396             fprintf(stderr,"v4l2:   tuner cap:    
397                     (tuner.capability&V4L2_TUN    
398                     (tuner.capability&V4L2_TUN    
399                     (tuner.capability&V4L2_TUN    
400             fprintf(stderr,"v4l2:   tuner rxs:    
401                     (tuner.rxsubchans&V4L2_TUN    
402                     (tuner.rxsubchans&V4L2_TUN    
403                     (tuner.rxsubchans&V4L2_TUN    
404                     (tuner.rxsubchans&V4L2_TUN    
405             fprintf(stderr,"v4l2:   tuner cur:    
406                     (tuner.audmode==V4L2_TUNER    
407                     (tuner.audmode==V4L2_TUNER    
408                     (tuner.audmode==V4L2_TUNER    
409                     (tuner.audmode==V4L2_TUNER    
410         }                                         
411 #endif                                            
412     }                                             
413     return value;                                 
414 }                                                 
415                                                   
416 static void v4l2_write_attr(struct ng_attribut    
417 {                                                 
418     struct v4l2_handle *h = attr->handle;         
419     const struct v4l2_queryctrl *ctl = attr->p    
420     struct v4l2_control c;                        
421     struct v4l2_tuner tuner;                      
422                                                   
423     if (NULL != ctl) {                            
424         c.id = ctl->id;                           
425         c.value = value;                          
426         xioctl(h->fd,VIDIOC_S_CTRL,&c,0);         
427                                                   
428     } else if (attr->id == ATTR_ID_NORM) {        
429         xioctl(h->fd,VIDIOC_S_STD,&h->std[valu    
430                                                   
431     } else if (attr->id == ATTR_ID_INPUT) {       
432         xioctl(h->fd,VIDIOC_S_INPUT,&value,0);    
433                                                   
434     } else if (attr->id == ATTR_ID_AUDIO_MODE)    
435         memset(&tuner,0,sizeof(tuner));           
436         xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0);    
437         tuner.audmode = value;                    
438         xioctl(h->fd,VIDIOC_S_TUNER,&tuner,0);    
439     }                                             
440 }                                                 
441                                                   
442 /* -------------------------------------------    
443                                                   
444 static void*                                      
445 v4l2_open(char *device)                           
446 {                                                 
447     struct v4l2_handle *h;                        
448     int i;                                        
449                                                   
450     h = malloc(sizeof(*h));                       
451     if (NULL == h)                                
452         return NULL;                              
453     memset(h,0,sizeof(*h));                       
454                                                   
455     if (-1 == (h->fd = open(device, O_RDWR)))     
456         fprintf(stderr,"v4l2: open %s: %s\n",d    
457         goto err;                                 
458     }                                             
459                                                   
460     if (-1 == xioctl(h->fd,VIDIOC_QUERYCAP,&h-    
461         goto err;                                 
462     if (ng_debug)                                 
463         fprintf(stderr, "v4l2: open\n");          
464     fcntl(h->fd,F_SETFD,FD_CLOEXEC);              
465     if (ng_debug)                                 
466         fprintf(stderr,"v4l2: device info:\n"     
467                 "  %s %d.%d.%d / %s @ %s\n",      
468                 h->cap.driver,                    
469                 (h->cap.version >> 16) & 0xff,    
470                 (h->cap.version >>  8) & 0xff,    
471                 h->cap.version         & 0xff,    
472                 h->cap.card,h->cap.bus_info);     
473     get_device_capabilities(h);                   
474                                                   
475     /* attributes */                              
476     v4l2_add_attr(h, NULL, ATTR_ID_NORM,  buil    
477     v4l2_add_attr(h, NULL, ATTR_ID_INPUT, buil    
478     if (h->cap.capabilities & V4L2_CAP_TUNER)     
479         v4l2_add_attr(h, NULL, ATTR_ID_AUDIO_M    
480     for (i = 0; i < MAX_CTRL*2; i++) {            
481         if (h->ctl[i].id == UNSET)                
482             continue;                             
483         v4l2_add_attr(h, &h->ctl[i], 0, NULL);    
484     }                                             
485                                                   
486     /* capture buffers */                         
487     for (i = 0; i < WANTED_BUFFERS; i++) {        
488         ng_init_video_buf(h->buf_me+i);           
489         h->buf_me[i].release = ng_wakeup_video    
490     }                                             
491                                                   
492     return h;                                     
493                                                   
494  err:                                             
495     if (h->fd != -1)                              
496         close(h->fd);                             
497     if (h)                                        
498         free(h);                                  
499     return NULL;                                  
500 }                                                 
501                                                   
502 static int                                        
503 v4l2_close(void *handle)                          
504 {                                                 
505     struct v4l2_handle *h = handle;               
506                                                   
507     if (ng_debug)                                 
508         fprintf(stderr, "v4l2: close\n");         
509                                                   
510     close(h->fd);                                 
511     free(h);                                      
512     return 0;                                     
513 }                                                 
514                                                   
515 static char*                                      
516 v4l2_devname(void *handle)                        
517 {                                                 
518     struct v4l2_handle *h = handle;               
519     return h->cap.card;                           
520 }                                                 
521                                                   
522 static int v4l2_flags(void *handle)               
523 {                                                 
524     struct v4l2_handle *h = handle;               
525     int ret = 0;                                  
526                                                   
527     if (h->cap.capabilities & V4L2_CAP_VIDEO_O    
528         ret |= CAN_OVERLAY;                       
529     if (h->cap.capabilities & V4L2_CAP_VIDEO_C    
530         ret |= CAN_CAPTURE;                       
531     if (h->cap.capabilities & V4L2_CAP_TUNER)     
532         ret |= CAN_TUNE;                          
533     return ret;                                   
534 }                                                 
535                                                   
536 static struct ng_attribute* v4l2_attrs(void *h    
537 {                                                 
538     struct v4l2_handle *h = handle;               
539     return h->attr;                               
540 }                                                 
541                                                   
542 /* -------------------------------------------    
543                                                   
544 static unsigned long                              
545 v4l2_getfreq(void *handle)                        
546 {                                                 
547     struct v4l2_handle *h = handle;               
548     struct v4l2_frequency f;                      
549                                                   
550     memset(&f,0,sizeof(f));                       
551     xioctl(h->fd, VIDIOC_G_FREQUENCY, &f, 0);     
552     return f.frequency;                           
553 }                                                 
554                                                   
555 static void                                       
556 v4l2_setfreq(void *handle, unsigned long freq)    
557 {                                                 
558     struct v4l2_handle *h = handle;               
559     struct v4l2_frequency f;                      
560                                                   
561     if (ng_debug)                                 
562         fprintf(stderr,"v4l2: freq: %.3f\n",(f    
563     memset(&f,0,sizeof(f));                       
564     f.type = V4L2_TUNER_ANALOG_TV;                
565     f.frequency = freq;                           
566     xioctl(h->fd, VIDIOC_S_FREQUENCY, &f, 0);     
567 }                                                 
568                                                   
569 static int                                        
570 v4l2_tuned(void *handle)                          
571 {                                                 
572     struct v4l2_handle *h = handle;               
573     struct v4l2_tuner tuner;                      
574                                                   
575     usleep(10000);                                
576     memset(&tuner,0,sizeof(tuner));               
577     if (-1 == xioctl(h->fd,VIDIOC_G_TUNER,&tun    
578         return 0;                                 
579     return tuner.signal ? 1 : 0;                  
580 }                                                 
581                                                   
582 /* -------------------------------------------    
583 /* overlay                                        
584                                                   
585 static int                                        
586 v4l2_setupfb(void *handle, struct ng_video_fmt    
587 {                                                 
588     struct v4l2_handle *h = handle;               
589                                                   
590     if (-1 == xioctl(h->fd, VIDIOC_G_FBUF, &h-    
591         return -1;                                
592                                                   
593     /* double-check settings */                   
594     if (NULL != base && h->ov_fb.base != base)    
595         fprintf(stderr,"v4l2: WARNING: framebu    
596         fprintf(stderr,"v4l2: me=%p v4l=%p\n",    
597         h->ov_error = 1;                          
598         return -1;                                
599     }                                             
600     if (h->ov_fb.fmt.width  != fmt->width ||      
601         h->ov_fb.fmt.height != fmt->height) {     
602         fprintf(stderr,"v4l2: WARNING: framebu    
603         fprintf(stderr,"v4l2: me=%dx%d v4l=%dx    
604                 fmt->width,fmt->height,h->ov_f    
605         h->ov_error = 1;                          
606         return -1;                                
607     }                                             
608     if (fmt->bytesperline > 0 &&                  
609         fmt->bytesperline != h->ov_fb.fmt.byte    
610         fprintf(stderr,"v4l2: WARNING: framebu    
611         fprintf(stderr,"v4l2: me=%d v4l=%d\n",    
612                 fmt->bytesperline,h->ov_fb.fmt    
613         h->ov_error = 1;                          
614         return -1;                                
615     }                                             
616 #if 0                                             
617     if (h->ov_fb.fmt.pixelformat != xawtv_pixe    
618         fprintf(stderr,"v4l2: WARNING: framebu    
619         fprintf(stderr,"v4l2: me=%c%c%c%c [%s]    
620                 xawtv_pixelformat[fmt->fmtid]     
621                 (xawtv_pixelformat[fmt->fmtid]    
622                 (xawtv_pixelformat[fmt->fmtid]    
623                 (xawtv_pixelformat[fmt->fmtid]    
624                 ng_vfmt_to_desc[fmt->fmtid],      
625                 h->ov_fb.fmt.pixelformat & 0xf    
626                 (h->ov_fb.fmt.pixelformat >>      
627                 (h->ov_fb.fmt.pixelformat >> 1    
628                 (h->ov_fb.fmt.pixelformat >> 2    
629         h->ov_error = 1;                          
630         return -1;                                
631     }                                             
632 #endif                                            
633     return 0;                                     
634 }                                                 
635                                                   
636 static int                                        
637 v4l2_overlay(void *handle, struct ng_video_fmt    
638              struct OVERLAY_CLIP *oc, int coun    
639 {                                                 
640     struct v4l2_handle *h = handle;               
641     struct v4l2_format win;                       
642     int rc,i;                                     
643                                                   
644     if (h->ov_error)                              
645         return -1;                                
646                                                   
647     if (NULL == fmt) {                            
648         if (ng_debug)                             
649             fprintf(stderr,"v4l2: overlay off\    
650         if (h->ov_enabled) {                      
651             h->ov_enabled = 0;                    
652             h->ov_on = 0;                         
653             xioctl(h->fd, VIDIOC_OVERLAY, &h->    
654         }                                         
655         return 0;                                 
656     }                                             
657                                                   
658     if (ng_debug)                                 
659         fprintf(stderr,"v4l2: overlay win=%dx%    
660                 fmt->width,fmt->height,x,y,cou    
661     memset(&win,0,sizeof(win));                   
662     win.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;       
663     win.fmt.win.w.left    = x;                    
664     win.fmt.win.w.top     = y;                    
665     win.fmt.win.w.width   = fmt->width;           
666     win.fmt.win.w.height  = fmt->height;          
667                                                   
668     /* check against max. size */                 
669     xioctl(h->fd,VIDIOC_TRY_FMT,&win,0);          
670     if (win.fmt.win.w.width != (int)fmt->width    
671         win.fmt.win.w.left = x + (fmt->width -    
672     if (win.fmt.win.w.height != (int)fmt->heig    
673         win.fmt.win.w.top = y + (fmt->height -    
674     if (aspect)                                   
675         ng_ratio_fixup(&win.fmt.win.w.width,&w    
676                        &win.fmt.win.w.left,&wi    
677                                                   
678     /* fixups */                                  
679     ng_check_clipping(win.fmt.win.w.width, win    
680                       x - win.fmt.win.w.left,     
681                       oc, &count);                
682                                                   
683     h->ov_win = win;                              
684     if (h->ov_fb.capability & V4L2_FBUF_CAP_LI    
685         h->ov_win.fmt.win.clips      = h->ov_c    
686         h->ov_win.fmt.win.clipcount  = count;     
687                                                   
688         for (i = 0; i < count; i++) {             
689             h->ov_clips[i].next = (i+1 == coun    
690             h->ov_clips[i].c.left   = oc[i].x1    
691             h->ov_clips[i].c.top    = oc[i].y1    
692             h->ov_clips[i].c.width  = oc[i].x2    
693             h->ov_clips[i].c.height = oc[i].y2    
694         }                                         
695     }                                             
696 #if 0                                             
697     if (h->ov_fb.flags & V4L2_FBUF_FLAG_CHROMA    
698         h->ov_win.chromakey  = 0;    /* FIXME     
699     }                                             
700 #endif                                            
701     rc = xioctl(h->fd, VIDIOC_S_FMT, &h->ov_wi    
702                                                   
703     h->ov_enabled = (0 == rc) ? 1 : 0;            
704     h->ov_on      = (0 == rc) ? 1 : 0;            
705     xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0    
706                                                   
707     return 0;                                     
708 }                                                 
709                                                   
710 /* -------------------------------------------    
711 /* capture helpers                                
712                                                   
713 static int                                        
714 v4l2_queue_buffer(struct v4l2_handle *h)          
715 {                                                 
716     int frame = h->queue % h->reqbufs.count;      
717     int rc;                                       
718                                                   
719     if (0 != h->buf_me[frame].refcount) {         
720         if (0 != h->queue - h->waiton)            
721             return -1;                            
722         fprintf(stderr,"v4l2: waiting for a fr    
723         ng_waiton_video_buf(h->buf_me+frame);     
724     }                                             
725                                                   
726     rc = xioctl(h->fd,VIDIOC_QBUF,&h->buf_v4l2    
727     if (0 == rc)                                  
728         h->queue++;                               
729     return rc;                                    
730 }                                                 
731                                                   
732 static void                                       
733 v4l2_queue_all(struct v4l2_handle *h)             
734 {                                                 
735     for (;;) {                                    
736         if (h->queue - h->waiton >= h->reqbufs    
737             return;                               
738         if (0 != v4l2_queue_buffer(h))            
739             return;                               
740     }                                             
741 }                                                 
742                                                   
743 static int                                        
744 v4l2_waiton(struct v4l2_handle *h)                
745 {                                                 
746     struct v4l2_buffer buf;                       
747     struct timeval tv;                            
748     fd_set rdset;                                 
749                                                   
750     /* wait for the next frame */                 
751  again:                                           
752     tv.tv_sec  = 5;                               
753     tv.tv_usec = 0;                               
754     FD_ZERO(&rdset);                              
755     FD_SET(h->fd, &rdset);                        
756     switch (select(h->fd + 1, &rdset, NULL, NU    
757     case -1:                                      
758         if (EINTR == errno)                       
759             goto again;                           
760         perror("v4l2: select");                   
761         return -1;                                
762     case  0:                                      
763         fprintf(stderr,"v4l2: oops: select tim    
764         return -1;                                
765     }                                             
766                                                   
767     /* get it */                                  
768     memset(&buf,0,sizeof(buf));                   
769     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;       
770     if (-1 == xioctl(h->fd,VIDIOC_DQBUF,&buf,     
771         return -1;                                
772     h->waiton++;                                  
773     h->buf_v4l2[buf.index] = buf;                 
774                                                   
775 #if 0                                             
776     if (1) {                                      
777         /* for driver debugging */                
778         static const char *fn[] = {               
779                 "any", "none", "top", "bottom"    
780                 "interlaced", "tb", "bt", "alt    
781         };                                        
782         static struct timeval last;               
783         signed long  diff;                        
784                                                   
785         diff  = (buf.timestamp.tv_sec - last.t    
786         diff += buf.timestamp.tv_usec - last.t    
787         fprintf(stderr,"\tdiff %6.1f ms  buf %    
788                 diff/1000.0, buf.index, buf.fi    
789         last = buf.timestamp;                     
790     }                                             
791 #endif                                            
792                                                   
793     return buf.index;                             
794 }                                                 
795                                                   
796 static int                                        
797 v4l2_start_streaming(struct v4l2_handle *h, in    
798 {                                                 
799     int disable_overlay = 0;                      
800     unsigned int i;                               
801                                                   
802     /* setup buffers */                           
803     h->reqbufs.count  = buffers;                  
804     h->reqbufs.type   = V4L2_BUF_TYPE_VIDEO_CA    
805     h->reqbufs.memory = V4L2_MEMORY_MMAP;         
806     if (-1 == xioctl(h->fd, VIDIOC_REQBUFS, &h    
807         return -1;                                
808     for (i = 0; i < h->reqbufs.count; i++) {      
809         h->buf_v4l2[i].index  = i;                
810         h->buf_v4l2[i].type   = V4L2_BUF_TYPE_    
811         h->buf_v4l2[i].memory = V4L2_MEMORY_MM    
812         if (-1 == xioctl(h->fd, VIDIOC_QUERYBU    
813             return -1;                            
814         h->buf_me[i].fmt  = h->fmt_me;            
815         h->buf_me[i].size = h->buf_me[i].fmt.b    
816             h->buf_me[i].fmt.height;              
817         h->buf_me[i].data = mmap(NULL, h->buf_    
818                                  PROT_READ | P    
819                                  h->fd, h->buf    
820         if (MAP_FAILED == h->buf_me[i].data) {    
821             perror("mmap");                       
822             return -1;                            
823         }                                         
824         if (ng_debug)                             
825             print_bufinfo(&h->buf_v4l2[i]);       
826     }                                             
827                                                   
828     /* queue up all buffers */                    
829     v4l2_queue_all(h);                            
830                                                   
831  try_again:                                       
832     /* turn off preview (if needed) */            
833     if (disable_overlay) {                        
834         h->ov_on = 0;                             
835         xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_o    
836         if (ng_debug)                             
837             fprintf(stderr,"v4l2: overlay off     
838     }                                             
839                                                   
840     /* start capture */                           
841     if (-1 == xioctl(h->fd,VIDIOC_STREAMON,&h-    
842                      h->ov_on ? EBUSY : 0)) {     
843         if (h->ov_on && errno == EBUSY) {         
844             disable_overlay = 1;                  
845             goto try_again;                       
846         }                                         
847         return -1;                                
848     }                                             
849     return 0;                                     
850 }                                                 
851                                                   
852 static void                                       
853 v4l2_stop_streaming(struct v4l2_handle *h)        
854 {                                                 
855     unsigned int i;                               
856                                                   
857     /* stop capture */                            
858     if (-1 == ioctl(h->fd,VIDIOC_STREAMOFF,&h-    
859         perror("ioctl VIDIOC_STREAMOFF");         
860                                                   
861     /* free buffers */                            
862     for (i = 0; i < h->reqbufs.count; i++) {      
863         if (0 != h->buf_me[i].refcount)           
864             ng_waiton_video_buf(&h->buf_me[i])    
865         if (ng_debug)                             
866             print_bufinfo(&h->buf_v4l2[i]);       
867         if (-1 == munmap(h->buf_me[i].data,h->    
868             perror("munmap");                     
869     }                                             
870     h->queue = 0;                                 
871     h->waiton = 0;                                
872                                                   
873     /* turn on preview (if needed) */             
874     if (h->ov_on != h->ov_enabled) {              
875         h->ov_on = h->ov_enabled;                 
876         xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_o    
877         if (ng_debug)                             
878             fprintf(stderr,"v4l2: overlay on (    
879     }                                             
880 }                                                 
881                                                   
882 /* -------------------------------------------    
883 /* capture interface                              
884                                                   
885 /* set capture parameters */                      
886 static int                                        
887 v4l2_setformat(void *handle, struct ng_video_f    
888 {                                                 
889     struct v4l2_handle *h = handle;               
890                                                   
891     h->fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAP    
892     h->fmt_v4l2.fmt.pix.pixelformat  = xawtv_p    
893     h->fmt_v4l2.fmt.pix.width        = fmt->wi    
894     h->fmt_v4l2.fmt.pix.height       = fmt->he    
895     h->fmt_v4l2.fmt.pix.field        = V4L2_FI    
896     //h->fmt_v4l2.fmt.pix.field        = V4L2_    
897     if (fmt->bytesperline != fmt->width * ng_v    
898         h->fmt_v4l2.fmt.pix.bytesperline = fmt    
899     else                                          
900         h->fmt_v4l2.fmt.pix.bytesperline = 0;     
901                                                   
902     if (-1 == xioctl(h->fd, VIDIOC_S_FMT, &h->    
903         return -1;                                
904     if (h->fmt_v4l2.fmt.pix.pixelformat != xaw    
905         return -1;                                
906     fmt->width        = h->fmt_v4l2.fmt.pix.wi    
907     fmt->height       = h->fmt_v4l2.fmt.pix.he    
908     fmt->bytesperline = h->fmt_v4l2.fmt.pix.by    
909     if (0 == fmt->bytesperline)                   
910         fmt->bytesperline = fmt->width * ng_vf    
911     h->fmt_me = *fmt;                             
912     if (ng_debug)                                 
913         fprintf(stderr,"v4l2: new capture para    
914                 fmt->width,fmt->height,           
915                 h->fmt_v4l2.fmt.pix.pixelforma    
916                 (h->fmt_v4l2.fmt.pix.pixelform    
917                 (h->fmt_v4l2.fmt.pix.pixelform    
918                 (h->fmt_v4l2.fmt.pix.pixelform    
919                 h->fmt_v4l2.fmt.pix.sizeimage)    
920     return 0;                                     
921 }                                                 
922                                                   
923 /* start/stop video */                            
924 static int                                        
925 v4l2_startvideo(void *handle, int fps, unsigne    
926 {                                                 
927     struct v4l2_handle *h = handle;               
928                                                   
929     if (0 != h->fps)                              
930         fprintf(stderr,"v4l2_startvideo: oops:    
931     h->fps = fps;                                 
932     h->first = 1;                                 
933     h->start = 0;                                 
934                                                   
935     if (h->cap.capabilities & V4L2_CAP_STREAMI    
936         return v4l2_start_streaming(h,buffers)    
937     return 0;                                     
938 }                                                 
939                                                   
940 static void                                       
941 v4l2_stopvideo(void *handle)                      
942 {                                                 
943     struct v4l2_handle *h = handle;               
944                                                   
945     if (0 == h->fps)                              
946         fprintf(stderr,"v4l2_stopvideo: oops:     
947     h->fps = 0;                                   
948                                                   
949     if (h->cap.capabilities & V4L2_CAP_STREAMI    
950         v4l2_stop_streaming(h);                   
951 }                                                 
952                                                   
953 /* read images */                                 
954 static struct ng_video_buf*                       
955 v4l2_nextframe(void *handle)                      
956 {                                                 
957     struct v4l2_handle *h = handle;               
958     struct ng_video_buf *buf = NULL;              
959     int rc,size,frame = 0;                        
960                                                   
961     if (h->cap.capabilities & V4L2_CAP_STREAMI    
962         v4l2_queue_all(h);                        
963         frame = v4l2_waiton(h);                   
964         if (-1 == frame)                          
965             return NULL;                          
966         h->buf_me[frame].refcount++;              
967         buf = &h->buf_me[frame];                  
968         memset(&buf->info,0,sizeof(buf->info))    
969         buf->info.ts = ng_tofday_to_timestamp(    
970     } else {                                      
971         size = h->fmt_me.bytesperline * h->fmt    
972         buf = ng_malloc_video_buf(&h->fmt_me,s    
973         rc = read(h->fd,buf->data,size);          
974         if (rc != size) {                         
975             if (-1 == rc) {                       
976                 perror("v4l2: read");             
977             } else {                              
978                 fprintf(stderr, "v4l2: read: r    
979             }                                     
980             ng_release_video_buf(buf);            
981             return NULL;                          
982         }                                         
983         memset(&buf->info,0,sizeof(buf->info))    
984         buf->info.ts = ng_get_timestamp();        
985     }                                             
986                                                   
987     if (h->first) {                               
988         h->first = 0;                             
989         h->start = buf->info.ts;                  
990         if (ng_debug)                             
991             fprintf(stderr,"v4l2: start ts=%ll    
992     }                                             
993     buf->info.ts -= h->start;                     
994     return buf;                                   
995 }                                                 
996                                                   
997 static struct ng_video_buf*                       
998 v4l2_getimage(void *handle)                       
999 {                                                 
1000     struct v4l2_handle *h = handle;              
1001     struct ng_video_buf *buf;                    
1002     int size,frame,rc;                           
1003                                                  
1004     size = h->fmt_me.bytesperline * h->fmt_me    
1005     buf = ng_malloc_video_buf(&h->fmt_me,size    
1006     if (h->cap.capabilities & V4L2_CAP_READWR    
1007         rc = read(h->fd,buf->data,size);         
1008         if (-1 == rc  &&  EBUSY == errno  &&     
1009             h->ov_on = 0;                        
1010             xioctl(h->fd, VIDIOC_OVERLAY, &h-    
1011             rc = read(h->fd,buf->data,size);     
1012             h->ov_on = 1;                        
1013             xioctl(h->fd, VIDIOC_OVERLAY, &h-    
1014         }                                        
1015         if (rc != size) {                        
1016             if (-1 == rc) {                      
1017                 perror("v4l2: read");            
1018             } else {                             
1019                 fprintf(stderr, "v4l2: read:     
1020             }                                    
1021             ng_release_video_buf(buf);           
1022             return NULL;                         
1023         }                                        
1024     } else {                                     
1025         if (-1 == v4l2_start_streaming(h,1))     
1026             v4l2_stop_streaming(h);              
1027             return NULL;                         
1028         }                                        
1029         frame = v4l2_waiton(h);                  
1030         if (-1 == frame) {                       
1031             v4l2_stop_streaming(h);              
1032             return NULL;                         
1033         }                                        
1034         memcpy(buf->data,h->buf_me[0].data,si    
1035         v4l2_stop_streaming(h);                  
1036     }                                            
1037     return buf;                                  
1038 }                                                
1039                                                  
1040 /* ------------------------------------------    
1041                                                  
1042 extern void ng_plugin_init(void);                
1043 void ng_plugin_init(void)                        
1044 {                                                
1045     ng_vid_driver_register(NG_PLUGIN_MAGIC,__    
1046 }                                                
1047                                                  
  This page was automatically generated by the LXR engine.