• 展锐S 上微距模式不识别问题跟进 --- sensor_config的解析


    问题:在md.mk中配置了打开macro的属性 persist.vendor.cam.macrophoto.enable,但是CameraApp中仍然不显示微距模式。

    按照之前的经验,mk中打开微距的配置,上层就能自动显示微距模式。但是S上这个项目log显示微距的feature是false。

    来到SprdCamera3Setting中,看到关于微距feature的控制

     property_get("persist.vendor.cam.macrophoto.enable", prop, "0");//1
     if (SENSOR_ID_INVALID != sensorGetPhyId4Role(SENSOR_ROLE_SINGLE_MACRO, SNS_FACE_BACK)) {
         HAL_LOGD("addMacro photo %d", atoi(prop));
         available_cam_features.add(atoi(prop));
     } else {
         HAL_LOGD("addMacro photo 0");
         available_cam_features.add(0);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    看来这个 sensorGetPhyId4Role 函数 是关键。
    在 vendor\sprd\modules\libcamera\sensor\sensor_drv_u.c中看到该函数的实现
    省略不相关的 case role条目,看到主要是从 phyPtr = sensorGetPhysicalSnsInfo(phyId); 这个phyPtr对象中拿 code 和 face 值做判断,是否符合 SENSOR_ROLE_SINGLE_MACRO 的条件。

    int sensorGetPhyId4Role(enum sensor_role role, enum face_type facing) {
        int phyId = SENSOR_ID_INVALID;
        cmr_u32 code = 0;
        cmr_u32 face = 0;
        struct phySensorInfo *phyPtr = NULL;
        /* only return the first sensor that meets role,
         * and surely this sensor has been identified successfully */
        for (phyId = 0; phyId < SENSOR_ID_MAX; phyId++) {
            phyPtr = sensorGetPhysicalSnsInfo(phyId);
            code = phyPtr->sensor_role_code;
            face = phyPtr->face_type;
            SENSOR_LOGI("cyy_phyId=%d code=%d face=%d facing=%d role=%d SENSOR_ROLE_SINGLE_MACRO=%d", phyId, code, face, facing, role, SENSOR_ROLE_SINGLE_MACRO);
    
            switch (role) {
            case SENSOR_ROLE_DUALCAM_MASTER:
                break;
            case SENSOR_ROLE_DUALCAM_SLAVE:
                break;
            case SENSOR_ROLE_MULTICAM_SUPERWIDE:
                break;
            case SENSOR_ROLE_MULTICAM_WIDE:
                break;
            case SENSOR_ROLE_MULTICAM_TELE:
                break;
            case SENSOR_ROLE_SINGLE_MACRO:
                if ((code & 0xf) == 0x2 && face == facing) {
                    goto exit;
                }
                break;
            default:
                SENSOR_LOGD("not support sensor_role %d", role);
                return SENSOR_ID_INVALID;
            }
        }
        SENSOR_LOGD("can't find sensor_role %d at facing %d", role, facing);
        return SENSOR_ID_INVALID;
    
    exit:
        SENSOR_LOGD("find sensor_role %d at facing %d, phyId %d", role, facing,
                    phyId);
        return phyId;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    log看到:

    	Line 16357: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=0 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16359: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=1 code=0 face=1 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16360: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=2 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16361: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=3 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16363: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=4 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16364: 07-05 15:17:20.694   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=5 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16386: 07-05 15:17:20.700   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=0 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16387: 07-05 15:17:20.701   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=1 code=0 face=1 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16388: 07-05 15:17:20.701   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=2 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16389: 07-05 15:17:20.701   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=3 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16390: 07-05 15:17:20.701   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=4 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16391: 07-05 15:17:20.701   523   523 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=5 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    log中所有cameraId的 code 为 0(我们已知macro的camera id为2),导致 case SENSOR_ROLE_SINGLE_MACRO 的 if 条件进去不去。

    那就在追,为什么 从 sensorGetPhysicalSnsInfo 里面拿的 phyPtr->sensor_role_code 为 0。

    PHYSICAL_SENSOR_INFO_T *sensorGetPhysicalSnsInfo(int phy_id) {
    
        if (phy_id >= SENSOR_ID_MAX)
            return NULL;
    
        return &phy_sensor_info_list[phy_id];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    追 phy_sensor_info_list 的数据来源。

    sensor_drv_create_phy_sensor_info(struct sensor_drv_context *sensor_cxt,
                                      cmr_u32 slot_id, cmr_u32 phy_id) {
    	phyPtr->sensor_role_code = sensor_cxt->xml_info->cfgPtr->sensor_role_code;
        phyPtr->face_type = sensor_cxt->xml_info->cfgPtr->facing;
        phyPtr->angle = sensor_cxt->xml_info->cfgPtr->orientation;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    信息来自 sensor_cxt->xml_info,在sensor目录下搜一下,找到了 sensor_drv_xml_parse.c中有为该对象赋值,从文件名字也容易看出,是做解析xml文件的。

    sensor_drv_xml_str_to_integer(sensor_role[i],&cfgPtr->sensor_role_code);
    
    static int sensor_drv_xml_str_to_integer(char *str, cmr_u32 *digit) {
        if (!strcmp(str, "BACK")) {
            *digit = SNS_FACE_BACK;
        } else if (!strcmp(str, "FRONT")) {
            *digit = SNS_FACE_FRONT;
        } else if (!strcmp(str, "dualcam_master")) {
            *digit = (*digit & ~(0xf << 4)) | (0x1 << 4);
        } else if (!strcmp(str, "dualcam_slave")) {
            *digit = (*digit & ~(0xf << 4)) | (0x2 << 4);
        } else if (!strcmp(str, "multicam_superwide")) {
            *digit = (*digit & ~(0xf << 8)) | (0x1 << 8);
        } else if (!strcmp(str, "multicam_wide")) {
            *digit = (*digit & ~(0xf << 8)) | (0x2 << 8);
        } else if (!strcmp(str, "multicam_tele")) {
            *digit = (*digit & ~(0xf << 8)) | (0x3 << 8);
        } else if (!strcmp(str, "stl3d_rgb")) {
            *digit = (*digit & ~(0xf << 12)) | (0x1 << 12);
        } else if (!strcmp(str, "stl3d_ir_left")) {
            *digit = (*digit & ~(0xf << 12)) | (0x2 << 12);
        } else if (!strcmp(str, "stl3d_ir_right")) {
            *digit = (*digit & ~(0xf << 12)) | (0x3 << 12);
        } else if (!strcmp(str, "single_ir")) {
            *digit = (*digit & ~0xf) | 0x1;
        } else if (!strcmp(str, "macro")) {
            *digit = (*digit & ~0xf) | 0x2;
        } else if (!strcmp(str, "single")) {
            *digit = (*digit & ~0xf) | 0x0;
        } else {
            return -1;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    这里case了xml的各个标签,其中 else if (!strcmp(str, “macro”)) 是我们要关注的 marco 相关的,这里看到确实读了macro的信息了,在去sensor_config.xml中确认下配置:

    <CameraModuleCfg>
     <SlotId>2</SlotId>
     <SensorName>bf2253L_macro</SensorName>
     <Facing>BACK</Facing>
     <Orientation>90</Orientation>
     <Resource_cost>0</Resource_cost>
     <SensorRole>single_macro</SensorRole>
     <TuningParameter>
         <TuningName>bf2253L_macro</TuningName>
     </TuningParameter>
    </CameraModuleCfg>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    额额额,看到 SensorRole 的这项配置为 single_macro,而 sensor_drv_xml_parse.c 是else if匹配的 macro。

    找到坑了,改下sensor_config.xml的 SensorRole 配置 为 macro , push 该文件到 vendor/ect下面,在重启下手机就行了。
    改过之后的log

    	Line 16373: 07-05 15:39:10.750   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=0 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16374: 07-05 15:39:10.750   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=1 code=0 face=1 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16375: 07-05 15:39:10.750   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=2 code=2 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16376: 07-05 15:39:10.750   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=3 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16377: 07-05 15:39:10.750   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=4 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    	Line 16378: 07-05 15:39:10.751   525   525 I sns_drv_u: 5282, sensorGetPhyId4Role: cyy_phyId=5 code=0 face=0 facing=0 role=7 SENSOR_ROLE_SINGLE_MACRO=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    cyy_phyId=2 code=2 ,这样在sensor_drv_u.c中 case SENSOR_ROLE_SINGLE_MACRO: 的 if 就能走进去了。SprdCamera3Setting中 sensorGetPhyId4Role(SENSOR_ROLE_SINGLE_MACRO, SNS_FACE_BACK),就能获取到正常的cameraId,从而将 macro的feature值add为1

    总结:平台的代码流程理论上是不会出大的问题的,要跟着平台的设计思路去排查,多半是一些细节地方没有注意。

  • 相关阅读:
    [附源码]计算机毕业设计校园招聘系统Springboot程序
    使用米联客FPGA开发板进行光口开发时遇到的问题总结
    springboot日志使用 SLF4J+Logback 实现(springboot默认的日志实现),日志打印到控制台及日志输出到指定文件
    如何实现图片懒加载,原生 + React 实现方式
    记录一次Flink安装记录
    GateWay网关
    可重构柔性装配产线:为工业制造领域注入了新的活力
    electron汇总
    黑苹果外接显示器最优解决方案
    uniapp 手机端实现pdf文件下载和预览
  • 原文地址:https://blog.csdn.net/u010869159/article/details/125625354