-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
313 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
|
||
// following the calling order: | ||
// 6# is in the kernel space, and others | ||
// in the user space. | ||
|
||
0. Camera APP | ||
packages/apps/Camera/ | ||
1. Camera Java API | ||
android.hardware.Camera | ||
2. libandroid_runtime.so | ||
android_hardware_Camera.cpp | ||
3. libcamera_client.so | ||
frameworks/av/camera/ | ||
4. libcameraservice.so | ||
frameworks/av/services/camera/ | ||
5. HAL layer | ||
hardware/qcom/camera | ||
6. kernel driver | ||
kernel/dirvers/media/video/msm/ | ||
7. vendor | ||
vendor/qcom/proprietary/mm-camera/ | ||
|
||
��framework��HAL������(��takePicture()������)�� | ||
4-5.0 [@CameraService.cpp] | ||
// take a picture - image is returned in callback | ||
status_t CameraService::Client::takePicture(int msgType) { | ||
// ...... | ||
return mHardware->takePicture(); | ||
} | ||
|
||
4-5.1 [CameraService.cpp] | ||
CameraService::Client::Client(const sp<CameraService>& cameraService, | ||
const sp<ICameraClient>& cameraClient, | ||
const sp<CameraHardwareInterface>& hardware, | ||
int cameraId, int cameraFacing, int clientPid) { | ||
// ...... | ||
mCameraService = cameraService; | ||
mCameraClient = cameraClient; | ||
// mHardware comes here | ||
mHardware = hardware; | ||
mCameraId = cameraId; | ||
// ...... | ||
} | ||
|
||
4-5.2 [CameraService.cpp] | ||
sp<ICamera> CameraService::connect( | ||
const sp<ICameraClient>& cameraClient, int cameraId) { | ||
// ...... | ||
hardware = new CameraHardwareInterface(camera_device_name); | ||
if (hardware->initialize(&mModule->common) != OK) { | ||
hardware.clear(); | ||
return NULL; | ||
} | ||
client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid); | ||
// ...... | ||
} | ||
|
||
4-5.3 [@CameraHardwareInterface.h::CameraHardwareInterface] | ||
status_t initialize(hw_module_t *module) | ||
{ | ||
ALOGI("Opening camera %s", mName.string()); | ||
// CameraHardwareInterface::mDevice(camera_device_t) comes here. | ||
int rc = module->methods->open(module, mName.string(), | ||
(hw_device_t **)&mDevice); | ||
if (rc != OK) { | ||
ALOGE("Could not open camera %s: %d", mName.string(), rc); | ||
return rc; | ||
} | ||
initHalPreviewWindow(); | ||
return rc; | ||
} | ||
|
||
4-5.4 [@CameraHardwareInterface.h::CameraHardwareInterface] | ||
status_t takePicture() | ||
{ | ||
ALOGV("%s(%s)", __FUNCTION__, mName.string()); | ||
if (mDevice->ops->take_picture) | ||
return mDevice->ops->take_picture(mDevice); | ||
return INVALID_OPERATION; | ||
} | ||
|
||
// ����Ϊֹ��Ҳ����˵��takePicture()�������յ��õ�CameraHardwareInterface | ||
// ���mDevice(camera_device_t ���͵Ķ���)���takePicture()�������� | ||
// mDevice����������mModule(hw_module_t���͵Ķ���)���������� | ||
|
||
4-5.5 where comes "module" object? [@CameraService.cpp] | ||
void CameraService::onFirstRef() | ||
{ | ||
BnCameraService::onFirstRef(); | ||
|
||
if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, | ||
(const hw_module_t **)&mModule) < 0) { | ||
ALOGE("Could not load camera HAL module"); | ||
mNumberOfCameras = 0; | ||
} | ||
else { | ||
mNumberOfCameras = mModule->get_number_of_cameras(); | ||
if (mNumberOfCameras > MAX_CAMERAS) { | ||
ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", | ||
mNumberOfCameras, MAX_CAMERAS); | ||
mNumberOfCameras = MAX_CAMERAS; | ||
} | ||
for (int i = 0; i < mNumberOfCameras; i++) { | ||
setCameraFree(i); | ||
} | ||
} | ||
} | ||
|
||
4-5.6 [@hardware/libhardware/hardware.c] | ||
int hw_get_module(const char *id, const struct hw_module_t **module) { | ||
return hw_get_module_by_class(id, null, module); | ||
} | ||
int hw_get_module_by_class(const char class_id, const char *inst, const struct hw_module_t **module) { | ||
// ...... | ||
int status; | ||
status = load(class_id, path, module); | ||
// path ������/system/lib/hw/xxx.so | ||
} | ||
static int load(const char *id, const char *path, const struct hw_module_t **pHmi) { | ||
void *handle; | ||
struct hw_module_t *hmi; | ||
handle = dlopen(path, RTLD_NOW); | ||
const char *sym = HAL_MODULE_INFO_SYM_AS_STR; | ||
// #define HAL_MODULE_INFO_SYM HMI [@hardware/libhardware/include/hardware/hardware.h] | ||
// #define HAL_MODULE_INFO_SYM_AS_STR "HMI" [@hardware/libhardware/include/hardware/hardware.h] | ||
hmi = (struct hw_module_t *)slsym(handle, sym); | ||
// ...... | ||
*pHmi = hmi; | ||
} | ||
// �ɴ˻��hw_module_t���͵Ķ����浽CameraHardwareInterface�����о���mModule���� | ||
// �����Եĺ����ӿڣ�����takePicture(), startPreview(), setParameters()��������Щ�أ����е���Щ�������� | ||
// camera.h[@hardware/libhardware/include/hardware/] | ||
// ���.h�ж���ı���android��־�Ľӿڣ����������Լ�ʵ���Լ��ķ���������qualcomm��ʵ���ڣ� | ||
// QualcommCamera2.h[@hardware/qcom/camera/] | ||
// ������������mModule(hw_module_t)������δ���mDevice(camera_device_t)�ģ��ⲿ�־���ʵ�ֶ��ڸ�оƬ�����Լ��� | ||
// HALʵ���У��Ը�ͨΪ��[@QualcommCamera2.cpp]�� | ||
camera_module_t HAL_MODULE_INFO_SYM = { | ||
common: camera_common, | ||
get_number_of_cameras: get_number_of_cameras, | ||
get_camera_info: get_camera_info, | ||
} | ||
// ���� | ||
// #define HAL_MODULE_INFO_SYM HMI [@hardware/libhardware/include/hardware/hardware.h] | ||
// ��ǡ����hardware/libhardware/hardware.c::load()�����е�dlsym(handle, sym)ͳһ������ | ||
// �����common��һ��hw_module_t�ṹ�壬camera_common�Ķ������£� | ||
static hw_module_t camera_common = { | ||
tag: | ||
version_major: | ||
version_minor: | ||
id: | ||
name: "Qcamera", | ||
author: "Qcom", | ||
methods: &camera_module_methods, | ||
dso: NULL, | ||
} | ||
static struct hw_module_methods_t camera_module_methods = { | ||
open: camera_device_open | ||
}; | ||
|
||
typedef struct { | ||
camera_device hw_dev; | ||
QCameraHardwareInterface *hardware; | ||
int camera_released; | ||
int cameraId; | ||
} camera_hardware_t; | ||
|
||
[@hardware/libhardware/include/hardware/camera.h] | ||
typedef struct camera_device { | ||
hw_device_t common; | ||
camera_device_ops_t *ops; | ||
void *priv; | ||
} camera_device_t; | ||
|
||
// �����м���ɾ���� | ||
extern "C" int camera_device_open(const struct hw_module_t *module, | ||
const char *id, struct hw_device_t **hw_device) { | ||
camera_device *device = NULL; | ||
int cameraId = atoi(id); | ||
camera_hardware_t *camHAL = (camera_hardware_t *)malloc(sizeof(camera_hardware_t)); | ||
memset(camHal, 0, sizeof(camera_hardware_t)); | ||
camHal->hardware = new QCameraHardwareInterface(cameraId, mode); | ||
camHal->cameraId = cameraId; | ||
device = &camHal->hw_dev; | ||
device->common.close = close_camera_device; | ||
device->ops = &camera_ops; | ||
device->priv = (void *)camHal; | ||
|
||
// ��hw_device_t���͵Ķ����ˣ�mModule������������mDevice����ġ� | ||
*hardware = (hw_device_t *)&device->common; | ||
} | ||
|
||
// ����������QCameraHardwareInterface[@hardware/qcom/camera/QCameraHWI.cpp]�������� | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* HAL Implementation | ||
* --- take Qualcomm for example. | ||
*/ | ||
|
||
/* | ||
* 这是qualcomm 8960平台的HAL实现,该部分代码并非**private**的,Google网站可以下载到! | ||
* | ||
* 总体思路如下: | ||
* 1. 创建名为HMI的hw_module_t对象,libhardware在load HAL的.so文件时会查找该对象 | ||
* 2. 创建新的数据类型:camera_hardware_t,它代表一个camera device,对上提供 | ||
* camera_device_t对象,对下保存QCameraHardwareInterface对象,通过该对象完成具体功能 | ||
* 所有代码均位于:[@hardware/libhardware/include/hardware/QualcommCamera2.cpp] | ||
*/ | ||
|
||
// 一、创建hw_module_t对象:HMI,并初始化 | ||
camera_module_t HAL_MODULE_INFO_SYM = { | ||
common: camera_common, | ||
get_number_of_cameras: get_number_of_cameras, | ||
get_camera_info: get_camera_info, | ||
}; | ||
|
||
static hw_module_t camera_common = { | ||
tag: HARDWARE_MODULE_TAG, | ||
version_major: 0, | ||
version_minor: 01, | ||
id: CAMERA_HARDWARE_MODULE_ID, // equals "camera" | ||
name: "Qcamera", | ||
author: "Qcom", | ||
methods: &camera_module_methods, | ||
dso: NULL, | ||
}; | ||
|
||
static hw_module_methods_t camera_module_methods = { | ||
open: camera_device_open, | ||
}; | ||
|
||
extern "C" int camera_device_open(const struct hw_module_t *module, | ||
const char *id, struct hw_device_t **hw_device) { | ||
// 以下为伪代码! | ||
camera_device *device = NULL; | ||
// 0. create camera_hardware_t object | ||
camera_hardware_t *camHal = (camera_hardware_t *)malloc(sizeof(camera_hardware_t)); | ||
memset(camHal, 0, sizeof(camera_hardware_t)); | ||
// 1. set QCameraHardwareInterface object | ||
camHal->hardware = new QCameraHardwareInterface(cameraId); | ||
// 2. set camera_device_t object | ||
device = &camHal->hw_dev; | ||
device->common.close = close_camera_device; | ||
device->ops = &camera_ops; | ||
device->priv = (void *)camHal; | ||
|
||
// 返回hw_device_t对象 | ||
*hw_device = (hw_device_t *)&device->common; | ||
} | ||
// 以下是camera的两个特殊HAL接口实现 [@hardware/qcom/camera/QualcommCamera2.cpp] | ||
extern "C" int get_number_of_cameras() { | ||
return android::HAL_getNumberOfCameras(); | ||
} | ||
|
||
extern "C" int get_camera_info(int camera_id, struct camera_info *info) { | ||
} | ||
|
||
extern "C" int HAL_getNumberOfCameras() // [@hardware/qcom/camera/QCameraHAL.cpp] | ||
{ | ||
|
||
} | ||
|
||
// 二、使用camera_hardware_t代表一个camera device,其中包括对上提供的camera_device_t对象 | ||
// 和对下调用的QCameraHardwareInterface对象 | ||
typedef struct { | ||
camera_device hw_dev; // framework会通过module对象获取该device对象 | ||
QCameraHardwareInterface *hardware; // 具体的功能要通过该对象来完成,它会进一步深入到kernel中 | ||
int camera_released; | ||
int cameraId; | ||
} camera_hardware_t; | ||
/* | ||
* 我们完全可以把自己理解为"驱动程序",而libhardware提供的接口struct camera_device类似于linux kernel提供的 | ||
* struct file接口,我们需要提供struct camera_device中的struct camera_device_ops中的各个函数接口。 | ||
* 此处的camera_hardware_t是高通为了保存自己的程序状态和私有数据而创建的,如果让我们自己实现一个简单的HAL, | ||
* 完全可以不用创建类似的数据结构,而只需提供struct camera_device_ops中的各个函数接口实现,还是那句话: | ||
* "类似于linux device driver" | ||
*/ | ||
camera_device_ops_t camera_ops = { | ||
// ... | ||
start_preview: android::start_preview, | ||
// ... | ||
take_picture: android::take_picture, | ||
// ... | ||
}; | ||
/* | ||
* 这里以take_picture()函数为例,它会通过struct camera_device对象获取到QCameraHardwareInterface对象, | ||
* 可是QCameraHardwareInterface对象是包含在camera_hardware_t对象中的,这里却通过camera_device对象获取, | ||
* 怎么做到的呢? | ||
* 其实,对比驱动程序的框架就不难理解了: | ||
* struct file <=> struct camera_device | ||
* struct scull <=> struct camera_hardware_t | ||
* 但是这个比喻并不完全吻合,考虑cdev,就知道了,这个需要图表来解释。 | ||
* util_get_Hal_obj(): | ||
* camera_device_t -> camera_hardware_t -> QCameraHardwareInterface | ||
*/ | ||
int take_picture(struc camera_device *device) { | ||
int rc = -1; | ||
QCameraHardwareInterface *hardware = util_get_Hal_obj(device); | ||
if(hardware != NULL) { | ||
rc = hardware->takePicture(); | ||
} | ||
return rc; | ||
} | ||
|
||
//************* 后面便是HAL到kernel的内容了 ***************// |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters