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

📄 drv0-v4l2.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 v4l2 driver * *   (c) 1998-2002 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 <inttypes.h>#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/mman.h>#include <pthread.h>#include <asm/types.h>		/* XXX glibc */#include "videodev2.h"#include "grab-ng.h"#include "struct-dump.h"#include "struct-v4l2.h"/* ---------------------------------------------------------------------- *//* open+close */static void*   v4l2_init(char *device);static int     v4l2_open(void *handle);static int     v4l2_close(void *handle);static int     v4l2_fini(void *handle);static struct ng_devinfo* v4l2_probe(int verbose);/* attributes */static char*   v4l2_devname(void *handle);static char*   v4l2_busname(void *handle);static int     v4l2_flags(void *handle);static struct ng_attribute* v4l2_attrs(void *handle);static int     v4l2_read_attr(struct ng_attribute*);static void    v4l2_write_attr(struct ng_attribute*, int val);#if 0/* overlay */static int   v4l2_setupfb(void *handle, struct ng_video_fmt *fmt, void *base);static int   v4l2_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 v4l2_setformat(void *handle, struct ng_video_fmt *fmt);static int v4l2_startvideo(void *handle, int fps, unsigned int buffers);static void v4l2_stopvideo(void *handle);static struct ng_video_buf* v4l2_nextframe(void *handle);static struct ng_video_buf* v4l2_getimage(void *handle);/* mpeg */static char *v4l2_setup_mpeg(void *handle, int flags);/* tuner */static unsigned long v4l2_getfreq(void *handle);static void v4l2_setfreq(void *handle, unsigned long freq);static int v4l2_tuned(void *handle);/* ---------------------------------------------------------------------- */#define WANTED_BUFFERS 32#define MAX_INPUT   16#define MAX_NORM    16#define MAX_FORMAT  32#define MAX_CTRL    32struct v4l2_handle {    int                         fd;    char                        *device;    /* device descriptions */    int                         ninputs,nstds,nfmts;    struct v4l2_capability	cap;    struct v4l2_streamparm	streamparm;    struct v4l2_input		inp[MAX_INPUT];    struct v4l2_standard      	std[MAX_NORM];    struct v4l2_fmtdesc		fmt[MAX_FORMAT];    struct v4l2_queryctrl	ctl[MAX_CTRL*2];    int                         flags;    int                         mpeg;    /* attributes */    int                         nattr;    struct ng_attribute         *attr;    /* capture */    int                            fps,first;    long long                      start;    struct v4l2_format             fmt_v4l2;    struct ng_video_fmt            fmt_me;    struct v4l2_requestbuffers     reqbufs;    struct v4l2_buffer             buf_v4l2[WANTED_BUFFERS];    struct ng_video_buf            buf_me[WANTED_BUFFERS];    unsigned int                   queue,waiton;    /* overlay */    struct v4l2_framebuffer        ov_fb;    struct v4l2_format             ov_win;    struct v4l2_clip               ov_clips[256];#if 0    enum v4l2_field                ov_fields;#endif    int                            ov_error;    int                            ov_enabled;    int                            ov_on;};static void v4l2_probe_mpeg(struct v4l2_handle *h);/* ---------------------------------------------------------------------- */struct ng_vid_driver v4l2_driver = {    .name          = "v4l2",    .priority      = 1,    .init          = v4l2_init,    .open          = v4l2_open,    .close         = v4l2_close,    .fini          = v4l2_fini,    .devname       = v4l2_devname,    .busname       = v4l2_busname,    .probe         = v4l2_probe,        .capabilities  = v4l2_flags,    .list_attrs    = v4l2_attrs,#if 0    .setupfb       = v4l2_setupfb,    .overlay       = v4l2_overlay,#endif    .setformat     = v4l2_setformat,    .startvideo    = v4l2_startvideo,    .stopvideo     = v4l2_stopvideo,    .nextframe     = v4l2_nextframe,    .getimage      = v4l2_getimage,        .getfreq       = v4l2_getfreq,    .setfreq       = v4l2_setfreq,    .is_tuned      = v4l2_tuned,    .setup_mpeg    = v4l2_setup_mpeg,};static __u32 xawtv_pixelformat[VIDEO_FMT_COUNT] = {    [ VIDEO_RGB08 ]    = V4L2_PIX_FMT_HI240,    [ VIDEO_GRAY ]     = V4L2_PIX_FMT_GREY,    [ VIDEO_RGB15_LE ] = V4L2_PIX_FMT_RGB555,    [ VIDEO_RGB16_LE ] = V4L2_PIX_FMT_RGB565,    [ VIDEO_RGB15_BE ] = V4L2_PIX_FMT_RGB555X,    [ VIDEO_RGB16_BE ] = V4L2_PIX_FMT_RGB565X,    [ VIDEO_BGR24 ]    = V4L2_PIX_FMT_BGR24,    [ VIDEO_BGR32 ]    = V4L2_PIX_FMT_BGR32,    [ VIDEO_RGB24 ]    = V4L2_PIX_FMT_RGB24,    [ VIDEO_YUYV ]     = V4L2_PIX_FMT_YUYV,    [ VIDEO_UYVY ]     = V4L2_PIX_FMT_UYVY,    [ VIDEO_YUV422P ]  = V4L2_PIX_FMT_YUV422P,    [ VIDEO_YUV420P ]  = V4L2_PIX_FMT_YUV420,};static struct STRTAB stereo[] = {    {  V4L2_TUNER_MODE_MONO,   "mono"    },    {  V4L2_TUNER_MODE_STEREO, "stereo"  },    {  V4L2_TUNER_MODE_LANG1,  "lang1"   },    {  V4L2_TUNER_MODE_LANG2,  "lang2"   },    { -1, NULL },};/* ---------------------------------------------------------------------- *//* debug output                                                           */#define PREFIX "ioctl: "static intxioctl(int fd, int cmd, void *arg, int mayfail){    int rc;    rc = ioctl(fd,cmd,arg);    if (0 == rc && ng_debug < 2)	return rc;    if (mayfail && errno == mayfail && ng_debug < 2)	return rc;    print_ioctl(stderr,ioctls_v4l2,PREFIX,cmd,arg);    fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno));    return rc;}static voidprint_bufinfo(struct v4l2_buffer *buf){    static char *type[] = {	[V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",	[V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",	[V4L2_BUF_TYPE_VIDEO_OUTPUT]  = "video-out",	[V4L2_BUF_TYPE_VBI_CAPTURE]   = "vbi-cap",	[V4L2_BUF_TYPE_VBI_OUTPUT]    = "vbi-out",    };    fprintf(stderr,"v4l2: buf %d: %s 0x%x+%d, used %d\n",	    buf->index,	    buf->type < sizeof(type)/sizeof(char*)	    ? type[buf->type] : "unknown",	    buf->m.offset,buf->length,buf->bytesused);}/* ---------------------------------------------------------------------- *//* helpers                                                                */static voidget_device_capabilities(struct v4l2_handle *h){    int i;        for (h->ninputs = 0; h->ninputs < MAX_INPUT; h->ninputs++) {	h->inp[h->ninputs].index = h->ninputs;	if (-1 == xioctl(h->fd, VIDIOC_ENUMINPUT, &h->inp[h->ninputs], EINVAL))	    break;    }    for (h->nstds = 0; h->nstds < MAX_NORM; h->nstds++) {	h->std[h->nstds].index = h->nstds;	if (-1 == xioctl(h->fd, VIDIOC_ENUMSTD, &h->std[h->nstds], EINVAL))	    break;    }    for (h->nfmts = 0; h->nfmts < MAX_FORMAT; h->nfmts++) {	h->fmt[h->nfmts].index = h->nfmts;	h->fmt[h->nfmts].type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;	if (-1 == xioctl(h->fd, VIDIOC_ENUM_FMT, &h->fmt[h->nfmts], EINVAL))	    break;    }    h->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    ioctl(h->fd,VIDIOC_G_PARM,&h->streamparm);    /* controls */    for (i = 0; i < MAX_CTRL; i++) {	h->ctl[i].id = V4L2_CID_BASE+i;	if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i], EINVAL) ||	    (h->ctl[i].flags & V4L2_CTRL_FLAG_DISABLED))	    h->ctl[i].id = -1;    }    for (i = 0; i < MAX_CTRL; i++) {	h->ctl[i+MAX_CTRL].id = V4L2_CID_PRIVATE_BASE+i;	if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i+MAX_CTRL], EINVAL) ||	    (h->ctl[i+MAX_CTRL].flags & V4L2_CTRL_FLAG_DISABLED))	    h->ctl[i+MAX_CTRL].id = -1;    }}static struct STRTAB *build_norms(struct v4l2_handle *h){    struct STRTAB *norms;    int i;    norms = malloc(sizeof(struct STRTAB) * (h->nstds+1));    for (i = 0; i < h->nstds; i++) {	norms[i].nr  = i;	norms[i].str = h->std[i].name;    }    norms[i].nr  = -1;    norms[i].str = NULL;    return norms;}static struct STRTAB *build_inputs(struct v4l2_handle *h){    struct STRTAB *inputs;    int i;    inputs = malloc(sizeof(struct STRTAB) * (h->ninputs+1));    for (i = 0; i < h->ninputs; i++) {	inputs[i].nr  = i;	inputs[i].str = h->inp[i].name;    }    inputs[i].nr  = -1;    inputs[i].str = NULL;    return inputs;}/* ---------------------------------------------------------------------- */static struct V4L2_ATTR {    unsigned int id;    unsigned int v4l2;} v4l2_attr[] = {    { ATTR_ID_VOLUME,   V4L2_CID_AUDIO_VOLUME },    { ATTR_ID_MUTE,     V4L2_CID_AUDIO_MUTE   },    { ATTR_ID_COLOR,    V4L2_CID_SATURATION   },    { ATTR_ID_BRIGHT,   V4L2_CID_BRIGHTNESS   },    { ATTR_ID_HUE,      V4L2_CID_HUE          },    { ATTR_ID_CONTRAST, V4L2_CID_CONTRAST     },};#define NUM_ATTR (sizeof(v4l2_attr)/sizeof(struct V4L2_ATTR))static struct STRTAB*v4l2_menu(int fd, const struct v4l2_queryctrl *ctl){    struct STRTAB *menu;    struct v4l2_querymenu item;    int i;    menu = malloc(sizeof(struct STRTAB) * (ctl->maximum-ctl->minimum+2));    for (i = ctl->minimum; i <= ctl->maximum; i++) {	item.id = ctl->id;	item.index = i;	if (-1 == xioctl(fd, VIDIOC_QUERYMENU, &item, 0)) {	    free(menu);	    return NULL;	}	menu[i-ctl->minimum].nr  = i;	menu[i-ctl->minimum].str = strdup(item.name);    }    menu[i-ctl->minimum].nr  = -1;    menu[i-ctl->minimum].str = NULL;    return menu;}static voidv4l2_add_attr(struct v4l2_handle *h, struct v4l2_queryctrl *ctl,	      int id, struct STRTAB *choices){    static int private_ids = ATTR_ID_COUNT;    unsigned int i;        h->attr = realloc(h->attr,(h->nattr+2) * sizeof(struct ng_attribute));    memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2);    if (ctl) {	for (i = 0; i < NUM_ATTR; i++)	    if (v4l2_attr[i].v4l2 == ctl->id)		break;	if (i != NUM_ATTR) {	    h->attr[h->nattr].id   = v4l2_attr[i].id;	} else {	    h->attr[h->nattr].id   = private_ids++;	}	h->attr[h->nattr].name     = ctl->name;	h->attr[h->nattr].priority = 2;	h->attr[h->nattr].priv     = ctl;	h->attr[h->nattr].defval   = ctl->default_value;	switch (ctl->type) {	case V4L2_CTRL_TYPE_INTEGER:	    h->attr[h->nattr].type    = ATTR_TYPE_INTEGER;	    h->attr[h->nattr].defval  = ctl->default_value;	    h->attr[h->nattr].min     = ctl->minimum;	    h->attr[h->nattr].max     = ctl->maximum;	    break;	case V4L2_CTRL_TYPE_BOOLEAN:	    h->attr[h->nattr].type    = ATTR_TYPE_BOOL;	    break;	case V4L2_CTRL_TYPE_MENU:	    h->attr[h->nattr].type    = ATTR_TYPE_CHOICE;	    h->attr[h->nattr].choices = v4l2_menu(h->fd, ctl);	    break;	default:	    memset(h->attr+h->nattr,0,sizeof(struct ng_attribute)*2);	    return;	}    } else {	/* for norms + inputs */	h->attr[h->nattr].id      = id;	if (-1 == h->attr[h->nattr].id)	    h->attr[h->nattr].id  = private_ids++;	h->attr[h->nattr].defval  = 0;	h->attr[h->nattr].type    = ATTR_TYPE_CHOICE;	h->attr[h->nattr].choices = choices;    }    if (h->attr[h->nattr].id < ATTR_ID_COUNT)	h->attr[h->nattr].name = ng_attr_to_desc[h->attr[h->nattr].id];    h->attr[h->nattr].read    = v4l2_read_attr;    h->attr[h->nattr].write   = v4l2_write_attr;    h->attr[h->nattr].handle  = h;    h->nattr++;}static int v4l2_read_attr(struct ng_attribute *attr){    struct v4l2_handle *h = attr->handle;    const struct v4l2_queryctrl *ctl = attr->priv;    struct v4l2_control c;    struct v4l2_tuner tuner;    v4l2_std_id std;    int value = 0;    int i;    if (NULL != ctl) {	c.id = ctl->id;	xioctl(h->fd,VIDIOC_G_CTRL,&c,0);	value = c.value;	    } else if (attr->id == ATTR_ID_NORM) {	value = -1;	xioctl(h->fd,VIDIOC_G_STD,&std,0);	for (i = 0; i < h->nstds; i++)	    if (std & h->std[i].id)		value = i;	    } else if (attr->id == ATTR_ID_INPUT) {	xioctl(h->fd,VIDIOC_G_INPUT,&value,0);    } else if (attr->id == ATTR_ID_AUDIO_MODE) {	memset(&tuner,0,sizeof(tuner));	xioctl(h->fd,VIDIOC_G_TUNER,&tuner,0);	value = tuner.audmode;

⌨️ 快捷键说明

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