当前位置: 首页 > news >正文

Android影像基础--cameraAPI2核心流程

作为影像从业者,花几期时间扒一扒高通和MTK影像系统的软件和硬件细节,现在是第二期。

无论是高通还是MTK主要是在HAL层以下,在安卓系统体系,frwk层及以上都是用的安卓基础框架的内容。

安卓影像的入门都不得不提的图像的核心数据和关键数据流程open、config、request/result、close。

感谢博友们的支持和鼓励,让我继续有动力写下去,没有白熬的夜。
在这里插入图片描述

一、综述

承接上一期,分享的是高通影像的软件框架的核心概念和camX框架以及分层接口。高通影像入门基础-软件影像框架CamX-CHI

本期继续上文往上层走一步,分享谷歌安卓影像的核心数据和流程以及实例,图像的数据包括码流数据和metadata数据,针对图像数据,基于Android Camera API2 相机功能实现的核心流程包括open、config、request、result、close。

对应应用工程师而言,使用JAVA调用API2实现相机类的应用开发,而影像系统工程师则完成API2的具体实现。

影像系统中的核心是处理图像数据,底层软件负责驱动,影像软件主要是关心图像数据的流转过程,算法负责其中具体的处理过程,app软件负责把UI交互,屏显负责图形显示,从而构成影像系统的软件完整流程。

在安卓影像框架中,影像的核心数据不变,谷歌把影像处理和核心流程抽离了出来,即解决了接口统一性问题,又为开发者降低了入门门槛。

二、影像核心数据

本期我们主要总结影像核心流程,核心数据流程使用影像的数据,无论是什么的影像平台,处理图像,我们都是把数据分为frame和metadata,frame是图像数据本身,metadata是图像属性的元数据。

2.1frame和stream

图像数据在图像处理链路的不同节点的名称可能会有变化。以常见frame和stream为例,

frame一般是指未压缩的图像数据(RAW/YUV/RGB),用于实时处理或显示,一般常被影像软件工程师的代码中使用;

stream一般指压缩后的二进制数据(H.265/JPEG),用于存储或传输,一般用于影像和其他模块交互中使用,但是stream有时候也被笼统的理解为图像码流数据。

图像数据流的流转,指从图像采集到最终输出的完整流水线中的数据流控制方式,这个在影像架构的驱动流程中根据产品特性不同会有所差异,常见的有有Push模式和Pull模式。

Push模式是指传感器或处理单元主动推送数据,下游模块编码器等被动接收并处理,常用于视频通话或者监控等;pull模式是指下游模块编码器按需请求数据,Sensor 或 ISP 仅在收到请求时才输出,适用于拍照模式等。

以手机产品为例,一般采用混合模式,根据不同场景动态切换。

2.2 metadata

图像metadata的流转在Android应用框架中的配置、数据的传递与获取,以及在不同组件间的作用。

metadata是一组名值对name-value pair,用于描述或附加关于应用程序、组件或其他数据的信息,用于信息存储、组件通信等。

它通常定义在AndroidManifest.xml文件中,为、、、、等不同组件提供附加数据项。

例如在图像码流链路中,metadata存储比如3A信息,可以把信息从底层HAL给到上层APP,甚至提供给三方相机app开发。

metadata的设计有利于代码的模块化和分层开发,一个服务可以通过读取metadata来获取另一个Service的配置信息。

metadata在框架内的流转发生在配置和运行两个阶段,

配置阶段在xml中写入默认的配置信息,在软件的配置流程中读取该信息,在运行阶段通过相应的api可以set和get这些加载到内存中的metadata信息。
在这里插入图片描述

三、关键数据流程

在Android Camera2的数据流中,stream流、session会话、request请求和result结果是核心概念,它们在相机数据的核心流程比如捕获、处理和传输过程中都起重要作用。

以相机HDR拍照流程为例:首先HDR 场景下发 3 帧拍照请求,从而获得3帧拍照请求帧,返回3帧 result callback帧,然后进行HDR 算法处理,之后送去算法编解码处理。

典型场景的大概流程如下:

预览+拍照:openconfig(预览流+拍照流)setRepeatingRequest(预览)capture(拍照)processResult(保存图片)close

视频录制:openconfig(录像流)setRepeatingRequest(录像)processResult(编码存储)close

3.1 open 打开相机

抽取打开相机一些关键的流程函数如下:

(1)应用层

应用层调用Android系统的Camera API来初始化相机。

比如使用Camera.open()CameraManageropenCamera()方法打开指定的相机设备。

(2)框架层调用JNI接口

框架层通过Binder IPC调用至CameraService,Camera服务CameraService.cpp是系统服务的一部分,通过系统调用Camera::connect()方法来建立与相机服务的连接。

当应用请求打开相机时,Camera服务根据HAL版本会创建对应Camera设备客户端CameraDeviceClient并初始化它,并通过Binder IPC将请求传递至HAL层。

(3)HAL层

当Camera服务请求打开相机时,高通CamX架构中,HAL3调用CamX::camxhal3.cpp中的open()方法,初始化相机硬件模块如传感器、ISP等。

HAL层会向下调用相应的硬件接口函数camera_device_open(),并最终会调用到具体的硬件驱动程序比如msm_open()来打开相机设备。

(4)驱动层

驱动程序包含控制相机硬件所需的代码和指令。open相机设备文件/dev/video0/dev/video2,并进行读写操作read()write()等。

启动阶段一些关键函数:

  • 权限检查:需动态申请android.permission.CAMERA权限。

  • HAL版本兼容:通过CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL检查设备是否支持API2特性(如FULL/LIMITED级别)。

  • 回调机制:通过CameraDevice.StateCallback监听相机状态(如onOpened()onError())。

  • 性能优化:通过CHIUSECASE::AcquirePerfLock()提升CPU频率,确保硬件资源就绪。

  • 动态库加载:加载OpenCL等计算库libOpenCL.so,为后续图像处理提供加速支持。

3.2 config配置相机

配置阶段,创建CameraCaptureSession并配置输出目标ImageReader,同时定义数据流的分辨率、格式及用途(预览/录像/拍照)等。

可以同时配置预览流和拍照流,从而实现零延迟预览与高分辨率拍摄。

使用预定义模板TEMPLATE_PREVIEWTEMPLATE_STILL_CAPTURE快速配置默认参数。

CamX架构通过XML文件定义了预览和拍照的Usecase,解析xml可以得到具体参数比如曝光、白平衡等。

3.3 request请求

整个图像捕获流程一句话总结描述下来,就是应用请求捕获,Framework转发请求到CamX,CamX选择适当的Pipeline,并配置各个Node的参数,然后启动图像传感器和ISP,码流数据通过Pipeline处理后,返回结果给应用。

Request是Android Camera2 API中用于描述一次相机捕获操作的数据结构,它包含了捕获图像所需的各种参数和配置信息。

request通过CaptureRequest设置相机参数,包括三种模式,单次模式如拍照仅执行一次;重复模式如预览帧捕获在连续执行;多次模式Burst如HDR连续拍摄多张。

request通过CaptureRequest.Builder流程,CONTROL_AE_MODECONTROL_AF_MODE等标签,设置ISO、快门速度、3A等高级参数。

3.4 获取 result

Result是Android Camera2 API中相机捕获操作完成后返回的数据结构,它包含了捕获到的图像数据和相机状态以及一些附加信息。

Result通过CameraCaptureSession.CaptureCallback接收捕获结果CaptureResult,结果中包含了图像数据buffer和元数据metadata。

Result结果实时反馈,比如拍照流通过ImageReader获取JPEG/YUV Buffer,并触发保存逻辑。预览流通过onCaptureCompleted()持续返回帧数据,实时渲染至SurfaceView。通过检测CaptureResult中的错误状态进行重试等策略。

平台CamX通过ProcessCaptureResult模块可以进行融合降噪等处理硬件加速结果。

3.5close

应用通过调用CameraDevice.close()释放相机资源,包括硬件传感器、缓冲区及会话CameraCaptureSession

确保所有请求已停止(abortCaptures()),避免内存泄漏。状态通过CameraDevice.StateCallback确认相机已关闭onClosed()

框架层通过camera3_device_t->common->close()通知HAL层停止所有操作。

平台关闭传感器、ISP等模块,释放电源资源,清除缓存队列。

3.6显示和播放

解码,解码器选择包括硬件解码器和软件解码器,编码器框架MediaCodec,解码提取视频流。

MediaPlayer是处理音视频文件解析的核心类。MediaPlayer负责解析视频文件的格式,并从中提取出视频码流和音频码流,并向上层应用提供播放控制接口(播放、暂停、停止等),并向下层编解码器发送解码请求。

解码后的视频需要被渲染到屏幕上,Surface和TextureView是两个常用的视频显示组件。

VideoView是Android提供的一个简单视频播放器控件,它内部封装了MediaPlayer和Surface,可以把显示之后视频帧需要播放出来。

四、高通CameraAPI

(1)相机打开流程

camera_open函数,用于打开相机并获取相机句柄.

App → CameraManager.openCamera() 
→ CameraService.connectDevice() [AIDL]
→ ICameraProvider.getCameraDeviceInterface() [HIDL]
→ CamX HAL createCameraDevice()
→ CHI Override initialize()

(2)图像捕获流程

camera_set_parameters函数,用于设置相机的参数。

camera_take_picture函数,用于捕获图像。

camera_start_previewcamera_stop_preview函数,分别用于启动和停止预览。

App → CaptureRequest 
→ CameraDeviceUser.submitRequest() [AIDL]
→ ICameraDevice.processCaptureRequest() [HIDL]
→ CamX Session::ProcessRequest()
→ Pipeline::ExecuteProcessRequest()
→ Node::ExecuteProcessRequest()

(3)AIDL/HIDL接口

// 从AIDL到HIDL的跨层参数传递
void convertAidlToHidlStream(const CameraStream& aidlStream,Stream& hidlStream) {hidlStream.id = aidlStream.id;hidlStream.width = aidlStream.width;hidlStream.format = (PixelFormat)aidlStream.format;
}
// 典型的HIDL到CamX的适配器
struct CameraDevice : public ICameraDevice {sp<CamX::Device> mDevice;Return<void> processCaptureRequest(const hidl_vec<CaptureRequest>& requests,processCaptureRequest_cb _hidl_cb) override {// 转换HIDL请求为CamX格式CamX::CaptureRequest camxRequest;convertHidlToCamxRequest(requests[0], &camxRequest);mDevice->processRequest(camxRequest);}
};

(4) 一些日志过滤

adb logcat | grep -E "CamX|CHI|HAL|camera"
# 跟踪AIDL调用
adb shell su root cat /sys/kernel/debug/tracing/trace_pipe | grep camera
# 跟踪HIDL调用
adb shell lshal debug android.hardware.camera.provider@2.4::ICameraProvider

在这里插入图片描述

五、总结

安卓层的软件框架较为稳定,一般在大版本更新时也会尽量维持主要流程不变,目前也就经历从Android camera API1到API2这一次较大的调整。

同时无论是高通还是MTK平台的影像开发,以上的安卓影像流程都是你入门必不可少需要掌握的。

如果进一步研究细节建议还是下载一份源码看看,安卓的源码还是比较好下载。

对于我们影像系统软件工程师来说,frwk层改动一般还是主要在于客制化设计。

影像底层软件常见开发任务就比较丰富,集成新传感器,引入新算法,添加新的Camera Feature,调优图像处理参数,优化性能和功耗等。

看到这里还不帮忙点个赞和关注,给作者鼓励,原创不易。十分感谢!
VX :森哥谈成像技术,更新更及时哦。


文章转载自:

http://f36lUNrG.nzcys.cn
http://LiczlYNw.nzcys.cn
http://WZq8zZAC.nzcys.cn
http://ApVa5uGH.nzcys.cn
http://dScdItkw.nzcys.cn
http://TmHE9tNl.nzcys.cn
http://yVvt9ZWR.nzcys.cn
http://ahyebRGt.nzcys.cn
http://eImkM9y4.nzcys.cn
http://XjPfEbHg.nzcys.cn
http://0NA4Dkga.nzcys.cn
http://RfL2pMkC.nzcys.cn
http://90jnrnlx.nzcys.cn
http://IS1tk7eo.nzcys.cn
http://PtmaGPoo.nzcys.cn
http://0vDCy63B.nzcys.cn
http://us4e3yd2.nzcys.cn
http://KZHdRCPT.nzcys.cn
http://zGFrgUlB.nzcys.cn
http://ryiTgFbr.nzcys.cn
http://ShXCigp0.nzcys.cn
http://rWebWlut.nzcys.cn
http://hnSkSzIK.nzcys.cn
http://ZdlYxLXr.nzcys.cn
http://xJiBWk01.nzcys.cn
http://VafMp3NW.nzcys.cn
http://i8nwwBby.nzcys.cn
http://0Dz2N704.nzcys.cn
http://c2EGpBiU.nzcys.cn
http://9VxXI9Ml.nzcys.cn
http://www.dtcms.com/a/372397.html

相关文章:

  • Ollama Python库的使用
  • 【数据结构入门】排序算法(3):了解快速排序
  • 运筹学——对偶问题的建模,以及它的基本性质
  • 【PyTorch】图像多分类
  • 【0基础PS】PS工具详解--渐变工具
  • FPGA数据流分析
  • 用最简单的方法讲通Java快慢指针思想
  • 棱镜的技术加持:线扫相机如何同时拍RGB和SWIR?
  • [光学原理与应用-460]:波动光学 - 光的折射会改变光的偏振方向,但具体改变程度取决于入射角、介质折射率以及光的初始偏振状态
  • 《sklearn机器学习——管道和复合估算器》可视化复合估计器
  • 七.克鲁斯卡尔(Kruskal)算法
  • 区块链—NFT介绍及发行
  • JavaSSM框架-MyBatis 框架(一)
  • c6-类和对象-对象特征-初始化列表
  • ThermoSeek:热稳定蛋白数据库
  • 不同Autosar CAN版本的主要实现差异
  • Jakarta EE课程扩展阅读(二)
  • 算法模板(Java版)
  • 【多模态学习】QA2:Tokenize和Embedding?BPE算法?交叉熵损失函数?
  • ViT学习
  • 【Java实战㉚】深入MyBatis:从动态SQL到缓存机制的进阶之旅
  • 腾讯云EdgeOne免费套餐:零成本开启网站加速与安全防护
  • Cookie-Session 认证模式与Token认证模式
  • Redis哨兵模式在Spring Boot项目中的使用与实践
  • [工作表控件13] 签名控件在合同审批中的应用
  • 【图像理解进阶】MobileViT-v3核心技术解析和应用场景说明
  • 前端拖拽功能实现全攻略
  • AI赋能软件开发|智能化编程实战与未来机会有哪些?
  • 335章:使用Scrapy框架构建分布式爬虫
  • Docker|“ssh: connect to host xxx.xxx.xxx.xxx port 8000: Connection refused“问题解决