USB摄像头前后置调试

固定端口前后置:
在Android的系统会有前置摄像头和后置摄像头的定义,摄像头分为SOC类型的摄像头和USB这一类的摄像头,接下要分析就是USB摄像头这一类 。一般在android或者linux系统中分析一个模块,先从总体的框架上有一个认识,然后在局部细细的研究。
一、Android 摄像头总体架构
在这里插入图片描述

上面的框架,分析的比较粗糙,主要是一些自己看代码后总结下来的东西。以USB摄像为例,在插入的USB摄像头后,会生成/dev/video0这样的设备节点,而在硬件抽象层中,会去判断是否存在该设备节点,以提供给android系统层使用。再往上分析就是android部分的了,先暂时不分析。
二、Linux层中UVC摄像头注册流程
在这里插入图片描述

在USB子系统判断有UVC设备接入后,会去调用uvc_probe(代码位置:/driver/media/uvc/uvc_driver.c)来完成USB摄像头的创建,通过一步一步的分析,最终会走到v4L2框架中,创建摄像头的设备节点。
三、固定USB摄像头硬件端口
前面分析了这么多,都是为了接下来的做准备。
现在客户那么使用我们的主板机器,其中会使用两个USB摄像头,一个作为前置摄像头用于人脸识别,一个用于后置摄像头,由于在安装时并不知道那个端口的摄像头先插入,那个后插入(设备节点中先接入的就会分配video0,而在android中一般定义video0为后置摄像头,video1为前置摄像头),就导致android系统层前后置摄像头混乱。
为了解决该问题,就需要在驱动中,将前后置摄像头和USB的硬件端口做一个绑定。
具体改法如下:
(1)在/include/media/v4l2-dev.h的video_device结构体中添加变量portnum

struct video_device
     struct list_head    fh_list; /* List of struct v4l2_fh */
     int debug;            /* Activates debug level*/
+    int portnum;        /*usb hw port*/

(2)在/drivers/media/usb/uvc/uvc_driver.c的uvc_register_video函数中添加vdev->portnum = dev->udev->portnum;
static int uvc_register_video(struct uvc_device *dev,

...
     stream->vdev = vdev;
     video_set_drvdata(vdev, stream);
+    vdev->portnum = dev->udev->portnum;
     ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);

这里先将USB的portnum存下来,在创建设备节点的是否,就会根据该变量来区分硬件的上哪个USB是前置,哪个USB是后置了
(3)在/drivers/media/v4l2-core/v4l2-dev.c的__video_register_device函数中,修改。
int __video_register_device(struct video_device *vdev, int type, int nr,
 ...
     /* Pick a device node number */
     mutex_lock(&videodev_lock);+    if(vdev->vfl_type == VFL_TYPE_GRABBER) {
+        if(4 == vdev->portnum) {
+            nr = 1;
+        }else {
+            nr = 0;
+        }
+    }else {
+        nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
+    }
+
     if (nr == minor_cnt)
         nr = devnode_find(vdev, 0, minor_cnt);

注意:这里的“4 == vdev->portnum”是根据时机板子的端口上的,在调试的时候,可以先将portnum变量的值打印出来,就知道如何区分了。

Platform: RK3368
OS: Android 6.0
Kernel: 3.10.0

UVC摄像头方向调试
方法1修改CameraHal:
———————————————————————————————————————
修改代码位置hardware/rockchip/camera/CameraHal直接在CameraHal中修改facing_info.
———————————————————————————————————————

diff --git a/CameraHal/CameraHal_Module.cpp b/CameraHal/CameraHal_Module.cpp
index ec56a08..78500e3 100755
--- a/CameraHal/CameraHal_Module.cpp
+++ b/CameraHal/CameraHal_Module.cpp
@@ -771,14 +771,14 @@ int camera_get_number_of_cameras(void)
                 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;
+                    camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
                 }  
                 ptr = strstr((char*)&capability.card[0],"-");
                 if (ptr != NULL) {
                     ptr++;
                     camInfoTmp[cam_cnt&0x01].facing_info.orientation = atoi(ptr);
                 } else {
-                    camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;
+                    camInfoTmp[cam_cnt&0x01].facing_info.orientation = 180;
                 }
 
                 memset(version,0x00,sizeof(version));

方法2修改驱动:
———————————————————————————————————————
将capability card改为"facing-orientation".
例如facing(1), orientation(180)就是"front-180",android的CameraHal会根据命名规则来解析是前置摄像头还是后置摄像头,以及摄像头的方向.如果要做多个摄像头兼容可以加上VID与PID匹配.
———————————————————————————————————————

diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 196198f..d81586f 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -564,6 +564,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                memset(cap, 0, sizeof *cap);
                strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
                strlcpy(cap->card, vdev->name, sizeof cap->card);
+
+               if(le16_to_cpu(stream->dev->udev->descriptor.idVendor)==0x058f &&
+                       le16_to_cpu(stream->dev->udev->descriptor.idProduct)==0x3841){//058f:3841
+                       pr_info("uvc vendor product matched\n");
+                       memset(cap->card, 0, sizeof cap->card);
+                       strlcpy(cap->card, "front-180", sizeof cap->card);
+               }
+
                usb_make_path(stream->dev->udev,
                              cap->bus_info, sizeof(cap->bus_info));
                cap->version = LINUX_VERSION_CODE;
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那肯定是很多年以后!

你的鼓励就我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值