📄 drv0-bsd.c
字号:
memcpy(h->attr,bsd_attr,sizeof(bsd_attr)); for (i = 0; h->attr[i].name != NULL; i++) h->attr[i].handle = h; return h; err: if (-1 != h->fd) close(h->fd); if (-1 != h->tfd) close(h->tfd); if (h) free(h); return NULL;}static intbsd_close(void *handle){ struct bsd_handle *h = handle; if (ng_debug) fprintf(stderr, "bktr: close\n"); close(h->fd); if (-1 != h->tfd) close(h->tfd); if (NULL != h->map) munmap(h->map,768*576*4); free(h); return 0;}static int bsd_flags(void *handle){ int ret = 0; ret |= CAN_OVERLAY; ret |= CAN_CAPTURE; ret |= CAN_TUNE; return ret;}static struct ng_attribute* bsd_attrs(void *handle){ struct bsd_handle *h = handle; return h->attr;}/* ---------------------------------------------------------------------- */static intbsd_get_range(int id, int *get, int *set){ switch (id) { case ATTR_ID_HUE: *get = BT848_GHUE; *set = BT848_SHUE; break; case ATTR_ID_BRIGHT: *get = BT848_GBRIG; *set = BT848_SBRIG; break; case ATTR_ID_CONTRAST: *get = BT848_GCONT; *set = BT848_SCONT; break; case ATTR_ID_COLOR: *get = BT848_GCSAT; *set = BT848_SCSAT; break; default: return -1; } return 0;}static int bsd_read_attr(struct ng_attribute *attr){ struct bsd_handle *h = attr->handle; int arg, get, set, i; int value = -1; switch (attr->id) { case ATTR_ID_NORM: if (-1 != xioctl(h->fd,BT848GFMT,&arg)) for (i = 0; i < sizeof(norms_map)/sizeof(int); i++) if (arg == norms_map[i]) value = i; break; case ATTR_ID_INPUT: if (-1 != xioctl(h->fd,METEORGINPUT,&arg)) for (i = 0; i < sizeof(inputs_map)/sizeof(int); i++) if (arg == inputs_map[i]) value = i; break; case ATTR_ID_MUTE: if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg)) value = (arg == AUDIO_MUTE) ? 1 : 0; break; case ATTR_ID_HUE: case ATTR_ID_BRIGHT: case ATTR_ID_CONTRAST: case ATTR_ID_COLOR: bsd_get_range(attr->id,&get,&set); if (-1 != xioctl(h->tfd,get,&arg)) value = arg; break; case ATTR_ID_COUNT+1: /* AUDIO */ if (-1 != xioctl(h->tfd, BT848_GAUDIO, &arg)) for (i = 0; i < sizeof(audio_map)/sizeof(int); i++) if (arg == audio_map[i]) value = i; break; default: break; } return value;}static void bsd_write_attr(struct ng_attribute *attr, int value){ struct bsd_handle *h = attr->handle; int arg, get, set; switch (attr->id) { case ATTR_ID_NORM: xioctl(h->fd,BT848SFMT,&norms_map[value]); break; case ATTR_ID_INPUT: xioctl(h->fd,METEORSINPUT,&inputs_map[value]); break; case ATTR_ID_MUTE: h->muted = value; arg = h->muted ? AUDIO_MUTE : AUDIO_UNMUTE; xioctl(h->tfd, BT848_SAUDIO, &arg); break; case ATTR_ID_HUE: case ATTR_ID_BRIGHT: case ATTR_ID_CONTRAST: case ATTR_ID_COLOR: bsd_get_range(attr->id,&get,&set); arg = value; xioctl(h->tfd,set,&arg); break; case ATTR_ID_COUNT+1: /* audio */ xioctl(h->tfd, BT848_SAUDIO,&audio_map[value]); break; default: break; }}static unsigned long bsd_getfreq(void *handle){ struct bsd_handle *h = handle; unsigned long freq = 0; if (-1 == ioctl(h->tfd, TVTUNER_GETFREQ, &freq)) perror("bktr: ioctl TVTUNER_GETFREQ"); if (ng_debug) fprintf(stderr,"bktr: get freq: %.3f\n",(float)freq/16); return freq;}static void bsd_setfreq(void *handle, unsigned long freq){ struct bsd_handle *h = handle; if (ng_debug) fprintf(stderr,"bktr: set freq: %.3f\n",(float)freq/16); if (-1 == ioctl(h->tfd, TVTUNER_SETFREQ, &freq)) perror("bktr: ioctl TVTUNER_SETFREQ");}static int bsd_tuned(void *handle){ return 0;}/* ---------------------------------------------------------------------- *//* overlay */static voidset_overlay(struct bsd_handle *h, int state){ if (h->ov_on == state) return; h->ov_on = state; if (state) { /* enable */ xioctl(h->fd, METEORSVIDEO, &h->pos); xioctl(h->fd, METEORSETGEO, &h->ovgeo); xioctl(h->fd, METEORSACTPIXFMT, h->ovfmt); xioctl(h->fd, BT848SCLIP, &h->clip); xioctl(h->fd, METEORCAPTUR, &start); } else { /* disable */ xioctl(h->fd, METEORCAPTUR, &stop); }}static int bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base){ struct bsd_handle *h = handle; h->fb.addr = (long)base; h->fb.width = fmt->bytesperline; h->fb.banksize = fmt->bytesperline * fmt->height; h->fb.ramsize = fmt->bytesperline * fmt->height / 1024; return 0;}static int bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect){ struct bsd_handle *h = handle; int i,win_width,win_height,win_x,win_y; h->ov_enabled = 0; set_overlay(h,h->ov_enabled); if (NULL == fmt) return 0; if (-1 == h->xawtv2pf[fmt->fmtid]) return -1; /* fixups - fixme: no fixed max size */ win_x = x; win_y = y; win_width = fmt->width; win_height = fmt->height; if (win_width > 768) { win_width = 768; win_x += (fmt->width - win_width)/2; } if (win_height > 576) { win_height = 576; win_y += (fmt->height - win_height)/2; } if (aspect) ng_ratio_fixup(&win_width,&win_height,&win_x,&win_y); ng_check_clipping(win_width, win_height, x - win_x, y - win_y, oc, &count); /* fill data */ h->pos = h->fb; h->pos.addr += win_y*h->pos.width; h->pos.addr += win_x*ng_vfmt_to_depth[fmt->fmtid]>>3; h->ovgeo.rows = win_height; h->ovgeo.columns = win_width; h->ovgeo.frames = 1; h->ovgeo.oformat = 0x10000; if (ng_debug) fprintf(stderr,"bktr: overlay win=%dx%d+%d+%d, %d clips\n", win_width,win_height,win_x,win_y,count); /* clipping */ memset(h->clip,0,sizeof(h->clip)); for (i = 0; i < count; i++) {#if 0 /* This way it *should* work IMHO ... */ h->clip[i].x_min = oc[i].x1; h->clip[i].x_max = oc[i].x2; h->clip[i].y_min = oc[i].y1; h->clip[i].y_max = oc[i].y2;#else /* This way it does work. Sort of ... */ h->clip[i].x_min = (oc[i].y1) >> 1; h->clip[i].x_max = (oc[i].y2) >> 1; h->clip[i].y_min = oc[i].x1; h->clip[i].y_max = oc[i].x2;#endif } h->ovfmt = h->pf+h->xawtv2pf[fmt->fmtid]; h->ov_enabled = 1; set_overlay(h,h->ov_enabled); return 0;}/* ---------------------------------------------------------------------- *//* capture */static voidcatchsignal(int signal){ if (signal == SIGUSR1 && ng_debug > 1) fprintf(stderr,"bktr: sigusr1\n"); if (signal == SIGALRM) fprintf(stderr,"bktr: sigalrm\n");}static voidsiginit(void){ struct sigaction act,old; memset(&act,0,sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = catchsignal; sigaction(SIGUSR1,&act,&old); sigaction(SIGALRM,&act,&old);}static int bsd_setformat(void *handle, struct ng_video_fmt *fmt){ struct bsd_handle *h = handle; if (-1 == h->xawtv2pf[fmt->fmtid]) return -1; if (fmt->width > 768) fmt->width = 768; if (fmt->height > 576) fmt->height = 576; fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8; h->capfmt = h->pf+h->xawtv2pf[fmt->fmtid]; h->capgeo.rows = fmt->height; h->capgeo.columns = fmt->width; h->capgeo.frames = 1; h->capgeo.oformat = 0 /* FIXME */; if (fmt->height <= 320) h->capgeo.oformat |= METEOR_GEO_ODD_ONLY; h->fmt = *fmt; return 0;}static voidset_capture(struct bsd_handle *h, int state){ if (state) { /* enable */ xioctl(h->fd, METEORSVIDEO, &h->nofb); xioctl(h->fd, METEORSETGEO, &h->capgeo); xioctl(h->fd, METEORSACTPIXFMT, h->capfmt); xioctl(h->fd, BT848SCLIP, &h->noclip); } else { /* disable */ xioctl(h->fd, METEORCAPTUR, &stop); }}static int bsd_startvideo(void *handle, int fps, unsigned int buffers){ struct bsd_handle *h = handle; set_overlay(h,0); h->fps = fps; h->start = ng_get_timestamp(); set_capture(h,1); xioctl(h->fd, METEORSSIGNAL, &signal_on); xioctl(h->fd, METEORCAPTUR, &start); return 0;}static void bsd_stopvideo(void *handle){ struct bsd_handle *h = handle; h->fps = 0; set_capture(h,0); xioctl(h->fd, METEORCAPTUR, &stop); xioctl(h->fd, METEORSSIGNAL, &signal_off); set_overlay(h,h->ov_enabled);}static struct ng_video_buf* bsd_nextframe(void *handle){ struct bsd_handle *h = handle; struct ng_video_buf *buf; int size; sigset_t sa_mask; size = h->fmt.bytesperline * h->fmt.height; buf = ng_malloc_video_buf(&h->fmt,size); alarm(1); sigfillset(&sa_mask); sigdelset(&sa_mask,SIGUSR1); sigdelset(&sa_mask,SIGALRM); sigsuspend(&sa_mask); alarm(0); memcpy(buf->data,h->map,size); buf->info.ts = ng_get_timestamp() - h->start; return buf;}static struct ng_video_buf* bsd_getimage(void *handle){ struct bsd_handle *h = handle; struct ng_video_buf *buf; int size; set_overlay(h,0); set_capture(h,1); size = h->fmt.bytesperline * h->fmt.height; buf = ng_malloc_video_buf(&h->fmt,size); xioctl(h->fd, METEORCAPTUR, &single); memcpy(buf->data,h->map,size); set_capture(h,0); set_overlay(h,h->ov_enabled); return buf;}/* ---------------------------------------------------------------------- */extern void ng_plugin_init(void);void ng_plugin_init(void){ ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&bsd_driver);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -