v4l2 camera测试程序 保存成图片

v4l2 camera测试程序 保存成图片
标签: c语言linuxuvc_camera
445人阅读 评论(0) 收藏 举报
本文章已收录于:

使用的usb camera 是 0ac8:3420,使用网上找到的代码改

保存在图片,中间的LCD部分可以删了,我还要用就没改。

  1. /* 
  2.  * main.c 
  3.  * 
  4.  *  Created on: Apr 25, 2016 
  5.  *      Author: anzyelay 
  6.  */  
  7. #include <unistd.h>  
  8. #include <linux/fb.h>  
  9. #include <stdio.h>  
  10. #include <stdlib.h>  
  11. #include <string.h>  
  12. #include <assert.h>  
  13. #include <getopt.h>  
  14. #include <fcntl.h>  
  15. #include <unistd.h>  
  16. #include <errno.h>  
  17. #include <malloc.h>  
  18. #include <sys/stat.h>  
  19. #include <sys/types.h>  
  20. #include <sys/time.h>  
  21. #include <sys/mman.h>  
  22. #include <sys/ioctl.h>  
  23.   
  24. #include <asm/types.h>  
  25. #include <linux/videodev2.h>  
  26.   
  27. #include "bmp.h"  
  28.   
  29. #define CAMERA_DEVICE "/dev/video0"  
  30. #define FB_DEVICE "/dev/fb0"  
  31.   
  32. #define VIDEO_WIDTH 640  
  33. #define VIDEO_HEIGHT 480  
  34. #define BUFFER_COUNT 4  
  35.   
  36. typedef struct VideoBuffer {  
  37.     void   *start;  
  38.     size_t  length;  
  39. } VideoBuffer;  
  40.   
  41. VideoBuffer framebuf[BUFFER_COUNT];  
  42.   
  43. //查表法,把YUV422转换为RGB32  
  44. void process(unsigned long *rgb_buf, unsigned char *v_buf)  
  45. {  
  46.     int r,g,b;  
  47.     int u,v;  
  48.     int y[2];  
  49.     int rv,guv,bu,i;  
  50.     unsigned int *fb_buf = (unsigned int *)rgb_buf;  
  51.     y[0]=(int)*v_buf;  
  52.     v=(int)*(v_buf+1);  
  53.     y[1]=(int)*(v_buf+2);  
  54.     u=(int)*(v_buf+3);  
  55.     rv=rvarrxyp[v];  
  56.     guv=guarrxyp[u]+gvarrxyp[v];  
  57.     bu=buarrxyp[u];  
  58.   
  59.     for(i=0;i<2;i++){  
  60.         r=y[i]+rv;  
  61.         g=y[i]-guv;  
  62.         b=y[i]+bu;  
  63.         if (r>255) r=255;  
  64.         if (r<0) r=0;  
  65.         if (g>255) g=255;  
  66.         if (g<0) g=0;  
  67.         if (b>255) b=255;  
  68.         if (b<0) b=0;  
  69.         *(fb_buf+i)=(b<<16)+(g<<8)+r;  
  70.     }  
  71. }  
  72.   
  73. int main()  
  74. {  
  75.     int i, ret;  
  76.     // 打开摄像头设备  
  77.     int fd;  
  78.     fd = open(CAMERA_DEVICE, O_RDWR, 0);  
  79.     if (fd < 0) {  
  80.         printf("Open %s failed\n", CAMERA_DEVICE);  
  81.         return -1;  
  82.     }  
  83.   
  84.     // 获取驱动信息  
  85.     struct v4l2_capability cap;  
  86.     ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);  
  87.     if (ret < 0) {  
  88.         printf("VIDIOC_QUERYCAP failed (%d)\n", ret);  
  89.         goto __error1;  
  90.     }  
  91.   
  92.     printf("Capability Informations:\n");  
  93.     printf(" driver: %s\n", cap.driver);  
  94.     printf(" card: %s\n", cap.card);  
  95.     printf(" bus_info: %s\n", cap.bus_info);  
  96.     printf(" version: %u.%u.%u\n", (cap.version>>16)&0XFF, (cap.version>>8)&0XFF,cap.version&0XFF);  
  97.     printf(" capabilities: %08X\n", cap.capabilities);  
  98.   
  99.     // 设置视频格式  
  100.     struct v4l2_format fmt;  
  101.     memset(&fmt, 0, sizeof(fmt));  
  102.     fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  103.     fmt.fmt.pix.width       = VIDEO_WIDTH;  
  104.     fmt.fmt.pix.height      = VIDEO_HEIGHT;  
  105.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;  
  106.     fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;  
  107.     ret = ioctl(fd, VIDIOC_S_FMT, &fmt);  
  108.     if (ret < 0) {  
  109.         printf("VIDIOC_S_FMT failed (%d)\n", ret);  
  110.         goto __error1;  
  111.     }  
  112.   
  113.     //获取视频格式(原因是设置视频格式时如果有错误,VIDIOC_S_FMT时会自动转换成合作的格式,所以再获取一次)  
  114.     ret = ioctl(fd, VIDIOC_G_FMT, &fmt);  
  115.     if (ret < 0) {  
  116.         printf("VIDIOC_G_FMT failed (%d)\n", ret);  
  117.         goto __error1;  
  118.     }  
  119.     // Print Stream Format  
  120.     printf("Stream Format Informations:\n");  
  121.     printf(" type: %d\n", fmt.type);  
  122.     printf(" width: %d\n", fmt.fmt.pix.width);  
  123.     printf(" height: %d\n", fmt.fmt.pix.height);  
  124.     char fmtstr[8];  
  125.     memset(fmtstr, 0, 8);  
  126.     memcpy(fmtstr, &fmt.fmt.pix.pixelformat, 4);  
  127.     printf(" pixelformat: %s\n", fmtstr);  
  128.     printf(" field: %d\n", fmt.fmt.pix.field);  
  129.     printf(" bytesperline: %d\n", fmt.fmt.pix.bytesperline);  
  130.     printf(" sizeimage: %d\n", fmt.fmt.pix.sizeimage);  
  131.     printf(" colorspace: %d\n", fmt.fmt.pix.colorspace);  
  132.     printf(" priv: %d\n", fmt.fmt.pix.priv);  
  133.     printf(" raw_date: %s\n", fmt.fmt.raw_data);  
  134.   
  135. //-----------------------------------------------  
  136.     //请求分配内存  
  137.     struct v4l2_requestbuffers reqbuf;  
  138.     reqbuf.count = BUFFER_COUNT;  
  139.     reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  140.     reqbuf.memory = V4L2_MEMORY_MMAP;  
  141.   
  142.     ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);//在内核虚拟地址空间中申请reqbuf.count个连续的内存  
  143.     if(ret < 0) {  
  144.         printf("VIDIOC_REQBUFS failed (%d)\n", ret);  
  145.         goto __error1;  
  146.     }  
  147.   
  148.     struct v4l2_buffer buf;  
  149.     for (i = 0; i < reqbuf.count; i++)  
  150.     {  
  151.         buf.index = i;  
  152.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  153.         buf.memory = V4L2_MEMORY_MMAP;  
  154.         //根据buf.index询访内存为后面的映射做准备(本质就是设置buf.m.offset+=buf.length偏移)  
  155.         ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);  
  156.         if(ret < 0) {  
  157.             printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);  
  158.             goto __error1;  
  159.         }  
  160.         //映射到用户空间  
  161.         //就是将之前内核分配的视频缓冲(VIDIOC_REQBUFS)映射到用户空间,这样用户空间就可以直接读取内核扑获的视频数据  
  162.         //buf.m.offset表示要对内核中的哪个video buffer进行映射操作  
  163.         framebuf[i].length = buf.length;  
  164.         framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);  
  165.         if (framebuf[i].start == MAP_FAILED) {  
  166.             printf("mmap (%d) failed: %s\n", i, strerror(errno));  
  167.             ret = -1;  
  168.             goto __error1;  
  169.         }  
  170.   
  171.         //内存入队列  
  172.         ret = ioctl(fd , VIDIOC_QBUF, &buf);  
  173.         if (ret < 0) {  
  174.             printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);  
  175.             goto __error2;  
  176.         }  
  177.   
  178.         printf("Frame buffer %d: address=0x%x, length=%d\n", i,  
  179.                 (unsigned long)framebuf[i].start,  
  180.                 (unsigned int)framebuf[i].length);  
  181.     }  
  182. //--------------------------------------  
  183.   
  184.     // 启动视频流  
  185.     enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  186.     ret = ioctl(fd, VIDIOC_STREAMON, &type);  
  187.     if (ret < 0) {  
  188.         printf("VIDIOC_STREAMON failed (%d)\n", ret);  
  189.         goto __error2;  
  190.     }  
  191.   
  192.     struct fb_var_screeninfo vinfo;  
  193.     struct fb_fix_screeninfo finfo;  
  194.     int x,y;  
  195.     int fd_fb;  
  196.     long int screen_size = 0;  
  197.     unsigned long  *fbp32 = NULL;  
  198.     //打开LCD设备  
  199.     fd_fb = open(FB_DEVICE, O_RDWR);  
  200.     if (fd_fb < 0)  
  201.     {  
  202.         printf("Error: cannot open framebuffer device.\n");  
  203.         goto __error2;  
  204.     }  
  205.     if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &finfo))  
  206.     {  
  207.         printf("Error reading fixed information.\n");  
  208.         goto __error3;  
  209.     }  
  210.     //获取LCD属性信息  
  211.     if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &vinfo))  
  212.     {  
  213.         printf("Error 2 reading variable information.\n");  
  214.         goto __error3;  
  215.     }  
  216.   
  217.     //一屏的字节数  
  218.     screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;  
  219.     printf("LCD:  %dx%d, %dbpp, screen_size = %ld\n",  
  220.             vinfo.xres,  
  221.             vinfo.yres,  
  222.             vinfo.bits_per_pixel,  
  223.             screen_size );  
  224.   
  225.     //映射framebuffer到用户空间  
  226.     fbp32 = (unsigned long *)mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);  
  227.     if (fbp32 == MAP_FAILED)  
  228.     {  
  229.         printf("Error: failed to map framebuffer device to memory.\n");  
  230.         goto __error3;  
  231.     }  
  232.   
  233.     printf("start camera testing...\n");  
  234.     //开始视频显示  
  235. //    while(1)  
  236.     unsigned long *picdata = (unsigned long *)malloc(fmt.fmt.pix.height*fmt.fmt.pix.width*4);  
  237.     memset(picdata,0,fmt.fmt.pix.height*fmt.fmt.pix.width*4);  
  238.     for(i=0;i<1;i++)  
  239.     {  
  240.         memset(&buf,0,sizeof(buf));  
  241.         buf.index = 0;  
  242.         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  243.         buf.memory = V4L2_MEMORY_MMAP;  
  244.         //内存空间出队列  
  245.        ret = ioctl(fd, VIDIOC_DQBUF, &buf);  
  246.        if (ret < 0)  
  247.        {  
  248.            printf("VIDIOC_DQBUF failed (%d)\n", ret);  
  249.            break;  
  250.        }  
  251.        if(vinfo.bits_per_pixel == 32)  
  252.        {  
  253.            //yuv422 两个像素占4个字节(Y0,V,Y1,U),两个像素共用一个UV对,总字节数为W*H*2,  
  254.            //而RGB32则正好两个像素是一个LONG型对齐,以LONG为单位一次可计算两个像素点,之后framebuf自增4个字节地址指向一两个像素点  
  255.            for(y = 0; y < fmt.fmt.pix.height;  y++)  
  256.            {  
  257.                for(x = 0; x < fmt.fmt.pix.width/2; x++)  
  258.                {  
  259.                    //YUV422转换为RGB32  
  260. //                   process(fbp32 + y*vinfo.xres + x,  
  261. //                         (U8 *)framebuf[buf.index].start + (y*fmt.fmt.pix.width+x)*2);  
  262.                    //由于是以long为基数自增,所以一行long数为:width(long)=width(int)/2  
  263.                    process((picdata + y*fmt.fmt.pix.width/2 + x),  
  264.                            (U8 *)framebuf[buf.index].start + y*fmt.fmt.pix.width*2+x*4);  
  265.                }  
  266.             }  
  267.   
  268.         }  
  269.   
  270.         // 内存重新入队列  
  271.         ret = ioctl(fd, VIDIOC_QBUF, &buf);  
  272.         if (ret < 0)  
  273.           {  
  274.             printf("VIDIOC_QBUF failed (%d)\n", ret);  
  275.             break;  
  276.           }  
  277.   
  278.     }//while(1)  
  279.   
  280.     /*save image picture captured*/  
  281.     char picname[100];  
  282.     sprintf(picname,"./niu_%d*%d.bmp",fmt.fmt.pix.width,fmt.fmt.pix.height);  
  283.     GenBmpFile((U8 *)picdata,32,fmt.fmt.pix.width,fmt.fmt.pix.height,picname);  
  284.   
  285.     //释放fbp32资源  
  286.     munmap(fbp32, screen_size);  
  287.  __error3://关闭fd_fb设备  
  288.     close(fd_fb);  
  289.  __error2://释放framebuf资源  
  290.     for (i=0; i< 4; i++)  
  291.     {  
  292.         munmap(framebuf[i].start, framebuf[i].length);  
  293.     }  
  294.  __error1://关闭fd设备  
  295.     close(fd);  
  296.     return ret;  
  297. }  
  298.   
  299.   
  300. //------------save image picture captured--------///  
  301. int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename)  
  302. {  
  303.     FILE *fp = fopen(filename, "wb");  
  304.     if(!fp)  
  305.     {  
  306.         printf("fopen failed : %s, %d\n", __FILE__, __LINE__);  
  307.         return 0;  
  308.     }  
  309.     U32 bmppitch = ((width*bitCountPerPix + 31) >> 5) << 2;  
  310.     U32 filesize = bmppitch*height;  
  311.   
  312.     BITMAPFILE bmpfile;  
  313.     bmpfile.bfHeader.bfType = 0x4D42;  
  314.     bmpfile.bfHeader.bfSize = filesize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  315.     bmpfile.bfHeader.bfReserved1 = 0;  
  316.     bmpfile.bfHeader.bfReserved2 = 0;  
  317.     bmpfile.bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  318.   
  319.     bmpfile.biInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  320.     bmpfile.biInfo.bmiHeader.biWidth = width;  
  321.     bmpfile.biInfo.bmiHeader.biHeight = height;  
  322.     bmpfile.biInfo.bmiHeader.biPlanes = 1;  
  323.     bmpfile.biInfo.bmiHeader.biBitCount = bitCountPerPix;  
  324.     bmpfile.biInfo.bmiHeader.biCompression = 0;  
  325.     bmpfile.biInfo.bmiHeader.biSizeImage = filesize;  
  326.     bmpfile.biInfo.bmiHeader.biXPelsPerMeter = 0;  
  327.     bmpfile.biInfo.bmiHeader.biYPelsPerMeter = 0;  
  328.     bmpfile.biInfo.bmiHeader.biClrUsed = 0;  
  329.     bmpfile.biInfo.bmiHeader.biClrImportant = 0;  
  330.   
  331.     fwrite(&(bmpfile.bfHeader), sizeof(BITMAPFILEHEADER), 1, fp);  
  332.     fwrite(&(bmpfile.biInfo.bmiHeader), sizeof(BITMAPINFOHEADER), 1, fp);  
  333.     fwrite(pData,filesize,1, fp);  
  334. //    U8 *pEachLinBuf = (U8*)malloc(bmppitch);  
  335. //    memset(pEachLinBuf, 0, bmppitch);  
  336. //    U8 BytePerPix = bitCountPerPix >> 3;  
  337. //    U32 pitch = width * BytePerPix;  
  338. //    if(pEachLinBuf)  
  339. //    {  
  340. //        int h,w;  
  341. //        for(h = height-1; h >= 0; h--)  
  342. //        {  
  343. //            for(w = 0; w < width; w++)  
  344. //            {  
  345. //                //copy by a pixel  
  346. //                pEachLinBuf[w*BytePerPix+0] = pData[h*pitch + w*BytePerPix + 0];  
  347. //                pEachLinBuf[w*BytePerPix+1] = pData[h*pitch + w*BytePerPix + 1];  
  348. //                pEachLinBuf[w*BytePerPix+2] = pData[h*pitch + w*BytePerPix + 2];  
  349. //            }  
  350. //            fwrite(pEachLinBuf, bmppitch, 1, fp);  
  351. //  
  352. //        }  
  353. //        free(pEachLinBuf);  
  354. //    }  
  355.   
  356.     fclose(fp);  
  357.   
  358.     return 1;  
  359. }  
