Elaine个人小馆 / Camera HAL / Android Camera 系统架构源码分析(1)

0 0

   

Android Camera 系统架构源码分析(1)

2016-09-02  Elaine个...
系统:MTK Android4.4
日期:2015年10月10日
stamp&data  setParameters  Utils::Property::tryGet

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

二. 分析思路
1. 先从Camera的初始化开始,以cameraID为线索,简单地从Frameworks开始贯穿到底层。主要任务Camera如何被打开的,完成源码的贯穿。
2. 然后再从startPreview开始去了解,Camera被打开之后,取出的数据流是什么,数据流经过了怎么的处理,然后又是怎么被送出到APK,显示出来的

三. 上层入口
针对于上面的两个分析点,从APK上层入口开始:
private Camera mCamera;
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.cpp mediatek/hardward/mtkcam/devicemgr
CameraClient.cpp frameworks/av/services/camera/libcameraservice/api1
CameraHardwareInterface.h: frameworks/av/services/camera/libcameraservice/device


(2) Frameworks层
第一个被调用的是Camera.java文件里的open函数。然后调用的是Camera(int cameraId)的
native_setup(new WeakReference<Camera>(this), cameraId, packageName);
上面的函数对应的是android_hardware_Camera.cpp里的android_hardware_Camera_native_setup()函数
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jstring clientPackageName)
{
//打开Camera,把回一个Camera设备
sp<Camera> camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID);
 
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera);
}
我们开始从Camera::connect开始深入,connect函数在Camera.cpp:
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName, int clientUid){
return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}
这里调用了CameraBaseT的connect
CameraBaseT是CameraBase的类成员,CameraBase是一个模板类,其定义如下:
template <typename TCam>
struct CameraTraits {
};
 
template <typename TCam, typename TCamTraits = CameraTraits<TCam> >
class CameraBase : public IBinder::DeathRecipient
{
public:
typedef typename TCamTraits::TCamListener TCamListener;
typedef typename TCamTraits::TCamUser TCamUser;
typedef typename TCamTraits::TCamCallbacks TCamCallbacks;
typedef typename TCamTraits::TCamConnectService TCamConnectService;
 
static sp<TCam> connect(int cameraId, const String16& clientPackageName, int clientUid);
//...
 
protected:
CameraBase(int cameraId);
//...
typedef CameraBase<TCam> CameraBaseT;
};
}; // namespace android
Camera.cpp里的Camera类继承于CameraBase,同时初始化了CameraBase的模板
class Camera : public CameraBase<Camera>, public BnCameraClient
在Camera.h里也初始化了CameraTraits这个模板类:
template <>
struct CameraTraits<Camera>
{
typedef CameraListener TCamListener;
typedef ICamera TCamUser;
typedef ICameraClient TCamCallbacks;
typedef status_t (ICameraService::*TCamConnectService)(const sp<ICameraClient>&, int, const String16&, int,
/*out*/
sp<ICamera>&);
static TCamConnectService fnConnectService;
};
CameraBase这个模板中的TCamConnectService成员的类型为TCamTraits::TCamConnectService,所以在这里被定义成一个TCamConnectService类型的函数指针,其余的CameraBase成员依此类推。
我们继续回到connect函数里。Camera.cpp里调用了模板类里的connect函数,这个函数的实现在CameraBase.cpp里
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, const String16& clientPackageName, int clientUid)
{
ALOGV('%s: connect', __FUNCTION__);
//把所有的TCam替换成Camera,构造了一个Camera对象。这个构造函数只有初始化mCameraId的值
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
 
//获取ICameraService
const sp<ICameraService>& cs = getCameraService();
 
//fnConnectService在Camera.cpp里被定义为&ICameraService::connect
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
//调用CameraService里的connect函数
status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, /*out*/ c->mCamera);
 
return c;
}

