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

📄 drv0-v4l2.c

📁 It s a tool designed to extract as much information as possible from Bluetooth devices without the r
💻 C
📖 第 1 页 / 共 3 页
字号:
{    for (;;) {	if (h->queue - h->waiton >= h->reqbufs.count)	    return;	if (0 != v4l2_queue_buffer(h))	    return;    }}static intv4l2_waiton(struct v4l2_handle *h){    struct v4l2_buffer buf;    struct timeval tv;    fd_set rdset;        /* wait for the next frame */ again:    tv.tv_sec  = 5;    tv.tv_usec = 0;    FD_ZERO(&rdset);    FD_SET(h->fd, &rdset);    switch (select(h->fd + 1, &rdset, NULL, NULL, &tv)) {    case -1:	if (EINTR == errno)	    goto again;	perror("v4l2: select");	return -1;    case  0:	fprintf(stderr,"v4l2: oops: select timeout\n");	return -1;    }    /* get it */    memset(&buf,0,sizeof(buf));    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    if (-1 == xioctl(h->fd,VIDIOC_DQBUF,&buf, 0))	return -1;    h->waiton++;    h->buf_v4l2[buf.index] = buf;#if 0    if (1) {	/* for driver debugging */	static const char *fn[] = {		"any", "none", "top", "bottom",		"interlaced", "tb", "bt", "alternate",	};	static struct timeval last;	signed long  diff;	diff  = (buf.timestamp.tv_sec - last.tv_sec) * 1000000;	diff += buf.timestamp.tv_usec - last.tv_usec;	fprintf(stderr,"\tdiff %6.1f ms  buf %d  field %d [%s]\n",		diff/1000.0, buf.index, buf.field, fn[buf.field%8]);	last = buf.timestamp;    }#endif    return buf.index;}static intv4l2_start_streaming(struct v4l2_handle *h, int buffers){    int disable_overlay = 0;    unsigned int i;        /* setup buffers */    h->reqbufs.count  = buffers;    h->reqbufs.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;    h->reqbufs.memory = V4L2_MEMORY_MMAP;    if (-1 == xioctl(h->fd, VIDIOC_REQBUFS, &h->reqbufs, 0))	return -1;    for (i = 0; i < h->reqbufs.count; i++) {	h->buf_v4l2[i].index  = i;	h->buf_v4l2[i].type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;	h->buf_v4l2[i].memory = V4L2_MEMORY_MMAP;	if (-1 == xioctl(h->fd, VIDIOC_QUERYBUF, &h->buf_v4l2[i], 0))	    return -1;	h->buf_me[i].fmt  = h->fmt_me;	h->buf_me[i].size = h->buf_me[i].fmt.bytesperline *	    h->buf_me[i].fmt.height;	h->buf_me[i].data = mmap(NULL, h->buf_v4l2[i].length,				 PROT_READ | PROT_WRITE, MAP_SHARED,				 h->fd, h->buf_v4l2[i].m.offset);	if (MAP_FAILED == h->buf_me[i].data) {	    perror("mmap");	    return -1;	}	if (ng_debug)	    print_bufinfo(&h->buf_v4l2[i]);    }    /* queue up all buffers */    v4l2_queue_all(h); try_again:    /* turn off preview (if needed) */    if (disable_overlay) {	h->ov_on = 0;	xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0);	if (ng_debug)	    fprintf(stderr,"v4l2: overlay off (start_streaming)\n");    }    /* start capture */    if (-1 == xioctl(h->fd,VIDIOC_STREAMON,&h->fmt_v4l2.type,		     h->ov_on ? EBUSY : 0)) {	if (h->ov_on && errno == EBUSY) {	    disable_overlay = 1;	    goto try_again;	}	return -1;    }    return 0;}static voidv4l2_stop_streaming(struct v4l2_handle *h){    unsigned int i;        /* stop capture */    if (-1 == ioctl(h->fd,VIDIOC_STREAMOFF,&h->fmt_v4l2.type))	perror("ioctl VIDIOC_STREAMOFF");        /* free buffers */    for (i = 0; i < h->reqbufs.count; i++) {	if (0 != h->buf_me[i].refcount)	    ng_waiton_video_buf(&h->buf_me[i]);	if (ng_debug)	    print_bufinfo(&h->buf_v4l2[i]);	if (-1 == munmap(h->buf_me[i].data,h->buf_v4l2[i].length))	    perror("munmap");    }    h->queue = 0;    h->waiton = 0;    /* turn on preview (if needed) */    if (h->ov_on != h->ov_enabled) {	h->ov_on = h->ov_enabled;	xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0);	if (ng_debug)	    fprintf(stderr,"v4l2: overlay on (stop_streaming)\n");    }}/* ---------------------------------------------------------------------- *//* capture interface                                                      *//* set capture parameters */static intv4l2_setformat(void *handle, struct ng_video_fmt *fmt){    struct v4l2_handle *h = handle;        BUG_ON(h->fd == -1,"device not open");    h->fmt_v4l2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    h->fmt_v4l2.fmt.pix.pixelformat  = xawtv_pixelformat[fmt->fmtid];    h->fmt_v4l2.fmt.pix.width        = fmt->width;    h->fmt_v4l2.fmt.pix.height       = fmt->height;    h->fmt_v4l2.fmt.pix.field        = V4L2_FIELD_ANY;    //h->fmt_v4l2.fmt.pix.field        = V4L2_FIELD_ALTERNATE;    if (fmt->bytesperline != fmt->width * ng_vfmt_to_depth[fmt->fmtid]/8)	h->fmt_v4l2.fmt.pix.bytesperline = fmt->bytesperline;    else	h->fmt_v4l2.fmt.pix.bytesperline = 0;    if (-1 == xioctl(h->fd, VIDIOC_S_FMT, &h->fmt_v4l2, EINVAL))	return -1;    if (h->fmt_v4l2.fmt.pix.pixelformat != xawtv_pixelformat[fmt->fmtid])	return -1;    fmt->width        = h->fmt_v4l2.fmt.pix.width;    fmt->height       = h->fmt_v4l2.fmt.pix.height;    fmt->bytesperline = h->fmt_v4l2.fmt.pix.bytesperline;    if (0 == fmt->bytesperline)	fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;    h->fmt_me = *fmt;    if (ng_debug)	fprintf(stderr,"v4l2: new capture params (%dx%d, %c%c%c%c, %d byte)\n",		fmt->width,fmt->height,		h->fmt_v4l2.fmt.pix.pixelformat & 0xff,		(h->fmt_v4l2.fmt.pix.pixelformat >>  8) & 0xff,		(h->fmt_v4l2.fmt.pix.pixelformat >> 16) & 0xff,		(h->fmt_v4l2.fmt.pix.pixelformat >> 24) & 0xff,		h->fmt_v4l2.fmt.pix.sizeimage);    return 0;}/* start/stop video */static intv4l2_startvideo(void *handle, int fps, unsigned int buffers){    struct v4l2_handle *h = handle;    BUG_ON(h->fd == -1,"device not open");    if (0 != h->fps)	fprintf(stderr,"v4l2_startvideo: oops: fps!=0\n");    h->fps = fps;    h->first = 1;    h->start = 0;    if (h->cap.capabilities & V4L2_CAP_STREAMING)	return v4l2_start_streaming(h,buffers);    return 0;}static voidv4l2_stopvideo(void *handle){    struct v4l2_handle *h = handle;    BUG_ON(h->fd == -1,"device not open");    if (0 == h->fps)	fprintf(stderr,"v4l2_stopvideo: oops: fps==0\n");    h->fps = 0;    if (h->cap.capabilities & V4L2_CAP_STREAMING)	v4l2_stop_streaming(h);}/* read images */static struct ng_video_buf*v4l2_nextframe(void *handle){    struct v4l2_handle *h = handle;    struct ng_video_buf *buf = NULL;    int rc,frame = 0;    BUG_ON(h->fd == -1,"device not open");    if (h->cap.capabilities & V4L2_CAP_STREAMING) {	v4l2_queue_all(h);	frame = v4l2_waiton(h);	if (-1 == frame)	    return NULL;	h->buf_me[frame].refcount++;	buf = &h->buf_me[frame];	memset(&buf->info,0,sizeof(buf->info));	buf->info.ts = ng_tofday_to_timestamp(&h->buf_v4l2[frame].timestamp);    } else {	buf = ng_malloc_video_buf(NULL, &h->fmt_me);	rc = read(h->fd,buf->data,buf->size);	if (rc != buf->size) {	    if (-1 == rc) {		perror("v4l2: read");	    } else {		fprintf(stderr, "v4l2: read: rc=%d/size=%ld\n",rc,buf->size);	    }	    ng_release_video_buf(buf);	    return NULL;	}	memset(&buf->info,0,sizeof(buf->info));	buf->info.ts = ng_get_timestamp();    }    if (h->first) {	h->first = 0;	h->start = buf->info.ts;	if (ng_debug)	    fprintf(stderr,"v4l2: start ts=%lld\n",h->start);    }    buf->info.ts -= h->start;    return buf;}static struct ng_video_buf*v4l2_getimage(void *handle){    struct v4l2_handle *h = handle;    struct ng_video_buf *buf;     int frame,rc;    BUG_ON(h->fd == -1,"device not open");    buf = ng_malloc_video_buf(NULL, &h->fmt_me);    if (h->cap.capabilities & V4L2_CAP_READWRITE) {	rc = read(h->fd,buf->data,buf->size);	if (-1 == rc  &&  EBUSY == errno  &&  h->ov_on) {	    h->ov_on = 0;	    xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0);	    rc = read(h->fd,buf->data,buf->size);	    h->ov_on = 1;	    xioctl(h->fd, VIDIOC_OVERLAY, &h->ov_on, 0);	}	if (rc != buf->size) {	    if (-1 == rc) {		perror("v4l2: read");	    } else {		fprintf(stderr, "v4l2: read: rc=%d/size=%ld\n",rc,buf->size);	    }	    ng_release_video_buf(buf);	    return NULL;	}    } else {	if (-1 == v4l2_start_streaming(h,1)) {	    v4l2_stop_streaming(h);	    return NULL;	}	frame = v4l2_waiton(h);	if (-1 == frame) {	    v4l2_stop_streaming(h);	    return NULL;	}	memcpy(buf->data,h->buf_me[0].data,buf->size);	v4l2_stop_streaming(h);    }    return buf;}/* ---------------------------------------------------------------------- */#define MPEG_TYPE_V4L2 1#define MPEG_TYPE_IVTV 2/* from ivtv.h */#define IVTV_IOC_G_CODEC        0xFFEE7703#define IVTV_IOC_S_CODEC        0xFFEE7704#define IVTV_STREAM_PS          0#define IVTV_STREAM_TS          1/* more follow .... */struct ivtv_ioctl_codec {        uint32_t aspect;        uint32_t audio_bitmap;        uint32_t bframes;        uint32_t bitrate_mode;        uint32_t bitrate;        uint32_t bitrate_peak;        uint32_t dnr_mode;        uint32_t dnr_spatial;        uint32_t dnr_temporal;        uint32_t dnr_type;        uint32_t framerate;        uint32_t framespergop;        uint32_t gop_closure;        uint32_t pulldown;        uint32_t stream_type;};static void v4l2_probe_mpeg(struct v4l2_handle *h){    struct ivtv_ioctl_codec codec;    int i;    /* check for v4l2 device */    for (i = 0; i < h->nfmts; i++) {	if (h->fmt[i].pixelformat == V4L2_PIX_FMT_MPEG) {	    /* saa7134 sets this and deliveres a transport stream */	    /* FIXME: v4l2 API needs some refinements for this... */	    h->flags |= CAN_MPEG_TS;	    h->mpeg = MPEG_TYPE_V4L2;	}    }    if (h->mpeg)	goto done;    /* check for ivtv driver */    if (0 == ioctl(h->fd, IVTV_IOC_G_CODEC, &codec)) {	h->flags |= CAN_MPEG_PS;	h->flags |= CAN_MPEG_TS;	h->mpeg = MPEG_TYPE_IVTV;    }    if (h->mpeg)	goto done;done:    if (!ng_debug)	return;    switch (h->mpeg) {    case MPEG_TYPE_V4L2:	fprintf(stderr, "v4l2: detected MPEG-capable v4l2 device.\n");	break;    case MPEG_TYPE_IVTV:	fprintf(stderr, "v4l2: detected ivtv driver\n");	break;    default:	return;    }    if (h->flags & CAN_MPEG_TS)	fprintf(stderr, "v4l2:   supports mpeg transport streams\n");    if (h->flags & CAN_MPEG_TS)	fprintf(stderr, "v4l2:   supports mpeg programs streams\n");}static char *v4l2_setup_mpeg(void *handle, int flags){    struct v4l2_handle *h = handle;    switch (h->mpeg) {    case MPEG_TYPE_V4L2:	return h->device;    case MPEG_TYPE_IVTV:    {	struct ivtv_ioctl_codec codec;	if (0 != ioctl(h->fd, IVTV_IOC_G_CODEC, &codec))	    return NULL;	if (flags & MPEG_FLAGS_PS)	    codec.stream_type = IVTV_STREAM_PS;	if (flags & MPEG_FLAGS_TS)	    codec.stream_type = IVTV_STREAM_TS;	if (0 != ioctl(h->fd, IVTV_IOC_S_CODEC, &codec))	    return NULL;	return h->device;    }    default:	return NULL;    }}/* ---------------------------------------------------------------------- */static void __init plugin_init(void){    ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&v4l2_driver);}

⌨️ 快捷键说明

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