Skip to content

Commit

Permalink
update camera driver files.
Browse files Browse the repository at this point in the history
  • Loading branch information
ybin committed Apr 7, 2013
1 parent 92b5f81 commit 4613f39
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 0 deletions.
193 changes: 193 additions & 0 deletions 0.camera_structure.txt
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.
7 changes: 7 additions & 0 deletions libhardware_X.c → 2.libhardware_X.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,13 @@ typedef struct camera_device {
camera_device_ops_t *ops;
void *priv;
} camera_device_t;
/*
* 这里的方法非常类似于kernel的struct file接口,驱动程序只需完成对应的struct file_operations对象中
* 列举的各个operations即可。这里,各个硬件厂商只需提供camera_device_ops_t中列举的各个操作即可。
* 类似于struct file中的void *priv属性,struct camera_device中的void *priv属性如出一辙:
* "方便驱动程序保存自己的状态数据"
* 理解这一点很重要!
*/
// 这里面的接口是不是很眼熟的呢?! 在framework的角度看底层,只能看到这些功能。
typedef struct camera_device_ops {
/** Set the ANativeWindow to which preview frames are sent */
Expand Down
111 changes: 111 additions & 0 deletions 3.HAL_implementation_Qualcomm.c
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的内容了 ***************//
1 change: 1 addition & 0 deletions 4.HAL_interface_impl_Qcomm_X.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* * HAL的功能接口实现 * * HAL的主要功能就是要实现 hardware/libhardware/include/hardware/camera.h 里面定义的operation接口, * 这些接口在camera_hardware_t中有对应的"初步"实现,然后调用到 QCameraHardwareInterface 对象中的对应接口, * 本节就来介绍QCameraHardwareInterface对象中的实现。 * 从framework到现在,大致的调用流程如下: * CameraService::Client => QualcommCamera2.cpp::camera_hardware_t => QCameraHWI.cpp::QCameraHardwareInterface */
Expand Down
1 change: 1 addition & 0 deletions 5.mm_camera_interface_X.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* * mm_camera_interface2.c * 这个文件提供进入mm-camera的接口,功能如其名称所述。 * * 该文件的大致结构如下: * 1. 提供一个全局变量(g_cam_ctrl)作为所有摄像头实例的总控 * 2. 对上: 为 QCameraHardwareInterface 对象(QCameraHWI.cpp)提供接口(如cam_ops_open函数) * 3. 对下: 调用mm_camera_t对象(代表mm-camera对象)的接口(如mm_camera_open函数)完成具体功能 */// 一、全景变量:g_cam_ctrl对象// 二、对上,为QCameraHardwareInterface对象提供接口// 三、对下,调用mm_camera_t对象的接口来完成具体功能// 四、以open操作为例,流程大致如下:[@hardware/qcom/camera/QCameraHWI.cpp]QCamearHardwareInterface(int cameraId, int mode) { // ... result = cam_ops_open(mCameraId, MM_CAMERA_OP_MODE_NOTUSED); // ...}// cam_ops_open()函数为mm_camera_interface2.c为上层提供的接口[@hardware/qcom/camera/mm_camera_interface2.c]int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode) { // 首先,从全景变量中找到mm-camera对应的对象:mm_cam // 见:A, B, C 三步操作 mm_camera_t *mm_cam = get_camera_by_id(cam_id); if(mm_cam) { // 然后,调用mm-camera对象的接口来完成具体功能 mm_cam->ops->open(mm_cam, op_mode); }}///////////// A.[@hardware/qcom/camera/mm_camera_interface2.c]static mm_camera_t *get_camera_by_id(int cam_id) { mm_camera_t *mm_cam; mm_cam = *g_cam_ctrl.camera[cam_id]; return mm_cam;}///////////// B.[@hardware/qcom/camera/mm_camera_interface2.c]extern mm_camera_t *mm_camera_query(uint8_t num_cameras) { // ... g_cam_ctrl.camera[i].ops = &mm_camera_ops; // ...}///////////// C.[@hardware/qcom/camera/mm_camera_interface2.c]static mm_camera_ops_t mm_camera_ops = { // ... .open = mm_camera_ops_open, // ...}// mm_camera_ops_open()对应的即为.open函数,它调用到mm-camera里面去了[@hardware/qcom/camera/mm_camera_interface2.c]static int32_t mm_camera_ops_open(mm_camera_t *camera, mm_camera_op_mode_type_t op_mode) { // ... rc = mm_camera_open(g_cam_ctrl.cam_obj[camera_id], op_mode); // ...}[@hardware/qcom/camera/mm_camera.c]int32_t mm_camera_open(mm_camera_obj_t *my_obj, mm_camera_op_mode_type_t op_mode) { // ... snprintf(dev_name, sizeof(dev_name), "/dev/%s", mm_camera_util_get_dev_name(my_obj)); // ... my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);}
Expand Down

0 comments on commit 4613f39

Please sign in to comment.