/*
 * main.c
 *
 *  Created on: Apr 25, 2016
 *      Author: anzyelay
 */
#include <unistd.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h>
#include <fcntl.h>
#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 <asm/types.h>
#include <linux/videodev2.h>

#include "bmp.h"

#define CAMERA_DEVICE "/dev/video0"
#define FB_DEVICE "/dev/fb0"

#define VIDEO_WIDTH 640
#define VIDEO_HEIGHT 480
#define BUFFER_COUNT 4

typedef struct VideoBuffer {
    void   *start;
    size_t  length;
} VideoBuffer;

VideoBuffer framebuf[BUFFER_COUNT];

//查表法,把YUV422转换为RGB32
void process(unsigned long *rgb_buf, unsigned char *v_buf)
{
    int r,g,b;
    int u,v;
    int y[2];
    int rv,guv,bu,i;
    unsigned int *fb_buf = (unsigned int *)rgb_buf;
    y[0]=(int)*v_buf;
    v=(int)*(v_buf+1);
    y[1]=(int)*(v_buf+2);
    u=(int)*(v_buf+3);
    rv=rvarrxyp[v];
    guv=guarrxyp[u]+gvarrxyp[v];
    bu=buarrxyp[u];

    for(i=0;i<2;i++){
        r=y[i]+rv;
        g=y[i]-guv;
        b=y[i]+bu;
        if (r>255) r=255;
        if (r<0) r=0;
        if (g>255) g=255;
        if (g<0) g=0;
        if (b>255) b=255;
        if (b<0) b=0;
        *(fb_buf+i)=(b<<16)+(g<<8)+r;
    }
}

