ICS 中 沿用了linux驱动模块化的方式,把camera hal 形成一个hardware module,这点跟HC明显不同。
打开camera时, cameraservice 会先打开camera hw_moudle, 如下代码所示:
- void CameraService::onFirstRef()
- {
- BnCameraService::onFirstRef();
- if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, //获得camera 模块,
- (const hw_module_t **)&mModule) < 0) { //&mModule 应该就是camera.medfield.so.
- LOGE("Could not load camera HAL module");
- mNumberOfCameras = 0;
- }
- else {
- mNumberOfCameras = mModule->get_number_of_cameras(); //调用camera hal 层函数。
- if (mNumberOfCameras > MAX_CAMERAS) {
- LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
- mNumberOfCameras, MAX_CAMERAS);
- mNumberOfCameras = MAX_CAMERAS;
- }
- for (int i = 0; i < mNumberOfCameras; i++) {
- setCameraFree(i);
- }
- }
- // Read the system property to determine if we have to use the
- // AUDIO_STREAM_ENFORCED_AUDIBLE type.
- char value[PROPERTY_VALUE_MAX];
- property_get("ro.camera.sound.forced", value, "0");
- if (strcmp(value, "0") != 0) {
- mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
- } else {
- mAudioStreamType = AUDIO_STREAM_MUSIC;
- }
- }
void CameraService::onFirstRef()
{
BnCameraService::onFirstRef();
if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, //获得camera 模块,
(const hw_module_t **)&mModule) < 0) { //&mModule 应该就是camera.medfield.so.
LOGE("Could not load camera HAL module");
mNumberOfCameras = 0;
}
else {
mNumberOfCameras = mModule->get_number_of_cameras(); //调用camera hal 层函数。
if (mNumberOfCameras > MAX_CAMERAS) {
LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
mNumberOfCameras, MAX_CAMERAS);
mNumberOfCameras = MAX_CAMERAS;
}
for (int i = 0; i < mNumberOfCameras; i++) {
setCameraFree(i);
}
}
// Read the system property to determine if we have to use the
// AUDIO_STREAM_ENFORCED_AUDIBLE type.
char value[PROPERTY_VALUE_MAX];
property_get("ro.camera.sound.forced", value, "0");
if (strcmp(value, "0") != 0) {
mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
} else {
mAudioStreamType = AUDIO_STREAM_MUSIC;
}
}
1. 这里的hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t **)&mModule)
调用了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);
- }
- const char *id ------- 应该是module name
- const struct hw_module_t **module -----应该是module模块地址。
- int hw_get_module_by_class(const char *class_id, const char *inst,
- const struct hw_module_t **module)
- {
- int status;
- int i;
- const struct hw_module_t *hmi = NULL;
- char prop[PATH_MAX];
- char path[PATH_MAX];
- char name[PATH_MAX];
- if (inst)
- snprintf(name, PATH_MAX, "%s.%s", class_id, inst); // 这里class_id 是camera,inst 应该是medfield,
- else
- strlcpy(name, class_id, PATH_MAX);
- /*
- * Here we rely on the fact that calling dlopen multiple times on
- * the same .so will simply increment a refcount (and not load
- * a new copy of the library).
- * We also assume that dlopen() is thread-safe.
- */
- /* Loop through the configuration variants looking for a module */
- for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
- if (i < HAL_VARIANT_KEYS_COUNT) {
- if (property_get(variant_keys[i], prop, NULL) == 0) {
- continue;
- }
- snprintf(path, sizeof(path), "%s/%s.%s.so",
- HAL_LIBRARY_PATH2, name, prop);
- if (access(path, R_OK) == 0) break;
- snprintf(path, sizeof(path), "%s/%s.%s.so",
- HAL_LIBRARY_PATH1, name, prop);
- if (access(path, R_OK) == 0) break;
- } else {
- snprintf(path, sizeof(path), "%s/%s.default.so",
- HAL_LIBRARY_PATH1, name);
- if (access(path, R_OK) == 0) break;
- }
- }
- status = -ENOENT;
- if (i < HAL_VARIANT_KEYS_COUNT+1) {
- /* load the module, if this fails, we're doomed, and we should not try
- * to load a different variant. */
- status = load(class_id, path, module);
- }
- return status;
- }
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
const char *id ------- 应该是module name
const struct hw_module_t **module -----应该是module模块地址。
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
int status;
int i;
const struct hw_module_t *hmi = NULL;
char prop[PATH_MAX];
char path[PATH_MAX];
char name[PATH_MAX];
if (inst)
snprintf(name, PATH_MAX, "%s.%s", class_id, inst); // 这里class_id 是camera,inst 应该是medfield,
else
strlcpy(name, class_id, PATH_MAX);
/*
* Here we rely on the fact that calling dlopen multiple times on
* the same .so will simply increment a refcount (and not load
* a new copy of the library).
* We also assume that dlopen() is thread-safe.
*/
/* Loop through the configuration variants looking for a module */
for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
if (i < HAL_VARIANT_KEYS_COUNT) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH2, name, prop);
if (access(path, R_OK) == 0) break;
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH1, name, prop);
if (access(path, R_OK) == 0) break;
} else {
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH1, name);
if (access(path, R_OK) == 0) break;
}
}
status = -ENOENT;
if (i < HAL_VARIANT_KEYS_COUNT+1) {
/* load the module, if this fails, we're doomed, and we should not try
* to load a different variant. */
status = load(class_id, path, module);
}
return status;
}
load(class_id, path, module) 代码如下:- /**
- * Load the file defined by the variant and if successful
- * return the dlopen handle and the hmi.
- * @return 0 = success, !0 = failure.
- */
- static int load(const char *id,
- const char *path,
- const struct hw_module_t **pHmi)
- {
- int status;
- void *handle;
- struct hw_module_t *hmi;
- /*
- * load the symbols resolving undefined symbols before
- * dlopen returns. Since RTLD_GLOBAL is not or'd in with
- * RTLD_NOW the external symbols will not be global
- */
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL) {
- char const *err_str = dlerror();
- LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
- status = -EINVAL;
- goto done;
- }
- /* Get the address of the struct hal_module_info. */
- const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
- hmi = (struct hw_module_t *)dlsym(handle, sym);
- if (hmi == NULL) {
- LOGE("load: couldn't find symbol %s", sym);
- status = -EINVAL;
- goto done;
- }
- /* Check that the id matches */
- if (strcmp(id, hmi->id) != 0) {
- LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
- status = -EINVAL;
- goto done;
- }
- hmi->dso = handle;
- /* success */
- status = 0;
- done:
- if (status != 0) {
- hmi = NULL;
- if (handle != NULL) {
- dlclose(handle);
- handle = NULL;
- }
- } else {
- LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
- id, path, *pHmi, handle);
- }
- *pHmi = hmi;
- return status;
- }
/**
* Load the file defined by the variant and if successful
* return the dlopen handle and the hmi.
* @return 0 = success, !0 = failure.
*/
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
int status;
void *handle;
struct hw_module_t *hmi;
/*
* load the symbols resolving undefined symbols before
* dlopen returns. Since RTLD_GLOBAL is not or'd in with
* RTLD_NOW the external symbols will not be global
*/
handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
char const *err_str = dlerror();
LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
status = -EINVAL;
goto done;
}
/* Get the address of the struct hal_module_info. */
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
if (hmi == NULL) {
LOGE("load: couldn't find symbol %s", sym);
status = -EINVAL;
goto done;
}
/* Check that the id matches */
if (strcmp(id, hmi->id) != 0) {
LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
status = -EINVAL;
goto done;
}
hmi->dso = handle;
/* success */
status = 0;
done:
if (status != 0) {
hmi = NULL;
if (handle != NULL) {
dlclose(handle);
handle = NULL;
}
} else {
LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
id, path, *pHmi, handle);
}
*pHmi = hmi;
return status;
}
2. mNumberOfCameras = mModule->get_number_of_cameras();调用了 hardware/intel/libcamera/IntelCameraHAL.cpp 中的
- camera_module_t HAL_MODULE_INFO_SYM = {
- common: {
- tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: CAMERA_HARDWARE_MODULE_ID,
- name: "Intel CameraHardware Module",
- author: "Intel",
- methods: &camera_module_methods, //这里面定义了各种函数接口。
- dso: NULL, /* remove compilation warnings */
- reserved: {0}, /* remove compilation warnings */
- },
- get_number_of_cameras: HAL_GetNumberOfCameras, //cameraservice 中会调用这两个函数。
- get_camera_info: HAL_GetCameraInfo,
- };
camera_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
version_minor: 0,
id: CAMERA_HARDWARE_MODULE_ID,
name: "Intel CameraHardware Module",
author: "Intel",
methods: &camera_module_methods, //这里面定义了各种函数接口。
dso: NULL, /* remove compilation warnings */
reserved: {0}, /* remove compilation warnings */
},
get_number_of_cameras: HAL_GetNumberOfCameras, //cameraservice 中会调用这两个函数。
get_camera_info: HAL_GetCameraInfo,
};
a.
get_number_of_cameras: HAL_GetNumberOfCameras,- int HAL_GetNumberOfCameras(void)
- {
- return android::CameraHardware::getNumberOfCameras();
- }
- /* This function will be called when the camera service is created.
- * Do some init work in this function.
- */
- int CameraHardware::getNumberOfCameras()
- {
- LogEntry(LOG_TAG, __FUNCTION__);
- if (num_cameras != 0)
- return num_cameras;
- int ret;
- struct v4l2_input input;
- int fd = -1;
- char *dev_name = "/dev/video0";
- fd = open(dev_name, O_RDWR);
- if (fd <= 0) {
- LogError("Error opening video device %s: %s",
- dev_name, strerror(errno));
- return 0;
- }
- int i;
- for (i = 0; i < MAX_CAMERAS; i++) {
- memset(&input, 0, sizeof(input));
- input.index = i;
- ret = ioctl(fd, VIDIOC_ENUMINPUT, &input); //从kernel 获得相应信息,枚举input通道信息。
- if (ret < 0) {
- break;
- }
- camInfo[i].port = input.reserved[1];
- strncpy(camInfo[i].name, (const char *)input.name, MAX_SENSOR_NAME_LENGTH);
- }
- close(fd);
- num_cameras = i;
- return num_cameras;
- }
int HAL_GetNumberOfCameras(void)
{
return android::CameraHardware::getNumberOfCameras();
}
/* This function will be called when the camera service is created.
* Do some init work in this function.
*/
int CameraHardware::getNumberOfCameras()
{
LogEntry(LOG_TAG, __FUNCTION__);
if (num_cameras != 0)
return num_cameras;
int ret;
struct v4l2_input input;
int fd = -1;
char *dev_name = "/dev/video0";
fd = open(dev_name, O_RDWR);
if (fd <= 0) {
LogError("Error opening video device %s: %s",
dev_name, strerror(errno));
return 0;
}
int i;
for (i = 0; i < MAX_CAMERAS; i++) {
memset(&input, 0, sizeof(input));
input.index = i;
ret = ioctl(fd, VIDIOC_ENUMINPUT, &input); //从kernel 获得相应信息,枚举input通道信息。
if (ret < 0) {
break;
}
camInfo[i].port = input.reserved[1];
strncpy(camInfo[i].name, (const char *)input.name, MAX_SENSOR_NAME_LENGTH);
}
close(fd);
num_cameras = i;
return num_cameras;
}
b.
get_camera_info: HAL_GetCameraInfo,
- int HAL_GetCameraInfo(int camera_id, struct camera_info *info)
- {
- return android::CameraHardware::getCameraInfo(camera_id, info);
- }
- int CameraHardware::getCameraInfo(int cameraId, struct camera_info* cameraInfo)
- {
- LogEntry(LOG_TAG, __FUNCTION__);
- if (cameraId >= MAX_CAMERAS)
- return -EINVAL;
- memcpy(cameraInfo, &HAL_cameraInfo[cameraId], sizeof(camera_info)); //从HAL_cameraInfo[cameraId] 中获得信息。
- return 0;
- }
int HAL_GetCameraInfo(int camera_id, struct camera_info *info)
{
return android::CameraHardware::getCameraInfo(camera_id, info);
}
int CameraHardware::getCameraInfo(int cameraId, struct camera_info* cameraInfo)
{
LogEntry(LOG_TAG, __FUNCTION__);
if (cameraId >= MAX_CAMERAS)
return -EINVAL;
memcpy(cameraInfo, &HAL_cameraInfo[cameraId], sizeof(camera_info)); //从HAL_cameraInfo[cameraId] 中获得信息。
return 0;
}
HAL_cameraInfo[cameraId] 定义如下:- static camera_info HAL_cameraInfo[MAX_CAMERAS] = {
- {
- CAMERA_FACING_FRONT,
- 180,
- },
- {
- CAMERA_FACING_BACK,
- 0,
- }
- };
static camera_info HAL_cameraInfo[MAX_CAMERAS] = {
{
CAMERA_FACING_FRONT,
180,
},
{
CAMERA_FACING_BACK,
0,
}
};
c.
methods: &camera_module_methods, //这里面定义了各种函数接口。
- static struct hw_module_methods_t camera_module_methods = {
- open: HAL_OpenCameraHardware // 也就是这个函数
- };
- open: HAL_OpenCameraHardware,
- int HAL_OpenCameraHardware(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- int rv = 0;
- int num_cameras = 0;
- int cameraid;
- intel_camera_device_t* camera_device = NULL;
- camera_device_ops_t* camera_ops = NULL;
- android::CameraHardware* camera = NULL;
- android::Mutex::Autolock lock(gCameraHalDeviceLock);
- LOGI("camera_device open");
- if (name != NULL) {
- cameraid = atoi(name);
- num_cameras = android::CameraHardware::getNumberOfCameras();
- if(cameraid > num_cameras)
- {
- LOGE("camera service provided cameraid out of bounds, "
- "cameraid = %d, num supported = %d",
- cameraid, num_cameras);
- rv = -EINVAL;
- goto fail;
- }
- if(gCamerasOpen >= MAX_CAMERAS)
- {
- LOGE("maximum number of cameras already open");
- rv = -ENOMEM;
- goto fail;
- }
- camera_device = (intel_camera_device_t*)malloc(sizeof(*camera_device));
- if(!camera_device)
- {
- LOGE("camera_device allocation fail");
- rv = -ENOMEM;
- goto fail;
- }
- camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
- if(!camera_ops)
- {
- LOGE("camera_ops allocation fail");
- rv = -ENOMEM;
- goto fail;
- }
- memset(camera_device, 0, sizeof(*camera_device));
- memset(camera_ops, 0, sizeof(*camera_ops));
- camera_device->device.common.tag = HARDWARE_DEVICE_TAG;
- camera_device->device.common.version = 0;
- camera_device->device.common.module = (hw_module_t *)(module);
- camera_device->device.common.close = HAL_CloseCameraHardware;
- camera_device->device.ops = camera_ops;
- camera_ops->set_preview_window = camera_set_preview_window;
- camera_ops->set_callbacks = camera_set_callbacks;
- camera_ops->enable_msg_type = camera_enable_msg_type;
- camera_ops->disable_msg_type = camera_disable_msg_type;
- camera_ops->msg_type_enabled = camera_msg_type_enabled;
- camera_ops->start_preview = camera_start_preview;
- camera_ops->stop_preview = camera_stop_preview;
- camera_ops->preview_enabled = camera_preview_enabled;
- camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
- camera_ops->start_recording = camera_start_recording;
- camera_ops->stop_recording = camera_stop_recording;
- camera_ops->recording_enabled = camera_recording_enabled;
- camera_ops->release_recording_frame = camera_release_recording_frame;
- camera_ops->auto_focus = camera_auto_focus;
- camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
- camera_ops->take_picture = camera_take_picture;
- camera_ops->cancel_picture = camera_cancel_picture;
- camera_ops->set_parameters = camera_set_parameters;
- camera_ops->get_parameters = camera_get_parameters;
- camera_ops->put_parameters = camera_put_parameters;
- camera_ops->send_command = camera_send_command;
- camera_ops->release = camera_release;
- camera_ops->dump = camera_dump;
- *device = &camera_device->device.common;
- camera_device->cameraId = cameraid;
- camera = new android::CameraHardware(cameraid);
- if(!camera)
- {
- LOGE("Couldn't create instance of CameraHardware class!");
- rv = -ENOMEM;
- goto fail;
- }
- gCameraHals[cameraid] = camera;
- gCamerasOpen++;
- }
- return rv;
- fail:
- if(camera_device) {
- free(camera_device);
- camera_device = NULL;
- }
- if(camera_ops) {
- free(camera_ops);
- camera_ops = NULL;
- }
- if(camera) {
- delete camera;
- camera = NULL;
- }
- *device = NULL;
- return rv;
- }
static struct hw_module_methods_t camera_module_methods = {
open: HAL_OpenCameraHardware // 也就是这个函数
};
open: HAL_OpenCameraHardware,
int HAL_OpenCameraHardware(const hw_module_t* module, const char* name,
hw_device_t** device)
{
int rv = 0;
int num_cameras = 0;
int cameraid;
intel_camera_device_t* camera_device = NULL;
camera_device_ops_t* camera_ops = NULL;
android::CameraHardware* camera = NULL;
android::Mutex::Autolock lock(gCameraHalDeviceLock);
LOGI("camera_device open");
if (name != NULL) {
cameraid = atoi(name);
num_cameras = android::CameraHardware::getNumberOfCameras();
if(cameraid > num_cameras)
{
LOGE("camera service provided cameraid out of bounds, "
"cameraid = %d, num supported = %d",
cameraid, num_cameras);
rv = -EINVAL;
goto fail;
}
if(gCamerasOpen >= MAX_CAMERAS)
{
LOGE("maximum number of cameras already open");
rv = -ENOMEM;
goto fail;
}
camera_device = (intel_camera_device_t*)malloc(sizeof(*camera_device));
if(!camera_device)
{
LOGE("camera_device allocation fail");
rv = -ENOMEM;
goto fail;
}
camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
if(!camera_ops)
{
LOGE("camera_ops allocation fail");
rv = -ENOMEM;
goto fail;
}
memset(camera_device, 0, sizeof(*camera_device));
memset(camera_ops, 0, sizeof(*camera_ops));
camera_device->device.common.tag = HARDWARE_DEVICE_TAG;
camera_device->device.common.version = 0;
camera_device->device.common.module = (hw_module_t *)(module);
camera_device->device.common.close = HAL_CloseCameraHardware;
camera_device->device.ops = camera_ops;
camera_ops->set_preview_window = camera_set_preview_window;
camera_ops->set_callbacks = camera_set_callbacks;
camera_ops->enable_msg_type = camera_enable_msg_type;
camera_ops->disable_msg_type = camera_disable_msg_type;
camera_ops->msg_type_enabled = camera_msg_type_enabled;
camera_ops->start_preview = camera_start_preview;
camera_ops->stop_preview = camera_stop_preview;
camera_ops->preview_enabled = camera_preview_enabled;
camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
camera_ops->start_recording = camera_start_recording;
camera_ops->stop_recording = camera_stop_recording;
camera_ops->recording_enabled = camera_recording_enabled;
camera_ops->release_recording_frame = camera_release_recording_frame;
camera_ops->auto_focus = camera_auto_focus;
camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
camera_ops->take_picture = camera_take_picture;
camera_ops->cancel_picture = camera_cancel_picture;
camera_ops->set_parameters = camera_set_parameters;
camera_ops->get_parameters = camera_get_parameters;
camera_ops->put_parameters = camera_put_parameters;
camera_ops->send_command = camera_send_command;
camera_ops->release = camera_release;
camera_ops->dump = camera_dump;
*device = &camera_device->device.common;
camera_device->cameraId = cameraid;
camera = new android::CameraHardware(cameraid);
if(!camera)
{
LOGE("Couldn't create instance of CameraHardware class!");
rv = -ENOMEM;
goto fail;
}
gCameraHals[cameraid] = camera;
gCamerasOpen++;
}
return rv;
fail:
if(camera_device) {
free(camera_device);
camera_device = NULL;
}
if(camera_ops) {
free(camera_ops);
camera_ops = NULL;
}
if(camera) {
delete camera;
camera = NULL;
}
*device = NULL;
return rv;
}
这个函数里 封装了一系列 camera interface。 但是cameraservice 并没有用到这些接口,还是老的调用方式,直接调用了 camerahardware, 而没经过这里的接口。只有 HAL_GetCameraInfo 和 HAL_GetNumberOfCameras 通过这些接口来调用。