c v4l2(拍照)


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(void)
{
	//1.打开设备
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	//得到摄像头信息
	struct v4l2_capability {
		__u8	driver[16];
		__u8	card[32];
		__u8	bus_info[32];
		__u32   version;
		__u32	capabilities;
		__u32	device_caps;
		__u32	reserved[3];
	}cap;
	if((ioctl(fd,VIDIOC_QUERYCAP,&cap))==-1){
		puts("ioctl error");
	}
	printf("%s\n",cap.driver);
	printf("%s\n",cap.card);
	printf("%x\n",cap.capabilities);
//查询支持的视频格式	
//	struct v4l2_fmtdesc fmtdesc;
	struct v4l2_fmtdesc {
		__u32		    index;             /* Format number      */
		__u32		    type;              /* enum v4l2_buf_type */
		__u32               flags;
		__u8		    description[32];   /* Description string */
		__u32		    pixelformat;       /* Format fourcc      */
		__u32		    mbus_code;		/* Media bus code    */
		__u32		    reserved[3];
	}fmtdesc;
	fmtdesc.index=0;
	fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	printf("Support format:\n");
	while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)       //查询摄像头支持格式
	{
		printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);
		fmtdesc.index++;                                          
	}
	
	//设置采集格式
	 
	/*720p格式,分辨率为1280×720p/60Hz,行频为45kHz 。*/
	struct v4l2_format {
		enum v4l2_buf_type {
			V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
			V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
			V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
			
			
		}type;
		
		
		union {
		//	struct v4l2_pix_format         pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
			struct v4l2_window             win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
			struct v4l2_vbi_format         vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
			struct v4l2_sliced_vbi_format  sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
			__u8   raw_data[200];                   /* user-defined */
			
			
			struct v4l2_pix_format {
				__u32			width;
				__u32			height;
				__u32			pixelformat;
				__u32			field;		/* enum v4l2_field */
				__u32			bytesperline;	/* for padding, zero if unused */
				__u32			sizeimage;
				__u32			colorspace;	/* enum v4l2_colorspace */
				__u32			priv;		/* private data, depends on pixelformat */
				__u32			flags;		/* format flags (V4L2_PIX_FMT_FLAG_*) */
				union {
					/* enum v4l2_ycbcr_encoding */
					__u32			ycbcr_enc;
					/* enum v4l2_hsv_encoding */
					__u32			hsv_enc;
				};
				__u32			quantization;	/* enum v4l2_quantization */
				__u32			xfer_func;	/* enum v4l2_xfer_func */
			}pix;
			
		} fmt;
	}vfmt;
	
//	memset(&vfmt,0,sizeof(vfmt));
    vfmt.type=1;
	
	vfmt.fmt.pix.width=1280;         //720p=1280*720
	vfmt.fmt.pix.height=720;
	vfmt.fmt.pix.pixelformat=V4L2_PIX_FMT_MJPEG;  //通过ioctl(VIDIOC_ENUM_FMT)查询摄像头支持的格式												  
	int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
	if(ret < 0)
	{
		perror("设置格式失败");
	}
	
	//4.申请内核缓冲区个数
//	struct v4l2_requestbuffers reqbuffer;
	
	struct v4l2_requestbuffers {
		__u32			count;
		__u32			type;		/* enum v4l2_buf_type */
		__u32			memory;		/* enum v4l2_memory */
		__u32			capabilities;
		__u32			reserved[1];
	}reqbuffer;
	
	reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	reqbuffer.count = 1; //申请4个缓冲区
	reqbuffer.memory = V4L2_MEMORY_MMAP ;//映射方式
	ret  = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer);
	if(ret < 0)
	{
		perror("申请队列空间失败");
	}
	
	//设置 设备映射到内存的选项
	struct v4l2_buffer {
		__u32			index;
		__u32			type;
		__u32			bytesused;
		__u32			flags;
		__u32			field;
		struct timeval		timestamp;
		struct v4l2_timecode	timecode;
		__u32			sequence;
		
		/* memory location */
		__u32			memory;
		union {
			__u32           offset;
			unsigned long   userptr;
			struct v4l2_plane *planes;
			__s32		fd;
		} m;
		__u32			length;
		__u32			reserved2;
		union {
			__s32		request_fd;
			__u32		reserved;
		};
	}mapbuffer;
	unsigned char *mptr;
	unsigned int  size;
	mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	mapbuffer.index = 0;
	
		ret = ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer);//查询缓冲区状态
		if(ret < 0)
		{
			perror("查询内核空间队列失败");
		}
		
		int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		ret = ioctl(fd, VIDIOC_STREAMON, &type);     //启动流
		if(ret < 0)
		{
			perror("开启失败");
		}

		mptr= (unsigned char *)mmap(NULL, mapbuffer.length, PROT_READ|PROT_WRITE, 
			MAP_SHARED, fd, mapbuffer.m.offset);       //设备映射到缓冲区内存
		size=mapbuffer.length;
		
		ret  = ioctl(fd, VIDIOC_QBUF, &mapbuffer);    //把缓冲区数据放入读队列中
		if(ret < 0)                                   
		{
			perror("放回失败");
		}

	ret = ioctl(fd, VIDIOC_DQBUF, &mapbuffer);       //读当前队列缓冲区的数据
	if(ret < 0)
	{
		perror("提取数据失败");
	  }
	
	FILE *file=fopen("my.jpg", "w+");

	fwrite(mptr,mapbuffer.length, 1, file);
	fclose(file);
	
	ret = ioctl(fd, VIDIOC_QBUF, &mapbuffer);       //把缓冲区放回队列中,准备存数据
	if(ret < 0)
	{
		perror("放回队列失败");
    }
	
	ret = ioctl(fd, VIDIOC_STREAMOFF, &type);

	munmap(mptr, size);

	close(fd);
	
	return 0;
}
​
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(void){
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	struct v4l2_format vfmt;
		vfmt.type=1;
	vfmt.fmt.pix.width=1680;         
	vfmt.fmt.pix.height=1080;
	vfmt.fmt.pix.pixelformat=V4L2_PIX_FMT_MJPEG; 
	int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
	if(ret < 0)
	{
		perror("设置格式失败");
	}
	
	struct v4l2_requestbuffers reqbuffer;
	reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	reqbuffer.count = 1; 
	reqbuffer.memory = V4L2_MEMORY_MMAP ;
	ret  = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer);
	if(ret < 0)
	{
		perror("申请队列空间失败");
	}
	
	struct v4l2_buffer mapbuffer;
	unsigned char *mptr;
	unsigned int  size;
	mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	mapbuffer.index = 0;
	
	ret = ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer);//查询缓冲区状态
	if(ret < 0)
	{
		perror("查询内核空间队列失败");
	}
	
	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(fd, VIDIOC_STREAMON, &type);     //启动流
	if(ret < 0)
	{
		perror("开启失败");
	}
	
	mptr= (unsigned char *)mmap(NULL, mapbuffer.length, PROT_READ|PROT_WRITE, 
		MAP_SHARED, fd,0);       //设备映射到缓冲区内存
	size=mapbuffer.length;
	
	ret  = ioctl(fd, VIDIOC_QBUF, &mapbuffer);    //把缓冲区数据放入读队列中
	if(ret < 0)                                   
	{
		perror("放回失败");
	}
	
	ret = ioctl(fd, VIDIOC_DQBUF, &mapbuffer);       //读当前队列缓冲区的数据
	if(ret < 0)
	{
		perror("提取数据失败");
	}
	
	FILE *file=fopen("my.jpg", "w+");
	
	fwrite(mptr,mapbuffer.length, 1, file);
	fclose(file);

	ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
	
	munmap(mptr, size);
	
	close(fd);
	
	return 0;
}

​

连续批量生成照片文件


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(void)
{
	//1.打开设备
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	//得到摄像头信息
	struct v4l2_capability {
		__u8	driver[16];
		__u8	card[32];
		__u8	bus_info[32];
		__u32   version;
		__u32	capabilities;
		__u32	device_caps;
		__u32	reserved[3];
	}cap;
	if((ioctl(fd,VIDIOC_QUERYCAP,&cap))==-1){
		puts("ioctl error");
	}
	printf("%s\n",cap.driver);
	printf("%s\n",cap.card);
	printf("%x\n",cap.capabilities);
//查询支持的视频格式	
//	struct v4l2_fmtdesc fmtdesc;
	struct v4l2_fmtdesc {
		__u32		    index;             /* Format number      */
		__u32		    type;              /* enum v4l2_buf_type */
		__u32               flags;
		__u8		    description[32];   /* Description string */
		__u32		    pixelformat;       /* Format fourcc      */
		__u32		    mbus_code;		/* Media bus code    */
		__u32		    reserved[3];
	}fmtdesc;
	fmtdesc.index=0;
	fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	printf("Support format:\n");
	while(ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) != -1)       //查询摄像头支持格式
	{
		printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);
		fmtdesc.index++;                                          
	}
	
	//设置采集格式
	 
	/*720p格式,分辨率为1280×720p/60Hz,行频为45kHz 。*/
	struct v4l2_format {
		enum v4l2_buf_type {
			V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
			V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
			V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
			
			
		}type;
		
		
		union {
		//	struct v4l2_pix_format         pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
			struct v4l2_window             win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
			struct v4l2_vbi_format         vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
			struct v4l2_sliced_vbi_format  sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
			__u8   raw_data[200];                   /* user-defined */
			
			
			struct v4l2_pix_format {
				__u32			width;
				__u32			height;
				__u32			pixelformat;
				__u32			field;		/* enum v4l2_field */
				__u32			bytesperline;	/* for padding, zero if unused */
				__u32			sizeimage;
				__u32			colorspace;	/* enum v4l2_colorspace */
				__u32			priv;		/* private data, depends on pixelformat */
				__u32			flags;		/* format flags (V4L2_PIX_FMT_FLAG_*) */
				union {
					/* enum v4l2_ycbcr_encoding */
					__u32			ycbcr_enc;
					/* enum v4l2_hsv_encoding */
					__u32			hsv_enc;
				};
				__u32			quantization;	/* enum v4l2_quantization */
				__u32			xfer_func;	/* enum v4l2_xfer_func */
			}pix;
			
		} fmt;
	}vfmt;
	
