操作:插拔USB摄像头,打开Camera应用;
现象一:
从日志上看,存在插入USB Camera后会快速的被remove掉,当前的status为0;
1. 问题分析
通过在onDeviceStatusChanged
中添加CallStack,发现会进来两次,一次是hal层provider remove,另外一次是cameraserver检测到USB DETACH然后就走了移除事件;
2. 解决办法
避免两次remove的动作出现,由于cameraserver remove的动作是谷歌针对Lazy hal加入的,USB Camera我们不申明为lazy,如果是单USB Camera方案(无CSI Camera),可以按照如下进行修改:
diff --git a/android/device/softwinner/ceres-b6/ceres_b6.mk b/android/device/softwinner/ceres-b6/ceres_b6.mk
index 1c86ad6b6f..10a44d41c7 100644
--- a/android/device/softwinner/ceres-b6/ceres_b6.mk
+++ b/android/device/softwinner/ceres-b6/ceres_b6.mk
@@ -99,7 +99,7 @@ ifeq ($(CONFIG_LOW_RAM_DEVICE),true)
dalvik.vm.madvise-random=true
# camera hal: Q Regular version must use camera hal v3
- USE_CAMERA_HAL_3_4 := true
+ USE_CAMERA_HAL_3_4 := false
else # ifeq ($(CONFIG_LOW_RAM_DEVICE),true)
$(call inherit-product, build/target/product/full_base.mk)
@@ -264,8 +264,10 @@ PRODUCT_SYSTEM_DEFAULT_PROPERTIES += \
ro.minui.default_rotation=ROTATION_LEFT \
ro.recovery.ui.touch_high_threshold=60
+ifeq ($(USE_CAMERA_HAL_3_4),true)
PRODUCT_PROPERTY_OVERRIDES += \
ro.camera.enableLazyHal=true
+endif
现象二:
日志打印:
logcat --pid=$(pidof [email protected])
提示open dev/video节点的时候No such device。
1. 问题分析
摄像头刚连接上不稳定,所以open的时候上报节点不存在;
2. 解决办法
增加retry机制保证稳定后open成功
diff --git a/android/hardware/interfaces/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/android/hardware/interfaces/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 3ae47f23ce..432abd414e 100644
--- a/android/hardware/interfaces/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
+++ b/android/hardware/interfaces/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -237,8 +237,17 @@ void ExternalCameraProviderImpl_2_4::addExternalCamera(const char* devName) {
void ExternalCameraProviderImpl_2_4::deviceAdded(const char* devName) {
{
base::unique_fd fd(::open(devName, O_RDWR));
- if (fd.get() < 0) {
- ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno));
+ for (int i=0; i<20; i++) {
+ if (fd.get() < 0 ) {
+ ALOGE("%s open v4l2 device %s failed:%s %d time", __FUNCTION__, devName, strerror(errno), i);
+ fd.reset(::open(devName, O_RDWR));
+ std::this_thread::sleep_for (std::chrono::milliseconds(50));
+ } else {
+ break;
+ }
+ }
+ if (fd.get() < 0) {
+ ALOGE("%s open v4l2 device %s finally failed:%s", __FUNCTION__, devName, strerror(errno));
return;
}