int main()
{
    int i, ret;
    // 打开摄像头设备
    int fd;
    fd = open(CAMERA_DEVICE, O_RDWR, 0);
    if (fd < 0) {
        printf("Open %s failed\n", CAMERA_DEVICE);
        return -1;
    }

    // 获取驱动信息
    struct v4l2_capability cap;
    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
    if (ret < 0) {
        printf("VIDIOC_QUERYCAP failed (%d)\n", ret);
        goto __error1;
    }

    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: %u.%u.%u\n", (cap.version>>16)&0XFF, (cap.version>>8)&0XFF,cap.version&0XFF);
    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       = VIDEO_WIDTH;
    fmt.fmt.pix.height      = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_S_FMT failed (%d)\n", ret);
        goto __error1;
    }

    //获取视频格式(原因是设置视频格式时如果有错误,VIDIOC_S_FMT时会自动转换成合作的格式,所以再获取一次)
    ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_G_FMT failed (%d)\n", ret);
        goto __error1;
    }
    // Print Stream Format
    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 reqbuf;
    reqbuf.count = BUFFER_COUNT;
    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuf.memory = V4L2_MEMORY_MMAP;

    ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf);//在内核虚拟地址空间中申请reqbuf.count个连续的内存
    if(ret < 0) {
        printf("VIDIOC_REQBUFS failed (%d)\n", ret);
        goto __error1;
    }

    struct v4l2_buffer buf;
    for (i = 0; i < reqbuf.count; i++)
    {
        buf.index = i;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        //根据buf.index询访内存为后面的映射做准备(本质就是设置buf.m.offset+=buf.length偏移)
        ret = ioctl(fd , VIDIOC_QUERYBUF, &buf);
        if(ret < 0) {
            printf("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret);
            goto __error1;
        }
        //映射到用户空间
        //就是将之前内核分配的视频缓冲(VIDIOC_REQBUFS)映射到用户空间,这样用户空间就可以直接读取内核扑获的视频数据
        //buf.m.offset表示要对内核中的哪个video buffer进行映射操作
        framebuf[i].length = buf.length;
        framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);
        if (framebuf[i].start == MAP_FAILED) {
            printf("mmap (%d) failed: %s\n", i, strerror(errno));
            ret = -1;
            goto __error1;
        }

        //内存入队列
        ret = ioctl(fd , VIDIOC_QBUF, &buf);
        if (ret < 0) {
            printf("VIDIOC_QBUF (%d) failed (%d)\n", i, ret);
            goto __error2;
        }

        printf("Frame buffer %d: address=0x%x, length=%d\n", i,
        		(unsigned long)framebuf[i].start,
        		(unsigned int)framebuf[i].length);
    }
