V4L2摄像头采集

  • e3_205524
    了解作者
  • 27.6KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-28 12:53
    上传日期
V4L2摄像头采集,根据分辨率和帧率 用于android
camera_jni.rar
  • camera
  • jni
  • ImageProc.h
    3KB
  • Android.mk
    812B
  • ImageProc.cpp
    14.9KB
  • make
    113B
  • Makefile
    56B
  • Application.mk
    150B
  • libs
  • armeabi-v7a
  • libImageProc.so
    45.2KB
内容介绍
#include "ImageProc.h" //01-24 07:43:06.439: E/TEST(3756): error 22, Invalid argument #include <string> using namespace std; // 定义一个 Camera的指针 Camera *camera=NULL; int n_buffers=0; char * g_buffer=NULL; char * g_buffer2=NULL; int setInterge(JNIEnv *env, jobject thiz, jobject p1, int value) { jclass c; jfieldID id; c = env->FindClass("java/lang/Integer"); if (c==NULL) { LOGD("FindClass failed"); return -1; } id = env->GetFieldID(c, "value", "I"); if (id==NULL) { LOGD("GetFiledID failed"); return -1; } env->SetIntField(p1, id, value); return 0; } void yuyv_2_yuv420( int inWidth, int inHeight ,unsigned char * psrc,unsigned char *pDest) { int i,j; unsigned char *Y ,*U,*V; unsigned char y1,y2,u,v; Y=pDest; U=pDest+inHeight*inWidth; V=U+inHeight*inWidth/4; for(i=0;i<inHeight;i++) { for(j=0;j<inWidth/2;j++) { y1 = *( psrc + (i*inWidth/2+j)*4); u = *( psrc + (i*inWidth/2+j)*4 + 1); y2 = *( psrc + (i*inWidth/2+j)*4 + 2); v = *( psrc + (i*inWidth/2+j)*4 + 3); *Y++=y1; *Y++=y2; if(i%2==0) { *U++=u; *V++=v; } } } } int xioctl(int fd, int request, void *arg) { int r = 0; do { r = ioctl(fd, request, arg); } while (-1 == r && EINTR == errno); return r; } //打开video设备 int open_camera(Camera *cam) { struct stat st; //stat() 获得文件属性,并判断是否为字符设备文件 if (-1 == stat (cam->device_name, &st)) { LOGE("Cannot identify '%s': %d, %s", cam->device_name, errno, strerror (errno)); return ERROR_DEVICE_NOT_EXIST;//改ID设备不存在 } if (!S_ISCHR (st.st_mode)) { LOGE("%s is no device", cam->device_name); return ERROR_DEVICE_TYPE_ERROR;//设备类型不匹配 } cam->fd = open(cam->device_name, O_RDWR| O_NONBLOCK, 0); // | O_NONBLOCK if (-1 == cam->fd) { LOGE("Cannot open '%s': %d, %s", cam->device_name, errno, strerror (errno)); return ERROR_DEVICE_OPEN_FALIED;//打开失败 } LOGD(" open '%s' ok", cam->device_name); // return SUCCESSED; } //初始化设备 int init_camera( Camera *cam) { struct v4l2_capability *cap = &(cam->v4l2_cap); struct v4l2_cropcap *cropcap = &(cam->v4l2_cropcap); struct v4l2_crop *crop = &(cam->crop); struct v4l2_format *fmt = &(cam->v4l2_fmt); unsigned int min; int ret =0; struct v4l2_fmtdesc fmtdesc; //VIDIOC_QUERYCAP 命令 来获得当前设备的各个属性 if (-1 == xioctl(cam->fd, VIDIOC_QUERYCAP, cap)) { if (EINVAL == errno) { LOGE("%s is no V4L2 device\n", cam->device_name); return ERROR_DEVICE_CAP_ERROR; } else { LOGE("%s error %d, %s\n", "VIDIOC_QUERYCAP", errno, strerror(errno)); return ERROR_DEVICE_CAP_ERROR; } } LOGI("\nVIDOOC_QUERYCAP\n"); LOGI("the camera driver is %s\n", cap->driver); LOGI("the camera card is %s\n", cap->card);//UVC Camera (046d:081b) LOGI("the camera bus info is %s\n", cap->bus_info); LOGI("the version is %d\n", cap->version);//199168 if (!(cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)) { LOGE( "%s is no video capture device\n", cam->device_name); return ERROR_DEVICE_CAP_ERROR; } fmtdesc.index=0; fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; LOGE("Support format:\n"); while(ioctl(cam->fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) { LOGE("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description); fmtdesc.index++; } if (!(cap->capabilities & V4L2_CAP_STREAMING)) { LOGE( "%s does not support streaming i/o\n",cam->device_name); return ERROR_DEVICE_CAP_ERROR; } //获得设备对 Image Cropping 和 Scaling 的支持 CLEAR (*cropcap); cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop->c.width = cam->width; crop->c.height = cam->height; crop->c.left = 0; crop->c.top = 0; crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //设置图形格式 CLEAR (*fmt); LOGI( "%s setfmt go...!\n", cam->device_name); fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmt->fmt.pix.width = cam->width; fmt->fmt.pix.height = cam->height; //fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; //yuv422 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; //隔行扫描 //检查流权限 if (-1 == xioctl(cam->fd, VIDIOC_S_FMT, fmt)){ LOGE("%s error %d, %s\n", "VIDIOC_S_FMT", errno, strerror(errno)); return ERROR_DEVICE_CAP_ERROR; } min = fmt->fmt.pix.width * 2; //每行像素所占的 byte 数 if (fmt->fmt.pix.bytesperline < min) fmt->fmt.pix.bytesperline = min; min = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height; if (fmt->fmt.pix.sizeimage < min) fmt->fmt.pix.sizeimage = min; LOGI("NEW yuyv buffer length = %d \n",cam->width*cam->height *2); LOGI("NEW yuv420 buffer length = %d \n",cam->width*cam->height /2*3); g_buffer = new char [cam->width*cam->height *2]; g_buffer2 = new char [cam->width*cam->height/2*3]; //设置帧率 struct v4l2_streamparm Stream_Parm; memset(&Stream_Parm, 0, sizeof(struct v4l2_streamparm)); Stream_Parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; Stream_Parm.parm.capture.timeperframe.denominator =cam->framerate;; Stream_Parm.parm.capture.timeperframe.numerator = 1; ret = xioctl(cam->fd, VIDIOC_S_PARM, &Stream_Parm); LOGI("VIDIOC_S_PARM= %d \n",ret); return initmmap (cam); } //I/O模式选择 int initmmap( Camera *cam) { struct v4l2_requestbuffers req; CLEAR (req); LOGI("initmap\n"); req.count = 4; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl (cam->fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { LOGE("%s does not support memory mapping", cam->device_name); return ERROR_LOCAL; } else { return ERROR_REQBUFS; } } if (req.count < 2) { LOGE("Insufficient buffer memory on %s", cam->device_name); return ERROR_LOCAL; } cam->buffers =(struct buffer *) calloc (req.count, sizeof (* (cam->buffers) )); if (!cam->buffers) { LOGE("Out of memory"); return ERROR_LOCAL; } for (n_buffers = 0; n_buffers < req.count; ++n_buffers) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = n_buffers; if (-1 == xioctl (cam->fd, VIDIOC_QUERYBUF, &buf)) return ERROR_VIDIOC_QUERYBUF; LOGI("MMAP_SIZE=%d\n",buf.length); cam->buffers[n_buffers].length = buf.length; cam->buffers[n_buffers].start = mmap (NULL , buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, cam->fd, buf.m.offset); if (MAP_FAILED == cam->buffers[n_buffers].start) return ERROR_MMAP_FAILD; } return SUCCESSED; } int startcapturing(Camera *cam) { unsigned int i; enum v4l2_buf_type type; for (i = 0; i < n_buffers; ++i) { struct v4l2_buffer buf; CLEAR (buf); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; buf.index = i; if (-1 == xioctl (cam->fd, VIDIOC_QBUF, &buf)) return ERROR_VIDIOC_QBUF; } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == xioctl (cam->fd, VIDIOC_STREAMON, &type)) return ERROR_VIDIOC_STREAMON; return SUCCESSED; } int readframeonce(Camera *cam,char *buf ,int * size) { for (;;) { fd_set fds; struct timeval tv; int r; FD_ZERO (&fds); FD_SET (cam->fd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; r = select (c
评论
    相关推荐
    • android
      掌握Android Studio开发环境的搭建步骤,能够独立搭建 Android Studio开发环境
    • android
      android
    • android
      Android回购
    • android
      android
    • android课件
      清华老师上课的android课件。ch_01android概述ch_02android开发基础ch_03资源的访问ch_04android用户界面ch_05Ativity和Intent。其他自己看。
    • androidandroid
      androidandroidandroidandroidandroidandroidandroid
    • Android 教程
      Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android 案例 教程,Android ...
    • Android
      Android
    • Android
      Android