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;}}

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,elsestrlcpy(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;}

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,};

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;}

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;}

HAL_cameraInfo[cameraId] 定义如下:

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;}

这个函数里 封装了一系列 camera interface。 但是cameraservice 并没有用到这些接口,还是老的调用方式,直接调用了 camerahardware, 而没经过这里的接口。
只有 HAL_GetCameraInfoHAL_GetNumberOfCameras 通过这些接口来调用。

camera hardware module相关推荐

  1. 【SPRD CAMERA】1 HAL层初始化流程

    一.前言 根据我的理解以前android在启动camera service 会直接去操作hal层,这样hal层和framework就耦合在一起了.现在 Android O 中,加入了Camera Pr ...

  2. android_驱动_qcom_【高通SDM660平台】(4) --- Camera Init 初始化流程

    [高通SDM660平台]Camera Init 初始化流程 一.Camera 系统架构 二.Camera Init 初始化流程 2.1 CameraService 启动 2.2 CameraServi ...

  3. Android Camera 五 Camera HAL v1

    Android Camera 一 源码路径 Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析 Android Camera 三 CameraService 和 Cli ...

  4. Android R camera Hal启动(下)

    文章目录 前言 代码流程分析 总结 前言 接上一篇Android R camera Hal启动(上)接着写,把谷歌的代码都分析完成,高通/MTK的代码就不贴了. 代码流程分析 上一篇说到getProv ...

  5. 增加录像时间戳水印、 camera框架介绍

    最近项目上要在mtk6589机器上增加录像的水印功能,那个纠结呀--  一大通 度娘.google啊-- 最终整个变通的方案:做好10几个bmp(8位深度黑底白字)贴图,把文件使用ue去除掉bmp文件 ...

  6. note_2020_4

    摄像头的一些基础知识: 逆光是一种由于被摄主体恰好处于光源和照相机之间的状况,这种状况极易造成使被摄主体曝光不充分. 高通平台打开更多的camera相关log: adb root adb remoun ...

  7. android camera工程师,浅析Android Camera架构

    本博文是基于Android 4.4讲解 1.application 层: 当我们Android工程师想打开camera时通常直接调用Camera.java中的  Camer.open(cameraId ...

  8. Android Camera 通过V4L2与kernel driver的完整交互过程

    Android Camera 通过V4L2与kernel driver的完整交互过程 之前在  Android Camera 的执行流程   http://blog.chinaunix.net/uid ...

  9. Android源码之Camera系统架构

    2019独角兽企业重金招聘Python工程师标准>>> https://blog.csdn.net/ljsbuct/article/details/7094670 https://w ...

  10. qcom Android Camera【转】

    本文转载自:http://blog.csdn.net/Wilsonboliu/article/details/54949196 1.总体架构 Android Camera 框架从整体上看是一个 cli ...

最新文章

  1. SQL操作语句之查询及删除重复记录的方法
  2. 广义线性模型GLM、GLMM、LMM、MLM、GMM、GEE、广义线性模型GLM和广义线性混合模型的GLMM区别
  3. 构建DHCP及中继服务器
  4. jmx rmi 穿越防火墙问题及jmxmp的替代方案
  5. python 读取yml文件_Python 读取 yaml 配置文件 | 文艺数学君
  6. springMVC 统一异常处理异常处理类的使用
  7. Bad Request: amp;quot;requirement failed: Local path /root/.livy-sessions/
  8. Java中,为什么子类的构造方法中必须调父类的构造方法?
  9. ecq php,ecqx.sdgz.site网页GZIP压缩检测结果
  10. git clone --depth=1引起的问题
  11. Latex 爬过的坑(4)——Latex中插入Emoji
  12. hadoop面试题(全)
  13. 19春招多益网络前端笔试题
  14. 阙值,阈值,阀值,傻傻分不清
  15. 如何快速有效的发散思维?
  16. Jeff Atwood倾情推荐——程序员必读之书 (zz)
  17. 分数换算小数补0法_小学数学常用公式大全(单位换算表) 长度单位换算【建议收藏】...
  18. STM32按键设计一之扫描
  19. Caustics焦散
  20. 合唱队形(动态规划)

热门文章

  1. comsol光学模块案例
  2. 论文中的Matlab画图常用技巧
  3. 【收藏级教程】专业Finereport教程,帆软报表教程
  4. 信息论与编码2 BCH码的构造
  5. 2021最新微信漫画小程序全开源商业版:带漫画资源,带搭建教程,流量变现利器。附安装说明和源码。
  6. MySQL memo优化_mysql memo
  7. DS Storage Manager 忘记管理密码恢复
  8. 证明连续随机变量形式Jensen不等式
  9. tftp java_TFTP服务器搭建
  10. 35.伪造请求超时的ICMP数据包