关键流程实现剖析
四、关键流程实现剖析
4.1 预览功能
- SurfaceView/TextureView与Camera2的绑定
- 数据流路径:HAL→CameraService→App Surface
4.1.1 SurfaceView/TextureView与Camera2的绑定流程
-
视图初始化与权限申请
- 在布局文件中定义
TextureView
或SurfaceView
,例如通过<TextureView>
标签声明预览控件。 - 动态申请相机权限(
android.permission.CAMERA
),并在AndroidManifest.xml
中声明硬件特性(如android.hardware.camera
)。
- 在布局文件中定义
-
Surface创建与配置
- TextureView:通过
SurfaceTextureListener
监听Surface可用性,在onSurfaceTextureAvailable
回调中获取SurfaceTexture
对象,并创建Surface
实例。 - SurfaceView:通过
SurfaceHolder
获取Surface
对象,并设置SurfaceHolder.Callback
监听生命周期。 - 示例代码片段:
SurfaceTexture texture = textureView.getSurfaceTexture(); texture.setDefaultBufferSize(previewWidth, previewHeight); Surface surface = new Surface(texture); // 绑定到Camera2的预览输出
- TextureView:通过
-
Camera2 API交互
- 通过
CameraManager
获取相机设备列表,选择指定摄像头(如后置摄像头)并调用openCamera
打开设备。 - 创建
CameraCaptureSession
时,将Surface
对象添加到会话的输出目标列表中,完成视图与相机的绑定。 - 示例关键步骤:
cameraDevice.createCaptureSession(Arrays.asList(surface), sessionCallback, null);
- 通过
4.1.2 数据流路径:HAL → CameraService → App Surface
-
HAL层(硬件抽象层)
- 相机硬件通过V4L2框架与内核驱动交互,HAL层(如CamX-CHI)负责将原始图像数据转换为Android标准格式(如YUV或RAW)。
- HAL通过
CameraProvider
进程暴露接口,接收来自CameraService
的配置请求(如分辨率、帧率)。
-
CameraService层
CameraService
作为系统服务,通过Binder机制接收应用的CaptureRequest
,并将其转发至HAL层。- 管理相机设备的生命周期,协调多个应用的访问权限,确保数据流的独占性或共享性。
-
应用层数据传递
- 图像数据从HAL层经
CameraProvider
传递到CameraService
,再通过CameraCaptureSession
的管道机制传输到应用层的Surface
。 - 最终,数据通过
SurfaceFlinger
渲染到屏幕,或通过ImageReader
回调供应用处理(如人脸识别)。
- 图像数据从HAL层经
4.1.3 关键流程示意图
Camera Hardware → HAL (CamX-CHI) → CameraProvider → CameraService → CameraCaptureSession → App Surface (TextureView/SurfaceView)
4.2 拍照流程
- 单帧捕获(ImageCapture)与连拍优化
- 视频编码器(MediaCodec)与Camera2的协同
4.2.1 单帧捕获(ImageCapture)流程
4.2.1.1 初始化相机设备
- 获取CameraManager:通过系统服务获取相机管理器实例,用于枚举和打开摄像头。
- 选择摄像头ID:遍历
getCameraIdList()
获取可用摄像头列表,并通过CameraCharacteristics
筛选前置/后置摄像头。 - 打开摄像头:调用
openCamera()
并注册CameraDevice.StateCallback
监听设备状态。
4.2.1.2 创建捕获会话
- 配置输出Surface:包括预览的
SurfaceView
/TextureView
和拍照的ImageReader
的Surface。 - 创建CaptureSession:通过
createCaptureSession()
建立会话,并在CameraCaptureSession.StateCallback
中处理会话就绪事件。
4.2.1.3 构建捕获请求
- 选择模板类型:使用
TEMPLATE_STILL_CAPTURE
创建静态图像请求模板。 - 设置参数:通过
CaptureRequest.Builder
配置自动对焦、曝光模式、JPEG质量等参数。 - 触发捕获:调用
capture()
方法发送请求,并在CaptureCallback
中接收结果。
4.2.1.4 图像处理与保存
- 获取Image数据:通过
ImageReader.OnImageAvailableListener
异步获取YUV或JPEG格式数据。 - 格式转换与压缩:使用
YuvImage
或BitmapFactory
处理原始数据,并通过异步线程保存至文件。
4.2.2 连拍优化策略
4.2.2.1 减少处理延迟
- 缓冲区复用:通过
ImageReader
预分配多个缓冲区,避免频繁内存分配。 - 异步处理链:将图像处理(如降噪、压缩)放入后台线程,防止阻塞主线程。
4.2.2.2 会话与请求优化
- 批量请求提交:使用
captureBurst()
一次性提交多个请求,减少IPC通信开销[。 - 动态参数调整:在连拍过程中动态调整曝光补偿或ISO值,避免逐帧配置。
4.2.2.3 内存与存储优化
- 内存池管理:限制连拍缓存数量(如5-10帧),防止OOM异常。
- 存储异步写入:通过
AsyncTask