//--------------------------------------

    // 启动视频流
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMON, &type);
    if (ret < 0) {
        printf("VIDIOC_STREAMON failed (%d)\n", ret);
        goto __error2;
    }

    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    int x,y;
    int fd_fb;
    long int screen_size = 0;
    unsigned long  *fbp32 = NULL;
    //打开LCD设备
    fd_fb = open(FB_DEVICE, O_RDWR);
    if (fd_fb < 0)
    {
        printf("Error: cannot open framebuffer device.\n");
        goto __error2;
    }
    if (ioctl(fd_fb, FBIOGET_FSCREENINFO, &finfo))
    {
        printf("Error reading fixed information.\n");
        goto __error3;
    }
    //获取LCD属性信息
    if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &vinfo))
    {
        printf("Error 2 reading variable information.\n");
        goto __error3;
    }

    //一屏的字节数
    screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
    printf("LCD:  %dx%d, %dbpp, screen_size = %ld\n",
    		vinfo.xres,
    		vinfo.yres,
    		vinfo.bits_per_pixel,
    		screen_size );

    //映射framebuffer到用户空间
    fbp32 = (unsigned long *)mmap(0, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
    if (fbp32 == MAP_FAILED)
    {
        printf("Error: failed to map framebuffer device to memory.\n");
        goto __error3;
    }

    printf("start camera testing...\n");
    //开始视频显示
//    while(1)
    unsigned long *picdata = (unsigned long *)malloc(fmt.fmt.pix.height*fmt.fmt.pix.width*4);
    memset(picdata,0,fmt.fmt.pix.height*fmt.fmt.pix.width*4);
    for(i=0;i<1;i++)
    {
    	memset(&buf,0,sizeof(buf));
        buf.index = 0;
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
    	//内存空间出队列
       ret = ioctl(fd, VIDIOC_DQBUF, &buf);
       if (ret < 0)
       {
           printf("VIDIOC_DQBUF failed (%d)\n", ret);
           break;
       }
       if(vinfo.bits_per_pixel == 32)
       {
    	   //yuv422 两个像素占4个字节(Y0,V,Y1,U),两个像素共用一个UV对,总字节数为W*H*2,
    	   //而RGB32则正好两个像素是一个LONG型对齐,以LONG为单位一次可计算两个像素点,之后framebuf自增4个字节地址指向一两个像素点
    	   for(y = 0; y < fmt.fmt.pix.height;  y++)
           {
               for(x = 0; x < fmt.fmt.pix.width/2; x++)
               {
                   //YUV422转换为RGB32
//                   process(fbp32 + y*vinfo.xres + x,
//                		   (U8 *)framebuf[buf.index].start + (y*fmt.fmt.pix.width+x)*2);
            	   //由于是以long为基数自增,所以一行long数为:width(long)=width(int)/2
            	   process((picdata + y*fmt.fmt.pix.width/2 + x),
            			   (U8 *)framebuf[buf.index].start + y*fmt.fmt.pix.width*2+x*4);
               }
            }

        }

        // 内存重新入队列
        ret = ioctl(fd, VIDIOC_QBUF, &buf);
        if (ret < 0)
          {
            printf("VIDIOC_QBUF failed (%d)\n", ret);
            break;
          }

    }//while(1)

    /*save image picture captured*/
    char picname[100];
    sprintf(picname,"./niu_%d*%d.bmp",fmt.fmt.pix.width,fmt.fmt.pix.height);
    GenBmpFile((U8 *)picdata,32,fmt.fmt.pix.width,fmt.fmt.pix.height,picname);

    //释放fbp32资源
    munmap(fbp32, screen_size);
 __error3://关闭fd_fb设备
 	close(fd_fb);
 __error2://释放framebuf资源
    for (i=0; i< 4; i++)
    {
        munmap(framebuf[i].start, framebuf[i].length);
    }
 __error1://关闭fd设备
    close(fd);
    return ret;
}


