zoukankan      html  css  js  c++  java
  • android摄像头(camera)之 v4l2的c测试代码【转】

    转自:https://blog.csdn.net/ldswfun/article/details/8745577

    在移植android hal的过程中,移植的首要任务是要确保驱动完好,camera是属于字符设备,但是对于其测试代码的编写就不像一般的驱动那么简单啦,因为camera的测试代码一定是要用v4l2 api,所以接下来就是介绍我们写camera的测试代码的流程。

    1,打开设备

    [c] view plain copy
     
    1.    
    2. static int open_device(char *dev_name)  
    3. {  
    4.     assert(dev_name);  
    5.   
    6.     int fd = -1;  
    7.   
    8.     fd = open(dev_name , O_RDWR);  
    9.     if( -1 == fd )  
    10.     {  
    11.         MYLOGD("open %s fail: %s ", dev_name, strerror (errno));  
    12.         exit(EXIT_FAILURE);  
    13.     }  
    14.       
    15.     MYLOGD("the fd of %s is %d ", dev_name, fd);  
    16.     return fd;  
    17.       
    18. }     

    2,初始化camera,设置camera输出图像的格式

    [c] view plain copy
     
    1.  static int init_cam_device(int dev_fd)  
    2. {  
    3.     int ret = -1;  
    4.     int input_index;  
    5.   
    6.     //ret = fimc_v4l2_querycap(dev_fd);  
    7.     //assert(ret == 0);  
    8.     //获取到输入源通道  
    9.     input_index = cam_v4l2_enuminput(dev_fd);     
    10.     assert(input_index == 0);  
    11.       
    12.     ret = cam_v4l2_s_input(dev_fd, input_index);  
    13.     assert(ret == 0);  
    14.   
    15.     MYLOGD("VIDIOC_S_FMT start... dev_fd = %d ", dev_fd);  
    16.   
    17.     ret = cam_v4l2_s_format(dev_fd, IMAGE_HEIGHT, IMAGE_WIDTH, V4L2_PIX_FMT_YUYV);  
    18.     assert(ret == 0);  
    19.   
    20.     ret = cam_v4l2_g_fmt(dev_fd);  
    21.     assert(ret == 0);  
    22.           
    23.     init_cam_mmap(dev_fd);  
    24.       
    25.     return 1;     
    26.       
    27. }  


    4,向内核申请buffer,并将buffer映射mmap到引用空间

    struct buffer
    {
      void *start; //mmap后的地址;
      size_t length//大小;
    }user_buffers[4]; //用于记录将内核buffer映射mmap到用户空间的地址和大小

    //申请4个buffer

    cam_v4l2_reqbuf(dev_fd, 4);
    //查询申请到的buffer信息,比如每个buffer的其实位置和大小

    cam_v4l2_querybuf(dev_fd, &buf, buf_index);

    //将buffer映射到用户空间

    user_buffers[buf_index].length = buf.length;

            user_buffers[buf_index].start = mmap(NULL   buf.length,
          PROT_READ | PROT_WRITE /* required */ ,
          MAP_SHARED /* recommended */ ,
          dev_fd, buf.m.offset);

    注释  :  NULL: /* start anywhere */

    buf.length: buffer在内核的地址

                            buf.m.offset:内核中的buffer大小

    5,将所有的buffer全部放到循环工作队列中,集中管理

    for (i = 0; i < max_buffers; ++i)
    {
    cam_v4l2_qbuf(dev_fd, i);
    }

    6,开始获取图像:

    ioctl(dev_fd, VIDIOC_STREAMON, &type);

    7,通过select来监控camera数据是否准备好

     FD_ZERO (&rd_set);
    FD_SET (dev_fd, &rd_set);

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if(FD_ISSET(dev_fd, &rd_set))//如果camera准备好,就可以去读数据了

    read_frame(dev_fd)

    8,read_frame(dev_fd)的实现:

    //select仅仅是知道有数据可以读了,但是在多个buffer中,

    //不知道是哪个buffer准备好了,所以将准备好的buffer出队列,从而知道buffer的编号

    int index = cam_v4l2_dqbuf(dev_fd);

    //将buffer中的yuv420数据转换成rgb565,

    //因为lcd是没办法显示yuv的,所以需要将yuv转换成rgb565

    yuyv_to_rgb(src_address, data_buf);

    //将转换好的rgb565数据方到framebuffer中去显示

    show_rgb565_img(data_buf, LCD_WIDTH, LCD_HEIGHT);

    这个过程仅仅是将一个流程写下来了,每个函数都是封装了一次,没办法一一去写出来,

    所以我会将源代码文件上传,给大家去下载。包含Android.mk

    可以到这个链接下载:

    http://download.csdn.net/detail/ldswfun/5208766

    同时附上一些图片让大家去理解这个过程

  • 相关阅读:
    python-MongoDB 非关系型数据库
    python-爬虫-Beautifulsoup模块
    python-flask-路由匹配源码分析
    python-flask-配置文件的源码分析
    python-爬虫-selenium模块
    python-flask-请求源码流程
    python-爬虫
    iOS开发——创建你自己的Framework
    手把手教你封装下载管理器
    AFNetwork 作用和用法详解
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/9534696.html
Copyright © 2011-2022 走看看