CameraService .cpp的CameraService::connect
status_t CameraService::connect(const sp<ICameraClient>& cameraClient, int cameraId,
const String16& clientPackageName, int clientUid, /*out*/ sp<ICamera>& device) {
 
int facing = -1;
//获得hardware层的版本是CAMERA_DEVICE_API_VERSION_1_0
int deviceVersion = getDeviceVersion(cameraId, &facing);
 
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
//CameraClient也在hardware层里定义了
client = new CameraClient(this, cameraClient,
clientPackageName, cameraId,
facing, callingPid, clientUid, getpid());
break;
case CAMERA_DEVICE_API_VERSION_2_0:
//...
}
status_t status = connectFinishUnsafe(client, client->getRemote());
 
mClient[cameraId] = client;
 
// important: release the mutex here so the client can call back
// into the service from its destructor (can be at the end of the call)
 
device = client;
return OK;
}
 
//getDeviceVersion
int CameraService::getDeviceVersion(int cameraId, int* facing) {
struct camera_info info;
mModule->get_camera_info(cameraId, &info);
int deviceVersion;
if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
deviceVersion = info.device_version;
} else {
//从hardware层的hw_module_t mModule里获得版本号
deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
}
 
return deviceVersion;
}
 
//mModule的初始化在onFirstRef函数里
void CameraService::onFirstRef()
{
hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_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()函数。
static int get_camera_info(int cameraId, camera_info* info){
//CamDeviceManager继承于CamDeviceManagerBase
//这里相当于直接调用CamDeviceManagerBase的getDeviceInfo函数
return NSCam::getCamDeviceManager()->getDeviceInfo(cameraId, *info);
}
 
//CamDeviceManagerBase.cpp
CamDeviceManagerBase::
getDeviceInfo(int const deviceId, 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.cpp enumDeviceLocked()
enumDeviceLocked()
{
//增加ImageSensor的Sensor信息,后面会被get
    DevMetaInfo::add(deviceId, camInfo, i4DevSetupOrientation, eDevId_ImgSensor, eHalSensorDev);
sp<EnumInfo> pInfo = new EnumInfo;
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(const sp<CameraService>& cameraService,
Client(cameraService, cameraClient, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid)
{
// Callback is disabled by default
mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
//摄像头方向
mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
//拍照声音
mPlayShutterSound = true;
LOG1('CameraClient::CameraClient X (pid %d, id %d)', callingPid, cameraId);
}
connect里构造了CameraClient后调用了connectFinishUnsafe()函数,这个函数里调用了CameraClient的initialize函数
status_t CameraClient::initialize(camera_module_t *module) {
// Verify ops permissions
res = startCameraOps();
 
char camera_device_name[10];
snprintf(camera_device_name, sizeof(camera_device_name), '%d', mCameraId);
 
//在CameraHardwareInterface.cpp
mHardware = new CameraHardwareInterface(camera_device_name);
//打开hardware mModule
res = mHardware->initialize(&module->common);
 
mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, (void *)mCameraId);
 
// Enable zoom, error, focus, and metadata messages by default
enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
 
// Enable MTK-extended messages by default
enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY | MTK_CAMERA_MSG_EXT_DATA);
}

CameraHardwareInterface.cpp initialize()函数
initialize()之后获得了Hardware对接的设备接口mDevice,上层的Frameworks正是通过CameraHardwareInterface类,对Hardware层进行操作,然后Hardware层对硬件进行进一步的操作。CameraHardwareInterface是上下层对接的接口。
status_t initialize(hw_module_t *module){
 
//调用了module.h open_device()
module->methods->open(module, mName.string(), (hw_device_t **)&mDevice);
 
//初始化预览窗口
initHalPreviewWindow();
}

(3) Hardware层
文件列表:
CamDeviceManagerBase.cpp mediatek/hardward/mtkcam/devicemgr
Cam1DeviceFactory.cpp mediatek/hardware/mtkcam/v1/device
DefaultCam1Device.cpp mediatek/mt8127/hardware/mtkcam/v1/device
Cam1DeviceBase.cpp mediatek/hardware/mtkcam/v1/device
Cam1Device.cpp mediatek/hardware/mtkcam/v1/device
Sensor_hal.cpp mediatek/platform/mt8127/hardware/mtkcam/core/drv/imgsensor
imgsensor_drv.cpp mediatek/platform/mt8127/hardware/mtkcam/core/drv/imgsensor
Camclient.cpp mediatek/hardware/mtkcam/v1/client/camclient
PreviewClient.cpp mediatek/hardware/mtkcam/v1/client/camclient/previewcallback
ImgBufQueue.cpp mediatek/hardware/mtkcam/v1/common/camutils
MtkDefaultCamAdapter.cpp mediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault
BaseCamAdapter.cpp mediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/
State.cpp mediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/state
PreviewCmdQueThread.cpp mediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/preview
PreviewBufMgr.cpp mediatek/platform/mt8127/hardware/mtkcam/v1/hal/adapter/mtkdefault/preview

CameraHardwareInterface.cpp initialize()调用了Module.h 的open_device()函数
open_device(hw_module_t const* module, const char* name, hw_device_t** device)
{
return NSCam::getCamDeviceManager()->open(module, name, device);
}
CamDeviceManagerImp 继承于 CamDeviceManagerBase。直接调用了CamDeviceManagerBase的open(),open()函数又只是调用了CamDeviceManagerBase::
openDeviceLocked()。此函数在同文件夹下的CamDeviceManagerBase.openDevice.cpp文件里。
在这里有点不明白,这个函数会获取一个属性值,这个值是从哪里来的,这个似乎要从开机流程里找了。先Mark一下,有空再看一下开机流程
CamDeviceManagerBase::
openDeviceLocked( hw_module_t const* module, char const* name, hw_device_t** device)
{
//获得AppMode,这个属性在哪里被初始化的呢?我们这里的s8ClientAppMode = APP_MODE_NAME_DEFAULT
String8 const s8ClientAppMode = queryClientAppMode();
//这个我们在之前已经看到了在哪里初始化,结果为CAMERA_DEVICE_API_VERSION_1_0
uint32_t const version = determineOpenDeviceVersionLocked(s8ClientAppMode, i4OpenId);
 
if ( version == CAMERA_DEVICE_API_VERSION_1_0 )
{ //获得Camera设备,并打开硬件和初始化。这里的设备并不是指硬件设备
//而是包含硬件设备,设备参数,设备操作(预览等)。的一个操作类
pDevice = pPlatform->createCam1Device(s8ClientAppMode.string(), i4OpenId);
}
}
上面的createCam1Device函数在Cam1DeviceFactory.cpp
NSCam::Cam1Device*
createCam1Device(String8 const s8ClientAppMode, int32_t const i4OpenId)
{
// if ( s8ClientAppMode == MtkCameraParameters::APP_MODE_NAME_DEFAULT )
{
String8 const s8CamDeviceInstFactory = String8::format('createCam1Device_Default');
void* pCreateInstance = ::dlsym(RTLD_DEFAULT, s8CamDeviceInstFactory.string());
MY_LOGF_IF(0==pCreateInstance, 'Not exist: %s for %s', s8CamDeviceInstFactory.string(), s8ClientAppMode.string());
//这里相当于调用 createCam1Device_Default()函数
pdev = reinterpret_cast<NSCam::Cam1Device* (*)(String8 const&, int32_t const)>
(pCreateInstance)(s8ClientAppMode, i4OpenId);
}
 
if ( pdev )
{
//初始化硬件设备等
if ( OK != pdev->initialize() )
{
MY_LOGE('Cam1Device::initialize() device:%p', pdev);
// use ref. count to delete raw pointer.
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( String8 const& rDevName, int32_t const i4OpenId)
{
return new DefaultCam1Device(rDevName, i4OpenId);
}
 
//DefaultCam1Device继承于Cam1DeviceBase
DefaultCam1Device::
DefaultCam1Device(String8 const& rDevName, int32_t const i4OpenId)
: Cam1DeviceBase(rDevName, i4OpenId)
{
}
 
//Cam1DeviceBase继承于Cam1Device
Cam1DeviceBase::
Cam1DeviceBase( String8 const& rDevName, int32_t const i4OpenId)
: 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()
{
int const iHalSensorDevId = DevMetaInfo::queryHalSensorDev(getOpenId());
 
//Android的资源管理器
IResManager* pResManager = IResManager::getInstance();
if(!(pResManager->open('DefaultCam1Device'))){}
 
// (1) Open Sensor 下面的SensorHal包含了imageSensor和ISP
mpSensorHal = SensorHal::createInstance();
 
err = mpSensorHal->sendCommand((halSensorDev_e)iHalSensorDevId, SENSOR_CMD_SET_SENSOR_DEV);
 
err = mpSensorHal->init();
 
// (2) Open 3A
mp3AHal = NS3A::Hal3ABase::createInstance(iHalSensorDevId);
 
// (3) Init Base.
Cam1DeviceBase::onInit();
}

SensorHal在Sensor_hal.cpp,我们从SensorHal::createInstance();开始,此函数只是创建了ISP管理驱动,并没打开ImageSensor设备。ISP不是我们重点,先忽略
SensorHal* SensorHal::createInstance()
{
return SensorHalImp::getInstance();
}
 
SensorHal* SensorHalImp::getInstance()
{
static SensorHalImp singleton;
ret = singleton.createImp();
return &singleton;
}
 
MINT32 SensorHalImp::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
MINT32 SensorHalImp::init()
{
//这里直接调用的是ImgSensorDrv::getInstance()
//返回的是ImgSensorDrv(imgsensor_drv.cpp),也就是我们找的摄像头驱动管理
//构造函数只在做了简单的数据处理
pSensorDrv = SensorDrv::createInstance(mSensorDev);
 
//初始化ISP
ret = pSeninfDrv->init();
 
// Before searching sensor, need to turn on TG
ret = initSensor();
 
// Get sensor info before setting TG phase counter
ret = getSensorInfo(scenarioId);
 
ret = setTgPhase();
ret = setSensorIODrivingCurrent();
 
ret = initCSI2Peripheral(1); // if the interface is mipi, enable the csi2
 
ret = setCSI2Config(1); // enable and config CSI2.
 
#ifdef ATV_SUPPORT
#ifdef MTK_MATV_SERIAL_IF_SUPPORT
pSeninfDrv->initTg1Serial(MFALSE);
#endif
#endif
// Open sensor, try to open 3 time
for (int i =0; i < 3; i++)
ret = pSensorDrv->open();
}
 
MINT32 SensorHalImp::initSensor()
{
switch (mSensorDev)
{
case SENSOR_DEV_MAIN:
eSensorDev = SENSOR_MAIN;
if(!(mSearchSensorDev & SENSOR_DEV_MAIN)) {
LOG_ERR('initSensor fail,mSensorDev = 0x%x, mSearchSensorDev = 0x%x\n',mSensorDev,mSearchSensorDev);
return -1;
}
break;
case SENSOR_DEV_SUB:
//....
}
//imgsensor_drv.cpp ImgSensorDrv::init()函数
//在此打开底层的驱动文件,并获取一些信息
ret = pSensorDrv->init(mSensorDev);
// Get Sensor Resolution
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) )
{
// Full Resolution
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(' Sensor resolution after fixing: Full: %d/%d\n', sensorResolution[0].SensorFullWidth, sensorResolution[0].SensorFullHeight);
}
}
}
 
if(eSensorDev == SENSOR_DEV_SUB) {
//...
}
}
 
 
MINT32 ImgSensorDrv::init(MINT32 sensorIdx)
{
 
//打开底层设备文件,至于是打开sensorlist哪个摄像头
//摄像头怎么匹配的就是靠CAMERA_HW_DEVNAME这个驱动了。
sprintf(cBuf,'/dev/%s',CAMERA_HW_DEVNAME);
m_fdSensor = ::open(cBuf, O_RDWR);
 
//set sensor driver
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,目的已经达到,点到为止

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多