//------------save image picture captured--------///
int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename)
{
    FILE *fp = fopen(filename, "wb");
    if(!fp)
    {
        printf("fopen failed : %s, %d\n", __FILE__, __LINE__);
        return 0;
    }
    U32 bmppitch = ((width*bitCountPerPix + 31) >> 5) << 2;
    U32 filesize = bmppitch*height;

    BITMAPFILE bmpfile;
    bmpfile.bfHeader.bfType = 0x4D42;
    bmpfile.bfHeader.bfSize = filesize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmpfile.bfHeader.bfReserved1 = 0;
    bmpfile.bfHeader.bfReserved2 = 0;
    bmpfile.bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    bmpfile.biInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpfile.biInfo.bmiHeader.biWidth = width;
    bmpfile.biInfo.bmiHeader.biHeight = height;
    bmpfile.biInfo.bmiHeader.biPlanes = 1;
    bmpfile.biInfo.bmiHeader.biBitCount = bitCountPerPix;
    bmpfile.biInfo.bmiHeader.biCompression = 0;
    bmpfile.biInfo.bmiHeader.biSizeImage = filesize;
    bmpfile.biInfo.bmiHeader.biXPelsPerMeter = 0;
    bmpfile.biInfo.bmiHeader.biYPelsPerMeter = 0;
    bmpfile.biInfo.bmiHeader.biClrUsed = 0;
    bmpfile.biInfo.bmiHeader.biClrImportant = 0;

    fwrite(&(bmpfile.bfHeader), sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&(bmpfile.biInfo.bmiHeader), sizeof(BITMAPINFOHEADER), 1, fp);
    fwrite(pData,filesize,1, fp);
//    U8 *pEachLinBuf = (U8*)malloc(bmppitch);
//    memset(pEachLinBuf, 0, bmppitch);
//    U8 BytePerPix = bitCountPerPix >> 3;
//    U32 pitch = width * BytePerPix;
//    if(pEachLinBuf)
//    {
//        int h,w;
//        for(h = height-1; h >= 0; h--)
//        {
//            for(w = 0; w < width; w++)
//            {
//                //copy by a pixel
//                pEachLinBuf[w*BytePerPix+0] = pData[h*pitch + w*BytePerPix + 0];
//                pEachLinBuf[w*BytePerPix+1] = pData[h*pitch + w*BytePerPix + 1];
//                pEachLinBuf[w*BytePerPix+2] = pData[h*pitch + w*BytePerPix + 2];
//            }
//            fwrite(pEachLinBuf, bmppitch, 1, fp);
//
//        }
//        free(pEachLinBuf);
//    }

    fclose(fp);

    return 1;
}

