码字不易,多谢支持
Android Q 之MTK代码分析(一)--Camera Hal3 Service:https://blog.csdn.net/weixin_38328785/article/details/106720202
https://www.cnblogs.com/reality-soul/p/4668532.html
《Android Q 之MTK代码分析(一)--Camera Hal3 Service》
《Android Q 之MTK代码分析(二)--Camera Hal3 Search Sensor》
《Android Q 之MTK代码分析(三)--Camera Hal3 Open/Close》
《Android Q 之MTK代码分析(四)--Camera Hal3 configure_Streams》
《Android Q 之MTK代码分析(五)--Camera Hal3 process_capture_request》
《Android Q 之MTK代码分析(六)--Camera Hal3 process_capture_result》
备忘:
文末支持一波,感谢鞠躬
0、前文回顾
前文简单了解下CameraService、CameraHalService、CameraProvider服务(加载其rc文件,注册在CameraHalService服务上)的启动。《interface》 IVirtualDevice,给camera service暴露接口去操作camera,给Camera Device Manager 暴露接口去交互。在这之后会立即启动searchSesnor流程
(1)、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/service.cpp
Camerahalservice服务main函数,通过registerPassthroughServiceImplementation来注册CameraProvider,之后可以通过getservice()来获取CameraProvider实例对象
int main()
{
ALOGI("Camera HAL Server is starting..., ADV_CAM_SUPPORT(%d)", MTKCAM_ADV_CAM_SUPPORT);
{
using android::hardware::camera::provider::V2_4::ICameraProvider;
registerPassthroughServiceImplementation<ICameraProvider>("internal/0" /*"internal" for binderized mode*/);
}
}
(2)、getService(name)获得provider实例,然后registerAsService(name),最后registerServiceCb(service,name)注册provider服务回调函数,以便后面调用。
system/libhidl/transport/include/hidl/LegacySupport.h
namespace android {
namespace hardware {
namespace details {
template <class Interface, typename Func>
__attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
Func registerServiceCb, const std::string& name = "default") {
sp<Interface> service = Interface::getService(name, true /* getStub */); //CameraProvider 实例化对象
status_t status = registerServiceCb(service, name);
}
} // namespace details
registerPassthroughServiceImplementation(
const std::string& name = "default") {
return details::registerPassthroughServiceImplementation<Interface>(
[](const sp<Interface>& service, const std::string& name) {
return service->registerAsService(name); //将 CameraProvider 注册为一个服务,
其他进程需要使用 camera 的 hal 层时通过 binder 得到 CameraProvider 代理类即可操作camera hal 层
},
name);
frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
const std::string &serviceName) = 0;
system/libhidl/transport/include/hidl/HidlTransportSupport.h
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
(3)、获取PassthroughServiceManager对象pm,pm->get()获取ICameraProvider实例
system/libhidl/transport/ServiceManagement.cpp
namespace android {
namespace hardware {
struct PassthroughServiceManager : IServiceManager1_1 {
static void openLibs(
const std::string sym = "HIDL_FETCH_" + ifaceName;
......
Return<sp<IBase>> get(const hidl_string& fqName,
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
IBase* (*generator)(const char* name)
}
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr); //获取ICameraProvider实例
(4)、HIDL_FETCH_ICameraProvider为AOSP所定义的接口
(5)、创建CameraDeviceManager对象
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/instance.cpp
extern "C"
NSCam::ICameraDeviceManager*
getCameraDeviceManager()
{
static bool init = singleton.initialize();
return &singleton;
}
(6)、vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/CameraDeviceManagerBase.cpp
auto
CameraDeviceManagerBase::
initialize() -> bool
{
CAM_TRACE_NAME(LOG_TAG ":initialize");
status = enumerateDevicesLocked(); //从这块开始枚举相机设备
}
7、创建CameraProvider对象
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/devicemgr/depend/instance.cpp
extern "C"
ICameraProvider*
HIDL_FETCH_ICameraProvider(const char* name)
{
return createICameraProvider_V2_4(name, getCameraDeviceManager());
}
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/provider/2.4/CameraProviderImpl.cpp
extern "C"
ICameraProvider*
createICameraProvider_V2_4(const char* providerName, NSCam::ICameraDeviceManager* manager)
{
auto provider = new CameraProviderImpl(providerName, manager); //创建cameraprovider对象
}
1、camera 架构分析
Camera的框架分为Kernel部分和hal部分,其中kernel部分主要有两块:
image sensor driver,负责具体型号的sensor的id检测,上电,以及在preview、capture、初始化、3A等等功能设定时的寄存器配置;
isp driver,通过DMA将sensor数据流上传;
HAL层部分主要有三部分组成:
imageio,主要负责数据buffer上传的pipe;
drv,包含imgsensor和isp的hal层控制;
feature io,包含各种3A等性能配置;
2、Search Sensor
下图有search sensor的流程
(1)、开始SearchSensor
压轴戏
(2)、创建IMetadataProvider对象
(3)、创建VirtualCameraDevice对象
(4)、创建CameraDevice3实例
(5)、创建CameraDevice3Session实例
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/entry/hidl/device/3.x/HidlCameraDeviceSession.cpp
auto
HidlCameraDeviceSession::
create(
const ::android::sp<ICameraDevice3Session>& session
)-> HidlCameraDeviceSession*
{
auto pInstance = new HidlCameraDeviceSession(session);
HidlCameraDeviceSession::
HidlCameraDeviceSession(const ::android::sp<ICameraDevice3Session>& session)
: ICameraDeviceSession()
, mSession(session)
, mCameraDeviceCallback(nullptr)
, mLogPrefix(std::to_string(session->getInstanceId())+"-hidl-session")
, mBufferHandleCacheMgr()
, mRequestMetadataQueue()
, mResultMetadataQueue()
{
MY_LOGI("ctor");
}
(6)、添加Virtual 设备 表和物理设备表
和上面前文回顾中第六个接上继续分析,
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/CameraDeviceManagerBase.cpp
auto
CameraDeviceManagerBase::
initialize() -> bool
{
CAM_TRACE_NAME(LOG_TAG ":initialize");
// enumerating devices...
status = enumerateDevicesLocked();
}
vendor/mediatek/proprietary/hardware/mtkcam/main/hal/devicemgr/depend/CameraDeviceManagerImpl.cpp
/******************************************************************************
*
* Invoked by CamDeviceManagerBase::enumerateDevicesLocked()
*
******************************************************************************/
auto
CameraDeviceManagerImpl::
onEnumerateDevicesLocked() -> ::android::status_t
{
pHalDeviceList = MAKE_HalLogicalDeviceList();//IHalLogicalDeviceList::get();
size_t const deviceNum = pHalDeviceList->searchDevices(); //(1)查找匹配的Devices
pMetadataProvider = IMetadataProvider::create(instanceId); //(2) new IMetadataProvider
}
vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/utils/LogicalCam/IHalLogicalDeviceList.h
#define MAKE_HalLogicalDeviceList(...) \
MAKE_MTKCAM_MODULE(MTKCAM_MODULE_ID_UTILS_LOGICALDEV, HalLogicalDeviceList_FACTORY_T, __VA_ARGS__)
CameraDeviceManagerImpl.cpp文件中函数pHalDeviceList->searchDevices()将调用HalLogicalDeviceList.cpp文件中HalLogicalDeviceList::searchDevices()函数,该函数再调用的HalLogicalDeviceList::createDeviceMap函数。在createDeviceMap里面有serachSensors的操作
vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/HalLogicalDeviceList.cpp
MINT32
HalLogicalDeviceList::
createDeviceMap()
{
SensorInfo_t vTempInfo;
unsigned int i = 0;
// firstly, we create a logical camera device per physical camera
IHalSensorList* const pHalSensorList = MAKE_HalSensorList(); //(1)创建sensor对象
size_t const sensorNum = pHalSensorList->searchSensors(); //(2)此函数入口,主要查找匹配的硬件sensor
mDeviceSensorMap.add(i, Info); //把找到的Device Map
}
}
函数 pHalSensorList->searchSensors()将调用HalSensorList:: enumerateSensor_Locked()函数,该函数再调用ImgSensor_drv.cpp文件中的 pSensorDrv->searchSensor函数。
typedef NSCam::IHalSensorList* (*HalSensorList_FACTORY_T)();
#define MAKE_HalSensorList(...) \
MAKE_MTKCAM_MODULE(MTKCAM_MODULE_ID_DRV_HAL_SENSORLIST, HalSensorList_FACTORY_T, __VA_ARGS__)
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/HalSensorList.enumList.cpp
MUINT
HalSensorList::
enumerateSensor_Locked()
{
SensorDrv *const pSensorDrv = SensorDrv::get();
pSensorDrv->init()
MY_LOGD("impSearchSensor search to %d\n", max_index_of_camera);
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= max_index_of_camera; i++) {
if((ret = pSensorDrv->searchSensor((IMGSENSOR_SENSOR_IDX)i)) == SENSOR_NO_ERROR) {
//query sensorinfo
querySensorDrvInfo((IMGSENSOR_SENSOR_IDX)i);
//fill in metadata
buildSensorMetadata((IMGSENSOR_SENSOR_IDX)i);
}
vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1/imgsensor_drv.cpp
MINT32
ImgSensorDrv::searchSensor(IMGSENSOR_SENSOR_IDX sensorIdx)
{
LOG_MSG("[searchSensor] Already processed");
GetSensorInitFuncList(&pSensorInitFunc); //--(1)获得Hal层的sensor列表
LOG_MSG("SENSOR search start");
featureControl(sensorIdx, SENSOR_FEATURE_SET_DRIVER, (MUINT8 *)&idx, &featureParaLen); //-- (2)调用kernel层的kdSetDriver函数
LOG_MSG("set sensor driver id =%x", idx);
}
MINT32
ImgSensorDrv::featureControl(
IMGSENSOR_SENSOR_IDX sensorIdx,
ACDK_SENSOR_FEATURE_ENUM FeatureId,
MUINT8 *pFeaturePara,
MUINT32 *pFeatureParaLen
)
{
if (ioctl(m_fdSensor, KDIMGSENSORIOC_X_FEATURECONCTROL , &featureCtrl) < 0) {
//这块会调用imgsensor.c中的adopt_CAMERA_HW_FeatureControl,
//调用imgsensor_sensor_open(psensor),会在获取get_sensor_id之前把sensor给open起来
}//halSensorFeatureControl
--(1)、获取hal层sensor列表GetSensorInitFuncList(&pSensorInitFunc);
vendor/mediatek/proprietary/custom/mt6768/hal/imgsensor_src/sensorlist.cpp
UINT32 GetSensorInitFuncList(MSDK_SENSOR_INIT_FUNCTION_STRUCT **ppSensorList)
{
*ppSensorList = &SensorList[0]; //这里直接调用hal层的sensor列表
} // GetSensorInitFuncList()
MSDK_SENSOR_INIT_FUNCTION_STRUCT SensorList[] =
{
/*IMX*/
...
#if defined(OV13B10_MIPI_RAW)
RAW_INFO(OV13B10_SENSOR_ID, SENSOR_DRVNAME_OV13B10_MIPI_RAW_FACTORY, CAM_CALGetCalData),
#endif
/* ADD sensor driver before this line */
{0, 0,{0}, NULL, NULL, NULL}//end of list
};
--(2)、调用kernel层的kdSetDriver函数
kernel-4.14/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor.c
/************************************************************************
* adopt_CAMERA_HW_FeatureControl
************************************************************************/
static inline int adopt_CAMERA_HW_FeatureControl(void *pBuf)
/* copy from user */
switch (pFeatureCtrl->FeatureId) {
case SENSOR_FEATURE_OPEN:
ret = imgsensor_sensor_open(psensor);
break;
case SENSOR_FEATURE_CLOSE:
ret = imgsensor_sensor_close(psensor);
/* reset the delay frame flag */
break;
case SENSOR_FEATURE_SET_DRIVER:
{
MINT32 drv_idx;
psensor->inst.sensor_idx = pFeatureCtrl->InvokeCamera;
drv_idx = imgsensor_set_driver(psensor);
memcpy(pFeaturePara, &drv_idx, FeatureParaLen);
break;
}
}
在这里面做一些设置,sensor的name、status、i2c_dev等
/************************************************************************
* imgsensor_set_driver
************************************************************************/
int imgsensor_set_driver(struct IMGSENSOR_SENSOR *psensor)
{
u32 drv_idx = 0;
int ret = -EIO;
struct IMGSENSOR_SENSOR_INST *psensor_inst = &psensor->inst;
struct IMGSENSOR_INIT_FUNC_LIST *pSensorList = kdSensorList;
//把sensor驱动列表放到这块
if (!imgsensor_check_is_alive(psensor)) {
//---(3)上下电camera并读取sensor的ID,如果匹配则成功
}
pSensorList = kdSensorList; -->
kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
#if defined(OV13B10_MIPI_RAW)
{OV13B10_SENSOR_ID,
SENSOR_DRVNAME_OV13B10_MIPI_RAW,
OV13B10_MIPI_RAW_SensorInit},
#endif
}
OV13B10_MIPI_RAW_SensorInit->pfFunc = &sensor_func
---(3)上下电camera并读取sensor的ID,如果匹配则成功
/************************************************************************
* imgsensor_check_is_alive
************************************************************************/
static inline int imgsensor_check_is_alive(struct IMGSENSOR_SENSOR *psensor)
{
err = imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_ON);
//3.1 sensor上电
if (err == IMGSENSOR_RETURN_SUCCESS)
imgsensor_sensor_feature_control(
//3.2 获取sensor id
psensor,
SENSOR_FEATURE_CHECK_SENSOR_ID,
(MUINT8 *)&sensorID,
&retLen);
imgsensor_hw_power(&pgimgsensor->hw,
psensor,
psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_OFF);
//下电
}
(3.1)Sensor 上电,
imgsensor_hw_power(&pgimgsensor->hw,psensor,psensor_inst->psensor_name,
IMGSENSOR_HW_POWER_STATUS_ON);
enum IMGSENSOR_RETURN imgsensor_hw_power(
struct IMGSENSOR_HW *phw,
struct IMGSENSOR_SENSOR *psensor,
char *curr_sensor_name,
enum IMGSENSOR_HW_POWER_STATUS pwr_status)
{
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
platform_power_sequence,
str_index);
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
sensor_power_sequence,
curr_sensor_name);
if (!strcmp(curr_sensor_name, "ov2180_ofilm_mipi_raw")) {
if ((pwr_status == 0) && sensor_idx == 3) {
pr_info("ov2180_ofilm_mipi_raw poweroff again.....\n");
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
platform_power_sequence,
str_index);
mdelay(5);
imgsensor_hw_power_sequence(
phw,
sensor_idx,
pwr_status,
sensor_power_sequence,
curr_sensor_name);
mdelay(10);
}
}
kernel-4.14/drivers/misc/mediatek/imgsensor/src/mt6768/camera_hw/imgsensor_cfg_table.c
/* Legacy design */
struct IMGSENSOR_HW_POWER_SEQ sensor_power_sequence[] = {
#if defined(S5K4H7YX_MIPI_RAW)
{
SENSOR_DRVNAME_S5K4H7YX_MIPI_RAW,
{
{SensorMCLK, Vol_High, 2},
{RST, Vol_Low, 1},
{AVDD, Vol_2800, 1},
{DVDD, Vol_1200, 1},
{DOVDD, Vol_1800, 1},
{RST, Vol_High, 0}
},
},
#endif
}
static enum IMGSENSOR_RETURN imgsensor_hw_power_sequence(
struct IMGSENSOR_HW *phw,
enum IMGSENSOR_SENSOR_IDX sensor_idx,
enum IMGSENSOR_HW_POWER_STATUS pwr_status,
struct IMGSENSOR_HW_POWER_SEQ *ppower_sequence,
char *pcurr_idx)
{
if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON &&
ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {
pdev = phw->pdev[psensor_pwr->id[ppwr_info->pin]];
pr_info(
"sensor_idx = %d, pin=%d, pin_state_on=%d, hw_id =%d\n",
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_on,
psensor_pwr->id[ppwr_info->pin]);
if (pdev->set != NULL)
pdev->set(
pdev->pinstance,
sensor_idx,
ppwr_info->pin,
ppwr_info->pin_state_on);
mdelay(ppwr_info->pin_on_delay);
}
if (pwr_status == IMGSENSOR_HW_POWER_STATUS_OFF) {
}
(3.2) 获取sensor id
MUINT32
imgsensor_sensor_feature_control(
struct IMGSENSOR_SENSOR *psensor,
MSDK_SENSOR_FEATURE_ENUM FeatureId,
MUINT8 *pFeaturePara,
MUINT32 *pFeatureParaLen)
{
struct SENSOR_FUNCTION_STRUCT *psensor_func = psensor->pfunc;
psensor_func->SensorFeatureControl &&
}
pSensorList = kdSensorList; -->
kdSensorList[MAX_NUM_OF_SUPPORT_SENSOR] = {
这里指定传下来具体的sensor
#if defined(OV13B10_MIPI_RAW)
{OV13B10_SENSOR_ID,
SENSOR_DRVNAME_OV13B10_MIPI_RAW,
OV13B10_MIPI_RAW_SensorInit},
#endif
}
OV13B10_MIPI_RAW_SensorInit->pfFunc = &sensor_func
kernel-4.14/drivers/misc/mediatek/imgsensor/src/common/v1/ov13b10_mipi_raw/ov13b10mipiraw_Sensor.c
static struct SENSOR_FUNCTION_STRUCT sensor_func = {
open,
get_info,
get_resolution,
feature_control,
control,
close
};
在前面的传下来的SENSOR_FEATURE_CHECK_SENSOR_ID
最后找到get_imgsensor_id
static kal_uint32 get_imgsensor_id(UINT32 *sensor_id)
{
*sensor_id = return_sensor_id();
}
static kal_uint32 return_sensor_id(void)
{
return ((read_cmos_sensor(0x300a) << 16) |
(read_cmos_sensor(0x300b) << 8) | read_cmos_sensor(0x300c));
}
到这里简单走读searchSensor的代码
3、log
//camera device manager enumerate device when initialize:
08-26 11:30:28.510464 4145 4145 I mtkcam-devicemgr: [CameraDeviceManagerBase]
08-26 11:30:28.684843 4145 4145 I mtkcam-devicemgr: [initialize] +
pHalDeviceList:0xb400007331528f20 searchDevices:6 queryNumberOfDevices:6
08-26 11:30:33.474766 4145 4145 I mtkcam-devicemgr: [logLocked] Physical Devices: # 5
08-26 11:30:33.475023 4145 4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.475221 4145 4145 I mtkcam-devicemgr: [logLocked] [00] -> orientation(wanted/setup)=( 90/90 ) BACK hasFlashUnit:1 SENSOR_DRVNAME_OV13B10_QTECH_MIPI_RAW [PhysEnumDevice:0xb400007311545730]
08-26 11:30:33.477061 4145 4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.477254 4145 4145 I mtkcam-devicemgr: [logLocked] Virtual Devices: # 6
08-26 11:30:33.477458 4145 4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.477671 4145 4145 I mtkcam-devicemgr: [logLocked] [device@3.6/internal/0] -> 00 torchModeStatus:AVAILABLE_OFF hasFlashUnit:1 [VirtEnumDevice:0xb4000072f1561b90 IVirtualDevice:0xb400007351526698]
08-26 11:30:33.477885 4145 4145 I mtkcam-devicemgr: [logLocked] --
08-26 11:30:33.478105 4145 4145 I mtkcam-devicemgr: [logLocked]
//camera provider hal:
08-26 11:30:33.480838 4145 4145 I mtkcam-camprovider: [createICameraProvider_V2_6] + internal/0
08-26 11:30:33.481076 4145 4145 I mtkcam-camprovider: [initialize] +
08-26 11:30:33.482122 4145 4145 I mtkcam-camprovider: [initialize] -
08-26 11:30:33.482340 4145 4145 I mtkcam-camprovider: [createICameraProvider_V2_6] - internal/0 provider:0xb4000073415248f0 manager:0x7235aa5908
search sensor的过程中,找到一个sensor,获取这个sensor的信息,然后fill in metadata。最后更新一些数据(效果参数、闪光灯、StaticInfo)。
4、结语
代码熟练度还不够溜,MTK Code细节不够火候,还需继续深入。我会不定期分享,以便查漏补缺,相互学习。奥里给!!!