Android9.0 系统摄像头前后置预览问题

1.Android 摄像头总体架构


在插入的USB摄像头后,会生成/dev/video0这样的设备节点,而在硬件抽象层中,会去判断是否存在该设备节点,以提供给android系统层使用,再往上分析就是android部分,暂时先不分析。

2.默认usb摄像头前后置预览

hardware/interfaces/目录下:
ANDROID_LENS_FACING_FRONT (前置); ANDROID_LENS_FACING_BACK (后置);

diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 3e346a21e..964c4ff5f 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -309,7 +309,7 @@ status_t ExternalCameraDevice::initDefaultCharsKeys(
     UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,
            &opticalStabilizationMode, 1);
-    const uint8_t facing = ANDROID_LENS_FACING_BACK;
+    const uint8_t facing = ANDROID_LENS_FACING_FRONT;
     UPDATE(ANDROID_LENS_FACING, &facing, 1);
     // android.noiseReduction

3.设备同时接两个usb摄像头时,一个固定为前摄,一个固定为后摄

使用场景:客户在使用主板机器时会使用到两个usb摄像头,一个作为前置摄像头用于人脸识别,另一个作为后置摄像头;由于在安装时并不知道哪个端口的摄像头先插入,哪个后插入(设备节点中先接入的就会分配video0,而在android中一般定义video0为后置摄像头,video1为前置摄像头),就导致android系统层前后置摄像头混乱。

为了解决该问题,就需要在驱动中,将前后置摄像头和USB的硬件端口做一个绑定:

  • 绑定usb端口号,从而绑定了固定的 /dev/video*:(目录:kernel/)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 435b2ee7a0f4..464f93e14a2f 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1909,6 +1909,9 @@ int uvc_register_video_device(struct uvc_device *dev,
      */
     video_set_drvdata(vdev, stream);
+    /*添加vdev->portnum = dev->udev->portnum, 这里先将USB的portnum存下来,在创建设备节点的是否,就	  会根据该变量来区分硬件的上哪个USB是前置,哪个USB是后置*/ 
+    vdev->hw_portnum = dev->udev->hw_portnum;
+    printk("vdev->hw_portnum=%d\n",vdev->hw_portnum); 
     ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
     if (ret < 0) {
    
    
         uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 72a8b8047bd0..e1a28ea90e37 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -849,6 +849,16 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
     /* Pick a device node number */
     mutex_lock(&videodev_lock);
+	 /*这里的“7 == vdev->portnum”是根据时机板子的端口上的,在调试的时候,可以先将portnum变量的值打印出来,就知道如何区分了*/
+    printk("dxq portnum=%d\n",vdev->hw_portnum); 
+    if(vdev->vfl_type == VFL_TYPE_GRABBER) {
    
    
+        if(7 == vdev->hw_portnum) {
    
    
+            nr = 7;
+        }else  if(8 == vdev->hw_portnum) {
    
    
+            nr = 8;
+        }
+    }
+
     nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
     if (nr == minor_cnt)
         nr = devnode_find(vdev, 0, minor_cnt);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1e5f55118d42..02d85ea9488d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2167,6 +2167,15 @@ static void show_string(struct usb_device *udev, char *id, char *string)
static void announce_device(struct usb_device *udev)
{
    
    
+    udev->hw_portnum=0;
+    //printk("kobject_name(&udev->dev->kobj)=%s\n",kobject_name(&(udev->dev.kobj)));
+    if(!strcmp("2-1.1.1",kobject_name(&(udev->dev.kobj)))){
    
    
+            udev->hw_portnum=7;
+    }else if(!strcmp("2-1.1.2",kobject_name(&(udev->dev.kobj)))){
    
    
+            udev->hw_portnum=8;
+    }
+    //printk("udev->hw_portnum=%d\n",udev->hw_portnum);
+
     dev_info(&udev->dev, "New USB device found, idVendor=%04x, idProduct=%04x\n",
         le16_to_cpu(udev->descriptor.idVendor),
         le16_to_cpu(udev->descriptor.idProduct));
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 5c03ebc6dfa0..05896dae09c5 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -572,6 +572,7 @@ struct usb_device {
    
    
     unsigned short bus_mA;
     u8 portnum;
+    u8 hw_portnum;
     u8 level;
     unsigned can_submit:1;
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 5a562ad58bb9..f74fbcaf0ba2 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -128,6 +128,7 @@ struct video_device
     /* Internal device debug flags, not for use by drivers */
     int dev_debug;
+    int hw_portnum;        /*usb hw port*/
     /* Video standard vars */
     v4l2_std_id tvnorms;        /* Supported tv norms */
  • hal层通过/dev/video* 做判断:(目录:hardware/interfaces/camera/)
diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp
index 9382c511b..9d246c36a 100644
--- a/camera/device/3.4/default/ExternalCameraDevice.cpp
+++ b/camera/device/3.4/default/ExternalCameraDevice.cpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <array>
#include <linux/videodev2.h>
+#include <string.h>
#include "android-base/macros.h"
#include "CameraMetadata.h"
#include "../../3.2/default/include/convert.h"
@@ -309,7 +310,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();
+    bool face_flage = false;
+    if(strcmp(dev,"/dev/video7") == 0){
    
    
+        face_flage = true;
+    } else {
    
    
+        face_flage = false;
+    }
+    const uint8_t facing = face_flage ?  ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT;
+    ALOGE("%s: dxq mCameraId.c_str()=%s ", __FUNCTION__, mCameraId.c_str());
     UPDATE(ANDROID_LENS_FACING, &facing, 1);
     // android.noiseReduction

猜你喜欢

转载自blog.csdn.net/weixin_45639314/article/details/126306436