RK平台USB摄像头FAQ

news/2024/12/2 18:42:55/

(记录android9以后调试所遇到的常见问题,有错请批评指正)

        UVC全称为USB video(device) class,是微软与另外几家设备厂商联合推出的为usb视频捕获设备定义的协议标准;所以说UVC仅仅是usb规范协议中设备类规范的其中一种,是用作usb接口的视频设备的一个统一的数据交换规范。

        插入USB摄像头会生成对应的video节点,使用如下指令,可以列举出插入的usb设备:

rk3399:/ # grep -H '' /sys/class/video4linux/video*/name
grep -H '' /sys/class/video4linux/video*/name
/sys/class/video4linux/video0/name:rkisp1_mainpath
/sys/class/video4linux/video1/name:rkisp1_selfpath
/sys/class/video4linux/video10/name:YHX5M   //第一个usb摄像头
/sys/class/video4linux/video11/name:YHX5M
/sys/class/video4linux/video12/name:USB 2.0 PC Camera    //第二个usb摄像头
/sys/class/video4linux/video13/name:USB 2.0 PC Camera
.................

        USB摄像头支持的格式有这几种:mjpg格式、yuv格式和h264;usb摄像头能够支持多种不同的分辨率,而且640x480是非常常见的分辨率;可以使用如下指令查询USB摄像头支持的格式,分辨率及帧率。USB camera的相机帧率一般是会根据光照自动调节帧率的;你用手电筒照下,帧率应该就会高了;如果你们需要固定帧率,需要USB camera的厂商控制;

v4l2-ctl -d /dev/videoX --list-formats-ext   (videox 就是对应的usb设备节点)

        新的SDK都有支持usb摄像头的插拔,一般应用在正常退出时会release摄像头,如果没有释放,再去用相机app打开摄像头时,会导致摄像头的video节点后移,出现打开异常现象。

        一般这种插拔问题,会出现在旧版本的,可能是预览中间断开,没有执行正常退出,没有wakeup这个wait_event,所以一直休着;等待超时发现有冗余未释放camera资源,及时通知释放就好了。

常见摄像头打不开问题

        首先配置方面先确保如下几点,具体可以参考文档 USB_UVC_Integrated_Cameras;

(1)以下设置是否都为true?/device/rockchip/rk3xxx/BoardConfig.mkBOARD_CAMERA_SUPPORT := trueBOARD_CAMERA_SUPPORT_EXT := true(2)cat /vendor/etc/vintf/manifest.xml | grep external //确定是否有external信息如果没有,则进行添加 /device/rockchip/rk3399/manifest.xml<interface><name>ICameraProvider</name><instance>legacy/0</instance><instance>external/0</instance>  //有该配置项吗? </interface>(3) 其它型号的usb摄像头是否也打不开? 也有可能是摄像头的问题,所以试试usb camera 插电脑(PC)上,看是否能正常预览出图;可以下载一个usbcamera的apk去看看:adb install usbcamera的apk

        其次,dumpsys media.camera看下是否注册上摄像头;若注册上了,摄像头还打不开,则需要具体logcat进行分析;

将下面三个文件的LOG_NDEBUG宏定义注释去掉
hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp
hardware/interfaces/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
hardware/interfaces/camera/device/3.4/default/ExternalCameraUtils.cpp
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0

        然后在hardware/interfaces/camera/device/3.4/default$ mm -j12 ;编译生成:camera.device@3.4-external-impl.so 在 vendor/lib目录下,所以修改库后,直接编译替换这个库即可!然后执行指令抓logcat

logcat -c && pkill camera* && pkill provider* && logcat
打开相机抓份logcat

        一般打不开时,很大概率是external_camera_config.xml 文件中没有添加usb camera的相关分辨率以及帧率;在xml中也可以修改旋转角度以及jpeg buffer。USB分辨率,例如预览想要3840x2160,拍照也想要3840x2160,那么需要在xml文件中将MaxJpegBufferSize改大一点,默认是3MB(1MB=1024KB,1KB=1024B, 1B=8bit),可以修改成4MB,5MB.

<Orientation  degree="90"/>
<MaxJpegBufferSize  bytes="3145728"/>  <!-- 3MB (~= 1080p YUV420) --> 
ps:3MB = 3*1024 KB = 3*1024*1024 B = 3145728 B

        查看内核log:表示usb设备已经识别到了;可以找到相关的video节点,用v4l2工具取流,看是否正常;

[ 194.108702] usb 1-1.3: new high-speed USB device number 5 using ehci-platform
[ 194.304772] usb 1-1.3: New USB device found, idVendor=046d, idProduct=082b, bcdDevice=28.25
[ 194.304899] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 194.304924] usb 1-1.3: Product: Webcam C170
[ 194.304946] usb 1-1.3: Manufacturer:
v4l2-ctl --verbose -d /dev/videox --set-fmt-video=width=640,height=480,pixelformat='MJPG' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=640,height=480

