上一篇说了下usb camera uvc标准的 顺便把CMOS做到一起 操作上基本一至 上一篇HAL层里我已经提供了CMOS的相关接口
JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_yuvtorgb
如果使用和UVC一样的处理 图像显示不出来 所以用另外一种方法 同时这里使用的是斯道ICOOL210开发板测试的 如果使用CMOS还需要修改一些地方 HAL层修改如下
首先增加一个函数如下
- int select_input(int input)
- {
- int ret;
- ret = ioctl(fd, VIDIOC_S_INPUT, &input);
- if (ret) {
- printf("xioctl VIDIOC_S_INPUT failed+++++\n");
- }
- return ret;
- }
- JNIEXPORT jint JNICALL Java_com_dao_usbcam_Fimcgzsd_init(JNIEnv * env, jclass obj, jint width, jint height,jint numbuf,jint ctype)
- {
- int ret;
- int i;
- bufnum = numbuf;
- mwidth = width;
- mheight = height;
- c_type = ctype;
- struct v4l2_format fmt;
- struct v4l2_capability cap;
- if(c_type == 2)
- select_input(0);
- else if(c_type == 3)
- select_input(1);
- 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;
- if(c_type > 0)
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
- else
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
- if(c_type > 1) {
- fmt.fmt.pix.field = V4L2_FIELD_NONE;//V4L2_FIELD_INTERLACED;//V4L2_FIELD_NONE;
- fmt.fmt.pix.priv = 1;
- }
- 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;
- }
- }
- rgb = (int *)malloc(sizeof(int) * (mwidth*mheight));
- ybuf = (int *)malloc(sizeof(int) * (mwidth*mheight));
- return 0;
- }
修改地方不是很多 这里当c_type为2的时候是针对CMOS的接口通道1 为3的时候是通道2
同时在
void yuyv422torgb(unsigned char *src,int *mrgb)
最后需要修改下 在测试过程中发现红色和蓝色反了 所以把最后的
- *lrgb++ = 0xff000000 | b1<<16 | g1<<8 | r1;
- *lrgb++ = 0xff000000 | b2<<16 | g2<<8 | r2;
- *lrgb++ = 0xff000000 | r1<<16 | g1<<8 | b1;
- *lrgb++ = 0xff000000 | r2<<16 | g2<<8 | b2;
- class StartThread extends Thread {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- //super.run();
- while(true) {
- index = Fimcgzsd.dqbuf(mdata);
- if(index < 0) {
- onDestroy();
- break;
- }
- switch(ctype) {
- case 0:
- mHandler.post(mUpdateUI);
- bitmap = BitmapFactory.decodeByteArray(mdata, 0, width * height);
- Fimcgzsd.qbuf(index);
- break;
- case 1:
- Fimcgzsd.pixeltobmp(bmp);
- mHandler.post(mUpdateUI);
- bitmap = bmp;
- Fimcgzsd.qbuf(index);
- break;
- case 2: case 3:
- Fimcgzsd.yuvtorgb(mdata, rgb);
- mHandler.post(mUpdateUI);
- bitmap = Bitmap.createBitmap(rgb,width,height,Bitmap.Config.ARGB_8888);
- Fimcgzsd.qbuf(index);
- break;
- }
- }
- }
CMOS效果如下
============================================
作者:hclydao
http://blog.youkuaiyun.com/hclydao
版权没有,但是转载请保留此段声明
============================================