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

本文梳理了MTK Android Camera系统的源码流程,从初始化到数据流处理,直至显示,全面覆盖了从Frameworks层到底层硬件的操作过程。着重介绍了CameraClient的作用以及CameraService如何与硬件层交互,提供了对MTK Camera系统深入理解的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系统: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 androiddroid

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,目的已经达到,点到为止
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值