- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>/* low-level i/o*/
- #include <unistd.h>
- #include <errno.h>
- #include <malloc.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/mman.h>
- #include <sys/ioctl.h>
- #include <linux/videodev2.h>
- #define DEVICE "/dev/video"
- static struct v4l2_requestbuffers req;
- struct buffer
- {
- void* start;
- unsigned int length;
-
};
- static struct buffer *buffers;
- static struct v4l2_buffer buf;
usb_camera.c
- #include "head.h"
- int main()
- {
- int fd;
- fd=open_device();
- get_device_info(fd);
- get_frame_fmt(fd);
- get_current_frame_info(fd);
- try_format_support(fd);
- set_frame_format(fd);
- apply_memory_buf(fd);
- memory_mapping(fd);
- buffer_enqueue(fd);
- close(fd);
- return 0;
- }
- int open_device()
- {
- int fd;
- if(-1==(fd=open(DEVICE,O_RDWR)))
- printf("info:Can't open video device\n");
- else
- printf("info:Open the device :%d\n",fd);
- return fd;
- }
- int get_device_info(int fd)
- {
- struct v4l2_capability cap;
- if(-1==ioctl(fd,VIDIOC_QUERYCAP,&cap))
- printf("info:VIDIOC_QUERYCAP ERROR\n");
- else
- printf("info:Driver Name:%s....Card Name:%s....Bus info:%s....Driver Version:%u.%u.%u\n",
- cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0XFF,(cap.version>>8)&0XFF,cap.version&0XFF);
- return 1;
- }
- int get_frame_fmt(int fd)
- {
- struct v4l2_fmtdesc fmtdesc;
- fmtdesc.index=0;
- fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- printf("info:Support format:");
- while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
- {
- printf("\t%d.%s",fmtdesc.index+1,fmtdesc.description);
- fmtdesc.index++;
- }
- printf("\n");
- return 1;
- }
- int get_current_frame_info(int fd)
- {
- struct v4l2_format fmt;
- fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ioctl(fd,VIDIOC_G_FMT,&fmt);
- printf("info:Current data format information:\n\twidth:%d\n\theight:%d\n",fmt.fmt.pix.width,fmt.fmt.pix.height);
- struct v4l2_fmtdesc fmtdesc;
- fmtdesc.index=0;
- fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
- {
- if(fmtdesc.pixelformat& fmt.fmt.pix.pixelformat)
- {
- printf("\tformat:%s\n",fmtdesc.description);
- break;
- }
- fmtdesc.index++;
-
}
- return 1;
- }
- int try_format_support(int fd)
- {
- struct v4l2_format fmt;
- fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- //fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_RGB32;
- fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
- if(ioctl(fd,VIDIOC_TRY_FMT,&fmt)==-1)
- if(errno==EINVAL)
-
printf("info:not support format RGB32!\n");
- return 1;
- }
- int set_frame_format(int fd)
- {
- struct v4l2_format fmt;
- fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width=640;
- fmt.fmt.pix.height=480;
- fmt.fmt.pix.pixelformat= V4L2_PIX_FMT_YUYV;
-
fmt.fmt.pix.field= V4L2_FIELD_INTERLACED;
- if(ioctl(fd,VIDIOC_S_FMT,&fmt)==-1)
- if(errno==EINVAL)
- printf("info:set frame format error!\n");
- return 1;
- }
- int apply_memory_buf(int fd)
- {
- //struct v4l2_requestbuffers req;
- req.count=4;
- req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- req.memory=V4L2_MEMORY_MMAP;
- if(-1==ioctl(fd,VIDIOC_REQBUFS,&req))
- printf("info:VIDIOC_REQBUFS FAILED\n");
- else
- printf("info:VIDIOC_REQBUFS SUCCESS\n");
- return 1;
- }
- int memory_mapping(int fd)
- {
- unsigned int n_buffers;
- buffers =(struct buffer*)calloc(req.count,sizeof(struct buffer));
- 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;
- memset(&buf,0,sizeof(buf));
- buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf.memory= V4L2_MEMORY_MMAP;
- buf.index= n_buffers;
- // 查询序号为n_buffers 的缓冲区,得到其起始物理地址和大小
- if(-1 == ioctl (fd, VIDIOC_QUERYBUF,&buf))
- exit(-1);
- buffers[n_buffers].length= buf.length;
- // 映射内存
- buffers[n_buffers].start=mmap (NULL,buf.length,PROT_READ| PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);
- if(MAP_FAILED == buffers[n_buffers].start)
- exit(-1);
-
}
- printf("info:memory mapping success\n");
- return 1;
- }
- int buffer_enqueue(int fd)
- {
- unsigned int i;
- enum v4l2_buf_type type;
- // 将缓冲帧放入队列
- for (i = 0; i< 4; ++i)
- {
- struct v4l2_buffer buf;
- buf.type= V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf.memory= V4L2_MEMORY_MMAP;
- buf.index= i;
- if(-1==ioctl(fd, VIDIOC_QBUF,&buf))
- printf("buffer enqueue failed\n");
- }
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- //open stream
- if(-1==ioctl(fd, VIDIOC_STREAMON,&type))
- printf("info:open stream failed\n");
- else
- printf("info:open stream success\n");
- return 1;
- }