bmp.h

  1. /* 
  2.  * bmp.h 
  3.  * 
  4.  *  Created on: Apr 26, 2016 
  5.  *      Author: anzyelay 
  6.  */  
  7.   
  8. #ifndef BMP_H_  
  9. #define BMP_H_  
  10.   
  11. #pragma pack(push, 1)  
  12. typedef unsigned char  U8;  
  13. typedef unsigned short U16;  
  14. typedef unsigned int   U32;  
  15.   
  16. typedef struct tagBITMAPFILEHEADER  
  17. {  
  18.  U16 bfType;  
  19.  U32 bfSize;  
  20.  U16 bfReserved1;  
  21.  U16 bfReserved2;  
  22.  U32 bfOffBits;  
  23. } BITMAPFILEHEADER;  
  24.   
  25. typedef struct tagBITMAPINFOHEADER  
  26. {  
  27.  U32 biSize;  
  28.  U32 biWidth;  
  29.  U32 biHeight;  
  30.  U16 biPlanes;  
  31.  U16 biBitCount;  
  32.  U32 biCompression;  
  33.  U32 biSizeImage;  
  34.  U32 biXPelsPerMeter;  
  35.  U32 biYPelsPerMeter;  
  36.  U32 biClrUsed;  
  37.  U32 biClrImportant;  
  38. } BITMAPINFOHEADER;  
  39.   
  40. typedef struct tagRGBQUAD  
  41. {  
  42.  U8 rgbBlue;  
  43.  U8 rgbGreen;  
  44.  U8 rgbRed;  
  45.  U8 rgbReserved;  
  46. } RGBQUAD;  
  47.   
  48. typedef struct tagBITMAPINFO  
  49. {  
  50.  BITMAPINFOHEADER bmiHeader;  
  51.  RGBQUAD bmiColors[1];  
  52. } BITMAPINFO;  
  53.   
  54.   
  55. typedef struct tagBITMAP  
  56. {  
  57.  BITMAPFILEHEADER bfHeader;  
  58.  BITMAPINFO biInfo;  
  59. }BITMAPFILE;  
  60.   
  61. #pragma pack(pop)  
  62.   
  63. int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename);  
  64.   
  65. //YUV422转换为RGB32表  
  66. const int rvarrxyp[]={  
  67. -180,-179,-177,-176,-175,-173,-172,-170,-169,-167,-166,-165,-163,-162,-160,-159,-158,-156,-155,-153,-152,-151,  
  68. -149,-148,-146,-145,-144,-142,-141,-139,-138,-137,-135,-134,-132,-131,-129,-128,-127,-125,-124,-122,-121,-120,  
  69. -118,-117,-115,-114,-113,-111,-110,-108,-107,-106,-104,-103,-101,-100,-99,-97,-96,-94,-93,-91,-90,-89,-87,-86,  
  70. -84,-83,-82,-80,-79,-77,-76,-75,-73,-72,-70,-69,-68,-66,-65,-63,-62,-61,-59,-58,-56,-55,-53,-52,-51,-49,-48,  
  71. -46,-45,-44,-42,-41,-39,-38,-37,-35,-34,-32,-31,-30,-28,-27,-25,-24,-23,-21,-20,-18,-17,-15,-14,-13,-11,-10,  
  72. -8,-7,-6,-4,-3,-1,0,1,3,4,6,7,8,10,11,13,14,15,17,18,20,21,23,24,25,27,28,30,31,32,34,35,37,38,39,41,42,44,45,  
  73. 46,48,49,51,52,53,55,56,58,59,61,62,63,65,66,68,69,70,72,73,75,76,77,79,80,82,83,84,86,87,89,90,91,93,94,96,  
  74. 97,99,100,101,103,104,106,107,108,110,111,113,114,115,117,118,120,121,122,124,125,127,128,129,131,132,134,135,  
  75. 137,138,139,141,142,144,145,146,148,149,151,152,153,155,156,158,159,160,162,163,165,166,167,169,170,172,173,175,  
  76. 176,177,179};  
  77.   
  78. const int guarrxyp[]={  
  79. -44,-44,-44,-43,-43,-42,-42,-42,-41,-41,-41,-40,-40,-40,-39,-39,-39,-38,-38,-38,-37,-37,-37,-36,-36,-36,-35,-35,  
  80. -35,-34,-34,-34,-33,-33,-32,-32,-32,-31,-31,-31,-30,-30,-30,-29,-29,-29,-28,-28,-28,-27,-27,-27,-26,-26,-26,-25,  
  81. -25,-25,-24,-24,-23,-23,-23,-22,-22,-22,-21,-21,-21,-20,-20,-20,-19,-19,-19,-18,-18,-18,-17,-17,-17,-16,-16,-16,  
  82. -15,-15,-15,-14,-14,-13,-13,-13,-12,-12,-12,-11,-11,-11,-10,-10,-10,-9,-9,-9,-8,-8,-8,-7,-7,-7,-6,-6,-6,-5,-5,-4,  
  83. -4,-4,-3,-3,-3,-2,-2,-2,-1,-1,-1,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,  
  84. 12,13,13,13,14,14,15,15,15,16,16,16,17,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,25,25,25,  
  85. 26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,38,  
  86. 39,39,39,40,40,40,41,41,41,42,42,42,43,43,44,44};  
  87.   
  88. const int gvarrxyp[]={  
  89. -92,-91,-90,-90,-89,-88,-87,-87,-86,-85,-85,-84,-83,-82,-82,-81,-80,-80,-79,-78,-77,-77,-76,-75,-75,-74,-73,-72,  
  90. -72,-71,-70,-70,-69,-68,-67,-67,-66,-65,-65,-64,-63,-62,-62,-61,-60,-60,-59,-58,-57,-57,-56,-55,-54,-54,-53,-52,-52,  
  91. -51,-50,-49,-49,-48,-47,-47,-46,-45,-44,-44,-43,-42,-42,-41,-40,-39,-39,-38,-37,-37,-36,-35,-34,-34,-33,-32,-32,-31,  
  92. -30,-29,-29,-28,-27,-27,-26,-25,-24,-24,-23,-22,-22,-21,-20,-19,-19,-18,-17,-16,-16,-15,-14,-14,-13,-12,-11,-11,-10,  
  93. -9,-9,-8,-7,-6,-6,-5,-4,-4,-3,-2,-1,-1,0,1,1,2,3,4,4,5,6,6,7,8,9,9,10,11,11,12,13,14,14,15,16,16,17,18,19,19,20,21,  
  94. 22,22,23,24,24,25,26,27,27,28,29,29,30,31,32,32,33,34,34,35,36,37,37,38,39,39,40,41,42,42,43,44,44,45,46,47,47,48,49,  
  95. 49,50,51,52,52,53,54,54,55,56,57,57,58,59,60,60,61,62,62,63,64,65,65,66,67,67,68,69,70,70,71,72,72,73,74,75,75,76,77,  
  96. 77,78,79,80,80,81,82,82,83,84,85,85,86,87,87,88,89,90,90,91};  
  97.   
  98. const int buarrxyp[]={  
  99. -228,-226,-224,-222,-221,-219,-217,-215,-213,-212,-210,-208,-206,-205,-203,-201,-199,-197,-196,-194,-192,-190,-189,  
  100. -187,-185,-183,-181,-180,-178,-176,-174,-173,-171,-169,-167,-165,-164,-162,-160,-158,-157,-155,-153,-151,-149,-148,  
  101. -146,-144,-142,-141,-139,-137,-135,-133,-132,-130,-128,-126,-125,-123,-121,-119,-117,-116,-114,-112,-110,-109,-107,  
  102. -105,-103,-101,-100,-98,-96,-94,-93,-91,-89,-87,-85,-84,-82,-80,-78,-76,-75,-73,-71,-69,-68,-66,-64,-62,-60,-59,-57,  
  103. -55,-53,-52,-50,-48,-46,-44,-43,-41,-39,-37,-36,-34,-32,-30,-28,-27,-25,-23,-21,-20,-18,-16,-14,-12,-11,-9,-7,-5,-4,  
  104. -2,0,2,4,5,7,9,11,12,14,16,18,20,21,23,25,27,28,30,32,34,36,37,39,41,43,44,46,48,50,52,53,55,57,59,60,62,64,66,68,69,  
  105. 71,73,75,76,78,80,82,84,85,87,89,91,93,94,96,98,100,101,103,105,107,109,110,112,114,116,117,119,121,123,125,126,128,  
  106. 130,132,133,135,137,139,141,142,144,146,148,149,151,153,155,157,158,160,162,164,165,167,169,171,173,174,176,178,180,  
  107. 181,183,185,187,189,190,192,194,196,197,199,201,203,205,206,208,210,212,213,215,217,219,221,222,224,226};  
  108.   
  109.   
  110. #endif /* BMP_H_ */  
