编写v4l2应用程序基本步骤:
代码:
#include "stdio.h"
#include "linux/videodev2.h"
#include
#include
#include
#include
#include
#include
#include
#include "string.h"
#include
#define CLEAR(type) memset(&type,0,sizeof(type))
#define PRINT_RET(ret) printf("%d ret: %d\n",__LINE__ ,ret)
void print_cap(struct v4l2_capability *cap);
void print_format( struct v4l2_format *format);
void print_input(struct v4l2_input*input);
void print_buff(struct v4l2_buffer*buff);
struct buf_addr{
unsigned long size;
void *addr;
};
int main(int argc,char*argv[])
{
struct v4l2_capability cap;
struct v4l2_format format;
struct v4l2_input input;
struct v4l2_requestbuffers req;
struct v4l2_buffer buff;
struct buf_addr buff_addr[5];
fd_set fds;
FILE *fp;
int ret;
int i;
printf("-----------------test camera----------------\n");
int fd = open("/dev/video0",O_RDWR|O_NONBLOCK);
fp = fopen("./camera.yuv","wb");
printf("fd: %d\n",fd);
CLEAR(cap);
CLEAR(format);
CLEAR(input);
CLEAR(req);
CLEAR(buff);
FD_ZERO(&fds);
ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
printf("1ret: %d\n",ret);
input.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd,VIDIOC_ENUMINPUT,&input);PRINT_RET(ret);
format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd,VIDIOC_G_FMT,&format);PRINT_RET(ret);
req.count = 5;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd,VIDIOC_REQBUFS,&req);PRINT_RET(ret);
for(i=0;i<5;i++){
CLEAR(buff);
buff.index = i;
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd,VIDIOC_QUERYBUF,&buff);PRINT_RET(ret);
buff_addr[i].size = buff.length;
buff_addr[i].addr = mmap(NULL, buff.length,
PROT_READ|PROT_WRITE, MAP_SHARED,
fd,buff.m.offset);
// printf("addr:%u size:%x\n",buff_addr[i].addr,buff_addr[i].size);
}
for(i=0;i<5;i++){
CLEAR(buff);
buff.index = i;
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd,VIDIOC_QBUF,&buff);PRINT_RET(ret);
}
ret = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd,VIDIOC_STREAMON,&ret);PRINT_RET(ret);
for(i=0;i<1000;i++){
FD_ZERO(&fds);
FD_SET(fd,&fds);
struct timeval t;
t.tv_sec = 5;
t.tv_usec=5;
ret = select(fd+1,&fds,NULL,NULL,&t);PRINT_RET(ret);
CLEAR(buff);
buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buff.memory = V4L2_MEMORY_MMAP;
ret = ioctl(fd,VIDIOC_DQBUF,&buff);PRINT_RET(ret);
/**********************************************/
print_buff(&buff);
fwrite(buff_addr[buff.index].addr,
buff_addr[buff.index].size,1,fp);
fflush(fp);
/**********************************************/
ret = ioctl(fd,VIDIOC_QBUF,&buff);PRINT_RET(ret);
}
print_cap(&cap);
print_input(&input);
print_format(&format);
ret = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(fd,VIDIOC_STREAMOFF,&ret);PRINT_RET(ret);
for(i=0;i<5;i++){
munmap(buff_addr[i].addr,buff_addr[i].size);
}
close(fd);
fclose(fp);
}
void print_cap(struct v4l2_capability *cap)
{
if(!cap)return;
printf("--------------print_cap------------------\n");
printf("driver: %s\n",cap->driver);
printf("card: %s\n",cap->card);
printf("bus_info: %s\n",cap->bus_info);
printf("version: %d\n",cap->version);
printf("capabilities: %x\n",cap->capabilities);
printf("device_caps: %x\n",cap->device_caps);
}
void print_format( struct v4l2_format *format)
{
if(!format)return;
printf("--------------print_format------------------\n");
printf("type: %d\n",format->type);
printf("width: %d\n",format->fmt.pix.width);
printf("height: %d\n",format->fmt.pix.height);
printf("pixelformat: %c %c %c %c\n",
format->fmt.pix.pixelformat&0xff,
(format->fmt.pix.pixelformat>>8)&0xff,
(format->fmt.pix.pixelformat>>16)&0xff,
(format->fmt.pix.pixelformat>>24)&0xff);
printf("field: %x\n",format->fmt.pix.field);
printf("bytesperline: %d\n",format->fmt.pix.bytesperline);
printf("sizeimage: %d\n",format->fmt.pix.sizeimage);
printf("colorspace: %x\n",format->fmt.pix.colorspace);
}
void print_input(struct v4l2_input*input)
{
if(!input)return;
printf("--------------print_input------------------\n");
printf("index: %d\n",input->index);
printf("name: %s\n",input->name);
printf("type: %d\n",input->type);
printf("audioset: %d\n",input->audioset);
printf("tuner: %d\n",input->tuner);
}
void print_buff(struct v4l2_buffer*buff)
{
static unsigned long count=0;
if(!buff)return;
printf("--------------print_buff------------------\n");
printf("count: %ld\n",count++);
printf("index: %d\n",buff->index);
printf("type: %d\n",buff->type);
printf("bytesused: %d\n",buff->bytesused);
printf("memory: %x\n",buff->memory);
printf("length: %d\n",buff->length);
}
注意:
我这里的摄像头输入的事yuyv格式,可用yuvplayer打开
播放器地址:播放yuv格式的视频支持常用的yuv和rgb格式-Linux文档类资源-CSDN文库