Android4.0 USB Camera instance (I) HAL Layer

Source: Internet
Author: User

I always wanted to write a Camera example from the HAL layer to the application layer, usb camera cannot be used on android4.0, so I decided to write a usb camera and coms on my own. The basic principle is the same. v4l2, but the source code data format is different. Now we will start from the HAL layer.

The following is my code. First, the code is explained step by step.

Fimcgzsd. c

/* * Android USB Camera zc3xx Library * * Copyright (c) 2014  Store information technology guangzhou ltd
 
   * Copyright (c) 2014  hclydao 
  
    * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. */#include 
   
    #include 
    
     #include 
     
      #include 
      
       #include 
       
        #include 
        
          #include 
         
          #include 
          
           #include 
           
            #include #include 
            
             #include 
             
              #include 
              
               #include 
               
                #include 
                
                 #include 
                 
                  #include 
                  
                   #include #include 
                   
                    #define LOG_TAG "FimcGzsd"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__)#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__)struct fimc_buffer { unsigned char *start; size_t length;};static int fd = -1;struct fimc_buffer *buffers=NULL;struct v4l2_buffer v4l2_buf;static int bufnum = 1;static int mwidth,mheight;/* *open usb camera device */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_open(JNIEnv * env, jclass obj, const jbyteArray devname){jbyte *dev = (jbyte*)(*env)->GetByteArrayElements(env, devname, 0);fd = open(dev, O_RDWR, 0); if (fd<0){LOGE("%s ++++ open error\n",dev);return -1;}(*env)->ReleaseByteArrayElements(env, devname, dev, 0);return fd;}/* * init device */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_init(JNIEnv * env, jclass obj, jint width, jint height,jint numbuf){int ret;int i;bufnum = numbuf;mwidth = width;mheight = height;struct v4l2_format fmt;struct v4l2_capability cap; ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); if (ret < 0) { LOGE("%d :VIDIOC_QUERYCAP failed\n",__LINE__); return -1; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { LOGE("%d : no capture devices\n",__LINE__); return -1; }memset( &fmt, 0, sizeof(fmt));fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;fmt.fmt.pix.width = width;fmt.fmt.pix.height = height;if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0){LOGE("++++%d : set format failed\n",__LINE__);return -1;} struct v4l2_requestbuffers req; req.count = numbuf; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_REQBUFS, &req); if (ret < 0) { LOGE("++++%d : VIDIOC_REQBUFS failed\n",__LINE__); return -1; } buffers = calloc(req.count, sizeof(*buffers)); if (!buffers) { LOGE ("++++%d Out of memory\n",__LINE__);return -1; }for(i = 0; i< bufnum; ++i) {memset(&v4l2_buf, 0, sizeof(v4l2_buf));v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;v4l2_buf.memory = V4L2_MEMORY_MMAP;v4l2_buf.index = i;ret = ioctl(fd , VIDIOC_QUERYBUF, &v4l2_buf);if(ret < 0) { LOGE("+++%d : VIDIOC_QUERYBUF failed\n",__LINE__); return -1;}buffers[i].length = v4l2_buf.length;if ((buffers[i].start = (char *)mmap(0, v4l2_buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, v4l2_buf.m.offset)) < 0) { LOGE("%d : mmap() failed",__LINE__); return -1;}}return 0;}/* *open usb camera device */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_streamon(JNIEnv * env, jclass obj){int i;int ret;enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;for(i = 0; i< bufnum; ++i) {memset(&v4l2_buf, 0, sizeof(v4l2_buf));v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;v4l2_buf.memory = V4L2_MEMORY_MMAP;v4l2_buf.index = i;ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buf);if (ret < 0) { LOGE("%d : VIDIOC_QBUF failed\n",__LINE__); return ret;}} ret = ioctl(fd, VIDIOC_STREAMON, &type); if (ret < 0) { LOGE("%d : VIDIOC_STREAMON failed\n",__LINE__); return ret; }return 0;}/* *get one frame data */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_dqbuf(JNIEnv * env, jclass obj,const jbyteArray videodata){ int ret;jbyte *data = (jbyte*)(*env)->GetByteArrayElements(env, videodata, 0); v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buf.memory = V4L2_MEMORY_MMAP; ret = ioctl(fd, VIDIOC_DQBUF, &v4l2_buf); if (ret < 0) { LOGE("%s : VIDIOC_DQBUF failed, dropped frame\n",__func__); return ret; }memcpy(data,buffers[v4l2_buf.index].start,buffers[v4l2_buf.index].length);(*env)->ReleaseByteArrayElements(env, videodata, data, 0);return v4l2_buf.index;}/* *put in frame buffer to queue */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_qbuf(JNIEnv * env, jclass obj,jint index){ int ret; v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buf.memory = V4L2_MEMORY_MMAP; v4l2_buf.index = index; ret = ioctl(fd, VIDIOC_QBUF, &v4l2_buf); if (ret < 0) { LOGE("%s : VIDIOC_QBUF failed\n",__func__); return ret; } return 0;}/* *streamoff */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_streamoff(JNIEnv * env, jclass obj,jint index){ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int ret; ret = ioctl(fd, VIDIOC_STREAMOFF, &type); if (ret < 0) { LOGE("%s : VIDIOC_STREAMOFF failed\n",__func__); return ret; } return 0;}/* *release */JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_release(JNIEnv * env, jclass obj){ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; int ret;int i; ret = ioctl(fd, VIDIOC_STREAMOFF, &type); if (ret < 0) { LOGE("%s : VIDIOC_STREAMOFF failed\n",__func__); return ret; } for (i = 0; i < bufnum; i++) { ret = munmap(buffers[i].start, buffers[i].length);if (ret < 0) { LOGE("%s : munmap failed\n",__func__); return ret; }}free (buffers);close(fd);return 0;}
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
 