/*
 * bmp.h
 *
 *  Created on: Apr 26, 2016
 *      Author: anzyelay
 */

#ifndef BMP_H_
#define BMP_H_

#pragma pack(push, 1)
typedef unsigned char  U8;
typedef unsigned short U16;
typedef unsigned int   U32;

typedef struct tagBITMAPFILEHEADER
{
 U16 bfType;
 U32 bfSize;
 U16 bfReserved1;
 U16 bfReserved2;
 U32 bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER
{
 U32 biSize;
 U32 biWidth;
 U32 biHeight;
 U16 biPlanes;
 U16 biBitCount;
 U32 biCompression;
 U32 biSizeImage;
 U32 biXPelsPerMeter;
 U32 biYPelsPerMeter;
 U32 biClrUsed;
 U32 biClrImportant;
} BITMAPINFOHEADER;

typedef struct tagRGBQUAD
{
 U8 rgbBlue;
 U8 rgbGreen;
 U8 rgbRed;
 U8 rgbReserved;
} RGBQUAD;

typedef struct tagBITMAPINFO
{
 BITMAPINFOHEADER bmiHeader;
 RGBQUAD bmiColors[1];
} BITMAPINFO;


typedef struct tagBITMAP
{
 BITMAPFILEHEADER bfHeader;
 BITMAPINFO biInfo;
}BITMAPFILE;

#pragma pack(pop)

int GenBmpFile(U8 *pData, U8 bitCountPerPix, U32 width, U32 height, const char *filename);

//YUV422转换为RGB32表
const int rvarrxyp[]={
-180,-179,-177,-176,-175,-173,-172,-170,-169,-167,-166,-165,-163,-162,-160,-159,-158,-156,-155,-153,-152,-151,
-149,-148,-146,-145,-144,-142,-141,-139,-138,-137,-135,-134,-132,-131,-129,-128,-127,-125,-124,-122,-121,-120,
-118,-117,-115,-114,-113,-111,-110,-108,-107,-106,-104,-103,-101,-100,-99,-97,-96,-94,-93,-91,-90,-89,-87,-86,
-84,-83,-82,-80,-79,-77,-76,-75,-73,-72,-70,-69,-68,-66,-65,-63,-62,-61,-59,-58,-56,-55,-53,-52,-51,-49,-48,
-46,-45,-44,-42,-41,-39,-38,-37,-35,-34,-32,-31,-30,-28,-27,-25,-24,-23,-21,-20,-18,-17,-15,-14,-13,-11,-10,
-8,-7,-6,-4,-3,-1,0,1,3,4,6,7,8,10,11,13,14,15,17,18,20,21,23,24,25,27,28,30,31,32,34,35,37,38,39,41,42,44,45,
46,48,49,51,52,53,55,56,58,59,61,62,63,65,66,68,69,70,72,73,75,76,77,79,80,82,83,84,86,87,89,90,91,93,94,96,
97,99,100,101,103,104,106,107,108,110,111,113,114,115,117,118,120,121,122,124,125,127,128,129,131,132,134,135,
137,138,139,141,142,144,145,146,148,149,151,152,153,155,156,158,159,160,162,163,165,166,167,169,170,172,173,175,
176,177,179};

const int guarrxyp[]={
-44,-44,-44,-43,-43,-42,-42,-42,-41,-41,-41,-40,-40,-40,-39,-39,-39,-38,-38,-38,-37,-37,-37,-36,-36,-36,-35,-35,
-35,-34,-34,-34,-33,-33,-32,-32,-32,-31,-31,-31,-30,-30,-30,-29,-29,-29,-28,-28,-28,-27,-27,-27,-26,-26,-26,-25,
-25,-25,-24,-24,-23,-23,-23,-22,-22,-22,-21,-21,-21,-20,-20,-20,-19,-19,-19,-18,-18,-18,-17,-17,-17,-16,-16,-16,
-15,-15,-15,-14,-14,-13,-13,-13,-12,-12,-12,-11,-11,-11,-10,-10,-10,-9,-9,-9,-8,-8,-8,-7,-7,-7,-6,-6,-6,-5,-5,-4,
-4,-4,-3,-3,-3,-2,-2,-2,-1,-1,-1,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,
12,13,13,13,14,14,15,15,15,16,16,16,17,17,17,18,18,18,19,19,19,20,20,20,21,21,21,22,22,22,23,23,23,24,24,25,25,25,
26,26,26,27,27,27,28,28,28,29,29,29,30,30,30,31,31,31,32,32,32,33,33,34,34,34,35,35,35,36,36,36,37,37,37,38,38,38,
39,39,39,40,40,40,41,41,41,42,42,42,43,43,44,44};

const int gvarrxyp[]={
-92,-91,-90,-90,-89,-88,-87,-87,-86,-85,-85,-84,-83,-82,-82,-81,-80,-80,-79,-78,-77,-77,-76,-75,-75,-74,-73,-72,
-72,-71,-70,-70,-69,-68,-67,-67,-66,-65,-65,-64,-63,-62,-62,-61,-60,-60,-59,-58,-57,-57,-56,-55,-54,-54,-53,-52,-52,
-51,-50,-49,-49,-48,-47,-47,-46,-45,-44,-44,-43,-42,-42,-41,-40,-39,-39,-38,-37,-37,-36,-35,-34,-34,-33,-32,-32,-31,
-30,-29,-29,-28,-27,-27,-26,-25,-24,-24,-23,-22,-22,-21,-20,-19,-19,-18,-17,-16,-16,-15,-14,-14,-13,-12,-11,-11,-10,
-9,-9,-8,-7,-6,-6,-5,-4,-4,-3,-2,-1,-1,0,1,1,2,3,4,4,5,6,6,7,8,9,9,10,11,11,12,13,14,14,15,16,16,17,18,19,19,20,21,
22,22,23,24,24,25,26,27,27,28,29,29,30,31,32,32,33,34,34,35,36,37,37,38,39,39,40,41,42,42,43,44,44,45,46,47,47,48,49,
49,50,51,52,52,53,54,54,55,56,57,57,58,59,60,60,61,62,62,63,64,65,65,66,67,67,68,69,70,70,71,72,72,73,74,75,75,76,77,
77,78,79,80,80,81,82,82,83,84,85,85,86,87,87,88,89,90,90,91};

const int buarrxyp[]={
-228,-226,-224,-222,-221,-219,-217,-215,-213,-212,-210,-208,-206,-205,-203,-201,-199,-197,-196,-194,-192,-190,-189,
-187,-185,-183,-181,-180,-178,-176,-174,-173,-171,-169,-167,-165,-164,-162,-160,-158,-157,-155,-153,-151,-149,-148,
-146,-144,-142,-141,-139,-137,-135,-133,-132,-130,-128,-126,-125,-123,-121,-119,-117,-116,-114,-112,-110,-109,-107,
-105,-103,-101,-100,-98,-96,-94,-93,-91,-89,-87,-85,-84,-82,-80,-78,-76,-75,-73,-71,-69,-68,-66,-64,-62,-60,-59,-57,
-55,-53,-52,-50,-48,-46,-44,-43,-41,-39,-37,-36,-34,-32,-30,-28,-27,-25,-23,-21,-20,-18,-16,-14,-12,-11,-9,-7,-5,-4,
-2,0,2,4,5,7,9,11,12,14,16,18,20,21,23,25,27,28,30,32,34,36,37,39,41,43,44,46,48,50,52,53,55,57,59,60,62,64,66,68,69,
71,73,75,76,78,80,82,84,85,87,89,91,93,94,96,98,100,101,103,105,107,109,110,112,114,116,117,119,121,123,125,126,128,
130,132,133,135,137,139,141,142,144,146,148,149,151,153,155,157,158,160,162,164,165,167,169,171,173,174,176,178,180,
181,183,185,187,189,190,192,194,196,197,199,201,203,205,206,208,210,212,213,215,217,219,221,222,224,226};


#endif /* BMP_H_ */
此代码在PC机上可以正常显示,但下到开发板老是出现
  1. VIDIOC_S_FMT failed -1  
VIDIOC_S_FMT failed -1

此错误,

检查 发现是 设置格式错误,百度各种说法,有说是pixelformat格式不对的,但在PC机上却是正常的,不管了,先换换,把VIDIOC_S_FMT 和 VIDIOC_G_FMT 反下,先查询支持什么格式再设置,

更改如下

  1. // 设置视频格式  
  2.     struct v4l2_format <span style="color:#FF0000;">fmt1</span>,fmt;    //fmt1临时查询格式使用  
  3.     memset(&fmt1, 0, sizeof(fmt1));  
  4.     memset(&fmt, 0, sizeof(fmt));  
  5.     fmt1.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;</span>  
  6.     //先获取视频格式  
  7.     ret = ioctl(fd, VIDIOC_G_FMT, &fmt1);  
  8.     if (ret < 0) {  
  9.         printf("VIDIOC_G_FMT failed (%d)\n", ret);  
  10.         goto __error1;  
  11.     }  
  12.     fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  13.     fmt.fmt.pix.width       = VIDEO_WIDTH;  
  14.     fmt.fmt.pix.height      = VIDEO_HEIGHT;  
  15.     fmt.fmt.pix.pixelformat = fmt1.fmt.pix.pixelformat;   //把上面查询到地格式赋给要设置的变量  
  16.     fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;  
  17.     ret = ioctl(fd, VIDIOC_S_FMT, &fmt);  
  18.     if (ret < 0) {  
  19.         printf("VIDIOC_S_FMT failed (%d)\n", ret);  
  20.         goto __error1;  
  21.     }  
// 设置视频格式
    struct v4l2_format <span style="color:#FF0000;">fmt1</span>,fmt;    //fmt1临时查询格式使用
    memset(&fmt1, 0, sizeof(fmt1));
    memset(&fmt, 0, sizeof(fmt));
    fmt1.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;</span>
    //先获取视频格式
    ret = ioctl(fd, VIDIOC_G_FMT, &fmt1);
    if (ret < 0) {
        printf("VIDIOC_G_FMT failed (%d)\n", ret);
        goto __error1;
    }
    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width       = VIDEO_WIDTH;
    fmt.fmt.pix.height      = VIDEO_HEIGHT;
    fmt.fmt.pix.pixelformat = fmt1.fmt.pix.pixelformat;   //把上面查询到地格式赋给要设置的变量
    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret < 0) {
        printf("VIDIOC_S_FMT failed (%d)\n", ret);
        goto __error1;
    }
