问题:在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);
}
看来这个 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;
}
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
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];
}
追 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;
信息来自 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;
}
这里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>
额额额,看到 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
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
总结:平台的代码流程理论上是不会出大的问题的,要跟着平台的设计思路去排查,多半是一些细节地方没有注意。