arm-linux V4L2 图像采集
下面是我写的一段关于V4L2采集图像输出图片的程序,可是出来的图片总是空白的,好像是存储空间分配的问题,但是我也没看出是什么错误,想让高手们看看是什么地方错了。方便的话也可以QQ联系。
QQ:877431484
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
int main()
{
printf("Program start!\n");
int fd;
fd=open("/dev/video0",O_RDWR);
if(fd == -1)
{printf("Failed to open video device!\n"); return -1; }
else
printf("Open video devive seccess!\n");
struct v4l2_capability cap;
if(ioctl(fd,VIDIOC_QUERYCAP,&cap)==-1)
{printf("VIDIOC_QUERYCAP failure!\n");return -1;}
printf("Capability Informations:\n");
printf(" driver: %s\n", cap.driver);
printf(" card: %s\n", cap.card);
printf(" bus_info: %s\n", cap.bus_info);
printf(" version: %08x\n", cap.version);
printf(" capabilities: %08x\n", cap.capabilities);
struct v4l2_format fmt;
memset (&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width= 720;
fmt.fmt.pix.height= 576;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field= V4L2_FIELD_INTERLACED;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{printf("can't fmt\n");return -1;}
if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{ printf("VIDIOC_G_FMT failed\n"); return -1;}
printf("Stream Format Informations:\n");
printf(" type: %d\n", fmt.type);
printf(" width: %d\n", fmt.fmt.pix.width);
printf(" height: %d\n", fmt.fmt.pix.height);
char fmtstr[8];
memset(fmtstr, 0, 8);
memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);
printf(" pixelformat: %s\n", fmtstr);
printf(" field: %d\n", fmt.fmt.pix.field);
printf(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);
printf(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);
printf(" colorspace: %d\n", fmt.fmt.pix.colorspace);
printf(" priv: %d\n", fmt.fmt.pix.priv);
printf(" raw_date: %s\n", fmt.fmt.raw_data);
struct v4l2_requestbuffers req;
req.count=4;
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1)
{printf("can't requesbuffers\n");return -1;}
typedef struct VideoBuffer
{
void *start;
size_t length;
}VideoBuffer;
VideoBuffer *buffers = calloc(req.count, sizeof(*buffers));
struct v4l2_buffer buf;
int numBufs;
for (numBufs=0;numBufs<req.count;numBufs++)
{
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = numBufs;
if (ioctl(fd,VIDIOC_QUERYBUF,&buf)==-1)
{ printf("can't querybuf\n");return -1; }
buffers[numBufs].length = buf.length;
buffers[numBufs].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED,fd, buf.m.offset);
if (buffers[numBufs].start == MAP_FAILED)
{ printf("can't mmap\n");return -1;}
if (ioctl(fd, VIDIOC_QBUF, &buf) == -1)
{printf("VIDIOC_QBUF failure!\n");return -1;}
printf("Frame buffer %d: address=0x%x, length=%d\n", numBufs, (unsigned int) buffers[numBufs].start, buffers[numBufs].length);
}
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(fd,VIDIOC_STREAMON,&type)==-1)
{printf("VIDIOC_STREAMON FAILURE!\n");return -1;}
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if(ioctl(fd,VIDIOC_DQBUF, &buf)==-1) { printf("can't dqbuf\n"); return -1;}
FILE *fp = fopen("frame.jpg", "wb");
if (fp < 0)
{
printf("open frame data file failed\n");
return -1;
}
fwrite(buffers[buf.index].start, buffers[buf.index].length, 1, fp);
fclose(fp);
printf("Capture one frame saved in %s\n", "frame.jpg");
if(ioctl(fd,VIDIOC_QBUF, &buf)==-1) { printf("can't qbuf\n"); return -1;}
if(ioctl(fd,VIDIOC_STREAMOFF, &buf.type)==-1)
{printf("Can't VIDIOC_STREAMOFF"); return -1;}
for (numBufs=0; numBufs< 4; numBufs++)
{
munmap(buffers[numBufs].start, buffers[numBufs].length);
}
close(fd);
printf("Program end!\n");
return 0;
}