编译在PC上可正常能过,调试信息时: pixelformat: YUYV

下到板子上也能正常运行下去了,调试信息:pixelformat: MJPG

输出格式居然不一样。。。。。。

终于知道错误原因了,应该是开发板和电脑上的UVC驱动版本不一样导致输出的支持格式不一。优化下代码,转MJPG格式输出,MJPG保存图片函数:

//保存为图片  test.jpg
int GenJpgFile(VideoBuffer *buffers,const char *filename){
    FILE *fp = NULL;
    fp = fopen(filename, "w");
    if(fp != NULL){
        fwrite(buffers->start, 1,buffers->length, fp);
        sync();
        fclose(fp);
        return 1;
    }
    return 0;
}

0
0
 
 
我的同类文章

参考知识库

img
Linux知识库

更多资料请参考:
猜你在找
Linux环境C语言编程基础
《C语言/C++学习指南》Linux开发篇
I2C总线和触摸屏驱动移植实战-linux驱动开发第9部分
2.6 内核I2C驱动框架
内存这个大话题-4.1.C语言高级专题第一部分
V4L2 soc-camera 子系统
linux系统V4L2架构OV3640摄像头视频捕获保存图片jpg格式
Camera driver&V4L2驱动架构介绍
嵌入式Linux下Camera编程--V4L2
深入浅出camera v4l2理解
查看评论

  暂无评论

发表评论
  • 用 户 名:
  • ASKLW
  •   
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值