精华内容
下载资源
问答
  • android USB 摄像头

    2018-09-13 10:43:55
    android手机usb摄像头工具,手机可以接摄像头拍照,部分手机可以不支持。android手机usb摄像头工具,手机可以接摄像头拍照,部分手机可以不支持。
  • Android Usb摄像头

    2015-11-19 14:30:22
    android调用usb摄像头进行拍照并把照片保存到本地的代码,请确保android已root,否则无法调用
  • AndroidUsb摄像头Demo

    2018-08-22 11:29:05
    AndroidUsb摄像头,读取外界摄像头,支持实时预览,拍照,录像,录音。
  • Android usb摄像头

    2015-04-28 10:45:56
    1、原生的mipi接口的摄像头,会生成/dev/media/节点来使用,USB摄像头也会生成dev/media节点,但是USB摄像头的media节点一直打开失败。
  • android usb摄像头 支持yuyv mjpeg格式 设备路径 /dev/videoid id可自己设
  • AndroidUSB摄像头源码,使用androidstudio编译,亲测可用,外接摄像头直接出现图像,可以拍照,录像,调节分辨率,亮度,对比度等。
  • Android USB 摄像头 Camera

    2017-10-31 10:52:59
    android 调用 USB 摄像头, 运到预览画面黑屏,参考https://bitbucket.org/neuralassembly/simplewebcam/src 对源码进行了 优化处理
  • AndroidUSB摄像头含拍照

    2019-08-08 16:24:33
    检测Android主板外接USB摄像头的PIC和VID,根据PIC和VID指定打开摄像头,自助切换并实现拍照功能,有完整的demo。
  • Android USB摄像头源码

    2018-11-01 17:39:11
    Android摄像头预览功能的实现,主要是通过JNI实现相关功能
  • Android板子外联usb摄像头模块,程序能实现拍照,录制视频等功能。
  • 开发板系统: android4.0 (Linux kernel 2.6.34) 插上zc301 USB 免驱摄像头,...需要在内核中去配置zc301系列USB摄像头。 make menuconfig Device Drivers ---> Multimedia support --->  * > Video For Linu

    开发板系统:

    android4.0 (Linux kernel 2.6.34)


    插上zc301 USB 免驱摄像头,/dev/目录下并没有此设备。需要在内核中去配置zc301系列USB摄像头。

    make menuconfig

    Device Drivers --->



    Multimedia support --->


    < * > Video For Linux

    Video capture adapters --->


    [ * ] V4L USB devices --->


    < * > USB Video Class (UVC)

    [ * ] UVC input events device support

    < * > GSPCA based webcams --->


    < * > ZC3XX USB Camera Driver


    make  uImage 重新编译内核,并烧到开发板

    再插上zc301摄像头,


    查看 /dev/目录,video0就是usb摄像头



    另外,附上别人的android 上usb摄像头应用程序。

    http://www.eoeandroid.com/thread-252676-1-1.html

    我在调试的时候,直接打开android的camera 便可得到图像。

    展开全文
  • 电脑安装完系统后USB摄像头却不能正常使用,一查硬件信息才发现是没有安装驱动的原因,而此时网课和直播时间马上就要到了,这个时间你是不是很抓狂。小编立刻给你秘密武器!慧眼视讯近日发布自主研发新品USB摄像头,...

    电脑安装完系统后USB摄像头却不能正常使用,一查硬件信息才发现是没有安装驱动的原因,而此时网课和直播时间马上就要到了,这个时间你是不是很抓狂。小编立刻给你秘密武器!慧眼视讯近日发布自主研发新品USB摄像头,是一款不用装驱动的USB摄像头,也叫USB摄像机。

    c8f241dc0cb9c78f8ab62aebfc07a892.gif

    慧眼视讯USB摄像头搭载君正T31系列芯片,君正T31系列芯片相比前代而言做出了全面的升级,采用的是22nm工艺,QFN/BGA多种封装,功耗极低。

    T31系列芯片最高支持500万分辨率实时视频,支持快速启动,支持人形侦测、人脸侦测/识别、哭声侦测、车辆侦测、动物侦测等丰富算法,极大的扩展了搭载设备的应用场景。

    c3b5718a64b4be4ad9dfdd5f1563ec99.png

    慧眼视讯USB摄像头适用于多种场景,包括但不限于企业办公、直播、公司会议、网课、照片采集等。兼容各种直播平台,支持多个社交、视频软件,集各大功能于一体,摄像头自带的高清摄影功能和图像增强算法更是用户在进行视频时的有力帮手。

    ec135e95f1aba7a23c7854f4f0e9a6b7.png

    慧眼视讯USB摄像头拥有200万高清像素,分辨率1920X1080,全高清1080P 30FPS输出。满足用户在网课和直播时画面的高清晰度,不受画质影响。相机还自带白平衡、3D去噪、美颜、图像增强等实用功能,让你随时随地都可外观出众。

    70767c6643363f3b314af4394e09ee6d.png

    慧眼视讯USB摄像头兼容windows、iOS、linux、Android、MAC OS等多种系统,支持MJPEG H.264编码输出,标准UVC/UVA协议 即插即用。

    4b68fd0af5ec20d97509dd06fa9f834c.png

    f59136a8a3776a26acc210f7d57f4e4b.gif

    总得来说,慧眼视讯USB摄像头在君正T31系列芯片的加持下,在视频功能方面,都挑不出什么太大的缺点。而其便捷的实用模式、优秀的视频画面产出、君正T31系列芯片加持带来的超低功耗,都让慧眼视讯USB摄像头成为了一款有口皆碑的优秀产品。

    5232f2f9ec6b679c09d4b09ba1f737cf.gif234ddc61fb5c9876021997e1449ddde4.png

    点击上方“北京君正”关注我们,了解更多精彩信息

    3a2cc02b0733026aa0a8fa9fe396c1c5.png
    展开全文
  • android USB摄像头做条形码及二维码扫描(2) 1. 前言 公司做的产品基于android开发板搭建的控制系统,需要做一个二维码扫描功能,用的UVCCamera。这里做一下笔记,顺便理一下之前的思路。android版本是4.4.4W,...

    摘要:

    1、前言

    2、底层配置

    3、JNI实现

    4、总结

    5、BUG及优化记录

    android USB摄像头做条形码及二维码扫描(2)

     

    1. 前言

    公司做的产品基于android开发板搭建的控制系统,需要做一个二维码扫描功能,用的UVCCamera。这里做一下笔记,顺便理一下之前的思路。android版本是4.4.4W,定制ROM。这个功能的实现是基于simplewebcam这个开源项目的,有兴趣的可以看看这个,但是这个源码有些异常处理有问题。

    2. 底层配置

    传送门:Android USB Camera(1) : 调试记录

    底层需要的操作不是我做的,所以就不啰嗦了,可以参考这篇文章。但是识别的摄像头的设备可能会不一样,我这个ROM识别出来的是video4,具体根据实际的开启对应摄像头设备。

    3、JNI实现

    V4L2是Video4linux2的简称,为linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video4下。

    关于UVC和V4L2不太懂的可以自行百度。

    3.1 操作流程

    盗个图:大概的流程如下图:

    3.2 具体代码实现

    JNI有4个接口方法

    jint Java_com_camera_usbcam_CameraPreview_prepareCamera( JNIEnv* env,jobject thiz, jint videoid, jint videobase, jint mirrorType, jint WIDTH, jint HEIGHT);
    jint Java_com_camera_usbcam_CameraPreview_processCamera( JNIEnv* env,jobject thiz);
    void Java_com_camera_usbcam_CameraPreview_stopCamera(JNIEnv* env,jobject thiz);
    void Java_com_camera_usbcam_CameraPreview_pixeltobmp(JNIEnv* env,jobject thiz, jobject bitmap);

    prepareCamera:在启动摄像头预览之前进行初始化,说明下:mirrorType是用来控制图像翻转的,摄像头是固定在仪器上的,所以需要翻转采集到的数据将图片显示为正的图片

    stopCamera:在界面退出的时候注销摄像头驱动

    processCamera:获取摄像头采集到的图像数据

    pixeltobmp:将图像数据转为bitmap用于java层显示

    (1) 打开设备驱动节点

    //打开video设备
    int opendevice(int i)
    {
    	struct stat st;
    
    	sprintf(dev_name,"/dev/video%d",i);
    
    	//stat() 获得文件属性,返回:若成功则为0,若出错则为-1
    	if (-1 == stat (dev_name, &st)) {
    		LOGE("Cannot identify '%s': %d, %s", dev_name, errno, strerror (errno));
    		return ERROR_LOCAL;
    	}
    
    	//判断是否为字符设备文件
    	if (!S_ISCHR (st.st_mode)) {
    		LOGE("%s is no device", dev_name);
    		return ERROR_LOCAL;
    	}
    
    	//打开设备
    	fd = open (dev_name, O_RDWR);
    
    	if (-1 == fd) {
    		LOGE("Cannot open '%s': %d, %s", dev_name, errno, strerror (errno));
    		return ERROR_LOCAL;
    	}
    	return SUCCESS_LOCAL;
    }

    (2) 查询并初始化摄像头驱动、设置视频格式

    //初始化设备
    int initdevice(void)
    {
    	struct v4l2_capability cap;
    	struct v4l2_cropcap cropcap;
    	struct v4l2_crop crop;
    	struct v4l2_format fmt;
    	unsigned int min;
    
    	//VIDIOC_QUERYCAP 命令 来获得当前设备的各个属性
    	if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
    		if (EINVAL == errno) {
    			LOGE("%s is no V4L2 device", dev_name);
    			return ERROR_LOCAL;
    		} else {
    			return errnoexit ("VIDIOC_QUERYCAP");
    		}
    	}
    
    	//V4L2_CAP_VIDEO_CAPTURE 0x00000001
    	// 这个设备支持 video capture 的接口,即这个设备具备 video capture 的功能
    	if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
    		LOGE("%s is no video capture device", dev_name);
    		return ERROR_LOCAL;
    	}
    
    	//V4L2_CAP_STREAMING 0x04000000
    	// 这个设备是否支持 streaming I/O 操作函数
    	if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
    		LOGE("%s does not support streaming i/o", dev_name);
    		return ERROR_LOCAL;
    	}
    
    	//获得设备对 Image Cropping 和 Scaling 的支持
    	CLEAR (cropcap);
    
    	cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    	//设置图形格式
    	CLEAR (fmt);
    
    	fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    	fmt.fmt.pix.width       = IMG_WIDTH;
    	fmt.fmt.pix.height      = IMG_HEIGHT;
    
    	fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    	fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
    
    	//检查流权限
    	if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
    		return errnoexit ("VIDIOC_S_FMT");
    
    	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;
    
    	return initmmap ();
    
    }

    (3) 设置IO模式、申请内存

    //I/O模式选择
    int initmmap(void)
    {
    	struct v4l2_requestbuffers req;
    
    	CLEAR (req);
    
    	req.count               = 4;
    	req.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	req.memory              = V4L2_MEMORY_MMAP;
    
    	if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
    		if (EINVAL == errno) {
    			LOGE("%s does not support memory mapping", dev_name);
    			return ERROR_LOCAL;
    		} else {
    			return errnoexit ("VIDIOC_REQBUFS");
    		}
    	}
    
    	if (req.count < 2) {
    		LOGE("Insufficient buffer memory on %s", dev_name);
    		return ERROR_LOCAL;
     	}
    
    	buffers = calloc (req.count, sizeof (*buffers));
    
    	if (!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 (fd, VIDIOC_QUERYBUF, &buf))
    			return errnoexit ("VIDIOC_QUERYBUF");
    
    		buffers[n_buffers].length = buf.length;
    		buffers[n_buffers].start =
    		mmap (NULL ,
    			buf.length,
    			PROT_READ | PROT_WRITE,
    			MAP_SHARED,
    			fd, buf.m.offset);
    
    		if (MAP_FAILED == buffers[n_buffers].start)
    			return errnoexit ("mmap");
    	}
    
    	return SUCCESS_LOCAL;
    }

    (4)开始采集

    int startcapturing(void)
    {
    	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 (fd, VIDIOC_QBUF, &buf))
    			return errnoexit ("VIDIOC_QBUF");
    	}
    
    	type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    
    	if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
    		return errnoexit ("VIDIOC_STREAMON");
    
    	return SUCCESS_LOCAL;
    }

    (5) 从缓存队列中取出一帧

    int readframeonce(void)
    {
    	for (;;) {
    		fd_set fds;
    		struct timeval tv;
    		int r;
    
    		FD_ZERO (&fds);
    		FD_SET (fd, &fds);
    
    		tv.tv_sec = 2;
    		tv.tv_usec = 0;
    
    		r = select (fd + 1, &fds, NULL, NULL, &tv);
    
    		if (-1 == r) {
    			if (EINTR == errno)
    				continue;
    
    			return errnoexit ("select");
    		}
    
    		if (0 == r) {
    			LOGE("select timeout");
    			return ERROR_LOCAL;
    
    		}
    
    		if (readframe ()==1)
    			break;
    		else
    //			LOGE(">>>  No device was found !");
    			return ERROR_LOCAL;
    	}
    
    //	LOGE(">>>  SUCCESS_LOCAL!");
    	return SUCCESS_LOCAL;
    
    }
    int readframe(void){
    
    	struct v4l2_buffer buf;
    	unsigned int i;
    
    	CLEAR (buf);
    
    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	//buf.memory = V4L2_MEMORY_USERPTR;
    	//LOGE("fd=%d,request=%d,buf=%d",fd,VIDIOC_DQBUF,&buf);
    	if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
    		switch (errno) {
    			case EAGAIN:
    				return 0;
    			case EIO:
    			default:
    				stopcapturing ();
    
    				uninitdevice ();
    
    				closedevice ();
    
    				if(rgb) {
    					free(rgb);
    					rgb = NULL;
    				}
    
    				return errnoexit ("VIDIOC_DQBUF");
    		}
    	}
    
    	assert (buf.index < n_buffers);
    
    	processimage (buffers[buf.index].start);
    
    	if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
    		return errnoexit ("VIDIOC_QBUF");
    
    	return 1;
    }

    (6) 将YUYV格式转为RGB格式

    void processimage (const void *p){
    		yuyv422toABGRY((unsigned char *)p);
    }
    void yuyv422toABGRY(unsigned char *src)
    {
    
    	int width=0;
    	int height=0;
    
    	width = IMG_WIDTH;
    	height = IMG_HEIGHT;
    
    	//后面会介绍为什么这里要乘以2
    	int frameSize =width*height*2;
    
    	int i;
    
    	if(!rgb){
    		return;
    	}
    	int *lrgb = NULL;
    	//modify by yozad.von  2019/05/21  删除没用到的lybuf
    
    	//将rgb的首地址赋给lrgb,这样只要给lrgb指向的地址赋值,那么rgb的值也会相应改变。
    	lrgb = &rgb[0];
    
    	if(yuv_tbl_ready==0){
    		for(i=0 ; i<256 ; i++){
    			//按照下面的代码,y1192_tbl[i]前面的16个数组都为0
    			y1192_tbl[i] = 1192*(i-16);
    			if(y1192_tbl[i]<0){
    				y1192_tbl[i]=0;
    			}
    
    			v1634_tbl[i] = 1634*(i-128);
    			v833_tbl[i] = 833*(i-128);
    			u400_tbl[i] = 400*(i-128);
    			u2066_tbl[i] = 2066*(i-128);
    		}
    		yuv_tbl_ready=1;
    	}
    
    	//由于是两个字节表示一个像素值,而这里每一次for循环,都会向前移4个字节,产生两个像素值,所以要产生IMG_WIDTH*IMG_HEIGHT个像素值,就必须乘以2
    	for(i=0 ; i<frameSize ; i+=4){
    		unsigned char y1, y2, u, v;
    		//由于在上面的采集图像设置中设定为两个字节表示一个像素值,所以这4个字节便表示两个像素值
    		y1 = src[i];
    		u = src[i+1];
    		y2 = src[i+2];
    		v = src[i+3];
    
    		//根据y1、u、y2、v,以及上面的y1192_tbl[]、v1634_tbl[i]、v833_tbl[i]、u2066_tbl[i]数组的值,来设定r、g、b的值
    		int y1192_1=y1192_tbl[y1];
    		int r1 = (y1192_1 + v1634_tbl[v])>>10;
    		int g1 = (y1192_1 - v833_tbl[v] - u400_tbl[u])>>10;
    		int b1 = (y1192_1 + u2066_tbl[u])>>10;
    
    		int y1192_2=y1192_tbl[y2];
    		int r2 = (y1192_2 + v1634_tbl[v])>>10;
    		int g2 = (y1192_2 - v833_tbl[v] - u400_tbl[u])>>10;
    		int b2 = (y1192_2 + u2066_tbl[u])>>10;
    
    		//当r、g、b的值大于255时,赋值为255.当小于0时,赋值为0.
    		r1 = r1>255 ? 255 : r1<0 ? 0 : r1;
    		g1 = g1>255 ? 255 : g1<0 ? 0 : g1;
    		b1 = b1>255 ? 255 : b1<0 ? 0 : b1;
    		r2 = r2>255 ? 255 : r2<0 ? 0 : r2;
    		g2 = g2>255 ? 255 : g2<0 ? 0 : g2;
    		b2 = b2>255 ? 255 : b2<0 ? 0 : b2;
    
    		//r由8位表示,g也由8位表示,b由8位表示。将两个点的RGB值传入lrgb中
    		*lrgb++ = 0xff000000 | b1<<16 | g1<<8 | r1;
    		*lrgb++ = 0xff000000 | b2<<16 | g2<<8 | r2;
    	}
    }

    (7) java层显示

    ...
    try {
    	if (dstRect == null) {
    	//如果dstRect为null,则获取显示的宽高,并初始化dstRect
    	winWidth = this.getWidth();
    	winHeight = this.getHeight();
    	LoggerUtils.e(TAG, ">>>  winWidth  "+winWidth+"  "+winHeight);
    	dstRect = new Rect(0, 0, winWidth, winHeight);
    	}
    	
    	if (!isNoDevice) {
    		if (processCamera() == 0) {
    			pixeltobmp(bmp);
    			Canvas canvas = holder.lockCanvas();
    			if (canvas != null) {
    				synchronized(bmp) {
    					// draw camera bmp on canvas
    					canvas.drawBitmap(bmp, null, dstRect, null);
    					getHolder().unlockCanvasAndPost(canvas);
    				}
    			}
    		}else {
    			isNoDevice = true;
    		}
    		
    	}else {
    		isQRCode = false;
    		((Main) context).exit(1);
    		scanStart = false;
    		cameraExists = false;
    	}
    } catch (Exception e1) {
    	e1.printStackTrace();
    }
    ...

    4. 总结

    之前提到的,相比较开源的SimpleWebCam,有些异常处理有问题,所以稍微有做改动。

    还有一个开源项目UVCCamera,因为项目及行业要求,故不采用。

    后面会更新,如何利用这个摄像头的预览进行二维码解析。

     

    5. BUG及优化记录

    5.1 BUG

    1、会导致APP停止运行的BUG,下面贴出部分错误日志,主要是内存方面的报错:

    06-11 13:25:29.260: E/ImageProc(1760): VIDIOC_STREAMOFF error 19, No such device
    06-11 13:25:29.260: I/EventHub(1572): Removing device '/dev/input/event2' due to inotify event
    06-11 13:25:29.260: I/EventHub(1572): Removed device: path=/dev/input/event2 name=USB 2.0 PC Cam2 id=1 fd=90 classes=0x80000001
    06-11 13:25:29.275: I/ActivityManager(1572): Start proc com.hp.android.printservice for broadcast com.hp.android.printservice/.usb.ReceiverUSBDeviceDetached: pid=3015 uid=10046 gids={50046, 3003, 1028, 1015, 1023}
    06-11 13:25:29.280: I/InputReader(1572): Device removed: id=1, name='USB 2.0 PC Cam2', sources=0x00000101
    06-11 13:25:29.280: E/ImageProc(1760): VIDIOC_DQBUF error 19, No such device
    06-11 13:25:29.280: E/ImageProc(1760): VIDIOC_STREAMOFF error 9, Bad file number
    06-11 13:25:29.280: A/libc(1760): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 2107 (pool-1-thread-1)
    ...
    06-11 13:25:29.385: I/DEBUG(1229): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    06-11 13:25:29.385: I/DEBUG(1229): Build fingerprint: 'Android/smdk4x12/smdk4x12:4.4.4/KTU84P/eng.root.20180107.235318:eng/test-keys'
    06-11 13:25:29.385: I/DEBUG(1229): Revision: '0'
    06-11 13:25:29.385: I/DEBUG(1229): pid: 1760, tid: 2107, name: pool-1-thread-1  >>> com.reallife.main <<<
    06-11 13:25:29.385: I/DEBUG(1229): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
    ...
    06-11 13:25:29.460: I/DEBUG(1229):     #00  pc 00001974  /data/app-lib/com.reallife.main-1/libImageProc.so (uninitdevice+35)
    06-11 13:25:29.460: I/DEBUG(1229):     #01  pc 0000225d  /data/app-lib/com.reallife.main-1/libImageProc.so (Java_com_camera_usbcam_CameraPreview_stopCamera+8)
    06-11 13:25:29.460: I/DEBUG(1229):     #02  pc 0001dbcc  /system/lib/libdvm.so (dvmPlatformInvoke+112)
    06-11 13:25:29.460: I/DEBUG(1229):     #03  pc 0004e123  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+398)
    06-11 13:25:29.460: I/DEBUG(1229):     #04  pc 00026fe0  /system/lib/libdvm.so
    06-11 13:25:29.460: I/DEBUG(1229):     #05  pc 0002dfa0  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76)
    06-11 13:25:29.460: I/DEBUG(1229):     #06  pc 0002b638  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
    06-11 13:25:29.460: I/DEBUG(1229):     #07  pc 0006057d  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+336)
    06-11 13:25:29.460: I/DEBUG(1229):     #08  pc 000605a1  /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20)
    06-11 13:25:29.460: I/DEBUG(1229):     #09  pc 00055287  /system/lib/libdvm.so
    06-11 13:25:29.460: I/DEBUG(1229):     #10  pc 0000d228  /system/lib/libc.so (__thread_entry+72)
    06-11 13:25:29.460: I/DEBUG(1229):     #11  pc 0000d3c0  /system/lib/libc.so (pthread_create+240)

    解决方法:因为这个JNI在操作出现问题是会调用

            stopcapturing();
            uninitdevice ();
            closedevice ();

    然后在surfaceview结束的时候还会再调用一次,但这时的buffers 已经变成NULL了,所以后续的操作就会包报异常,所以需要在uninitdevice中添加

    int uninitdevice(void)
    {
    	unsigned int i;
    
    	//加上这一句,防止多次调用但buffers=NULL造成内存异常的问题
    	if (buffers == NULL)
    		return SUCCESS_LOCAL;
    
    	for (i = 0; i < n_buffers; ++i)
    	...
    }

    2、原代码中

    free (buffers);

    后没有加

    buffers = NULL;

    这样会造成野指针的出现,在频繁开启摄像头的场景下就有可能内存问题

    Fatal signal XX (SIGSEGV) at XXX (code=X), thread XX

    5.2 优化

    1、这个库将YUV数据获取到了之后,远代码在processCamera中将YUV转为RGB,然后在pixeltobmp中将RGB转为bitmap,java层绘制bitmap,中间多了一步,所以转化的速度比较慢,导致解析度高的时候画面延时比较严重。所以稍作修改:

    删除pixeltobmp,在processCamera添加

            ... 
    
           AndroidBitmapInfo  info;
    		void*              pixels;
    		int                ret;
    
    		if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
    			LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
    			return -1;
    		}
    
    		if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
    			LOGE("Bitmap format is not RGBA_8888 !");
    			return -1;
    		}
    
    		if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
    			LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    			return -1;
    		}
    
    		//由于pixels所指向的地址与bitmap密切相关,将pixels指向的地址传递给colors,这时只要改变colors指向的地址的值,就可以改变pixel指向地址的值
    
    	int res = readframeonce((int*)pixels);
    
    		AndroidBitmap_unlockPixels(env, bitmap);
    
            ...

    原先需要的镜像操作在yuyv422toABGRY中进行(直接在将YUV转为RGB的时候进行镜像算法),这是原来在pixeltobmp中的镜像算法,基本思路是一样的,有需要的朋友可以参考下。简单来说就是左右镜像的时候讲一行中的最左边和最右边的像素互换,然后第二个,第三个...依次类推。

        if(mirror == 3){
    		//上下左右镜像 2019/04/19
    		for (j = height; j > 0; j--) {
    			lrgb = &rgb[j*width - 1];
    			for(i = 0; i < width; i++){
    				*colors++ = *lrgb--;
    			}
    		}
    	}else if (mirror == 2) {
    		//上下镜像 2019/04/19
    		for (j = height; j > 0; j--) {
    			lrgb = &rgb[(j-1)*width];
    			for(i=0 ; i < width ; i++){
    				*colors++ = *lrgb++;
    			}
    		}
    	}else if (mirror == 1) {
    		//左右镜像  2019/01/21
    		for (j = 0; j < height; ++j) {
    			lrgb = &rgb[(j+1)*width - 1];
    			for(i=0 ; i < width ; i++){
    				*colors++ = *lrgb--;
    			}
    		}
    	}else if (mirror == 0) {
    		//原数据  2019/01/21
    		lrgb = &rgb[0];
    		for(i=0 ; i < width*height ; i++){
    			*colors++ = *lrgb++;
    		}
    	}

     

    展开全文
  • 在实际项目中,有些客户可能需要支持usb摄像头功能,如果你也遇到usb摄像头支持的问题,那这篇文章一定能帮助到你。目前android是支持uvc协议的,也就是只要我们采用的usb摄像头是支...

    在实际项目中,有些客户可能需要支持usb摄像头功能,如果你也遇到usb摄像头支持的问题,那这篇文章一定能帮助到你。

    目前android是支持uvc协议的,也就是只要我们采用的usb摄像头是支持uvc协议的,那就可以在android上跑起来的。

    一、我们先来了解下啥是uvc?

    UVC UVC全称为USB Video Class,即:USB视频类,是一种为USB视频捕获设备定义的协议标准。是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,已成为USB org标准之一。(简单来说,就是一种协议标准)

    二、来看看usb摄像头长啥样?

    下面2张图片就是我目前手头上用的usb摄像头。

    三、关于uvcCamera的开源项目?

    GitHub开源项目:

           https://github.com/saki4510t/UVCCamera

    目前网上关于uvcCamera 的例子,基本是基于这个开源项目来的,整个项目包含了so库的实现代码,以及包含了8个测试程序代码。

    四、基于开源uvcCamera的项目,个人写的demo?

    (亲手撸的demo,在android 9.0上验证过各个功能正常)

    支持的功能:1) 预览 2) 拍照 3) 录像 4) 实时yuv数据回调

    Demo代码地址:

          https://github.com/yorkZJC/UvcCameraDemo

    推荐阅读:

    一篇文章带你简单了解音频视频

    Camera基础及基本概念

    分析音视频用到的一些软件

    我是怎么一步步将SystemUI导入到AndroidStudio的     

    Android Camera开发系列:预览镜头缩放(数码变焦)

    Android Camera开发系列:调整Camera预览方向


    深圳上班,

    生活简简单单,

    公众号记录生活和工作的点滴,

    点击关注“小驰笔记”,期待和你相遇~

    展开全文
  • 解决Android USB摄像头热擦拔问题

    千次阅读 2018-07-04 11:51:54
    usb到camera本来是支持热插拔的,但是由于正在preview时拔出camera,再插入时,camera注册到设备节点会由/dev/video0变为/dev/video1,或者插入多个video设备时,会变为/dev/video1、/dev/video2.。。。。。。而HAL...
  • Android USB摄像头推流到RTMP服务器

    千次阅读 2018-05-12 11:15:23
    整理中
  • 1. 前言 这里主要讲一下怎么编译ZBar,项目之前是直接用了google ZXing的jar包,但是zxing对条形码的扫描灵敏度不如zbar,但是项目又要求能扫描条形码,所以花了点时间集成zbar。项目同事用zxing和zbar,在zxing解...
  • USB摄像头开发时 引入依赖 同步出错,出现类似下面的报错,按照下面解决即可。 ERROR: Unable to resolve dependency for ':libusbcamera@debug/compileClasspath': Could not download common.aar ...
  • 我最近在安卓平板上调用USB摄像头时,用的是网上通用的https://bitbucket.org/neuralassembly/simplewebcam/src这个里边的jni,现在我发现拍出来的照片有的亮有的暗,我想问一下,该如何写函数去控制摄像头的参数,...
  • 此外,F(x)tec Pro 1 还配备了一个后置双摄镜头,分别为 1200 万像素 IMX363 主摄(这是 2018 年几款 Android 旗舰机使用过的感光元件),同时还配有一颗 500 万像素的辅助摄像头;前置镜头则为 800 万像素,在机身...
  • 5千价位的轻薄本CPU核心甚至达到8核,睿频甚至高达4.9GHZ,内存也都在16G以上, 不仅用来做Android开发、嵌入式开发、Web前端、小程序开发,还可以用来做Web后端开发,运行Oacle、Database等大型数据库。除了编程、...
  • Android驱动USB摄像头源码,使用UVC摄像头,有Android USB host的平板电脑或者电视
  • Android驱动USB摄像头

    2019-05-03 12:20:48
    Android驱动USB摄像头
  • AndroidUSB摄像头程序

    2020-12-24 14:18:06
    USB摄像头程序 运行环境Android studio java代码 可直接运行,两个USB摄像图像显示,图像处理
  • Android支持USB摄像头

    万次阅读 多人点赞 2016-03-10 11:05:20
    关于Android支持USB摄像头的帖子网上是有一些的,虽然内容都是转载过来的,前一段时间因为工作需要,必须实现在Android上实现USB摄像头和主摄像头同时录像,便自己动手尝试实现了一下,最终实现的效果是两个摄像头...
  • 改软件可以使Android手机用外部USB摄像头进行拍照
  • 1.引言本篇介绍USB摄像头的使用,实现的功能是通过摄像头进行拍照,生成jpg格式图片。2.环境介绍2.1.硬件1) NUC972开发板2) USB摄像头2.2.软件1) Uboot继续使用之前文章用的,无须改动。2) Kernel在上一篇基础上,要...
  • AndroidUSb外接摄像头驱动,IntelliJ IDEA开发环境。 源码可直接使用。
  • android USBcamera摄像头

    2015-07-23 15:00:01
    手机通过otg转USB线连接USB摄像头

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 584
精华内容 233
关键字:

androidusb摄像头