Android Camera FW到Camera Hal调用流程

2024-01-24 18:32
文章标签 android 流程 调用 hal camera fw

本文主要是介绍Android Camera FW到Camera Hal调用流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.       首先是调用framework层的Camera.java(frameworks\base\core\java\android\hardware)的takePicture方法
2.       接着会调用到JNI层的android_hardware_Camera.cpp(frameworks\base\core\jni)的android_hardware_Camera_takePicture方法,其中会通过get_native_camera获取一个Camera对象。
3.       上述Camera对象的定义在Camera.h(frameworks\av\include\camera),camera.h同时定义了CameraInfo。Camera对象继承自publicBnCameraClient,DeathRecipient。Camera对象的真正实现是在Camera.cpp(frameworks\av\camera)   。BnCameraClient是作为CameraService回调而存在的。Camera对象内含有一个mCameraService变量用于保存CameraService引用。
class Camera : public BnCameraClient,public IBinder::DeathRecipient
constsp<ICameraService>& Camera::getCameraService()
{Mutex::Autolock _l(mLock);if (mCameraService.get() == 0) {sp<IServiceManager> sm = defaultServiceManager();sp<IBinder> binder;do {binder =sm->getService(String16("media.camera"));if (binder != 0)break;ALOGW("CameraService notpublished, waiting...");usleep(500000); // 0.5 s} while(true);if (mDeathNotifier == NULL) {mDeathNotifier = newDeathNotifier();}binder->linkToDeath(mDeathNotifier);mCameraService =interface_cast<ICameraService>(binder);}

4.       在ICameraClient.h和ICameraService.h文件中,ICameraClient和ICameraService都继承自IInterface,也就是Binder通信的基础,此外ICamera.h也继承自IInterface
class ICameraClient:public IInterface
class ICameraService :public IInterface
class ICamera: publicIInterface
然后发现BnCameraClient继承自BnInterface<ICameraClient>,作为ICameraClient的服务器端存在:
class BnCameraClient: publicBnInterface<ICameraClient>
BnCameraService继承自BnInterface<ICameraService>,作为ICameraService的服务器端存在:
class BnCameraService: publicBnInterface<ICameraService>
BnCamera继承自BnInterface<ICamera>,作为ICamera的服务器端存在:
class BnCamera: public BnInterface<ICamera>
对应的上述三个分别存在一个作为Binder客户端的类存在,为Bp***:
class BpCameraClient:public BpInterface<ICameraClient>
class BpCameraService:public BpInterface<ICameraService>
class BpCamera: publicBpInterface<ICamera>
上述三个的实现分别在ICameraClient.cpp、ICameraService.cpp、ICamera.cpp,在这三支文件中分别实现了三组Binder的Server端和Client端,Camera常用的方法都在ICamera中实现。
5.       Camera.cpp文件connect方法在JNI层去setupCamera的时候会调用,JNI层是在上层opencamera的时候被调用的,在camera.cpp的connect方法中获取一个ICamera对象来完成对Camera的真正操作。
sp<Camera>Camera::connect(int cameraId)
{ALOGV("connect");sp<Camera> c = new Camera();const sp<ICameraService>& cs =getCameraService();if (cs != 0) {c->mCamera = cs->connect(c, cameraId);}if (c->mCamera != 0) {c->mCamera->asBinder()->linkToDeath(c);c->mStatus = NO_ERROR;} else {c.clear();}return c;
}

6.       在CameraService.h文件中可以看到CameraService定义内部类Client,CameraClient继承此类,在CameraService中持有对mClient对象的一个数组,这个数组也是Camera.cpp客户端调用connect方法后需要返回的Binder引用对象
class Client : public BnCamera
class CameraClient : public CameraService::Client
wp<Client>         mClient[MAX_CAMERAS];switch(deviceVersion) {case CAMERA_DEVICE_API_VERSION_1_0:client = new CameraClient(this,cameraClient, cameraId,info.facing, callingPid, getpid());break;case CAMERA_DEVICE_API_VERSION_2_0:client = new Camera2Client(this,cameraClient, cameraId,info.facing, callingPid,getpid());

并且Google好像有开发新的API2.0,在此处通过判断不同的version实例化不同的CameraClient的Binder引用对象回去,目前Camera2文件夹有Burst等实现

7.       在CameraService层的CameraClient对象的定义中,持有CameraHardwareInterface对象的引用mHardware.在CameraClient的initilize方法中会创建此对象,在对象的构造方法中传入需要打开的Camera的ID。
sp<CameraHardwareInterface>     mHardware;
status_t CameraClient::initialize(camera_module_t *module) {int callingPid = getCallingPid();LOG1("CameraClient::initialize E (pid%d, id %d)", callingPid, mCameraId);char camera_device_name[10];status_t res;snprintf(camera_device_name, sizeof(camera_device_name),"%d", mCameraId);mHardware = new CameraHardwareInterface(camera_device_name);res = mHardware->initialize(&module->common);if (res != OK) {ALOGE("%s: Camera %d: unable toinitialize device: %s (%d)",__FUNCTION__, mCameraId,strerror(-res), res);mHardware.clear();return NO_INIT;}mHardware->setCallbacks(notifyCallback,dataCallback,dataCallbackTimestamp,(void*)mCameraId);//Enable zoom, error, focus, and metadata messages by defaultenableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
//!++
#ifdef  MTK_CAMERA_BSP_SUPPORT// Enable MTK-extended messages by defaultenableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY |MTK_CAMERA_MSG_EXT_DATA);
#endif
//!--LOG1("CameraClient::initialize X (pid%d, id %d)", callingPid, mCameraId);return OK;
}

8.       在CameraService的onFirstRef方法中,会加载CameraHal  Module

void CameraService:: onFirstRef()
{BnCameraService::onFirstRef();if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t**)&mModule) < 0) {ALOGE("Could not load camera HALmodule");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);}}
}

