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

相关推荐
深圳市快瞳科技有限公司7 小时前
小场景大市场:猫狗识别算法在宠物智能设备中的应用
算法·计算机视觉·宠物
AndrewHZ10 小时前
【图像处理基石】图像在频域处理和增强时,如何避免频谱混叠?
图像处理·计算机视觉·傅里叶分析·图像增强·频域处理·摩尔纹·频谱混叠
前行的小黑炭11 小时前
Android 协程的使用:结合一个环境噪音检查功能的例子来玩玩
android·java·kotlin
阿华的代码王国11 小时前
【Android】内外部存储的读写
android·内外存储的读写
小王爱学人工智能13 小时前
OpenCV的阈值处理
人工智能·opencv·计算机视觉
湫兮之风14 小时前
OpenCV: Mat存储方式全解析-单通道、多通道内存布局详解
人工智能·opencv·计算机视觉
inmK114 小时前
蓝奏云官方版不好用?蓝云最后一版实测:轻量化 + 不限速(避更新坑) 蓝云、蓝奏云第三方安卓版、蓝云最后一版、蓝奏云无广告管理工具、安卓网盘轻量化 APP
android·工具·网盘工具
giaoho14 小时前
Android 热点开发的相关api总结
android
点云侠16 小时前
解决Visual Studio 2022编译工程速度慢的问题
开发语言·c++·ide·算法·计算机视觉·visual studio