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 ]
  1 /*
  2  * interface to the bsd bktr driver
  3  *
  4  *   (c) 2000,01 Gerd Knorr <kraxel@bytesex.org>
  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 <pthread.h>
 18 #include <sys/types.h>
 19 #include <sys/time.h>
 20 #include <sys/ioctl.h>
 21 #include <sys/stat.h>
 22 #include <sys/mman.h>
 23 
 24 #ifdef HAVE_DEV_IC_BT8XX_H
 25 # include <dev/ic/bt8xx.h>
 26 #endif
 27 #ifdef HAVE_MACHINE_IOCTL_BT848_H
 28 # include <machine/ioctl_bt848.h>
 29 # include <machine/ioctl_meteor.h>
 30 #endif
 31 
 32 #include "grab-ng.h"
 33 
 34 /* ---------------------------------------------------------------------- */
 35 /* global variables                                                       */
 36 
 37 struct bsd_handle {
 38     int fd;
 39     int tfd;
 40 
 41     /* formats */
 42     int                     pf_count;
 43     struct meteor_pixfmt    pf[64];
 44     int                     xawtv2pf[VIDEO_FMT_COUNT];
 45     unsigned char           *map;
 46 
 47     /* attributes */
 48     int muted;
 49     struct ng_attribute     *attr;
 50     
 51     /* overlay */
 52     struct meteor_video     fb,pos;
 53     struct meteor_geomet    ovgeo;
 54     struct meteor_pixfmt    *ovfmt;
 55     struct bktr_clip        clip[BT848_MAX_CLIP_NODE];
 56     int                     ov_enabled,ov_on;
 57 
 58     /* capture */
 59     int                     fps;
 60     long long               start;
 61     struct ng_video_fmt     fmt;
 62     struct meteor_video     nofb;
 63     struct meteor_geomet    capgeo;
 64     struct meteor_pixfmt    *capfmt;
 65     struct bktr_clip        noclip[BT848_MAX_CLIP_NODE];
 66 };
 67 
 68 /* ---------------------------------------------------------------------- */
 69 /* prototypes                                                             */
 70 
 71 /* open/close */
 72 static void*   bsd_open(char *device);
 73 static int     bsd_close(void *handle);
 74 
 75 /* attributes */
 76 static int     bsd_flags(void *handle);
 77 static struct ng_attribute* bsd_attrs(void *handle);
 78 static int     bsd_read_attr(struct ng_attribute*);
 79 static void    bsd_write_attr(struct ng_attribute*, int val);
 80 
 81 static int   bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base);
 82 static int   bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y,
 83                          struct OVERLAY_CLIP *oc, int count, int aspect);
 84 
 85 /* capture */
 86 static void catchsignal(int signal);
 87 static void siginit(void);
 88 static int bsd_setformat(void *handle, struct ng_video_fmt *fmt);
 89 static int bsd_startvideo(void *handle, int fps, unsigned int buffers);
 90 static void bsd_stopvideo(void *handle);
 91 static struct ng_video_buf* bsd_nextframe(void *handle);
 92 static struct ng_video_buf* bsd_getimage(void *handle);
 93 
 94 /* tuner */
 95 static unsigned long bsd_getfreq(void *handle);
 96 static void bsd_setfreq(void *handle, unsigned long freq);
 97 static int bsd_tuned(void *handle);
 98 
 99 struct ng_vid_driver bsd_driver = {
100     name:          "bktr",
101     open:          bsd_open,
102     close:         bsd_close,
103 
104     capabilities:  bsd_flags,
105     list_attrs:    bsd_attrs,
106 
107     setupfb:       bsd_setupfb,
108     overlay:       bsd_overlay,
109 
110     setformat:     bsd_setformat,
111     startvideo:    bsd_startvideo,
112     stopvideo:     bsd_stopvideo,
113     nextframe:     bsd_nextframe,
114     getimage:      bsd_getimage,
115     
116     getfreq:       bsd_getfreq,
117     setfreq:       bsd_setfreq,
118     is_tuned:      bsd_tuned,
119 };
120 
121 /* ---------------------------------------------------------------------- */
122 
123 static struct STRTAB inputs[] = {
124     {  0, "Television"   },
125     {  1, "Composite1"   },
126     {  2, "S-Video"      },
127     {  3, "CSVIDEO"      },
128     { -1, NULL }
129 };
130 static int inputs_map[] = {
131     METEOR_INPUT_DEV1,
132     METEOR_INPUT_DEV0,
133     METEOR_INPUT_DEV_SVIDEO,
134     METEOR_INPUT_DEV2,
135 };
136 
137 static struct STRTAB norms[] = {
138     {  0, "NTSC"      },
139     {  1, "NTSC-JP"   },
140     {  2, "PAL"       },
141     {  3, "PAL-M"     },
142     {  4, "PAL-N"     },
143     {  5, "SECAM"     },
144     {  6, "RSVD"      },
145     { -1, NULL }
146 };
147 static int norms_map[] = {
148     BT848_IFORM_F_NTSCM,
149     BT848_IFORM_F_NTSCJ,
150     BT848_IFORM_F_PALBDGHI,
151     BT848_IFORM_F_PALM,
152     BT848_IFORM_F_PALN,
153     BT848_IFORM_F_SECAM,
154     BT848_IFORM_F_RSVD,
155 };
156 
157 static struct STRTAB audio[] = {
158     {  0, "Tuner"   },
159     {  1, "Extern"   },
160     {  2, "Intern"      },
161     { -1, NULL }
162 };
163 static int audio_map[] = {
164     AUDIO_TUNER,
165     AUDIO_EXTERN,
166     AUDIO_INTERN,
167 };
168 
169 static struct ng_attribute bsd_attr[] = {
170     {
171         id:       ATTR_ID_COUNT+1,
172         name:     "audio",
173         type:     ATTR_TYPE_CHOICE,
174         choices:  audio,
175         read:     bsd_read_attr,
176         write:    bsd_write_attr,
177     },{
178         id:       ATTR_ID_NORM,
179         name:     "norm",
180         type:     ATTR_TYPE_CHOICE,
181         choices:  norms,
182         read:     bsd_read_attr,
183         write:    bsd_write_attr,
184     },{
185         id:       ATTR_ID_INPUT,
186         name:     "input",
187         type:     ATTR_TYPE_CHOICE,
188         choices:  inputs,
189         read:     bsd_read_attr,
190         write:    bsd_write_attr,
191     },{
192         id:       ATTR_ID_MUTE,
193         name:     "mute",
194         type:     ATTR_TYPE_BOOL,
195         read:     bsd_read_attr,
196         write:    bsd_write_attr,
197     },{
198         id:       ATTR_ID_HUE,
199         name:     "hue",
200         type:     ATTR_TYPE_INTEGER,
201         min:      BT848_HUEREGMIN,
202         max:      BT848_HUEREGMAX,
203         read:     bsd_read_attr,
204         write:    bsd_write_attr,
205     },{
206         id:       ATTR_ID_BRIGHT,
207         name:     "bright",
208         type:     ATTR_TYPE_INTEGER,
209         min:      BT848_BRIGHTREGMIN,
210         max:      BT848_BRIGHTREGMAX,
211         read:     bsd_read_attr,
212         write:    bsd_write_attr,
213     },{
214         id:       ATTR_ID_CONTRAST,
215         name:     "contrast",
216         type:     ATTR_TYPE_INTEGER,
217         min:      BT848_CONTRASTREGMIN,
218         max:      BT848_CONTRASTREGMAX,
219         read:     bsd_read_attr,
220         write:    bsd_write_attr,
221     },{
222         id:       ATTR_ID_COLOR,
223         name:     "color",
224         type:     ATTR_TYPE_INTEGER,
225         min:      BT848_CHROMAREGMIN,
226         max:      BT848_CHROMAREGMAX,
227         read:     bsd_read_attr,
228         write:    bsd_write_attr,
229     },{
230         /* end of list */
231     }
232 };
233 
234 static int single     = METEOR_CAP_SINGLE;
235 static int start      = METEOR_CAP_CONTINOUS;
236 static int stop       = METEOR_CAP_STOP_CONT;
237 static int signal_on  = SIGUSR1;
238 static int signal_off = METEOR_SIG_MODE_MASK;
239 
240 /* ---------------------------------------------------------------------- */
241 
242 #define PREFIX "bktr: ioctl: "
243 
244 static int
245 xioctl(int fd, int cmd, void *arg)
246 {
247     int rc;
248 
249     rc = ioctl(fd,cmd,arg);
250     if (0 == rc && ng_debug < 2)
251         return 0;
252     switch (cmd) {
253     case METEORSVIDEO:
254     {
255         struct meteor_video *a = arg;
256 
257         fprintf(stderr,PREFIX "METEORSVIDEO(addr=0x%08lx,width=%ld,bank=%ld,ram=%ld)",
258                 a->addr,a->width,a->banksize,a->ramsize);
259         break;
260     }
261     case METEORSETGEO:
262     {
263         struct meteor_geomet *a = arg;
264 
265         fprintf(stderr,PREFIX "METEORSETGEO(%dx%d,frames=%d,oformat=0x%lx)",
266                 a->columns,a->rows,a->frames,a->oformat);
267         break;
268     }
269     case METEORSACTPIXFMT:
270     {
271         struct meteor_pixfmt *a = arg;
272 
273         fprintf(stderr,PREFIX "METEORSACTPIXFMT(%d,type=%d,bpp=%d,"
274                 "masks=0x%lx/0x%lx/0x%lx,sb=%d,ss=%d)",
275                 a->index,a->type,a->Bpp,a->masks[0],a->masks[1],a->masks[2],
276                 a->swap_bytes,a->swap_shorts);
277         break;
278     }
279     case METEORCAPTUR:
280     {
281         int *a = arg;
282 
283         fprintf(stderr,PREFIX "METEORCAPTUR(%d)",*a);
284         break;
285     }
286     case METEORSSIGNAL:
287     {
288         int *a = arg;
289 
290         fprintf(stderr,PREFIX "METEORSSIGNAL(0x%x)",*a);
291         break;
292     }
293     case BT848SCLIP:
294     {
295         fprintf(stderr,PREFIX "BT848SCLIP");
296         break;
297     }
298     default:
299         fprintf(stderr,PREFIX "UNKNOWN(cmd=0x%x)",cmd);
300         break;
301     }
302     fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno));
303     return rc;
304 }
305 
306 /* ---------------------------------------------------------------------- */
307 
308 static void
309 bsd_print_format(struct meteor_pixfmt *pf, int format)
310 {
311     switch (pf->type) {
312     case METEOR_PIXTYPE_RGB:
313         fprintf(stderr,
314                 "bktr: pf: rgb bpp=%d mask=%ld,%ld,%ld",
315                 pf->Bpp,pf->masks[0],pf->masks[1],pf->masks[2]);
316         break;
317     case METEOR_PIXTYPE_YUV:
318         fprintf(stderr,"bktr: pf: yuv h422 v111 (planar)");
319         break;
320     case METEOR_PIXTYPE_YUV_PACKED:
321         fprintf(stderr,"bktr: pf: yuyv h422 v111 (packed)");
322         break;
323     case METEOR_PIXTYPE_YUV_12:
324         fprintf(stderr,"bktr: pf: yuv h422 v422 (planar)");
325         break;
326     default:
327         fprintf(stderr,"bktr: pf: unknown");
328     }
329     fprintf(stderr," sbytes=%d sshorts=%d (fmt=%d)\n",
330             pf->swap_bytes,pf->swap_shorts,format);
331 }
332 
333 /* ---------------------------------------------------------------------- */
334 
335 static void*
336 bsd_open(char *filename)
337 {
338     struct bsd_handle *h;
339     int format,i;
340 
341     h = malloc(sizeof(*h));
342     if (NULL == h)
343         return NULL;
344     memset(h,0,sizeof(*h));
345     
346     if (-1 == (h->fd = open(filename,O_RDONLY))) {
347         fprintf(stderr,"bktr: open %s: %s\n", filename,strerror(errno));
348         goto err;
349     }
350 
351     /* video formats */
352     for (format = 0; format < VIDEO_FMT_COUNT; format++)
353         h->xawtv2pf[format] = -1;
354 
355     for (h->pf_count = 0; h->pf_count < 64; h->pf_count++) {
356         h->pf[h->pf_count].index = h->pf_count;
357         if (-1 == ioctl(h->fd, METEORGSUPPIXFMT,h->pf+h->pf_count)) {
358             if (ng_debug)
359                 perror("bktr: ioctl METEORGSUPPIXFMT");
360             if (0 == h->pf_count)
361                 goto err;
362             break;
363         }
364         format = -1;
365         switch (h->pf[h->pf_count].type) {
366         case METEOR_PIXTYPE_RGB:
367             switch(h->pf[h->pf_count].masks[0]) {
368             case 31744: /* 15 bpp */
369                 format = h->pf[h->pf_count].swap_bytes
370                     ? VIDEO_RGB15_LE : VIDEO_RGB15_BE;
371                 break;
372             case 63488: /* 16 bpp */
373                 format = h->pf[h->pf_count].swap_bytes
374                     ? VIDEO_RGB16_LE : VIDEO_RGB16_BE;
375                 break;
376             case 16711680: /* 24/32 bpp */
377                 if (h->pf[h->pf_count].Bpp == 3 &&
378                     h->pf[h->pf_count].swap_bytes == 1) {
379                     format = VIDEO_BGR24;
380                 } else if (h->pf[h->pf_count].Bpp == 4 &&
381                            h->pf[h->pf_count].swap_bytes == 1 &&
382                            h->pf[h->pf_count].swap_shorts == 1) {
383                     format = VIDEO_BGR32;
384                 } else if (h->pf[h->pf_count].Bpp == 4 &&
385                            h->pf[h->pf_count].swap_bytes == 0 &&
386                            h->pf[h->pf_count].swap_shorts == 0) {
387                     format = VIDEO_RGB32;
388                 }
389             }
390             break;
391         case METEOR_PIXTYPE_YUV:
392             format = VIDEO_YUV422P;
393             break;
394 #if 0
395         case METEOR_PIXTYPE_YUV_PACKED:
396             format = VIDEO_YUV422;
397             h->pf[h->pf_count].swap_shorts = 0; /* seems not to work */
398             break;
399 #endif
400         case METEOR_PIXTYPE_YUV_12:
401         case METEOR_PIXTYPE_YUV_PACKED:
402             /* nothing */
403             break;
404         }
405         if (-1 != format)
406             h->xawtv2pf[format] = h->pf_count;
407 
408         if (ng_debug)
409           bsd_print_format(h->pf+h->pf_count,format);
410     }
411 
412     h->map = mmap(0,768*576*4, PROT_READ, MAP_SHARED, h->fd, 0);
413     if ((unsigned char*)-1 == h->map) {
414         perror("bktr: mmap");
415         h->map = NULL;
416     }
417 
418     if (-1 == (h->tfd = open("/dev/tuner0",O_RDONLY))) {
419         fprintf(stderr,"bktr: open %s: %s\n", "/dev/tuner0",strerror(errno));
420     }
421     siginit();
422 
423     h->attr = malloc(sizeof(bsd_attr));
424     memcpy(h->attr,bsd_attr,sizeof(bsd_attr));
425     for (i = 0; h->attr[i].name != NULL; i++)
426         h->attr[i].handle = h;
427 
428     return h;
429 
430  err:
431     if (-1 != h->fd)
432         close(h->fd);
433     if (-1 != h->tfd)
434         close(h->tfd);
435     if (h)
436         free(h);
437     return NULL;
438 }
439 
440 static int
441 bsd_close(void *handle)
442 {
443     struct bsd_handle *h = handle;
444 
445     if (ng_debug)
446         fprintf(stderr, "bktr: close\n");
447 
448     close(h->fd);
449     if (-1 != h->tfd)
450         close(h->tfd);
451     if (NULL != h->map)
452         munmap(h->map,768*576*4);
453     free(h);
454     return 0;
455 }
456 
457 static int bsd_flags(void *handle)
458 {
459     int ret = 0;
460 
461     ret |= CAN_OVERLAY;
462     ret |= CAN_CAPTURE;
463     ret |= CAN_TUNE;
464     return ret;
465 }
466 
467 static struct ng_attribute* bsd_attrs(void *handle)
468 {
469     struct bsd_handle *h = handle;
470 
471     return h->attr;
472 }
473 
474 /* ---------------------------------------------------------------------- */
475 
476 static int
477 bsd_get_range(int id, int *get, int *set)
478 {
479     switch (id) {
480     case ATTR_ID_HUE:
481         *get = BT848_GHUE;
482         *set = BT848_SHUE;
483         break;
484     case ATTR_ID_BRIGHT:
485         *get = BT848_GBRIG;
486         *set = BT848_SBRIG;
487         break;
488     case ATTR_ID_CONTRAST:
489         *get = BT848_GCONT;
490         *set = BT848_SCONT;
491         break;
492     case ATTR_ID_COLOR:
493         *get = BT848_GCSAT;
494         *set = BT848_SCSAT;
495         break;
496     default:
497         return -1;
498     }
499     return 0;
500 }
501 
502 static int bsd_read_attr(struct ng_attribute *attr)
503 {
504     struct bsd_handle *h = attr->handle;
505     int arg, get, set, i;
506     int value = -1;
507 
508     switch (attr->id) {
509     case ATTR_ID_NORM:
510         if (-1 != xioctl(h->fd,BT848GFMT,&arg))
511             for (i = 0; i < sizeof(norms_map)/sizeof(int); i++)
512                 if (arg == norms_map[i])
513                     value = i;
514         break;
515     case ATTR_ID_INPUT:
516         if (-1 != xioctl(h->fd,METEORGINPUT,&arg))
517             for (i = 0; i < sizeof(inputs_map)/sizeof(int); i++)
518                 if (arg == inputs_map[i])
519                     value = i;
520         break;
521     case ATTR_ID_MUTE:
522         if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg))
523             value = (arg == AUDIO_MUTE) ? 1 : 0;
524         break;
525     case ATTR_ID_HUE:
526     case ATTR_ID_BRIGHT:
527     case ATTR_ID_CONTRAST:
528     case ATTR_ID_COLOR:
529         bsd_get_range(attr->id,&get,&set);
530         if (-1 != xioctl(h->tfd,get,&arg))
531             value = arg;
532         break;
533     case ATTR_ID_COUNT+1: /* AUDIO */
534         if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg))
535             for (i = 0; i < sizeof(audio_map)/sizeof(int); i++)
536                 if (arg == audio_map[i])
537                     value = i;
538         break;
539     default:
540         break;
541     }
542     return value;
543 }
544 
545 static void bsd_write_attr(struct ng_attribute *attr, int value)
546 {
547     struct bsd_handle *h = attr->handle;
548     int arg, get, set;
549 
550     switch (attr->id) {
551     case ATTR_ID_NORM:
552         xioctl(h->fd,BT848SFMT,&norms_map[value]);
553         break;
554     case ATTR_ID_INPUT:
555         xioctl(h->fd,METEORSINPUT,&inputs_map[value]);
556         break;
557     case ATTR_ID_MUTE:
558         h->muted = value;
559         arg = h->muted ? AUDIO_MUTE : AUDIO_UNMUTE;
560         xioctl(h->tfd, BT848_SAUDIO, &arg);
561         break;
562     case ATTR_ID_HUE:
563     case ATTR_ID_BRIGHT:
564     case ATTR_ID_CONTRAST:
565     case ATTR_ID_COLOR:
566         bsd_get_range(attr->id,&get,&set);
567         arg = value;
568         xioctl(h->tfd,set,&arg);
569         break;
570     case ATTR_ID_COUNT+1: /* audio */
571         xioctl(h->tfd, BT848_SAUDIO,&audio_map[value]);
572         break;
573     default:
574         break;
575     }
576 }
577 
578 static unsigned long bsd_getfreq(void *handle)
579 {
580     struct bsd_handle *h = handle;
581     unsigned long freq = 0;
582 
583     if (-1 == ioctl(h->tfd, TVTUNER_GETFREQ, &freq))
584         perror("bktr: ioctl TVTUNER_GETFREQ");
585     if (ng_debug)
586         fprintf(stderr,"bktr: get freq: %.3f\n",(float)freq/16);
587     return freq;
588 }
589 
590 static void bsd_setfreq(void *handle, unsigned long freq)
591 {
592     struct bsd_handle *h = handle;
593 
594     if (ng_debug)
595         fprintf(stderr,"bktr: set freq: %.3f\n",(float)freq/16);
596     if (-1 == ioctl(h->tfd, TVTUNER_SETFREQ, &freq))
597         perror("bktr: ioctl TVTUNER_SETFREQ");
598 }
599 
600 static int bsd_tuned(void *handle)
601 {
602     return 0;
603 }
604 
605 /* ---------------------------------------------------------------------- */
606 /* overlay                                                                */
607 
608 static void
609 set_overlay(struct bsd_handle *h, int state)
610 {
611     if (h->ov_on == state)
612         return;
613     h->ov_on = state;
614     
615     if (state) {
616         /* enable */
617         xioctl(h->fd, METEORSVIDEO, &h->pos);
618         xioctl(h->fd, METEORSETGEO, &h->ovgeo);
619         xioctl(h->fd, METEORSACTPIXFMT, h->ovfmt);
620         xioctl(h->fd, BT848SCLIP, &h->clip);
621         xioctl(h->fd, METEORCAPTUR, &start);
622     } else {
623         /* disable */
624         xioctl(h->fd, METEORCAPTUR, &stop);
625     }
626 }
627 
628 static int bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base)
629 {
630     struct bsd_handle *h = handle;
631 
632     h->fb.addr     = (long)base;
633     h->fb.width    = fmt->bytesperline;
634     h->fb.banksize = fmt->bytesperline * fmt->height;
635     h->fb.ramsize  = fmt->bytesperline * fmt->height / 1024;
636     return 0;
637 }
638 
639 static int bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y,
640                        struct OVERLAY_CLIP *oc, int count, int aspect)
641 {
642     struct bsd_handle *h = handle;
643     int i,win_width,win_height,win_x,win_y;
644 
645     h->ov_enabled = 0;
646     set_overlay(h,h->ov_enabled);
647     if (NULL == fmt)
648         return 0;
649 
650     if (-1 == h->xawtv2pf[fmt->fmtid])
651         return -1;
652 
653     /* fixups - fixme: no fixed max size */
654     win_x      = x;
655     win_y      = y;
656     win_width  = fmt->width;
657     win_height = fmt->height;
658     if (win_width > 768) {
659         win_width = 768;
660         win_x += (fmt->width - win_width)/2;
661     }
662     if (win_height > 576) {
663         win_height = 576;
664         win_y +=  (fmt->height - win_height)/2;
665     }
666     if (aspect)
667         ng_ratio_fixup(&win_width,&win_height,&win_x,&win_y);
668     ng_check_clipping(win_width, win_height,
669                       x - win_x, y - win_y,
670                       oc, &count);
671 
672     /* fill data */
673     h->pos           = h->fb;
674     h->pos.addr     += win_y*h->pos.width;
675     h->pos.addr     += win_x*ng_vfmt_to_depth[fmt->fmtid]>>3;
676     h->ovgeo.rows    = win_height;
677     h->ovgeo.columns = win_width;
678     h->ovgeo.frames  = 1;
679     h->ovgeo.oformat = 0x10000;
680 
681     if (ng_debug)
682         fprintf(stderr,"bktr: overlay win=%dx%d+%d+%d, %d clips\n",
683                 win_width,win_height,win_x,win_y,count);
684 
685     /* clipping */
686     memset(h->clip,0,sizeof(h->clip));
687     for (i = 0; i < count; i++) {
688 #if 0
689         /* This way it *should* work IMHO ... */
690         h->clip[i].x_min      = oc[i].x1;
691         h->clip[i].x_max      = oc[i].x2;
692         h->clip[i].y_min      = oc[i].y1;
693         h->clip[i].y_max      = oc[i].y2;
694 #else
695         /* This way it does work.  Sort of ... */
696         h->clip[i].x_min      = (oc[i].y1) >> 1;
697         h->clip[i].x_max      = (oc[i].y2) >> 1;
698         h->clip[i].y_min      = oc[i].x1;
699         h->clip[i].y_max      = oc[i].x2;
700 #endif
701     }
702     h->ovfmt = h->pf+h->xawtv2pf[fmt->fmtid];
703 
704     h->ov_enabled = 1;
705     set_overlay(h,h->ov_enabled);
706     return 0;
707 }
708 
709 /* ---------------------------------------------------------------------- */
710 /* capture                                                                */
711 
712 static void
713 catchsignal(int signal)
714 {
715     if (signal == SIGUSR1  &&  ng_debug > 1)
716         fprintf(stderr,"bktr: sigusr1\n");
717     if (signal == SIGALRM)
718         fprintf(stderr,"bktr: sigalrm\n");
719 }
720 
721 static void
722 siginit(void)
723 {
724     struct sigaction act,old;
725 
726     memset(&act,0,sizeof(act));
727     sigemptyset(&act.sa_mask);
728     act.sa_handler  = catchsignal;
729     sigaction(SIGUSR1,&act,&old);
730     sigaction(SIGALRM,&act,&old);
731 }
732 
733 static int bsd_setformat(void *handle, struct ng_video_fmt *fmt)
734 {
735     struct bsd_handle *h = handle;
736 
737     if (-1 == h->xawtv2pf[fmt->fmtid])
738         return -1;
739 
740     if (fmt->width > 768)
741         fmt->width = 768;
742     if (fmt->height > 576)
743         fmt->height = 576;
744     fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;
745 
746     h->capfmt = h->pf+h->xawtv2pf[fmt->fmtid];
747     h->capgeo.rows    = fmt->height;
748     h->capgeo.columns = fmt->width;
749     h->capgeo.frames  = 1;
750     h->capgeo.oformat = 0 /* FIXME */;
751     if (fmt->height <= 320)
752         h->capgeo.oformat |= METEOR_GEO_ODD_ONLY;
753     h->fmt = *fmt;
754     return 0;
755 }
756 
757 static void
758 set_capture(struct bsd_handle *h, int state)
759 {
760     if (state) {
761         /* enable */
762         xioctl(h->fd, METEORSVIDEO, &h->nofb);
763         xioctl(h->fd, METEORSETGEO, &h->capgeo);
764         xioctl(h->fd, METEORSACTPIXFMT, h->capfmt);
765         xioctl(h->fd, BT848SCLIP, &h->noclip);
766     } else {
767         /* disable */
768         xioctl(h->fd, METEORCAPTUR, &stop);
769     }
770 }
771 
772 static int bsd_startvideo(void *handle, int fps, unsigned int buffers)
773 {
774     struct bsd_handle *h = handle;
775 
776     set_overlay(h,0);
777     h->fps = fps;
778     h->start = ng_get_timestamp();
779     set_capture(h,1);
780     xioctl(h->fd, METEORSSIGNAL, &signal_on);
781     xioctl(h->fd, METEORCAPTUR, &start);
782     return 0;
783 }
784 
785 static void bsd_stopvideo(void *handle)
786 {
787     struct bsd_handle *h = handle;
788 
789     h->fps = 0;
790     set_capture(h,0);
791     xioctl(h->fd, METEORCAPTUR, &stop);
792     xioctl(h->fd, METEORSSIGNAL, &signal_off);
793     set_overlay(h,h->ov_enabled);
794 }
795 
796 static struct ng_video_buf* bsd_nextframe(void *handle)
797 {
798     struct bsd_handle *h = handle;
799     struct ng_video_buf *buf;
800     int size;
801     sigset_t sa_mask;
802 
803     size = h->fmt.bytesperline * h->fmt.height;
804     buf = ng_malloc_video_buf(&h->fmt,size);
805 
806     alarm(1);
807     sigfillset(&sa_mask);
808     sigdelset(&sa_mask,SIGUSR1);
809     sigdelset(&sa_mask,SIGALRM);
810     sigsuspend(&sa_mask);
811     alarm(0);
812 
813     memcpy(buf->data,h->map,size);
814     buf->info.ts = ng_get_timestamp() - h->start;
815     return buf;
816 }
817 
818 static struct ng_video_buf* bsd_getimage(void *handle)
819 {
820     struct bsd_handle *h = handle;
821     struct ng_video_buf *buf;
822     int size;
823 
824     set_overlay(h,0);
825     set_capture(h,1);
826 
827     size = h->fmt.bytesperline * h->fmt.height;
828     buf = ng_malloc_video_buf(&h->fmt,size);
829     xioctl(h->fd, METEORCAPTUR, &single);
830     memcpy(buf->data,h->map,size);
831 
832     set_capture(h,0);
833     set_overlay(h,h->ov_enabled);
834 
835     return buf;
836 }
837 
838 /* ---------------------------------------------------------------------- */
839 
840 extern void ng_plugin_init(void);
841 void ng_plugin_init(void)
842 {
843     ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&bsd_driver);
844 }
845 
  This page was automatically generated by the LXR engine.