📄 drv0-bsd.c
字号:
/* * interface to the bsd bktr driver * * (c) 2000,01 Gerd Knorr <kraxel@bytesex.org> * */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <math.h>#include <errno.h>#include <fcntl.h>#include <string.h>#include <signal.h>#include <pthread.h>#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/mman.h>#ifdef HAVE_DEV_IC_BT8XX_H# include <dev/ic/bt8xx.h>#endif#ifdef HAVE_MACHINE_IOCTL_BT848_H# include <machine/ioctl_bt848.h># include <machine/ioctl_meteor.h>#endif#include "grab-ng.h"/* ---------------------------------------------------------------------- *//* global variables */struct bsd_handle { int fd; int tfd; /* formats */ int pf_count; struct meteor_pixfmt pf[64]; int xawtv2pf[VIDEO_FMT_COUNT]; unsigned char *map; /* attributes */ int muted; struct ng_attribute *attr; /* overlay */ struct meteor_video fb,pos; struct meteor_geomet ovgeo; struct meteor_pixfmt *ovfmt; struct bktr_clip clip[BT848_MAX_CLIP_NODE]; int ov_enabled,ov_on; /* capture */ int fps; long long start; struct ng_video_fmt fmt; struct meteor_video nofb; struct meteor_geomet capgeo; struct meteor_pixfmt *capfmt; struct bktr_clip noclip[BT848_MAX_CLIP_NODE];};/* ---------------------------------------------------------------------- *//* prototypes *//* open/close */static void* bsd_open(char *device);static int bsd_close(void *handle);/* attributes */static int bsd_flags(void *handle);static struct ng_attribute* bsd_attrs(void *handle);static int bsd_read_attr(struct ng_attribute*);static void bsd_write_attr(struct ng_attribute*, int val);static int bsd_setupfb(void *handle, struct ng_video_fmt *fmt, void *base);static int bsd_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect);/* capture */static void catchsignal(int signal);static void siginit(void);static int bsd_setformat(void *handle, struct ng_video_fmt *fmt);static int bsd_startvideo(void *handle, int fps, unsigned int buffers);static void bsd_stopvideo(void *handle);static struct ng_video_buf* bsd_nextframe(void *handle);static struct ng_video_buf* bsd_getimage(void *handle);/* tuner */static unsigned long bsd_getfreq(void *handle);static void bsd_setfreq(void *handle, unsigned long freq);static int bsd_tuned(void *handle);struct ng_vid_driver bsd_driver = { name: "bktr", open: bsd_open, close: bsd_close, capabilities: bsd_flags, list_attrs: bsd_attrs, setupfb: bsd_setupfb, overlay: bsd_overlay, setformat: bsd_setformat, startvideo: bsd_startvideo, stopvideo: bsd_stopvideo, nextframe: bsd_nextframe, getimage: bsd_getimage, getfreq: bsd_getfreq, setfreq: bsd_setfreq, is_tuned: bsd_tuned,};/* ---------------------------------------------------------------------- */static struct STRTAB inputs[] = { { 0, "Television" }, { 1, "Composite1" }, { 2, "S-Video" }, { 3, "CSVIDEO" }, { -1, NULL }};static int inputs_map[] = { METEOR_INPUT_DEV1, METEOR_INPUT_DEV0, METEOR_INPUT_DEV_SVIDEO, METEOR_INPUT_DEV2,};static struct STRTAB norms[] = { { 0, "NTSC" }, { 1, "NTSC-JP" }, { 2, "PAL" }, { 3, "PAL-M" }, { 4, "PAL-N" }, { 5, "SECAM" }, { 6, "RSVD" }, { -1, NULL }};static int norms_map[] = { BT848_IFORM_F_NTSCM, BT848_IFORM_F_NTSCJ, BT848_IFORM_F_PALBDGHI, BT848_IFORM_F_PALM, BT848_IFORM_F_PALN, BT848_IFORM_F_SECAM, BT848_IFORM_F_RSVD,};static struct STRTAB audio[] = { { 0, "Tuner" }, { 1, "Extern" }, { 2, "Intern" }, { -1, NULL }};static int audio_map[] = { AUDIO_TUNER, AUDIO_EXTERN, AUDIO_INTERN,};static struct ng_attribute bsd_attr[] = { { id: ATTR_ID_COUNT+1, name: "audio", type: ATTR_TYPE_CHOICE, choices: audio, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_NORM, name: "norm", type: ATTR_TYPE_CHOICE, choices: norms, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_INPUT, name: "input", type: ATTR_TYPE_CHOICE, choices: inputs, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_MUTE, name: "mute", type: ATTR_TYPE_BOOL, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_HUE, name: "hue", type: ATTR_TYPE_INTEGER, min: BT848_HUEREGMIN, max: BT848_HUEREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_BRIGHT, name: "bright", type: ATTR_TYPE_INTEGER, min: BT848_BRIGHTREGMIN, max: BT848_BRIGHTREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_CONTRAST, name: "contrast", type: ATTR_TYPE_INTEGER, min: BT848_CONTRASTREGMIN, max: BT848_CONTRASTREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ id: ATTR_ID_COLOR, name: "color", type: ATTR_TYPE_INTEGER, min: BT848_CHROMAREGMIN, max: BT848_CHROMAREGMAX, read: bsd_read_attr, write: bsd_write_attr, },{ /* end of list */ }};static int single = METEOR_CAP_SINGLE;static int start = METEOR_CAP_CONTINOUS;static int stop = METEOR_CAP_STOP_CONT;static int signal_on = SIGUSR1;static int signal_off = METEOR_SIG_MODE_MASK;/* ---------------------------------------------------------------------- */#define PREFIX "bktr: ioctl: "static intxioctl(int fd, int cmd, void *arg){ int rc; rc = ioctl(fd,cmd,arg); if (0 == rc && ng_debug < 2) return 0; switch (cmd) { case METEORSVIDEO: { struct meteor_video *a = arg; fprintf(stderr,PREFIX "METEORSVIDEO(addr=0x%08lx,width=%ld,bank=%ld,ram=%ld)", a->addr,a->width,a->banksize,a->ramsize); break; } case METEORSETGEO: { struct meteor_geomet *a = arg; fprintf(stderr,PREFIX "METEORSETGEO(%dx%d,frames=%d,oformat=0x%lx)", a->columns,a->rows,a->frames,a->oformat); break; } case METEORSACTPIXFMT: { struct meteor_pixfmt *a = arg; fprintf(stderr,PREFIX "METEORSACTPIXFMT(%d,type=%d,bpp=%d," "masks=0x%lx/0x%lx/0x%lx,sb=%d,ss=%d)", a->index,a->type,a->Bpp,a->masks[0],a->masks[1],a->masks[2], a->swap_bytes,a->swap_shorts); break; } case METEORCAPTUR: { int *a = arg; fprintf(stderr,PREFIX "METEORCAPTUR(%d)",*a); break; } case METEORSSIGNAL: { int *a = arg; fprintf(stderr,PREFIX "METEORSSIGNAL(0x%x)",*a); break; } case BT848SCLIP: { fprintf(stderr,PREFIX "BT848SCLIP"); break; } default: fprintf(stderr,PREFIX "UNKNOWN(cmd=0x%x)",cmd); break; } fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno)); return rc;}/* ---------------------------------------------------------------------- */static voidbsd_print_format(struct meteor_pixfmt *pf, int format){ switch (pf->type) { case METEOR_PIXTYPE_RGB: fprintf(stderr, "bktr: pf: rgb bpp=%d mask=%ld,%ld,%ld", pf->Bpp,pf->masks[0],pf->masks[1],pf->masks[2]); break; case METEOR_PIXTYPE_YUV: fprintf(stderr,"bktr: pf: yuv h422 v111 (planar)"); break; case METEOR_PIXTYPE_YUV_PACKED: fprintf(stderr,"bktr: pf: yuyv h422 v111 (packed)"); break; case METEOR_PIXTYPE_YUV_12: fprintf(stderr,"bktr: pf: yuv h422 v422 (planar)"); break; default: fprintf(stderr,"bktr: pf: unknown"); } fprintf(stderr," sbytes=%d sshorts=%d (fmt=%d)\n", pf->swap_bytes,pf->swap_shorts,format);}/* ---------------------------------------------------------------------- */static void*bsd_open(char *filename){ struct bsd_handle *h; int format,i; h = malloc(sizeof(*h)); if (NULL == h) return NULL; memset(h,0,sizeof(*h)); if (-1 == (h->fd = open(filename,O_RDONLY))) { fprintf(stderr,"bktr: open %s: %s\n", filename,strerror(errno)); goto err; } /* video formats */ for (format = 0; format < VIDEO_FMT_COUNT; format++) h->xawtv2pf[format] = -1; for (h->pf_count = 0; h->pf_count < 64; h->pf_count++) { h->pf[h->pf_count].index = h->pf_count; if (-1 == ioctl(h->fd, METEORGSUPPIXFMT,h->pf+h->pf_count)) { if (ng_debug) perror("bktr: ioctl METEORGSUPPIXFMT"); if (0 == h->pf_count) goto err; break; } format = -1; switch (h->pf[h->pf_count].type) { case METEOR_PIXTYPE_RGB: switch(h->pf[h->pf_count].masks[0]) { case 31744: /* 15 bpp */ format = h->pf[h->pf_count].swap_bytes ? VIDEO_RGB15_LE : VIDEO_RGB15_BE; break; case 63488: /* 16 bpp */ format = h->pf[h->pf_count].swap_bytes ? VIDEO_RGB16_LE : VIDEO_RGB16_BE; break; case 16711680: /* 24/32 bpp */ if (h->pf[h->pf_count].Bpp == 3 && h->pf[h->pf_count].swap_bytes == 1) { format = VIDEO_BGR24; } else if (h->pf[h->pf_count].Bpp == 4 && h->pf[h->pf_count].swap_bytes == 1 && h->pf[h->pf_count].swap_shorts == 1) { format = VIDEO_BGR32; } else if (h->pf[h->pf_count].Bpp == 4 && h->pf[h->pf_count].swap_bytes == 0 && h->pf[h->pf_count].swap_shorts == 0) { format = VIDEO_RGB32; } } break; case METEOR_PIXTYPE_YUV: format = VIDEO_YUV422P; break;#if 0 case METEOR_PIXTYPE_YUV_PACKED: format = VIDEO_YUV422; h->pf[h->pf_count].swap_shorts = 0; /* seems not to work */ break;#endif case METEOR_PIXTYPE_YUV_12: case METEOR_PIXTYPE_YUV_PACKED: /* nothing */ break; } if (-1 != format) h->xawtv2pf[format] = h->pf_count; if (ng_debug) bsd_print_format(h->pf+h->pf_count,format); } h->map = mmap(0,768*576*4, PROT_READ, MAP_SHARED, h->fd, 0); if ((unsigned char*)-1 == h->map) { perror("bktr: mmap"); h->map = NULL; } if (-1 == (h->tfd = open("/dev/tuner0",O_RDONLY))) { fprintf(stderr,"bktr: open %s: %s\n", "/dev/tuner0",strerror(errno)); } siginit(); h->attr = malloc(sizeof(bsd_attr));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -