您的位置:首页 > 运维架构 > 网站架构

Android Camera 系统架构源码分析(1)---->Camera的初始化

2015-10-26 15:43 841 查看
系统:MTKAndroid4.4

日期:2015年10月10日

stamp&datasetParametersUtils::Property::tryGet

一.前述

之前对MTK的Camera的源码流程有过初步的了解,现在对以前了解的东西做一些梳理总结,但也仅是对源码流程一个贯穿,并不会对其进行深入分析,方便日后工作需求做一个铺垫。此文分析的是Camera系统源码,即Frameworks层之后的,并不是APK的源码分析。

二.分析思路

1.先从Camera的初始化开始,以cameraID为线索,简单地从Frameworks开始贯穿到底层。主要任务Camera如何被打开的,完成源码的贯穿。

2.然后再从startPreview开始去了解,Camera被打开之后,取出的数据流是什么,数据流经过了怎么的处理,然后又是怎么被送出到APK,显示出来的

三.上层入口

针对于上面的两个分析点,从APK上层入口开始:

privateCameramCamera;
mCamera=Camera.open(cameraID);
mCamera.startPreview();


四.Camera初始化化Open

(1)文件列表:

Camera.java:frameworks/base/core/java/android/hardware

android_hardware_Camera.cpp:frameworks/base/core/jni

Camera.cpp:frameworks/av/camera

CameraBase.cpp:frameworks/av/camera

CameraService.cpp:frameworks/av/services/camera/libcameraservice

module.h:frameworks/hardware/mtkcam/module
CamDeviceManagerBase.cppmediatek/hardward/mtkcam/devicemgr

CameraClient.cppframeworks/av/services/camera/libcameraservice/api1

CameraHardwareInterface.h:frameworks/av/services/camera/libcameraservice/device

(2)Frameworks层

第一个被调用的是Camera.java文件里的open函数。然后调用的是Camera(intcameraId)的

native_setup(newWeakReference<Camera>(this),cameraId,packageName);


上面的函数对应的是android_hardware_Camera.cpp里的android_hardware_Camera_native_setup()函数

//connecttocameraservice
staticvoidandroid_hardware_Camera_native_setup(JNIEnv*env,jobjectthiz,
jobjectweak_this,jintcameraId,jstringclientPackageName)
{
//打开Camera,把回一个Camera设备
sp<Camera>camera=Camera::connect(cameraId,clientName,
Camera::USE_CALLING_UID);
//WeuseaweakreferencesotheCameraobjectcanbegarbagecollected.
//Thereferenceisonlyusedasaproxyforcallbacks.
sp<JNICameraContext>context=newMtkJNICameraContext(env,weak_this,clazz,camera);
}


我们开始从Camera::connect开始深入,connect函数在Camera.cpp:

sp<Camera>Camera::connect(intcameraId,constString16&clientPackageName,intclientUid){
returnCameraBaseT::connect(cameraId,clientPackageName,clientUid);
}


这里调用了CameraBaseT的connect

CameraBaseT是CameraBase的类成员,CameraBase是一个模板类,其定义如下:

template<typenameTCam>
structCameraTraits{
};
template<typenameTCam,typenameTCamTraits=CameraTraits<TCam>>
classCameraBase:publicIBinder::DeathRecipient
{
public:
typedeftypenameTCamTraits::TCamListenerTCamListener;
typedeftypenameTCamTraits::TCamUserTCamUser;
typedeftypenameTCamTraits::TCamCallbacksTCamCallbacks;
typedeftypenameTCamTraits::TCamConnectServiceTCamConnectService;
staticsp<TCam>connect(intcameraId,constString16&clientPackageName,intclientUid);
//...
protected:
CameraBase(intcameraId);
//...
typedefCameraBase<TCam>CameraBaseT;
};
};//namespaceandroid


Camera.cpp里的Camera类继承于CameraBase,同时初始化了CameraBase的模板

classCamera:publicCameraBase<Camera>,publicBnCameraClient


在Camera.h里也初始化了CameraTraits这个模板类:

template<>
structCameraTraits<Camera>
{
typedefCameraListenerTCamListener;
typedefICameraTCamUser;
typedefICameraClientTCamCallbacks;
typedefstatus_t(ICameraService::*TCamConnectService)(constsp<ICameraClient>&,int,constString16&,int,
/*out*/
sp<ICamera>&);
staticTCamConnectServicefnConnectService;
};


CameraBase这个模板中的TCamConnectService成员的类型为TCamTraits::TCamConnectService,所以在这里被定义成一个TCamConnectService类型的函数指针,其余的CameraBase成员依此类推。

我们继续回到connect函数里。Camera.cpp里调用了模板类里的connect函数,这个函数的实现在CameraBase.cpp里

sp<TCam>CameraBase<TCam,TCamTraits>::connect(intcameraId,constString16&clientPackageName,intclientUid)
{
ALOGV("%s:connect",__FUNCTION__);
//把所有的TCam替换成Camera,构造了一个Camera对象。这个构造函数只有初始化mCameraId的值
sp<TCam>c=newTCam(cameraId);
sp<TCamCallbacks>cl=c;
//获取ICameraService
constsp<ICameraService>&cs=getCameraService();
//fnConnectService在Camera.cpp里被定义为&ICameraService::connect
TCamConnectServicefnConnectService=TCamTraits::fnConnectService;
//调用CameraService里的connect函数
status=(cs.get()->*fnConnectService)(cl,cameraId,clientPackageName,clientUid,/*out*/c->mCamera);
returnc;
}


CameraService.cpp的CameraService::connect

status_tCameraService::connect(constsp<ICameraClient>&cameraClient,intcameraId,
constString16&clientPackageName,intclientUid,/*out*/sp<ICamera>&device){
intfacing=-1;
//获得hardware层的版本是CAMERA_DEVICE_API_VERSION_1_0
intdeviceVersion=getDeviceVersion(cameraId,&facing);
switch(deviceVersion){
caseCAMERA_DEVICE_API_VERSION_1_0:
//CameraClient也在hardware层里定义了
client=newCameraClient(this,cameraClient,
clientPackageName,cameraId,
facing,callingPid,clientUid,getpid());
break;
caseCAMERA_DEVICE_API_VERSION_2_0:
//...
}
status_tstatus=connectFinishUnsafe(client,client->getRemote());
mClient[cameraId]=client;
//important:releasethemutexheresotheclientcancallback
//intotheservicefromitsdestructor(canbeattheendofthecall)
device=client;
returnOK;
}
//getDeviceVersion
intCameraService::getDeviceVersion(intcameraId,int*facing){
structcamera_infoinfo;
mModule->get_camera_info(cameraId,&info);
intdeviceVersion;
if(mModule->common.module_api_version>=CAMERA_MODULE_API_VERSION_2_0){
deviceVersion=info.device_version;
}else{
//从hardware层的hw_module_tmModule里获得版本号
deviceVersion=CAMERA_DEVICE_API_VERSION_1_0;
}
returndeviceVersion;
}
//mModule的初始化在onFirstRef函数里
voidCameraService::onFirstRef()
{
hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(consthw_module_t**)&mModule);
//......
}


CameraService里的onFirstRef函数通过CAMERA_HARDWARE_MODULE_ID获取了一个hw_module_t模块。这个模块是与hardware层对接的接口。这个模块在module.h里定义

再CameraService的getDeviceVersion()函数:

先是调用了mModule->get_camera_info(cameraId,&info),这里get_camera_info()函数就是Modle.h里的get_camera_info()函数。

staticintget_camera_info(intcameraId,camera_info*info){
//CamDeviceManager继承于CamDeviceManagerBase
//这里相当于直接调用CamDeviceManagerBase的getDeviceInfo函数
returnNSCam::getCamDeviceManager()->getDeviceInfo(cameraId,*info);
}
//CamDeviceManagerBase.cpp
CamDeviceManagerBase::
getDeviceInfo(intconstdeviceId,camera_info&rInfo){
//CameraService的getDeviceVersion()所需要的版本号
//mEumMap在CamDeviceManagerImp.cpp的enumDeviceLocked()函数里初始化
rInfo.device_version=mEnumMap.valueFor(deviceId)->uDeviceVersion;
rInfo.facing=mEnumMap.valueFor(deviceId)->iFacing;
rInfo.orientation=mEnumMap.valueFor(deviceId)->iWantedOrientation;
rInfo.static_camera_characteristics=mEnumMap.valueFor(deviceId)->pMetadata;
}
//CamDeviceManagerImp.cppenumDeviceLocked()
enumDeviceLocked()
{
//增加ImageSensor的Sensor信息,后面会被get
DevMetaInfo::add(deviceId,camInfo,i4DevSetupOrientation,eDevId_ImgSensor,eHalSensorDev);
sp<EnumInfo>pInfo=newEnumInfo;
pInfo->uDeviceVersion=CAMERA_DEVICE_API_VERSION_1_0;
pInfo->pMetadata=NULL;
pInfo->iFacing=camInfo.facing;
pInfo->iWantedOrientation=camInfo.orientation;
pInfo->iSetupOrientation=i4DevSetupOrientation;
mEnumMap.add(deviceId,pInfo);
i4DeviceNum++;
//...
}


connect最重要的是构造了CameraClient,这个CameraClient又是什么,有什么用的呢?

先来看看CameraClient的构造函数,在CameraClient.cpp里,似乎没有什么重要动作

CameraClient::CameraClient(constsp<CameraService>&cameraService,
Client(cameraService,cameraClient,clientPackageName,
cameraId,cameraFacing,clientPid,clientUid,servicePid)
{
//Callbackisdisabledbydefault
mPreviewCallbackFlag=CAMERA_FRAME_CALLBACK_FLAG_NOOP;
//摄像头方向
mOrientation=getOrientation(0,mCameraFacing==CAMERA_FACING_FRONT);
//拍照声音
mPlayShutterSound=true;
LOG1("CameraClient::CameraClientX(pid%d,id%d)",callingPid,cameraId);
}


connect里构造了CameraClient后调用了connectFinishUnsafe()函数,这个函数里调用了CameraClient的initialize函数

status_tCameraClient::initialize(camera_module_t*module){
//Verifyopspermissions
res=startCameraOps();
charcamera_device_name[10];
snprintf(camera_device_name,sizeof(camera_device_name),"%d",mCameraId);
//在CameraHardwareInterface.cpp
mHardware=newCameraHardwareInterface(camera_device_name);
//打开hardwaremModule
res=mHardware->initialize(&module->common);
mHardware->setCallbacks(notifyCallback,dataCallback,dataCallbackTimestamp,(void*)mCameraId);
//Enablezoom,error,focus,andmetadatamessagesbydefault
enableMsgType(CAMERA_MSG_ERROR|CAMERA_MSG_ZOOM|CAMERA_MSG_FOCUS|
CAMERA_MSG_PREVIEW_METADATA|CAMERA_MSG_FOCUS_MOVE);
//EnableMTK-extendedmessagesbydefault
enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY|MTK_CAMERA_MSG_EXT_DATA);
}


CameraHardwareInterface.cppinitialize()函数

initialize()之后获得了Hardware对接的设备接口mDevice,上层的Frameworks正是通过CameraHardwareInterface类,对Hardware层进行操作,然后Hardware层对硬件进行进一步的操作。CameraHardwareInterface是上下层对接的接口。

status_tinitialize(hw_module_t*module){
//调用了module.hopen_device()
module->methods->open(module,mName.string(),(hw_device_t**)&mDevice);
//初始化预览窗口
initHalPreviewWindow();
}


(3)Hardware层

文件列表:

CamDeviceManagerBase.cppmediatek/hardward/mtkcam/devicemgr

Cam1DeviceFactory.cppmediatek/hardware/mtkcam/v1/device

DefaultCam1Device.cppmediatek/mt8127/hardware/mtkcam/v1/device

Cam1DeviceBase.cppmediatek/hardware/mtkcam/v1/device

Cam1Device.cppmediatek/hardware/mtkcam/v1/device

Sensor_hal.cppmediatek/platform/mt8127/hardware/mtkcam/core/drv/imgsensor

imgsensor_drv.cppmediatek/platform/mt8127/hardware/mtkcam/core/drv/imgsensor

Camclient.cppmediatek/hardware/mtkcam/v1/client/camclient

PreviewClient.cppmediatek/hardware/mtkcam/v1/client/camclient/previewcallback

ImgBufQueue.cppmediatek/hardware/mtkcam/v1/common/camutils

MtkDefaultCamAdapter.cppmediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault

BaseCamAdapter.cppmediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/

State.cppmediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/state

PreviewCmdQueThread.cppmediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/preview

PreviewBufMgr.cppmediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/preview

CameraHardwareInterface.cppinitialize()调用了Module.h的open_device()函数

open_device(hw_module_tconst*module,constchar*name,hw_device_t**device)
{
returnNSCam::getCamDeviceManager()->open(module,name,device);
}


CamDeviceManagerImp继承于CamDeviceManagerBase。直接调用了CamDeviceManagerBase的open(),open()函数又只是调用了CamDeviceManagerBase::
openDeviceLocked()。此函数在同文件夹下的CamDeviceManagerBase.openDevice.cpp文件里。

在这里有点不明白,这个函数会获取一个属性值,这个值是从哪里来的,这个似乎要从开机流程里找了。先Mark一下,有空再看一下开机流程

CamDeviceManagerBase::
openDeviceLocked(hw_module_tconst*module,charconst*name,hw_device_t**device)
{
//获得AppMode,这个属性在哪里被初始化的呢?我们这里的s8ClientAppMode=APP_MODE_NAME_DEFAULT
String8consts8ClientAppMode=queryClientAppMode();
//这个我们在之前已经看到了在哪里初始化,结果为CAMERA_DEVICE_API_VERSION_1_0
uint32_tconstversion=determineOpenDeviceVersionLocked(s8ClientAppMode,i4OpenId);
if(version==CAMERA_DEVICE_API_VERSION_1_0)
{//获得Camera设备,并打开硬件和初始化。这里的设备并不是指硬件设备
//而是包含硬件设备,设备参数,设备操作(预览等)。的一个操作类
pDevice=pPlatform->createCam1Device(s8ClientAppMode.string(),i4OpenId);
}
}


上面的createCam1Device函数在Cam1DeviceFactory.cpp

NSCam::Cam1Device*
createCam1Device(String8consts8ClientAppMode,int32_tconsti4OpenId)
{
//if(s8ClientAppMode==MtkCameraParameters::APP_MODE_NAME_DEFAULT)
{
String8consts8CamDeviceInstFactory=String8::format("createCam1Device_Default");
void*pCreateInstance=::dlsym(RTLD_DEFAULT,s8CamDeviceInstFactory.string());
MY_LOGF_IF(0==pCreateInstance,"Notexist:%sfor%s",s8CamDeviceInstFactory.string(),s8ClientAppMode.string());
//这里相当于调用createCam1Device_Default()函数
pdev=reinterpret_cast<NSCam::Cam1Device*(*)(String8const&,int32_tconst)>
(pCreateInstance)(s8ClientAppMode,i4OpenId);
}
if(pdev)
{
//初始化硬件设备等
if(OK!=pdev->initialize())
{
MY_LOGE("Cam1Device::initialize()device:%p",pdev);
//useref.counttodeleterawpointer.
pdev->incStrong(pdev);
pdev->decStrong(pdev);
pdev=NULL;
}
}
}


我们先来看看createCam1Device_Default()函数,再看看pdev->initialize()函数。createCam1Device_Default()函数并没有干很多工作,只是调用了一些构造函数而已。更的工作在pdev->initialize()。但createCam1Device_Default()的构造顺序,可以帮助我们了解一下代码流程,但createCam1Device_Default()的基础的父类Cam1Device每重要,这里列出了一些接口让上层调用,但是这些接口的实现,都是其子类里,这很里很之间的继承关系,让我晕了一阵子。等会看startPreview()的时候会再看到Cam1Device

createCam1Device_Default()在DefaultCam1Device.cpp里

NSCam::Cam1Device*
createCam1Device_Default(String8const&rDevName,int32_tconsti4OpenId)
{
returnnewDefaultCam1Device(rDevName,i4OpenId);
}
//DefaultCam1Device继承于Cam1DeviceBase
DefaultCam1Device::
DefaultCam1Device(String8const&rDevName,int32_tconsti4OpenId)
:Cam1DeviceBase(rDevName,i4OpenId)
{
}
//Cam1DeviceBase继承于Cam1Device
Cam1DeviceBase::
Cam1DeviceBase(String8const&rDevName,int32_tconsti4OpenId)
:Cam1Device()
{
}


我们把这个继承关系写下来:DefaultCam1Device继承Cam1DeviceBase继承于Cam1Device。这三个父子类之间的操作函数相互调用,让逻辑看起来特别头疼。后面我们需要找操作Camera操作,如startPreview()。就需要从子类开始一个一个地往上找

再来看看createCam1Device的pdev->initialize()。这里的pdev是createCam1Device_Default返回来的指针,所以initialize()在DefaultCam1Device类,或者在其父类里。沿着构造顺序一层层地住上找,在Cam1DeviceBase类里

Cam1DeviceBase::
initialize()
{
if(!onInit())
{
return-ENODEV;
}
}


这里调用了onInit函数。Cam1DeviceBase实现了onInit函数。如果接着往下看就会是一个深渊,因为其子类里也实现了onInit(),应该是调用了子类的onInit()函数。所以又要回到DefaultCam1Device的onInit()。这个函数非常重要,正是这里打开了硬件。终于接近了底层了~

DefaultCam1Device::onInit()
{
intconstiHalSensorDevId=DevMetaInfo::queryHalSensorDev(getOpenId());
//Android的资源管理器
IResManager*pResManager=IResManager::getInstance();
if(!(pResManager->open("DefaultCam1Device"))){}
//(1)OpenSensor下面的SensorHal包含了imageSensor和ISP
mpSensorHal=SensorHal::createInstance();
err=mpSensorHal->sendCommand((halSensorDev_e)iHalSensorDevId,SENSOR_CMD_SET_SENSOR_DEV);
err=mpSensorHal->init();
//(2)Open3A
mp3AHal=NS3A::Hal3ABase::createInstance(iHalSensorDevId);
//(3)InitBase.
Cam1DeviceBase::onInit();
}


SensorHal在Sensor_hal.cpp,我们从SensorHal::createInstance();开始,此函数只是创建了ISP管理驱动,并没打开ImageSensor设备。ISP不是我们重点,先忽略

SensorHal*SensorHal::createInstance()
{
returnSensorHalImp::getInstance();
}
SensorHal*SensorHalImp::getInstance()
{
staticSensorHalImpsingleton;
ret=singleton.createImp();
return&singleton;
}
MINT32SensorHalImp::createImp()
{
mSensorDev=SENSOR_DEV_MAIN;
mIspSensorType[0]=SENSOR_TYPE_UNKNOWN;
mImageSensorType[0]=IMAGE_SENSOR_TYPE_UNKNOWN;
mIspSensorType[1]=SENSOR_TYPE_UNKNOWN;
mImageSensorType[1]=IMAGE_SENSOR_TYPE_UNKNOWN;
//创建ISP管理
pSeninfDrv=SeninfDrv::createInstance();
}


接下来是mpSensorHal->init();这里打开了两个设备,一个是ISP和ImageSensor

MINT32SensorHalImp::init()
{
//这里直接调用的是ImgSensorDrv::getInstance()
//返回的是ImgSensorDrv(imgsensor_drv.cpp),也就是我们找的摄像头驱动管理
//构造函数只在做了简单的数据处理
pSensorDrv=SensorDrv::createInstance(mSensorDev);
//初始化ISP
ret=pSeninfDrv->init();
//Beforesearchingsensor,needtoturnonTG
ret=initSensor();
//GetsensorinfobeforesettingTGphasecounter
ret=getSensorInfo(scenarioId);
ret=setTgPhase();
ret=setSensorIODrivingCurrent();
ret=initCSI2Peripheral(1);//iftheinterfaceismipi,enablethecsi2
ret=setCSI2Config(1);//enableandconfigCSI2.
#ifdefATV_SUPPORT
#ifdefMTK_MATV_SERIAL_IF_SUPPORT
pSeninfDrv->initTg1Serial(MFALSE);
#endif
#endif
//Opensensor,trytoopen3time
for(inti=0;i<3;i++)
ret=pSensorDrv->open();
}
MINT32SensorHalImp::initSensor()
{
switch(mSensorDev)
{
caseSENSOR_DEV_MAIN:
eSensorDev=SENSOR_MAIN;
if(!(mSearchSensorDev&SENSOR_DEV_MAIN)){
LOG_ERR("initSensorfail,mSensorDev=0x%x,mSearchSensorDev=0x%x\n",mSensorDev,mSearchSensorDev);
return-1;
}
break;
caseSENSOR_DEV_SUB:
//....
}
//imgsensor_drv.cppImgSensorDrv::init()函数
//在此打开底层的驱动文件,并获取一些信息
ret=pSensorDrv->init(mSensorDev);
//GetSensorResolution
pSensorResInfo[0]=&sensorResolution[0];
pSensorResInfo[1]=&sensorResolution[1];
ret=pSensorDrv->getResolution(pSensorResInfo);
if(eSensorDev==SENSOR_DEV_MAIN){
if(IMAGE_SENSOR_TYPE_RAW==pSensorDrv->getCurrentSensorType(eSensorDev))
{
//FullResolution
u4PaddedWidth=sensorResolution[0].SensorFullWidth+ISP_RAW_WIDTH_PADD;
u4PaddedHeight=sensorResolution[0].SensorFullHeight+ISP_RAW_HEIGHT_PADD;
if(0!=((u4PaddedWidth*u4PaddedHeight)%6))
{
sensorResolution[0].SensorFullHeight-=(u4PaddedHeight%6);
LOG_MSG("Sensorresolutionafterfixing:Full:%d/%d\n",sensorResolution[0].SensorFullWidth,sensorResolution[0].SensorFullHeight);
}
}
}
if(eSensorDev==SENSOR_DEV_SUB){
//...
}
}
MINT32ImgSensorDrv::init(MINT32sensorIdx)
{
//打开底层设备文件,至于是打开sensorlist哪个摄像头
//摄像头怎么匹配的就是靠CAMERA_HW_DEVNAME这个驱动了。
sprintf(cBuf,"/dev/%s",CAMERA_HW_DEVNAME);
m_fdSensor=::open(cBuf,O_RDWR);
//setsensordriver
ret=ioctl(m_fdSensor,KDIMGSENSORIOC_X_SET_DRIVER,sensorDrvInfo);
android_atomic_inc(&mUsers);
//init.resolution
pSensorResInfo[0]=&m_SenosrResInfo[0];
pSensorResInfo[1]=&m_SenosrResInfo[1];
ret=getResolution(pSensorResInfo);
}


基本上Camera从上到下的流程就是这样子了。基本上贯穿了我们整个Camera,目的已经达到,点到为止
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: