首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 平面设计 > 图形图像 >

arm-linux V4L2 图像采摘

2013-09-15 
arm-linux V4L2 图像采集下面是我写的一段关于V4L2采集图像输出图片的程序,可是出来的图片总是空白的,好像

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;
}


[解决办法]
24行,你将 pixelformat设置为其他格式试一下。我试了下你的代码,修改为MJPEG,是可以得到图片的。
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;//change from V4L2_PIX_FMT_YUYV;

热点排行