前后摄设置

        默认是后摄,前摄如下修改

hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cppconst uint8_t facing = ANDROID_LENS_FACING_FRONT; //BACKUPDATE(ANDROID_LENS_FACING, &facing, 1);

前后摄切换

1.android9,android10如下修改

/hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -309,7 +309,15 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,&opticalStabilizationMode, 1);-    const uint8_t facing = ANDROID_LENS_FACING_BACK;
+    const char* dev = mCameraId.c_str();
+    int index = (int) (*(dev + (strlen(dev) - 1)) - '0');
+    ALOGE("dev:%s index:%d", dev, index);
+    const uint8_t facing = (index / 2) % 2 ? ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;UPDATE(ANDROID_LENS_FACING, &facing, 1);

2.android11及12如下修改

/hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -309,7 +309,15 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,&opticalStabilizationMode, 1);-    const uint8_t facing = ANDROID_LENS_FACING_BACK;
+    const char* dev = mCameraId.c_str();
+    int index = atoi(dev);
+    ALOGE("dev:%s index:%d", dev, index);
+    const uint8_t facing = (index / 2) % 2 ? ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;UPDATE(ANDROID_LENS_FACING, &facing, 1);

录像问题

        录像分辨率及帧率在/device/rocchip/下的media_profiles_defaults.xml 里配置,编译时会拷到 /vendor/etc/media_profiles_V1_0.xml

        xml中通过id来识别摄像头即,根据实际情况可以添加或删除分辨率

## 录像问题​		录像分辨率及帧率在/device/rocchip/下的media_profiles_defaults.xml 
里配置,编译时会拷到      /vendor/etc/media_profiles_V1_0.xml ​		xml中通过id来识别摄像头即,根据实际情况可以添加或删除分辨率
<CamcorderProfiles cameraId="0">
<CamcorderProfiles cameraId="1">..........<EncoderProfile quality="480p" fileFormat="mp4" duration="30"><Video codec="h264"bitRate="3000000"     //录像模糊时,可以增大bitRatewidth="640"height="480"frameRate="25" />..........</EncoderProfile>

        例如usb摄像头是480p的,但是你录像时默认打开的分辨率为1080p,因此切换到录像时,会出现Can't connect to the camera报错,此时可以在xml中将对应sensor模块的1080p分辨率去除。

         USB摄像头拍照是正常的,但是录像的时候会提示报错;这种有可能是帧率不对,不支持导致的,具体可以看logcat。例如:device/rockchip里的media_profiles_default.xml 里framerate 改成25就解决了(dumpsys media.camera 里 可以看到支持帧率有25 但是没30帧)

镜像问题

Hardware/interfaces/camera/device/3.4/default/ExternalCameraDeviceSession.cpp ​ Hardware/interfaces/camera/device/3.4/default/ExternalCameraDevice.cpp

可以试下ExternalCameraDevice.cpp里 facing 改为BACK 后,看下预览是否会镜像了;

预览、拍照、录像这三种情况都会有镜像相关的问题(有相关patch)

1)预览镜像问题,在代码中修改成前置或后置就可以解决;

2)拍照镜像问题,libyuv::I420Scale 和 libyuv::I420MIrror 这段代码才是控制拍照镜像和翻转的

3)录像镜像问题:这是控制录像视频的mirror,即把 rga_nv12_scale_crop 里的 false 改成 (halBuf.usage & BufferUsage::VIDEO_ENCODER)

拉伸问题

        USB摄像头预览变形,换其他型号的USB摄像头也一样;看log picturesize:1920x1080,previewBuffer:1920x1080 预览分辨率为1080P,整体屏幕也是1080P,为什么会拉伸收缩变形?

需要注意的是摄像头成像长边要跟显示屏长边平行摆放;

默认竖屏设备 前摄 orientation 要为270,后摄为90;

默认横屏设备 前后摄 orientation都为0;

因此在xml中修改下orientation即可。

video节点权限问题

抓取logat后,关键字查询 E/CAM 发现没有权限

06-21 18:19:17.164 E/CamPvdr@2.4-external(  256): deviceAdded open v4l2 device /dev/video12 failed:Permission denied
06-21 18:19:17.165 E/CamPvdr@2.4-external(  256): deviceAdded open v4l2 device /dev/video13 failed:Permission denied

ls -l /dev/video* 查看下权限