hw_get_module方法的实现在hardware/libhardware/Hardware.c文件中实现
int hw_get_module(constchar *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL,module);
}
Camera_module_t的结构体定义在camera_common.h文件中
typedef structcamera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id,struct camera_info *info);
} camera_module_t;
Hw_module_t的定义在hardware.h文件中,hw_module_t持有对hw_module_methods_t引用,其中有定义一个open指针
typedef structhw_module_methods_t {
/** Open a specific device */
int (*open)(const struct hw_module_t*module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
而加载CamDevice的操作是在CameraHardwareInterface的init方法中调用open
int rc =module->methods->open(module, mName.string(),
(hw_device_t **)&mDevice);


转载:http://www.2cto.com/kf/201303/196681.html

可参考:http://blog.163.com/shawpin@126/blog/static/116663752201092394147937/

这篇关于Android Camera FW到Camera Hal调用流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640601

相关文章

使用MongoDB进行数据存储的操作流程

《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

Idea调用WebService的关键步骤和注意事项

《Idea调用WebService的关键步骤和注意事项》:本文主要介绍如何在Idea中调用WebService,包括理解WebService的基本概念、获取WSDL文件、阅读和理解WSDL文件、选... 目录前言一、理解WebService的基本概念二、获取WSDL文件三、阅读和理解WSDL文件四、选择对接

Python实现NLP的完整流程介绍

《Python实现NLP的完整流程介绍》这篇文章主要为大家详细介绍了Python实现NLP的完整流程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 编程安装和导入必要的库2. 文本数据准备3. 文本预处理3.1 小写化3.2 分词(Tokenizatio

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Nginx、Tomcat等项目部署问题以及解决流程

《Nginx、Tomcat等项目部署问题以及解决流程》本文总结了项目部署中常见的four类问题及其解决方法:Nginx未按预期显示结果、端口未开启、日志分析的重要性以及开发环境与生产环境运行结果不一致... 目录前言1. Nginx部署后未按预期显示结果1.1 查看Nginx的启动情况1.2 解决启动失败的

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指