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函数,用于打开相机并获取相机句柄.

plain 复制代码
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函数,分别用于启动和停止预览。

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

(3)AIDL/HIDL接口

plain 复制代码
// 从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) 一些日志过滤

plain 复制代码
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 :森哥谈成像技术,更新更及时哦。

相关推荐
liang_jy2 小时前
Android 事件分发机制(二)—— 点击事件透传
android·面试·源码
圆号本昊4 小时前
Flutter Android Live2D 2026 实战:模型加载 + 集成渲染 + 显示全流程 + 10 个核心坑( OpenGL )
android·flutter·live2d
冬奇Lab5 小时前
ANR实战分析:一次audioserver死锁引发的系统级故障排查
android·性能优化·debug
冬奇Lab5 小时前
Android车机卡顿案例剖析:从Binder耗尽到单例缺失的深度排查
android·性能优化·debug
小鸡吃米…5 小时前
带Python的人工智能——计算机视觉
人工智能·python·计算机视觉
ZHANG13HAO6 小时前
调用脚本实现 App 自动升级(无需无感、允许进程中断)
android
圆号本昊7 小时前
【2025最新】Flutter 加载显示 Live2D 角色,实战与踩坑全链路分享
android·flutter
小曹要微笑7 小时前
MySQL的TRIM函数
android·数据库·mysql
mrsyf9 小时前
Android Studio Otter 2(2025.2.2版本)安装和Gradle配置
android·ide·android studio