⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv1-v4l.c

📁 It s a tool designed to extract as much information as possible from Bluetooth devices without the r
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * interface to the v4l driver * *   (c) 1997-2004 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>#include "videodev.h"#include "grab-ng.h"#include "struct-dump.h"#include "struct-v4l.h"#define SYNC_TIMEOUT 5/* ---------------------------------------------------------------------- *//* open+close */static void*   v4l_init(char *device);static int     v4l_open(void *handle);static int     v4l_close(void *handle);static int     v4l_fini(void *handle);static char*   v4l_devname(void *handle);static struct ng_devinfo* v4l_probe(int verbose);/* attributes */static int     v4l_flags(void *handle);static struct ng_attribute* v4l_attrs(void *handle);static int     v4l_read_attr(struct ng_attribute*);static void    v4l_write_attr(struct ng_attribute*, int val);#if 0/* overlay */static int   v4l_setupfb(void *handle, struct ng_video_fmt *fmt, void *base);static int   v4l_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y,			 struct OVERLAY_CLIP *oc, int count, int aspect);#endif/* capture video */static int v4l_setformat(void *handle, struct ng_video_fmt *fmt);static int v4l_startvideo(void *handle, int fps, unsigned int buffers);static void v4l_stopvideo(void *handle);static struct ng_video_buf* v4l_nextframe(void *handle);static struct ng_video_buf* v4l_getimage(void *handle);/* tuner */static unsigned long v4l_getfreq(void *handle);static void v4l_setfreq(void *handle, unsigned long freq);static int v4l_tuned(void *handle);/* ---------------------------------------------------------------------- */static const char *device_cap[] = {    "capture", "tuner", "teletext", "overlay", "chromakey", "clipping",    "frameram", "scales", "monochrome", NULL};static const char *device_pal[] = {    "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15",    "yuv422", "yuyv", "uyvy", "yuv420", "yuv411", "raw",    "yuv422p", "yuv411p", "yuv420p", "yuv410p"};#define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN")static struct STRTAB stereo[] = {    {  0,                  "auto"    },    {  VIDEO_SOUND_MONO,   "mono"    },    {  VIDEO_SOUND_STEREO, "stereo"  },    {  VIDEO_SOUND_LANG1,  "lang1"   },    {  VIDEO_SOUND_LANG2,  "lang2"   },    { -1, NULL },};static struct STRTAB norms_v4l[] = {    {  VIDEO_MODE_PAL,     "PAL"   },    {  VIDEO_MODE_NTSC,    "NTSC"  },    {  VIDEO_MODE_SECAM,   "SECAM" },    {  VIDEO_MODE_AUTO,    "AUTO"  },    { -1, NULL }};static struct STRTAB norms_bttv[] = {    {  VIDEO_MODE_PAL,   "PAL"     },    {  VIDEO_MODE_NTSC,  "NTSC"    },    {  VIDEO_MODE_SECAM, "SECAM"   },    {  3,                "PAL-NC"  },    {  4,                "PAL-M"   },    {  5,                "PAL-N"   },    {  6,                "NTSC-JP" },    { -1, NULL }};static unsigned short format2palette[VIDEO_FMT_COUNT] = {    [ VIDEO_RGB08 ]    = VIDEO_PALETTE_HI240,    [ VIDEO_GRAY ]     = VIDEO_PALETTE_GREY,    [ VIDEO_RGB15_LE ] = VIDEO_PALETTE_RGB555,    [ VIDEO_RGB16_LE ] = VIDEO_PALETTE_RGB565,    [ VIDEO_BGR24 ]    = VIDEO_PALETTE_RGB24,    [ VIDEO_BGR32 ]    = VIDEO_PALETTE_RGB32,    [ VIDEO_YUYV ]     = VIDEO_PALETTE_YUV422,    [ VIDEO_UYVY ]     = VIDEO_PALETTE_UYVY,    [ VIDEO_YUV422P ]  = VIDEO_PALETTE_YUV422P,    [ VIDEO_YUV420P ]  = VIDEO_PALETTE_YUV420P,};#if 0/* pass 0/1 by reference */static int                      one = 1, zero = 0;#endif/* ---------------------------------------------------------------------- */struct v4l_handle {    int                      fd;    char                     *device;    /* general informations */    struct video_capability  capability;    struct video_channel     *channels;    struct video_tuner       tuner;    struct video_audio       audio;    struct video_picture     pict;    /* attributes */    int                      nattr;    struct ng_attribute      *attr;    int                      input;    int                      audio_mode;        /* overlay */    struct video_buffer      fbuf;    struct video_window      win;    int                      ov_error;    unsigned int             ov_fmtid;    int                      ov_enabled;    int                      ov_on;    /* capture */    int                      use_read;    int                      rw;    struct ng_video_fmt      fmt;    long long                start;    int                      fps;        /* capture via read() */    struct ng_video_fmt      rd_fmt;    struct video_window      rd_win;    unsigned int             rd_fmtid;        /* capture to mmap()'ed buffers */    struct video_mbuf        mbuf;    unsigned char            *mmap;    unsigned int             nbuf;    unsigned int             queue;    unsigned int             waiton;    int                      probe[VIDEO_FMT_COUNT];    struct video_mmap        *buf_v4l;    struct ng_video_buf      *buf_me;};struct ng_vid_driver v4l_driver = {    .name          = "v4l",    .priority      = 2,        .init          = v4l_init,    .open          = v4l_open,    .close         = v4l_close,    .fini          = v4l_fini,    .devname       = v4l_devname,    .probe         = v4l_probe,        .capabilities  = v4l_flags,    .list_attrs    = v4l_attrs,#if 0    .setupfb       = v4l_setupfb,    .overlay       = v4l_overlay,#endif        .setformat     = v4l_setformat,    .startvideo    = v4l_startvideo,    .stopvideo     = v4l_stopvideo,    .nextframe     = v4l_nextframe,    .getimage      = v4l_getimage,        .getfreq       = v4l_getfreq,    .setfreq       = v4l_setfreq,    .is_tuned      = v4l_tuned,};/* ---------------------------------------------------------------------- */static int alarms;static voidsigalarm(int signal){    alarms++;    fprintf(stderr,"v4l: timeout (got SIGALRM), hardware/driver problems?\n");}static voidsiginit(void){    struct sigaction act,old;        memset(&act,0,sizeof(act));    act.sa_handler  = sigalarm;    sigemptyset(&act.sa_mask);    sigaction(SIGALRM,&act,&old);}/* ---------------------------------------------------------------------- */#define PREFIX "ioctl: "static intxioctl(int fd, int cmd, void *arg){    int rc;    rc = ioctl(fd,cmd,arg);    if (0 == rc && ng_debug < 2)	return 0;    print_ioctl(stderr,ioctls_v4l1,PREFIX,cmd,arg);    fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno));    return rc;}/* ---------------------------------------------------------------------- */static voidv4l_add_attr(struct v4l_handle *h, int id, int type,	     int defval, struct STRTAB *choices){    h->attr = realloc(h->attr,(h->nattr+2) * sizeof(struct ng_attribute));    memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2);    h->attr[h->nattr].id       = id;    h->attr[h->nattr].priority = 2;    h->attr[h->nattr].type     = type;    h->attr[h->nattr].defval   = defval;    h->attr[h->nattr].choices  = choices;    if (ATTR_TYPE_INTEGER == type) {	h->attr[h->nattr].min  = 0;	h->attr[h->nattr].max  = 65535;    }    if (id < ATTR_ID_COUNT)	h->attr[h->nattr].name = ng_attr_to_desc[id];    h->attr[h->nattr].read     = v4l_read_attr;    h->attr[h->nattr].write    = v4l_write_attr;    h->attr[h->nattr].handle   = h;    h->nattr++;}static voidv4l_buffer_map(struct v4l_handle *h){    int i, flags;        if (0 == xioctl(h->fd,VIDIOCGMBUF,&h->mbuf)) {	if (ng_debug)	    fprintf(stderr,"  mbuf: size=%d frames=%d\n",		    h->mbuf.size,h->mbuf.frames);	flags = PROT_READ;	if (h->rw)	  flags |= PROT_WRITE;	h->mmap = mmap(0,h->mbuf.size, flags,		       MAP_SHARED,h->fd,0);	if (MAP_FAILED == h->mmap)	    perror("mmap");    } else {	h->mmap = MAP_FAILED;    }    if (MAP_FAILED != h->mmap) {	if (ng_debug)	    fprintf(stderr,"  v4l: using mapped buffers for capture\n");	h->use_read = 0;	h->nbuf = h->mbuf.frames;	h->buf_v4l = malloc(h->nbuf * sizeof(struct video_mmap));	memset(h->buf_v4l,0,h->nbuf * sizeof(struct video_mmap));	h->buf_me = malloc(h->nbuf * sizeof(struct ng_video_buf));	for (i = 0; i < h->nbuf; i++) {	    ng_init_video_buf(h->buf_me+i);	    h->buf_me[i].release = ng_wakeup_video_buf;	}    } else {	if (ng_debug)	    fprintf(stderr,"  v4l: using read() for capture\n");	h->use_read = 1;    }}static voidv4l_buffer_unmap(struct v4l_handle *h){    if (MAP_FAILED != h->mmap) {	munmap(h->mmap,h->mbuf.size);	free(h->buf_v4l);	free(h->buf_me);	h->buf_v4l = NULL;	h->buf_me  = NULL;	h->nbuf    = 0;	h->mmap    = MAP_FAILED;    } else {	h->use_read = 0;    }}/* ---------------------------------------------------------------------- */static intv4l_open(void *handle){    struct v4l_handle *h = handle;    if (ng_debug)	fprintf(stderr, "v4l: open\n");    BUG_ON(h->fd != -1,"device is open");    h->rw = 1;    h->fd = ng_chardev_open(h->device, O_RDWR, 81, 1);    if (-1 == h->fd) {      h->rw = 0;      h->fd = ng_chardev_open(h->device, O_RDONLY, 81, 1);       if (-1 == h->fd)	 return -1;    }    if (-1 == ioctl(h->fd,VIDIOCGCAP,&h->capability)) {	close(h->fd);	return -1;    }    v4l_buffer_map(h);    return 0;}static intv4l_close(void *handle){    struct v4l_handle *h = handle;    if (ng_debug)	fprintf(stderr, "v4l: close\n");    BUG_ON(h->fd == -1,"device not open");    v4l_buffer_unmap(h);    close(h->fd);    h->fd = -1;    return 0;}static void*v4l_init(char *device){    struct v4l_handle *h;    struct STRTAB *inputs;    struct STRTAB *norms;    unsigned int i;    int rc;    if (device && 0 != strncmp(device,"/dev/",5))	return NULL;    h = malloc(sizeof(*h));    if (NULL == h)	return NULL;    memset(h,0,sizeof(*h));    h->device = strdup(device ? device : ng_dev.video);    h->fd     = -1;    h->mmap   = MAP_FAILED;    /* open device */    if (0 != v4l_open(h))	goto err;    if (ng_debug)	fprintf(stderr, "v4l: init: %s (%s)\n",device,h->capability.name);    siginit();    if (ng_debug) {	fprintf(stderr,"  capabilities: ");	for (i = 0; device_cap[i] != NULL; i++)	    if (h->capability.type & (1 << i))		fprintf(stderr," %s",device_cap[i]);	fprintf(stderr,"\n");	fprintf(stderr,"  size    : %dx%d => %dx%d\n",		h->capability.minwidth,h->capability.minheight,		h->capability.maxwidth,h->capability.maxheight);    }    /* input sources */    if (ng_debug)	fprintf(stderr,"  channels: %d\n",h->capability.channels);    h->channels = malloc(sizeof(struct video_channel)*h->capability.channels);    memset(h->channels,0,sizeof(struct video_channel)*h->capability.channels);    inputs = malloc(sizeof(struct STRTAB)*(h->capability.channels+1));    memset(inputs,0,sizeof(struct STRTAB)*(h->capability.channels+1));    for (i = 0; i < h->capability.channels; i++) {	h->channels[i].channel = i;	xioctl(h->fd,VIDIOCGCHAN,&(h->channels[i]));	inputs[i].nr  = i;	inputs[i].str = h->channels[i].name;	if (ng_debug)	    fprintf(stderr,"    %s: %d %s%s %s%s\n",		    h->channels[i].name,		    h->channels[i].tuners,		    (h->channels[i].flags & VIDEO_VC_TUNER)   ? "tuner "  : "",		    (h->channels[i].flags & VIDEO_VC_AUDIO)   ? "audio "  : "",		    (h->channels[i].type & VIDEO_TYPE_TV)     ? "tv "     : "",		    (h->channels[i].type & VIDEO_TYPE_CAMERA) ? "camera " : "");    }    inputs[i].nr  = -1;    inputs[i].str = NULL;    v4l_add_attr(h,ATTR_ID_INPUT,ATTR_TYPE_CHOICE,0,inputs);        /* audios */    if (ng_debug)	fprintf(stderr,"  audios  : %d\n",h->capability.audios);    if (h->capability.audios) {	h->audio.audio = 0;	xioctl(h->fd,VIDIOCGAUDIO,&h->audio);	if (ng_debug) {	    fprintf(stderr,"    %d (%s): ",i,h->audio.name);	    if (h->audio.flags & VIDEO_AUDIO_MUTABLE)		fprintf(stderr,"muted=%s ",			(h->audio.flags&VIDEO_AUDIO_MUTE) ? "yes":"no");	    if (h->audio.flags & VIDEO_AUDIO_VOLUME)		fprintf(stderr,"volume=%d ",h->audio.volume);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -