Android Camera从Camera HAL1到Camera HAL3的过渡(已更新到Android6.0 HAL3.3)

2023-10-24 23:34

本文主要是介绍Android Camera从Camera HAL1到Camera HAL3的过渡(已更新到Android6.0 HAL3.3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. Android系统中Camera模块版本号的历史演变进度

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * All module versions <= HARDWARE_MODULE_API_VERSION(1, 0xFF) must be treated 
  3.  * as CAMERA_MODULE_API_VERSION_1_0 
  4.  */  
  5. #define CAMERA_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)  
  6. #define CAMERA_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0)  
  7. #define CAMERA_MODULE_API_VERSION_2_1 HARDWARE_MODULE_API_VERSION(2, 1)  
  8. #define CAMERA_MODULE_API_VERSION_2_2 HARDWARE_MODULE_API_VERSION(2, 2)  
  9. #define CAMERA_MODULE_API_VERSION_2_3 HARDWARE_MODULE_API_VERSION(2, 3)  
  10.   
  11. #define CAMERA_MODULE_API_VERSION_CURRENT CAMERA_MODULE_API_VERSION_2_3  
  12.   
  13. /** 
  14.  * All device versions <= HARDWARE_DEVICE_API_VERSION(1, 0xFF) must be treated 
  15.  * as CAMERA_DEVICE_API_VERSION_1_0 
  16.  */  
  17. #define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)  
  18. #define CAMERA_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0)  
  19. #define CAMERA_DEVICE_API_VERSION_2_1 HARDWARE_DEVICE_API_VERSION(2, 1)  
  20. #define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)  
  21. #define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)  
  22. #define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)  
  23.   
  24. // Device version 3.2 is current, older HAL camera device versions are not  
  25. // recommended for new devices.  
  26. #define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_2  
从上述对Camera版本的定义可知,Android将整个camera模块划分为module和device两个部分,前者拥有对后者的控制权,而后者直接就是代表的camera hal接口的实现。

对于Module API的区别主要在于2.1之后增加了set_callbacks接口,用于HAL检测当前module的工作状态,低版本的module不需要实现。

此外对于Module API版本号高于2.2时可支持get_vendor_tag_ops,Framework调用后课获取对厂商自己扩展定义的tag ops,便于操作厂商自己私有定义的camera所需的metadata信息,同理低版本的module不需要去实现该接口。

此外对于Module API 为2.3的版本增加了open_legacy接口:

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int (*open_legacy)(const struct hw_module_t* module, const char* id,  
  2.         uint32_t halVersion, struct hw_device_t** device);  

他描述的是可以根据自己所选的device version,比如对于一个camera hal他支持并实现了CAMERA_DEVICE_API_VERSION_1_0和CAMERA_DEVICE_API_VERSION_3_2两种版本下的hal接口的实现,只有module api定义的是2.3的版本的话,在Framework中就可以通过对open_legacy()来指定hal_version,从而获取不同版本下的hal device的实现接口即hw_device_t。但目前来看,Android提供了该接口,却在Framework层都没有给出直接的调用,此外可见的hal module api2.3的版本,也都不会去实现该接口。说明hw_module_t所属的open目前依旧还是获取对camera device控制权的唯一路径与方法,也许对于一个camera device而言实现一种版本的接口就已经够用和麻烦的了。


2 Camera Client

    关于CameraService相关的内容可以参考博文Android4.2.2 CameraService服务启动和应用端camera初始化记录来梳理整个Camera.so模块的加载与处理过程。每一个应用端的camera在connect到CameraService处会以一个Camera Client形式存在,该类继承并实现CameraService::Client的一个内部类,通过匿名的Binder服务与应用端进行交互。在CamerService启动并建立的时候,就会自动加载一个camera.xxx.so的模块,提取module相关的handle。

每当connect时,CameraService会执行一个getDeviceVersion的函数:

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int CameraService::getDeviceVersion(int cameraId, int* facing) {  
  2.     struct camera_info info;  
  3.     if (mModule->get_camera_info(cameraId, &info) != OK) {  
  4.         return -1;  
  5.     }  
  6.   
  7.     int deviceVersion;  
  8.     if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {  
  9.         deviceVersion = info.device_version;  
  10.     } else {  
  11.         deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;  
  12.     }  
  13.   
  14.     if (facing) {  
  15.         *facing = info.facing;  
  16.     }  
  17.   
  18.     return deviceVersion;  
  19. }  
即对于那些module_api_version小于2.0的版本,即所谓的1.0版本外,其他module对应的device 版本号,由HAL自行决定,决定权通过get_camera_info来获取hal支持的camera_info相关信息,其中包括device_version。1.0版本的module直接默认的device_verison则为1.0版本。
[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. case CAMERA_DEVICE_API_VERSION_1_0:  
  2.        client = new CameraClient(this, cameraClient,  
  3.                clientPackageName, cameraId,  
  4.                facing, callingPid, clientUid, getpid(), legacyMode);  
  5.        break;  
  6.      case CAMERA_DEVICE_API_VERSION_2_0:  
  7.      case CAMERA_DEVICE_API_VERSION_2_1:  
  8.      case CAMERA_DEVICE_API_VERSION_3_0:  
  9.      case CAMERA_DEVICE_API_VERSION_3_1:  
  10.      case CAMERA_DEVICE_API_VERSION_3_2:  
  11.        client = new Camera2Client(this, cameraClient,  
  12.                clientPackageName, cameraId,  
  13.                facing, callingPid, clientUid, getpid(), legacyMode);//CameraService端新建Camera2Client  
  14.        break;  
通过上述的代码逻辑可知,对于Camera Client的升级,由底层Device API Version来决定。很明显可以知道,目前1.0的device api以CameraClient的形式存在,而2.0以上的版本则均以Camera2Client的形式存在。 

对于Camera模块不同版本的DEVICE_API来说,其区别本质上就是在HAL所需要实现的接口不同,分别由以下三个版本的device接口:

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct camera_device {  
  2.     /** 
  3.      * camera_device.common.version must be in the range 
  4.      * HARDWARE_DEVICE_API_VERSION(0,0)-(1,FF). CAMERA_DEVICE_API_VERSION_1_0 is 
  5.      * recommended. 
  6.      */  
  7.     hw_device_t common;  
  8.     camera_device_ops_t *ops;  
  9.     void *priv;  
  10. } camera_device_t;  
对应的是1.0的DEVICE_API,目前低版本的Android系统中以该方式来实现的较多。


[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct camera2_device {  
  2.     /** 
  3.      * common.version must equal CAMERA_DEVICE_API_VERSION_2_0 to identify 
  4.      * this device as implementing version 2.0 of the camera device HAL. 
  5.      */  
  6.     hw_device_t common;  
  7.     camera2_device_ops_t *ops;  
  8.     void *priv;  
  9. } camera2_device_t;  
2.0版本的ops目前主流的IC厂商实现的较少。


[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct camera3_device {  
  2.     /** 
  3.      * common.version must equal CAMERA_DEVICE_API_VERSION_3_0 to identify this 
  4.      * device as implementing version 3.0 of the camera device HAL. 
  5.      * 
  6.      * Performance requirements: 
  7.      * 
  8.      * Camera open (common.module->common.methods->open) should return in 200ms, and must return 
  9.      * in 500ms. 
  10.      * Camera close (common.close) should return in 200ms, and must return in 500ms. 
  11.      * 
  12.      */  
  13.     hw_device_t common;  
  14.     camera3_device_ops_t *ops;  
  15.     void *priv;  
  16. } camera3_device_t;  
对于3.0而言,也就是所谓的HAL3.0就体现在这里,当下可见的只有高通、三星等有对该种接口形式进行了实现。

本质上来说,三个不同的版本都进行了全盘的升级,则重点则是归于在HAL中按照Google在Framework层定义的camerax_device_ops来实现该种接口,相关接口的实现形式在分析高通的HAL架构时再去分析。


3 Camera device

对于三个不同版本的hal层接口,在Camera的Framework中实现的过程略有不同,可以分为device1、device2、device3。

对于1.0版本的Device API,在创建CameraClient时,是以CameraHardwareInterface(可以认为是Camera Device1)来维护队整个对HAL层中Camera Device的控制权,即 camera_device_t归CameraHardwareInterface来调用。


对于2.0以上版本的Device API时,在创建Camera2Client时,会通过CameraDeviceFactory::createDevice来创建相应的Camera Device

[cpp] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. sp<CameraDeviceBase> CameraDeviceFactory::createDevice(int cameraId) {  
  2.   
  3.     sp<CameraService> svc = sService.promote();  
  4.     if (svc == 0) {  
  5.         ALOGE("%s: No service registered", __FUNCTION__);  
  6.         return NULL;  
  7.     }  
  8.   
  9.     int deviceVersion = svc->getDeviceVersion(cameraId, /*facing*/NULL);  
  10.   
  11.     sp<CameraDeviceBase> device;  
  12.   
  13.     switch (deviceVersion) {  
  14.         case CAMERA_DEVICE_API_VERSION_2_0:  
  15.         case CAMERA_DEVICE_API_VERSION_2_1:  
  16.             device = new Camera2Device(cameraId);  
  17.             break;  
  18.         case CAMERA_DEVICE_API_VERSION_3_0:  
  19.         case CAMERA_DEVICE_API_VERSION_3_1:  
  20.         case CAMERA_DEVICE_API_VERSION_3_2:  
  21.             device = new Camera3Device(cameraId);  
  22.             break;  
  23.         default:  
  24.             ALOGE("%s: Camera %d: Unknown HAL device version %d",  
  25.                   __FUNCTION__, cameraId, deviceVersion);  
  26.             device = NULL;  
  27.             break;  
  28.     }  
  29.   
  30.     ALOGV_IF(device != 0, "Created a new camera device for version %d",  
  31.                           deviceVersion);  
  32.   
  33.     return device;  
  34. }  
可以看到对于Camera2Client而言,对Device API2.0、2.1的版本通过Camera2Device来实现对底层device的控制,对3.0以上的版本通过Camera3Device来实现,前者可以说是调用的是Camera HAL2.0相关的camera2_device_t的接口,后者调用的是Camera HAL3.0相关的camera3_device_t的接口,当然重点就是两者内部实现的形式不同,3.0版本的处理也更显的复杂。 其中Camera Device API2.0的版本从Android4.2开始发布,而API3更多的是对前者的升级与换代而已在4.4.2的版本中科院看到。


4.小结

Camera不断的过渡,也算是Android系统源码中,变化较大的一个部分了,虽然Framework层核心的CameraService、Camera等的实现逻辑都没有发生很大的变化,但和底层HAL的交互却有着质的变异。而目前主流的IC厂商都在朝着Camera HAL3.0的方向进行发展,所有有必要对3.0实现的原理与本质进行探究与学习。


附图:camera在Android Framework层中的变迁



Camera HAL1.0 在Android4.0 ICE开始;
Camera HAL2.0、HAL3.0在Android4.2/4.3 JB版本开始支持;
Camera HAL3.1 在Androiod4.4 KitKat开始Support;
Camera HAL3.2 在Android5.0 L 开始支持;

Camera API2在Android5.0 L开始支持,并逐步deprecate Camera API1。


Android几个版本下camera_common.h的文档集:
Android4.0
# define  CAMERA_DEVICE_API_VERSION_1_0  HARDWARE_DEVICE_API_VERSION( 1, 0)

Android4.2
# define  CAMERA_DEVICE_API_VERSION_1_0  HARDWARE_DEVICE_API_VERSION( 1, 0)
# define  CAMERA_DEVICE_API_VERSION_2_0  HARDWARE_DEVICE_API_VERSION( 2, 0)

Android4.3
# define  CAMERA_DEVICE_API_VERSION_1_0  HARDWARE_DEVICE_API_VERSION( 1, 0)
# define  CAMERA_DEVICE_API_VERSION_2_0  HARDWARE_DEVICE_API_VERSION( 2, 0)
# define  CAMERA_DEVICE_API_VERSION_2_1  HARDWARE_DEVICE_API_VERSION( 21)
# define  CAMERA_DEVICE_API_VERSION_3_0  HARDWARE_DEVICE_API_VERSION( 3, 0)

Android4.4
98# define  CAMERA_DEVICE_API_VERSION_1_0  HARDWARE_DEVICE_API_VERSION( 1, 0)
99# define  CAMERA_DEVICE_API_VERSION_2_0  HARDWARE_DEVICE_API_VERSION( 2, 0)
100# define  CAMERA_DEVICE_API_VERSION_2_1  HARDWARE_DEVICE_API_VERSION( 21)
101# define  CAMERA_DEVICE_API_VERSION_3_0  HARDWARE_DEVICE_API_VERSION( 3, 0)
102# define  CAMERA_DEVICE_API_VERSION_3_1  HARDWARE_DEVICE_API_VERSION( 31)


Android5.0
#define CAMERA_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0)
#define CAMERA_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0)
#define CAMERA_DEVICE_API_VERSION_2_1 HARDWARE_DEVICE_API_VERSION(2, 1)
#define CAMERA_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0)
#define CAMERA_DEVICE_API_VERSION_3_1 HARDWARE_DEVICE_API_VERSION(3, 1)
#define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2)

Android6.0
#define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3)

这篇关于Android Camera从Camera HAL1到Camera HAL3的过渡(已更新到Android6.0 HAL3.3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

Android WebView的加载超时处理方案

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

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/