1.首先看下framework层CameraService服务初始化流程分析
<1>. main_cameraserver.cpp的路径
/frameworks/av/camera/cameraserver/
CameraService::instantiate()实际调用的是BinderService中的函数,因为CameraService是继承BinderService<CameraService>
<2>. BinderService的详细介绍
从CameraService中可以看出service的名称是“media.camera”.因为CameraService是继承的RefBase,只要初始化该对象就会调用onFirstRef。
<3>. CameraService的onFirstRef分析
主要是enumerateProviders函数初始化CameraProviderManager和CameraFlashlight,
2. hal层的camerahalserver服务初始化流程分析
<1>. camerahalserver.rc所在的路径
vendor/mediatek/proprietary/hardware/mtkcam3/main/hal/service/
<2>. ICameraProvider服务的注册
1). 在service.cpp中,调用 registerPassthroughServiceImplementation进行注册,服务名称是"internal/0" :
2). registerPassthroughServiceImplementation分析,函数实现在LegacySupport.h中
3). Interface::getService实现服务的加载,详细可以参考out目录下面的CameraProviderAll.cpp类
4). :details::getServiceInternal调用的是system下面的HidlTransportSupport.h
getRawServiceInternal的实现是在system下面的ServiceManagement.cpp中,最后调用的是PassthroughServiceManager的get函数:
PassthroughServiceManager的get函数主要是加载"internal/0"服务
instance.cpp(mtkcam3),来看下源码:
#include "MyUtils.h"
//
#include <string>
//
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
/******************************************************************************
*
******************************************************************************/
using namespace android::hardware::camera::provider::V2_4;
/******************************************************************************
*
******************************************************************************/
#define MY_LOGV(fmt, arg...) CAM_LOGV("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGD(fmt, arg...) CAM_LOGD("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGI(fmt, arg...) CAM_LOGI("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGW(fmt, arg...) CAM_LOGW("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGE(fmt, arg...) CAM_LOGE("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGA(fmt, arg...) CAM_LOGA("[%s] " fmt, __FUNCTION__, ##arg)
#define MY_LOGF(fmt, arg...) CAM_LOGF("[%s] " fmt, __FUNCTION__, ##arg)
//
#define MY_LOGV_IF(cond, ...) do { if ( (cond) ) { MY_LOGV(__VA_ARGS__); } }while(0)
#define MY_LOGD_IF(cond, ...) do { if ( (cond) ) { MY_LOGD(__VA_ARGS__); } }while(0)
#define MY_LOGI_IF(cond, ...) do { if ( (cond) ) { MY_LOGI(__VA_ARGS__); } }while(0)
#define MY_LOGW_IF(cond, ...) do { if ( (cond) ) { MY_LOGW(__VA_ARGS__); } }while(0)
#define MY_LOGE_IF(cond, ...) do { if ( (cond) ) { MY_LOGE(__VA_ARGS__); } }while(0)
#define MY_LOGA_IF(cond, ...) do { if ( (cond) ) { MY_LOGA(__VA_ARGS__); } }while(0)
#define MY_LOGF_IF(cond, ...) do { if ( (cond) ) { MY_LOGF(__VA_ARGS__); } }while(0)
/******************************************************************************
*
******************************************************************************/
static
std::string const&
getProviderType()
{
struct T
{
char const* kDefaultType =
#if 1
"internal"; // "internal" for binderized mode
#else
"legacy"; // "legacy" for passthrough mode
#endif
std::string mType;
T()
{
mType = kDefaultType;
}
};
static T singleton;
return singleton.mType;
}
/******************************************************************************
*
******************************************************************************/
extern "C"
NSCam::ICameraDeviceManager*
getCameraDeviceManager()
{
static NSCam::CameraDeviceManagerImpl singleton(getProviderType().c_str());
static bool init = singleton.initialize();
if ( ! init ) {
MY_LOGE("CameraDeviceManagerImpl::initialize fail %p", &singleton);
return nullptr;
}
return &singleton;
}
/******************************************************************************
*
******************************************************************************/
extern "C"
NSCam::ICameraDeviceManager*
getCameraDeviceManager()
{
static NSCam::CameraDeviceManagerImpl singleton(getProviderType().c_str());
static bool init = singleton.initialize();
if ( ! init ) {
MY_LOGE("CameraDeviceManagerImpl::initialize fail %p", &singleton);
return nullptr;
}
return &singleton;
}
/******************************************************************************
*
******************************************************************************/
extern "C"
ICameraProvider*
createICameraProvider_V2_4(const char* providerName, NSCam::ICameraDeviceManager* manager);
extern "C"
ICameraProvider*
HIDL_FETCH_ICameraProvider(const char* name)
{
// name must be either "internal/<id>" or "legacy/<id>".
std::string const strProviderName(name);
size_t const pos = strProviderName.find('/');
if ( 0 == pos || std::string::npos == pos ) {
MY_LOGE("provider name (%s) with bad \'/\' at position %zu", name, pos);
return nullptr;
}
//
if ( 0 != strProviderName.compare(0, pos, getProviderType()) ) {
MY_LOGW("provider name (%s) with mismatched type(%s) and \'/\' at position %zu",
name, getProviderType().c_str(), pos);
return nullptr;
}
//
return createICameraProvider_V2_4(name, getCameraDeviceManager());
}
可以看出初始化了CameraDeviceManagerImpl.cpp,并且调用了它的initialize函数。因为CameraDeviceManagerImpl继承CameraDeviceManagerBase,所以initialize实际是调用CameraDeviceManagerBase.cpp的initialize。createICameraProvider_V2_4的实现是在CameraDeviceManagerImpl中。
5). CameraDeviceManagerBase的initialize函数分析
主要是加载libmtkcam_device3.so库函数,并且用mCreateVirtualCameraDevice保存createVirtualCameraDevice函数。然后调用enumerateDevicesLocked函数加载mVirtEnumDeviceMap 和mPhysEnumDeviceMap。
6). enumerateDevicesLocked函数分析
enumerateDevicesLocked实现在CameraDeviceManagerBase_camera.cpp中,onEnumerateDevicesLocked的实现在CameraDeviceManagerImpl.cpp中。来看下onEnumerateDevicesLocked
MAKE_HalLogicalDeviceList获取的是HalLogicalDeviceList.cpp。addVirtualDevicesLocked的实现在CameraDeviceManagerBase_camera.cpp 中
create_device实际就是createVirtualCameraDevice函数。createVirtualCameraDevice的实现是在mtkcam3的CameraDevice3Factory.cpp中,new_device是CameraDevice3Impl,也就是pInfo->mVirtDevice = pVirtualDevice保存的mVirtDevice就是CameraDevice3Impl对象。
extern "C"
NSCam::ICameraDeviceManager::IVirtualDevice*
createVirtualCameraDevice(CreateVirtualCameraDeviceParams* params)
{
if ( ! params || ! params->pDeviceManager || ! params->pMetadataProvider ) {
MY_LOGE("Bad params");
return nullptr;
}
auto pDevice = new CameraDevice3Impl(
params->pDeviceManager,
params->pMetadataProvider,
params->deviceType,
params->instanceId
);
if ( ! pDevice ) {
MY_LOGE("Fail to new CameraDevice3Impl");
return nullptr;
}
NSCam::ICameraDevice3Session::CreationInfo const info = {
.mDeviceManager = params->pDeviceManager,
.mStaticDeviceInfo = pDevice->getStaticDeviceInfo(),
.mMetadataProvider = params->pMetadataProvider,
.mMetadataConverter = pDevice->getMetadataConverter(),
};
bool bInitSuccess = pDevice->initialize(createCameraDevice3Session(info));
if ( ! bInitSuccess ) {
delete pDevice;
pDevice = nullptr;
}
return pDevice;
}
7). MAKE_HalLogicalDeviceList分析
MAKE_HalLogicalDeviceList的实现在mtkcam里面,说明mtkcam3用到了mtkcam里面的部分内容,MTKCAM_MODULE_ID_UTILS_LOGICALDEV这个module_id很重要,后面会根据这个id找到HalLogicalDeviceList。
MAKE_MTKCAM_MODULE实现在module.h
getMtkcamModuleFactory 在helper.cpp中
查看register_utils.cpp可以看到 MTKCAM_MODULE_ID_UTILS_LOGICALDEV这个id对应的是NSCam::IHalLogicalDeviceList::get。
下面来看下NSCam::IHalLogicalDeviceList::get实现,得到的就是HalLogicalDeviceList对象:
/vendor/mediatek/proprietary/hardware/mtkcam/utils/LogicalCam/HalLogicalDeviceList.cpp
8).继续分析IHalLogicalDeviceList的searchDevices函数
a.由上面分析可知,最终会调用到HalLogicalDeviceList的searchDevices函数
MINT32
HalLogicalDeviceList::
createDeviceMap()
{
IHalSensorList* const pHalSensorList = MAKE_HalSensorList();
size_t const sensorNum = pHalSensorList->searchSensors();
SensorInfo_t vTempInfo;
TempSensorInfo TempInfo;
SensorStaticInfo sensorStaticInfo;
unsigned int i = 0;
std::vector<struct LogicalSensorStruct> CustomDevList;
MY_LOGD("sensorNum : %zu", sensorNum);
CustomDevList = get_LogicalDevice_CustomizeData();
MY_LOGD("manual device count = %zu", CustomDevList.size());
for(i = 0; i < sensorNum; i++)
{
memset(&sensorStaticInfo, 0, sizeof(SensorStaticInfo));
int sendorDevIndex = pHalSensorList->querySensorDevIdx(i);
pHalSensorList->querySensorStaticInfo(sendorDevIndex, &sensorStaticInfo);
TempInfo.SensorId = i;
TempInfo.RawType = sensorStaticInfo.rawFmtType;
TempInfo.Facing = sensorStaticInfo.facingDirection;
TempInfo.CaptureModeWidth = sensorStaticInfo.captureWidth;
strncpy(TempInfo.Name, pHalSensorList->queryDriverName(i), MAX_SENSOR_NAME_SIZE - 1);
vTempInfo.add(TempInfo.Name, TempInfo);
MY_LOGD("i : %d, facing : %d", i, sensorStaticInfo.facingDirection);
MY_LOGD("i : %d, Name : %s", i, TempInfo.Name);
MY_LOGD("i : %d, vTempInfo Name : %s", i, vTempInfo.valueFor(TempInfo.Name).Name);
sp<CamDeviceInfo> Info = new CamDeviceInfo();
Info->Sensors.push_back(i);
Info->DualFeature = 0;
Info->RawType = TempInfo.RawType;
strncpy(Info->Name, TempInfo.Name, sizeof(Info->Name));
// add physical sensor static metadata
Info->sensorStaticMetadata = MAKE_HalSensorList()->queryStaticInfo(Info->Sensors[0]);
MY_LOGD("i : %d, Info Name : %s, %p", i, Info->Name, Info->Name);
mDeviceSensorMap.add(i, Info);
}
// manually add logical device from custom
for(i = 0; i < CustomDevList.size(); i++)
{
for(int j = 0; j < CustomDevList[i].NumofDefinition; j++)
{
addLogicalDevice(vTempInfo, &CustomDevList[i], j);
}
}
dumpDebugInfo();
return 0;
}
MAKE_HalSensorList调用的是IHalSensor.h的函数,流程跟MAKE_HalLogicalDeviceList类似,最终是拿到HalSensorList.cpp
/vendor/mediatek/proprietary/hardware/mtkcam/include/mtkcam/drv/IHalSensor.h
/vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1_1/HalSensorList.cpp
b. 来看看HalSensorList的searchSensors函数
MUINT
HalSensorList::
searchSensors()
{
Mutex::Autolock _l(mEnumSensorMutex);
MY_LOGD("searchSensors");
char value[PROPERTY_VALUE_MAX] = {'\0'};
property_get("service.instantcam.running", value, "0");
bool camRunning = ::atoi(value) != 0;
if(camRunning)
MY_LOGW("instantcam is running!");
SeninfDrv *const pSeninfDrv = SeninfDrv::getInstance();
if(pSeninfDrv && pSeninfDrv->init() < 0) {
MY_LOGE("pSeninfDrv->init() fail");
return 0;
}
#ifdef MTK_MAIN3_IMGSENSOR
MY_LOGD("impSearchSensor search to main_3\n");
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= IMGSENSOR_SENSOR_IDX_MAIN3; i++) {
#else
#ifdef MTK_SUB2_IMGSENSOR
MY_LOGD("impSearchSensor search to sub2\n");
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= IMGSENSOR_SENSOR_IDX_SUB2; i++) {
#else
#ifdef MTK_MAIN2_IMGSENSOR
MY_LOGD("impSearchSensor search to main_2\n");
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= IMGSENSOR_SENSOR_IDX_MAIN2; i++) {
#else
#ifdef MTK_SUB_IMGSENSOR
MY_LOGD("impSearchSensor search to sub\n");
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i <= IMGSENSOR_SENSOR_IDX_SUB; i++) {
#else
MY_LOGD("impSearchSensor search to main\n");
for (MUINT i = IMGSENSOR_SENSOR_IDX_MIN_NUM; i < IMGSENSOR_SENSOR_IDX_SUB; i++) {
#endif
#endif
#endif
#endif
#ifndef MTK_SUB_IMGSENSOR
if (i == IMGSENSOR_SENSOR_IDX_SUB)
continue;
#endif
ImgSensorDrv *const pSensorDrv = ImgSensorDrv::getInstance((IMGSENSOR_SENSOR_IDX)i);
if(pSensorDrv->init((IMGSENSOR_SENSOR_IDX)i) != SENSOR_NO_ERROR)
continue;
MUINT32 mclkSrc;
pSensorDrv->sendCommand(CMD_SENSOR_GET_MCLK_CONNECTION, (MUINTPTR)&mclkSrc);
pSeninfDrv->setMclkIODrivingCurrent(mclkSrc, ISP_DRIVING_8MA);
if(!camRunning)
pSeninfDrv->setMclk(mclkSrc, true, 24);
if(pSensorDrv->searchSensor() == SENSOR_NO_ERROR) {
//query sensorinfo
querySensorInfo((IMGSENSOR_SENSOR_IDX)i);
//fill in metadata
buildSensorMetadata((IMGSENSOR_SENSOR_IDX)i);
addAndInitSensorEnumInfo_Locked(
(IMGSENSOR_SENSOR_IDX)i,
mapToSensorType(pSensorDrv->getType()),
(char *)pSensorDrv->getName());
}
if(!camRunning)
pSeninfDrv->setMclk(mclkSrc, false, 24);
pSensorDrv->uninit();
}
if(pSeninfDrv->uninit() < 0) {
MY_LOGE("pSeninfDrv->uninit() fail");
return 0;
}
return mEnumSensorList.size();
}
c. SeninfDrv的初始化:
init函数:
int SeninfDrvImp::init()
{
KD_SENINF_REG reg;
LOG_MSG("[init]: Entry count %d \n", mUser);
Mutex::Autolock lock(mLock);
if (mUser > 0) {
LOG_MSG("Already inited \n");
android_atomic_inc(&mUser);
return 0;
}
// Open seninf driver
mfd = open(SENINF_DEV_NAME, O_RDWR);
if (mfd < 0) {
LOG_ERR("error open kernel driver, %d, %s\n", errno, strerror(errno));
return -1;
}
if (ioctl(mfd, KDSENINFIOC_X_GET_REG_ADDR, ®) < 0) {
LOG_ERR("ERROR:KDSENINFIOC_X_GET_REG_ADDR\n");
return -2;
}
// mmap seninf reg
mpSeninfHwRegAddr = (unsigned char *) mmap(0, reg.seninf.map_length, (PROT_READ|PROT_WRITE|PROT_NOCACHE), MAP_SHARED, mfd, reg.seninf.map_addr);
if (mpSeninfHwRegAddr == MAP_FAILED) {
LOG_ERR("mmap err(1), %d, %s \n", errno, strerror(errno));
return -5;
}
// mipi rx analog address
mpCSI2RxAnalogRegStartAddrAlign = (unsigned char *) mmap(0, reg.ana.map_length, (PROT_READ|PROT_WRITE), MAP_SHARED, mfd, reg.ana.map_addr);
if (mpCSI2RxAnalogRegStartAddrAlign == MAP_FAILED) {
LOG_ERR("mmap err(5), %d, %s \n", errno, strerror(errno));
return -9;
}
//gpio
mpGpioHwRegAddr = (unsigned char *) mmap(0, reg.gpio.map_length, (PROT_READ|PROT_WRITE), MAP_SHARED, mfd, reg.gpio.map_addr);
if (mpGpioHwRegAddr == MAP_FAILED) {
LOG_ERR("mmap err(6), %d, %s \n", errno, strerror(errno));
return -10;
}
/*CSI2 Base address*/
//MMAP only support Page alignment(0x1000)
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] = mpCSI2RxAnalogRegStartAddrAlign;
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0A] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0];
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0B] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] + 0x1000;
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_1] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] + 0x2000;
#if 0
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_1A] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] + 0x2000;
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_1B] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] + 0x3000;
#endif
mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_2] = mpCSI2RxAnaBaseAddr[CUSTOM_CFG_CSI_PORT_0] + 0x4000;
/*SenINF base address*/
mpSeninfCtrlRegAddr[SENINF_1] = mpSeninfHwRegAddr;
mpSeninfCtrlRegAddr[SENINF_2] = mpSeninfHwRegAddr + 0x1000;
mpSeninfCtrlRegAddr[SENINF_3] = mpSeninfHwRegAddr + 0x2000;
mpSeninfCtrlRegAddr[SENINF_4] = mpSeninfHwRegAddr + 0x3000;
mpSeninfCtrlRegAddr[SENINF_5] = mpSeninfHwRegAddr + 0x4000;
/*SenINF Mux Base address*/
mpSeninfMuxBaseAddr[SENINF_MUX1] = mpSeninfHwRegAddr + 0x0d00;
mpSeninfMuxBaseAddr[SENINF_MUX2] = mpSeninfHwRegAddr + 0x1d00;
mpSeninfMuxBaseAddr[SENINF_MUX3] = mpSeninfHwRegAddr + 0x2d00;
mpSeninfMuxBaseAddr[SENINF_MUX4] = mpSeninfHwRegAddr + 0x3d00;
mpSeninfMuxBaseAddr[SENINF_MUX5] = mpSeninfHwRegAddr + 0x4d00;
mpSeninfMuxBaseAddr[SENINF_MUX6] = mpSeninfHwRegAddr + 0x5d00;
mpSeninfCSIRxConfBaseAddr[SENINF_1] = mpSeninfHwRegAddr + 0x0824;//18040800
mpSeninfCSIRxConfBaseAddr[SENINF_2] = mpSeninfHwRegAddr + 0x1824;//18041800
mpSeninfCSIRxConfBaseAddr[SENINF_3] = mpSeninfHwRegAddr + 0x2824;//18042800
mpSeninfCSIRxConfBaseAddr[SENINF_4] = mpSeninfHwRegAddr + 0x3824;//18043800
mpSeninfCSIRxConfBaseAddr[SENINF_5] = mpSeninfHwRegAddr + 0x4824;//18044800
#ifdef CSI2_EFUSE_SET
mCSI[0] = 0; /* initial CSI value*/
mCSI[1] = 0; /* initial CSI value*/
mCSI[2] = 0; /* initial CSI value*/
mCSI[3] = 0; /* initial CSI value*/
mCSI[4] = 0; /* initial CSI value*/
typedef struct {
unsigned int entry_num;
unsigned int data[200];
} DEVINFO_S;
int fd = 0;
int ret = 0;
DEVINFO_S devinfo;
fd = open("/proc/device-tree/chosen/atag,devinfo", O_RDONLY); /* v2 device node */
if (fd < 0) { /* Use v2 device node if v1 device node is removed */
LOG_ERR("/proc/device-tree/chosen/atag,devinfo kernel open fail, errno(%d):%s",errno,strerror(errno));
} else {
ret = read(fd, (void *)&devinfo, sizeof(DEVINFO_S));
if (ret < 0) {
LOG_ERR("Get Devinfo data fail, errno(%d):%s",errno,strerror(errno));
} else {
mCSI[0] = devinfo.data[103];//0x11F1018C
mCSI[1] = devinfo.data[104];//0x11F10190
mCSI[2] = devinfo.data[115];//0x11F101BC
mCSI[3] = devinfo.data[116];//0x11F101C0
}
LOG_MSG("Efuse Data:0x1045018c= 0x%x, 0x10450190= 0x%x, 0x104501bc= 0x%x, 0x104501c0= 0x%x\n", mCSI[0], mCSI[1], mCSI[2], mCSI[3]);
close(fd);
}
#endif
android_atomic_inc(&mUser);
LOG_MSG("[init]: Exit count %d \n", mUser);
return 0;
}
SENINF_DEV_NAME是
#define SENINF_DEV_NAME "/dev/seninf"
ioctl(mfd, KDSENINFIOC_X_GET_REG_ADDR, ®)这个就已经调用到驱动seninf.c里面去了,在驱动中搜索KDSENINFIOC_X_GET_REG_ADDR即可找到位置。
kernel-4.4/drivers/misc/mediatek/imgsensor/src/common/v1_1/seninf.c
d. ImgSensorDrv的初始化:
路径:/vendor/mediatek/proprietary/hardware/mtkcam/drv/src/sensor/common/v1_1/imgsensor_drv.cpp
CAMERA_HW_DEVNAME的定义:
/device/mediatek/common/kernel-headers/kd_imgsensor.h:265:#define CAMERA_HW_DEVNAME "kd_camera_hw"
看下featureControl函数,最终调用到imgsensor.c驱动文件中去了。
/kernel-4.4/drivers/misc/mediatek/imgsensor/src/common/v1_1/imgsensor.c
其他的参考时序图,到目前为止可以看到从hal层跟踪到kernel里面去了。
参考:
1.Mtk Camera MtkCam3架构学习_liujun3512159的博客-CSDN博客_camera mtk
2. Camera 服务启动流程简析_来自南陵县的平头哥的博客-CSDN博客_cameraservice启动流程
3. Android P之Camera HAL3流程分析(3)_Vincentywj的博客-CSDN博客
4. Android P之Camera HAL3流程分析(1)_Vincentywj的博客-CSDN博客
5. Android Camera2 Api 实现预览和拍照 - 知乎
6. 相机 | Android 开源项目 | Android Open Source Project
7. (1214条消息) Android P HIDL 之 CameraProvider_liujun3512159的博客-CSDN博客