//	memset(&vfmt,0,sizeof(vfmt));
    vfmt.type=1;
	
	vfmt.fmt.pix.width=1280;         //720p=1280*720
	vfmt.fmt.pix.height=720;
	vfmt.fmt.pix.pixelformat=V4L2_PIX_FMT_MJPEG;  //通过ioctl(VIDIOC_ENUM_FMT)查询摄像头支持的格式												  
	int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
	if(ret < 0)
	{
		perror("设置格式失败");
	}
	
	//4.申请内核缓冲区个数
//	struct v4l2_requestbuffers reqbuffer;
	
	struct v4l2_requestbuffers {
		__u32			count;
		__u32			type;		/* enum v4l2_buf_type */
		__u32			memory;		/* enum v4l2_memory */
		__u32			capabilities;
		__u32			reserved[1];
	}reqbuffer;
	
	reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	reqbuffer.count = 1; //申请4个缓冲区
	reqbuffer.memory = V4L2_MEMORY_MMAP ;//映射方式
	ret  = ioctl(fd, VIDIOC_REQBUFS, &reqbuffer);
	if(ret < 0)
	{
		perror("申请队列空间失败");
	}
	
	//设置 设备映射到内存的选项
	struct v4l2_buffer {
		__u32			index;
		__u32			type;
		__u32			bytesused;
		__u32			flags;
		__u32			field;
		struct timeval		timestamp;
		struct v4l2_timecode	timecode;
		__u32			sequence;
		
		/* memory location */
		__u32			memory;
		union {
			__u32           offset;
			unsigned long   userptr;
			struct v4l2_plane *planes;
			__s32		fd;
		} m;
		__u32			length;
		__u32			reserved2;
		union {
			__s32		request_fd;
			__u32		reserved;
		};
	}mapbuffer;
	
	mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	mapbuffer.index = 0;
	
	ret = ioctl(fd, VIDIOC_QUERYBUF, &mapbuffer);//查询缓冲区状态
	if(ret < 0)
		{
			perror("查询内核空间队列失败");
		}
		
	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret = ioctl(fd, VIDIOC_STREAMON, &type);     //启动流
	if(ret < 0)
		{
			perror("开启失败");
		}
		
	unsigned char *mptr;
	unsigned int  size;

	mptr= (unsigned char *)mmap(NULL,1280*720, PROT_READ|PROT_WRITE, 
			MAP_SHARED, fd,0);       //设备映射到缓冲区内存
	size=mapbuffer.length;
	
	ret  = ioctl(fd, VIDIOC_QBUF, &mapbuffer);    //把缓冲区数据放入读队列中
	if(ret < 0)                                   
		{
			perror("放回失败");
  }
    int t=0;
	while(1){
	
	ret = ioctl(fd, VIDIOC_DQBUF, &mapbuffer);       //读当前队列缓冲区的数据
	if(ret < 0)
	{
		perror("提取数据失败");
  }  
    char wj[4];
	sprintf(wj,"%d",t);                   //int-->char
	
	FILE *file=fopen(wj,"w+");
	fwrite(mptr,1280*720, 1, file);
	fclose(file);

	
	ret = ioctl(fd, VIDIOC_QBUF, &mapbuffer);       //把缓冲区放回队列中,准备存数据
	if(ret < 0)
	{
		perror("放回队列失败");
    }
    t++;
	sleep(1);
	}
  ret = ioctl(fd, VIDIOC_STREAMOFF, &type);

	munmap(mptr, size);

	close(fd);
	
	return 0;
}

ffmpeg -f image2 -i %d output.mp4
图片生成视频

你可能感兴趣的:(c语言,开发语言)