crw-rw---- 1 media camera 81, 10 2022-06-22 09:47 /dev/video10
crw-rw---- 1 media camera 81, 11 2022-06-22 09:47 /dev/video11
crw------- 1 root root 81, 16 2022-06-22 09:47 /dev/video12
crw------- 1 root root 81, 17 2022-06-22 09:47 /dev/video13

如下修改后即可

/device/rockchip/common/ueventd.rockchip.rc
#for external camera
/dev/video10         0660   media      camera
/dev/video11         0660   media      camera
+ /dev/video12         0660   media      camera
+ /dev/video13         0660   media      camera

dqbuf卡住问题

        主要是针对usb摄像头插拔导致的一系列问题,例如插拔usb摄像头时,导致camera服务卡死,画面卡着不动;正常情况下插拔摄像头后预览画面可以恢复的。这种可能是预览中间断开,没有执行正常退出,没有wakeup这个wait_event,所以一直休着;等待超时发现有冗余未释放camera资源,应及时通知释放。(3588更新代码,会有这个补丁的)

        此外还有可能要加上0001-DQBUF-add-select.patch,一般拔掉usb摄像头后,apk会弹窗报错自动退出;如果没有弹框报错,说明dqbuf还是被卡住了,线程得不到释放,导致apk出现anr;要检查下补丁是否有打进去,是否生效了。  

        后面有空介绍这些:


http://www.ppmy.cn/news/272671.html

相关文章

机器视觉项目 - 选型总结

一. 面阵相机和镜头选型 已知&#xff1a;被检测物体大小为A*B,要求能够分辨小于C&#xff0c;工作距为D 解答&#xff1a; 1. 计算短边对应的像素数 E B/C&#xff0c;相机长边和短边的像素数都要大于E&#xff1b; 2. 像元尺寸 物体短边尺寸B / 所选相机的短边像素数&…

ESP32-CAM之ST7789图像显示

ESP32-CAM之ST7789 最近笔者在学习使用安信可的ESP32-CAM开发板&#xff0c;该开发板自带一个OV2640摄像头。 官方提供的例程可以将摄像头视频通过WIFI传输到网页显示&#xff0c;而笔者手里正好有一块240x240像素的屏幕&#xff0c;便想将摄像头的图像显示到该屏幕上。 从es…

【软考笔记】9. 多媒体基础

文章目录 基本概念音频声音的带宽声音的采样采样频率采样精度 图像亮度色调饱和度彩色空间RGB&#xff1a;彩色显示器YUV&#xff08;YIQ YCBCR&#xff09;&#xff1a;电视CMY&#xff08;CMYK&#xff09;&#xff1a;印刷HSV&#xff08;HSB&#xff09;&#xff1a;艺术家…

Google bot能够执行Javascript,Google bot的分辨率是1600x1200

如图&#xff0c;Google搜索“js 播放器 支持 ipad”&#xff1a; 我用js做了一个字号自动放大功能&#xff0c;检测到用户的浏览器分辨率&#xff0c;然后设置字号。用js innerHTML一段提示显示分辨率。 今天突然发现此js提示出现在Google搜索结果中&#xff0c;显示Google bo…

Stm32标准库函数5——摄像头OV2640 F103C8T6 串口显示高分辨率图像640x480 1024x768 1024x1024 1600x1200 二百万像素

stm32f103c8t6串口发送 OV2640的图像&#xff0c;分辨率可选。网络上资料大部分是低分辨率的&#xff0c;这个可以做高分辨率 完整工程打包&#xff0c;包含VB串口显示界面&#xff1a; Stm32标准库函数5-OV2640PA0-7F103C8T64500000联合VB高分辨率资源-单片机文档类资源-CSDN…

Ubuntu12.04新增屏幕分辨率

有时ubuntu汇总没有我们需要的分辨率,这时需要自己新增,很简单,4个步骤即可完成,下面结合新增1600x1200例子来介绍如何新增分辨率: 使用两个工具&#xff1a; xrandr 和 cvt 1.终端输入 cvt 1600 1200 60 (60为分辨率) 这时终端会出现一串参数,先甭管它,后面会用到. 2.将上…

数字图像处理基本知识

1、数字图像&#xff1a; 数字图像&#xff0c;又称为数码图像或数位图像&#xff0c;是二维图像用有限数字数值像素的表示。数字图像是由模拟图像数字化得到的、以像素为基本元素的、可以用数字计算机或数字电路存储和处理的图像。 2、数字图像处理包括内容&#xff1a; 图像…

Effective第三版 中英 | 第二章 创建和销毁对象 | 固定资源首选使用依赖注入

文章目录 Effective第三版前言第二章 创建和销毁对象固定资源首选使用依赖注入 Effective第三版 前言 大家好&#xff0c;这里是 Rocky 编程日记 &#xff0c;喜欢后端架构及中间件源码&#xff0c;目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记&#xff0…