两个USB UVC Camera前后摄切换
os:android7.1
现象:
设备接用一个双目的USB Camera(IR+RGB),但只能打开其中一个,不能切换。
原因:
在HAL层会根据USB的card name来设置当前是前置还是后置Camera:
if (strstr((char*)&capability.card[0], "front") != NULL) { camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT; } else { camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK; }
事实上, UVC驱动返回给HAL层的card值都是&capability.card[0]=USB 2.0 Camera, 这就导致了上层APK看到的两颗Camera都是后置摄像头,而只能打开一颗了.
解决办法:
1. 修改驱动返回上来的card值. 比如根据UVC Camera的pid/vid不同来处理.
2.hal层判断摄像头个数大于1时候,就分别赋值前后摄属性
第一种:
--- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -548,13 +548,26 @@ static int uvc_v4l2_release(struct file *file) static int uvc_ioctl_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - struct video_device *vdev = video_devdata(file); + // struct video_device *vdev = video_devdata(file); struct uvc_fh *handle = file->private_data; struct uvc_video_chain *chain = handle->chain; struct uvc_streaming *stream = handle->stream; + printk("wmc idVendor:0x%x idProduct:0x%x\n ", stream->dev->udev->descriptor.idVendor, + stream->dev->udev->descriptor.idProduct); + strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver)); +#if 0 strlcpy(cap->card, vdev->name, sizeof(cap->card)); +#else + if(stream->dev->udev->descriptor.idProduct == 0xd570) { + printk("wmc----card:%s\n",cap->card); + strcpy(cap->card, "front"); + } else { + printk("wmc----card1:%s\n",cap->card); + strcpy(cap->card, "back"); + } +#endif
第二种:
hardware/rockchip/camera
diff --git a/CameraHal/CameraHal_Module.cpp b/CameraHal/CameraHal_Module.cpp index 5d776ad..599f63b 100755 --- a/CameraHal/CameraHal_Module.cpp +++ b/CameraHal/CameraHal_Module.cpp @@ -901,7 +901,18 @@ int camera_get_number_of_cameras(void) unsigned int mCamDriverSupportFmt[CAMERA_DRIVER_SUPPORT_FORMAT_MAX]={0}; unsigned int mCamDriverPreviewFmt=0; unsigned int maxfps; - + //add usb-cam patch by wmc + if(cam_cnt == 0) + { + camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT; + camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;//90; + } + else + { + camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK; + camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0; + } + //add end //add usb camera to board_profiles rk_DV_info *pDVResolution = new rk_DV_info(); memset(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName, 0x00, sizeof(pNewCamInfo->mHardInfo.mSensorInfo.mSensorName)); diff --git a/CameraHal/CameraHal_Module.h b/CameraHal/CameraHal_Module.h index 45c81ec..2b97e11 100755 --- a/CameraHal/CameraHal_Module.h +++ b/CameraHal/CameraHal_Module.h @@ -15,7 +15,7 @@ using namespace android; #if defined(TARGET_RK3399) #define CAMERAS_SUPPORTED_SIMUL_MAX 2 #else - #define CAMERAS_SUPPORTED_SIMUL_MAX 1 + #define CAMERAS_SUPPORTED_SIMUL_MAX 2 #endif #define CAMERA_DEVICE_NAME "/dev/video"
其他Android版本前后摄切换:
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);
参考:https://blog.csdn.net/kris_fei/article/details/53487734
https://blog.csdn.net/kris_fei/article/details/79550161
https://www.iotword.com/8242.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库