曾经在全志平台上调试过UVC摄像头,当时调试过程比较流畅,丝毫没有碰上异常情况,这一次在RK上碰到较大的困难,下面介绍一下我的调试过程。
首先,不用说当然在内核配置中配置上UVC摄像头,重新编译内核,烧录。
然后查看内核信息,cat /proc/kmsg 然后接上摄像头,会看到类似的设备信息,说明我们的摄像头已经可以正常使用了。
接着我们可以在/dev 目录下看到 videoX 的节点。
然后,尝试一下用系统相机看看是否能点亮摄像头,这里提示我无法连接上摄像头。
这里只能看出来
CameraService 连接相机0失败,
invalid cameraId 0 除此之外,不太明白为什么会有这样的信息。
抛开系统相机我们先自己写一个小应用来测试一下video是否正常工作。
linux下的摄像头驱动框架是V4L2,只要根据相关的API来写测试程序,然后封装成JNI函数,交给Android层调用即可。
这里我比较懒用了一下一个开源项目的相机demo来验证我的相机在当前环境下是工作正常的。
SimpleWebCam
https://bitbucket.org/neuralassembly/simplewebcam/src
附件也会提供这个项目稍微修改过的工程,因为涉及到Jni代码的编译,直接提供的工程就省去很多麻烦。
这里存在一个权限的问题,只是测试用,chmod 777 /dev/video* 防止因为权限打不开相机.
这里用的
640x480 resolution with YUYV format 的可能有些摄像头不支持,就需要研究一下改一下JNI代码了,
然后确认了LINUX驱动层不存在问题,我们就开始考虑一下故障的地方在哪里了。
首先进入
然后 我们知道
cameraId==0, 那么 Cameras的数量是0
为了验证相机的数量,我们在上一次启动相机的时候打印确认一下是不是真的是0
然后打印调试信息,发现确实是获取Camera的数量是0,这里相机的数量是直接调用HAL层相机的层层封装函数得到的。
那么很有可能uvc热插拔信息并没有在HAL层更新出来,从而导致并不知道存在这一个相机。
这个推理是通过我反复重启发现有事确实可以打开相机,但是死机了。
packages/apps/LegacyCamera/src/com/android/camera/CameraHolder.java
这个是相机程序的代码,可以看出是直接获取相机数量 。
android.hardware.Camera.getNumberOfCameras();
这里稍微增加cameraopne的时候去读相机的信息。
说明了一切问题的根源在于相机打开的过程中获取相机数量是不正确,这里又查看了CameraHal代码被加载的流程分析,发现
uvc摄像头是在
CameraHal代码被加载后才发现的,非常关键的信息是存储在HAL层的一个数组中的。
那么,我们肯定了HAL层不支持热插拔,那么如何要支持热插拔呢,我们需要分析一下cameraService中的流程。
frameworks/av/services/camera/libcameraservice/CameraService.cpp
- void CameraService::onFirstRef()
- {
- BnCameraService::onFirstRef();
- if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,//这个定义为"came"
- (const hw_module_t **)&mModule) < 0) {
- ALOGE("Could not load camera HAL module");
- mNumberOfCameras = 0;
- }
- else {
- mNumberOfCameras = mModule->get_number_of_cameras();
- if (mNumberOfCameras > MAX_CAMERAS) {
- ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
- mNumberOfCameras, MAX_CAMERAS);
- mNumberOfCameras = MAX_CAMERAS;
- }
- for (int i = 0; i < mNumberOfCameras; i++) {
- setCameraFree(i);
- }
- }
- }