The first is open.

Second, initialize the init function.

    ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);    if (ret < 0) {        LOGE("%d :VIDIOC_QUERYCAP failed\n",__LINE__);        return -1;    }    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {        LOGE("%d : no capture devices\n",__LINE__);        return -1;    }
Obtain the device information and check whether the capture mode is supported.

memset( &fmt, 0, sizeof(fmt));fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;fmt.fmt.pix.width = width;fmt.fmt.pix.height = height;if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0){LOGE("++++%d : set format failed\n",__LINE__);return -1;}
Set the format. usb camera has obtained the jpeg format. Therefore, set the format to RGB565.

    struct v4l2_requestbuffers req;    req.count = numbuf;    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    req.memory = V4L2_MEMORY_MMAP;    ret = ioctl(fd, VIDIOC_REQBUFS, &req);    if (ret < 0) {        LOGE("++++%d : VIDIOC_REQBUFS failed\n",__LINE__);        return -1;    }
Apply for a buffer. Here, apply for numbuf buffer frames.
    buffers = calloc(req.count, sizeof(*buffers));    if (!buffers) {        LOGE ("++++%d Out of memory\n",__LINE__);return -1;    }for(i = 0; i< bufnum; ++i) {memset(&v4l2_buf, 0, sizeof(v4l2_buf));v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;v4l2_buf.memory = V4L2_MEMORY_MMAP;v4l2_buf.index = i;ret = ioctl(fd , VIDIOC_QUERYBUF, &v4l2_buf);if(ret < 0) {   LOGE("+++%d : VIDIOC_QUERYBUF failed\n",__LINE__);   return -1;}buffers[i].length = v4l2_buf.length;if ((buffers[i].start = (char *)mmap(0, v4l2_buf.length,                                     PROT_READ | PROT_WRITE, MAP_SHARED,                                     fd, v4l2_buf.m.offset)) < 0) {     LOGE("%d : mmap() failed",__LINE__);     return -1;}}
Map virtual memory to physical address to obtain the physical address of each buffer zone


Streamon Functions

Put the buffer into the queue and enable the data stream

Dqbuf Function

Get a frame of data and return the serial number of the current buffer.

Qbuf Functions

Put the specified buffer into the queue. After obtaining the data in a buffer zone, you need to re-put the buffer into the queue.

I won't explain much about the next two.


Android. mk file:

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE_TAGS := engLOCAL_SRC_FILES:= fimcgzsd.cLOCAL_MODULE := libfimcgzsdLOCAL_LDLIBS    := -llogLOCAL_SHARED_LIBRARIES := libc libcutilsinclude $(BUILD_SHARED_LIBRARY)



Reference blog: http://blog.csdn.net/eastmoon502136/article/details/8190262

========================================================== ====
Author: hclydao
Http://blog.csdn.net/hclydao
No copyright, but please keep this statement for reprinting

========================================================== ====


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.