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

📄 rhduvc.c

📁 用Linux C写的基于minigui开源版本和V4L2的图像采集显示程序
💻 C
字号:
/* *  V4L2 video capture example * *  This program can be used and distributed without restrictions. */#include "rhduvc.h"char *           dev_name        = "/dev/video0";int              videofd              = -1;struct buffer *         buffers         = NULL;unsigned int     n_buffers       = 0;void errno_exit (char *s){        fprintf (stderr, "%s error %d, %s\n",                 s, errno, strerror (errno));        exit (EXIT_FAILURE);}int xioctl (int videofd, int request, void *arg){        int r;        do r = ioctl (videofd, request, arg);        while (-1 == r && EINTR == errno);        return r;}void process_image (void *videoptr, void *p, size_t l){
		memcpy(videoptr,p,l);/*				FILE* fp;
				fp = fopen("test","w");
                                fwrite(p,1,l,fp);
                                fclose(fp);
*/         printf("Process_a_frame_image!\n");}int read_frame (void *videoptr,size_t videosize){        struct v4l2_buffer buf;		CLEAR (buf);            	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;            	buf.memory = V4L2_MEMORY_MMAP;    		if (-1 == xioctl (videofd, VIDIOC_DQBUF, &buf)) {	printf("Read_frame VIDIOC_DQBUF error! %d\n",errno);            		switch (errno) {            		case EAGAIN:                    		return 0;			case EIO:				/* Could ignore EIO, see spec. */				/* fall through */			default:				errno_exit ("VIDIOC_DQBUF");			}		} 		printf("buf.index= %d  buffers.size = %d\n",buf.index,buffers[buf.index].length);	        videosize = buffers[buf.index].length;		process_image (videoptr,buffers[buf.index].start,buffers[buf.index].length);		if (-1 == xioctl (videofd, VIDIOC_QBUF, &buf))			errno_exit ("VIDIOC_QBUF");	return 1;}void stop_capturing (void){        enum v4l2_buf_type type;		type = V4L2_BUF_TYPE_VIDEO_CAPTURE;	printf("stop_capturing \n");		if (-1 == xioctl (videofd, VIDIOC_STREAMOFF, &type))			errno_exit ("VIDIOC_STREAMOFF");}void start_capturing (void){        unsigned int i;        enum v4l2_buf_type type;	printf("start_capturing IO_METHOD_MMAP n_buffers= %d\n",n_buffers);		for (i = 0; i < n_buffers; ++i) {            		struct v4l2_buffer buf;        		CLEAR (buf);        		buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;        		buf.memory      = V4L2_MEMORY_MMAP;        		buf.index       = i;        		if (-1 == xioctl (videofd, VIDIOC_QBUF, &buf))                    		errno_exit ("VIDIOC_QBUF");		}				type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		if (-1 == xioctl (videofd, VIDIOC_STREAMON, &type))			errno_exit ("VIDIOC_STREAMON");}void get_a_frame (void *videoptr,size_t videosize){                 for (;;) {                      fd_set fds;                        struct timeval tv;                        int r;                        FD_ZERO (&fds);                        FD_SET (videofd, &fds);                           tv.tv_sec = 1;                        tv.tv_usec = 0;                        r = select (videofd + 1, &fds, NULL, NULL, &tv);                        if (-1 == r) {                                if (EINTR == errno)                                        continue;                                errno_exit ("select");                        }                        if (0 == r) {                                fprintf (stderr, "select timeout\n");                                exit (EXIT_FAILURE);                        }			if (read_frame (videoptr,videosize))                    		break;				/* EAGAIN - continue select loop. */                }}void uninit_device (void){        unsigned int i;		for (i = 0; i < n_buffers; ++i)			if (-1 == munmap (buffers[i].start, buffers[i].length))				errno_exit ("munmap");	free (buffers);}void init_mmap (void){	struct v4l2_requestbuffers req;        CLEAR (req);        req.count               = 2;        req.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;        req.memory              = V4L2_MEMORY_MMAP;	printf("init_mmap\n");	if (-1 == xioctl (videofd, VIDIOC_REQBUFS, &req)) {                if (EINVAL == errno) {                        fprintf (stderr, "%s does not support "                                 "memory mapping\n", dev_name);                        exit (EXIT_FAILURE);                } else {                        errno_exit ("VIDIOC_REQBUFS");                }        }        if (req.count < 2) {                fprintf (stderr, "Insufficient buffer memory on %s\n",                         dev_name);                exit (EXIT_FAILURE);        }        buffers = calloc (req.count, sizeof (*buffers));        if (!buffers) {                fprintf (stderr, "Out of memory\n");                exit (EXIT_FAILURE);        }        for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {                struct v4l2_buffer buf;                CLEAR (buf);                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;                buf.memory      = V4L2_MEMORY_MMAP;                buf.index       = n_buffers;                if (-1 == xioctl (videofd, VIDIOC_QUERYBUF, &buf))                        errno_exit ("VIDIOC_QUERYBUF");                buffers[n_buffers].length = buf.length;                buffers[n_buffers].start =                        mmap (NULL /* start anywhere */,                              buf.length,                              PROT_READ | PROT_WRITE /* required */,                              MAP_SHARED /* recommended */,                              videofd, buf.m.offset);                if (MAP_FAILED == buffers[n_buffers].start)                        errno_exit ("mmap");        }}void init_device (void){        struct v4l2_capability cap;        struct v4l2_cropcap cropcap;        struct v4l2_crop crop;        struct v4l2_format fmt;	unsigned int min;	printf("init_device\n");        if (-1 == xioctl (videofd, VIDIOC_QUERYCAP, &cap)) {                if (EINVAL == errno) {                        fprintf (stderr, "%s is no V4L2 device\n",                                 dev_name);                        exit (EXIT_FAILURE);                } else {                        errno_exit ("VIDIOC_QUERYCAP");                }        }	printf("VIDIOC_QUERYCAP Success!\n");        if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {                fprintf (stderr, "%s is no video capture device\n",                         dev_name);                exit (EXIT_FAILURE);        }		if (!(cap.capabilities & V4L2_CAP_STREAMING)) {			fprintf (stderr, "%s does not support streaming i/o\n",				 dev_name);			exit (EXIT_FAILURE);		}        /* Select video input, video standard and tune here. */	CLEAR (cropcap);        cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        if (0 == xioctl (videofd, VIDIOC_CROPCAP, &cropcap)) {	printf("VIDIOC_CROPCAP Success!\n");    printf("Type:%d\n",cropcap.type);
    printf("bounds  width:%d,height:%d\n",cropcap.bounds.width ,cropcap.bounds.height);
    printf("defrect width:%d,height:%d\n",cropcap.defrect.width,cropcap.defrect.height);
                crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;                crop.c = cropcap.defrect; /* reset to default */                if (-1 == xioctl (videofd, VIDIOC_S_CROP, &crop)) {	printf("VIDIOC_S_CROP error %d\n",errno);                        switch (errno) {                        case EINVAL:                                /* Cropping not supported. */                                break;                        default:                                /* Errors ignored. */                                break;                        }                }        } else {	 	printf("VIDIOC_CROPCAP error %d\n",errno);               /* Errors ignored. */        }        CLEAR (fmt);        fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;        fmt.fmt.pix.width       = 320;         fmt.fmt.pix.height      = 240;        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;        fmt.fmt.pix.field       = V4L2_FIELD_ANY;        if (-1 == xioctl (videofd, VIDIOC_S_FMT, &fmt))              errno_exit ("VIDIOC_S_FMT");        if (-1 == xioctl (videofd, VIDIOC_G_FMT, &fmt))                errno_exit ("VIDIOC_G_FMT");	printf("VIDIOC_G_FMT Success!\n");    printf("Type:%d\n",fmt.type);
    printf("width:%d,height:%d\n",fmt.fmt.pix.width ,fmt.fmt.pix.height);
    printf("pixelformat:%8x,field:%d\n",fmt.fmt.pix.pixelformat,fmt.fmt.pix.field);
        /* Note VIDIOC_S_FMT may change width and height. */        /* set framerate *//*    struct v4l2_streamparm* setfps;      setfps=(struct v4l2_streamparm *) calloc(1, sizeof(struct v4l2_streamparm));    setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        if (-1 == xioctl (videofd, VIDIOC_G_PARM, setfps))                errno_exit ("VIDIOC_G_PARAM");printf("VIDIOC_G_PARAM ,  numerator= %d  timeperframe= %d  \n",           setfps->parm.capture.timeperframe.numerator,setfps->parm.capture.timeperframe.denominator);    setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    setfps->parm.capture.timeperframe.numerator=1;    setfps->parm.capture.timeperframe.denominator=25;        if (-1 == xioctl (videofd, VIDIOC_S_PARM, setfps))                errno_exit ("VIDIOC_S_PARAM");*//* Buggy driver paranoia. */	min = fmt.fmt.pix.width * 2;	if (fmt.fmt.pix.bytesperline < min)		fmt.fmt.pix.bytesperline = min;	min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;	if (fmt.fmt.pix.sizeimage < min)		fmt.fmt.pix.sizeimage = min;		init_mmap ();}void close_device (void){        if (-1 == close (videofd))	        errno_exit ("close");        videofd = -1;}void open_device (void){        struct stat st; 	printf("open_device\n");        if (-1 == stat (dev_name, &st)) {                fprintf (stderr, "Cannot identify '%s': %d, %s\n",                         dev_name, errno, strerror (errno));                exit (EXIT_FAILURE);        }        if (!S_ISCHR (st.st_mode)) {                fprintf (stderr, "%s is no device\n", dev_name);                exit (EXIT_FAILURE);        }        videofd = open (dev_name, O_RDWR /* required */| O_NONBLOCK, 0);        if (-1 == videofd) {                fprintf (stderr, "Cannot open '%s': %d, %s\n",                         dev_name, errno, strerror (errno));                exit (EXIT_FAILURE);        }}

⌨️ 快捷键说明

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