314.StreamConfigurationMap实现逻辑与解析过程详解:相机流能力的声明、匹配与验证机制全景
StreamConfigurationMap实现逻辑与解析过程详解:相机流能力的声明、匹配与验证机制全景
关键词:
StreamConfigurationMap、CameraCharacteristics、OutputFormat、InputFormat、Size 配置、帧率范围、流兼容性、配置失败调试
摘要:
StreamConfigurationMap 是 Android 相机框架中的关键数据结构之一,承载了 HAL 层报告的所有可支持流组合,包括输出格式、输入重处理格式、尺寸列表、最低帧率等信息。在开发中,无论是构建 ImageReader、配置 CaptureSession,还是校验目标尺寸是否支持,均离不开对其的正确解析与使用。本文将基于 AOSP 最新版本源码与平台实践,系统拆解 StreamConfigurationMap 的构建路径、接口实现、内部数据组织与典型问题处理策略,帮助开发者深入理解背后的匹配逻辑与流能力限制。
目录
一、系统定位:StreamConfigurationMap 的作用与关联模块概览
二、能力声明入口:HAL 如何填充 stream 配置能力并传递给 framework
三、构建路径追踪:从 HAL Metadata 到 Java 层 Map 对象的封装过程
四、关键接口详解:getOutputSizes / getInputFormats / getValidOutputFormatsForInput 行为分析
五、内部数据结构解析:Size 配置 × Format 映射 × Dynamic Range 支持方式
六、典型问题场景分析:尺寸不支持、流类型冲突、format 配置失败案例
七、性能与兼容性建议:构建 Session 前的能力预判与流选型策略
八、工程调试技巧:如何通过 dumpsys + HAL log + camera-profile.xml 还原 stream 匹配流程
一、系统定位:StreamConfigurationMap 的作用与关联模块概览
在 Android Camera 框架中,StreamConfigurationMap 是 CameraCharacteristics 返回结构的一部分,主要承载与流配置能力相关的声明信息,其本质是 HAL 层通过 metadata 报告的一组支持的输入/输出格式、尺寸、帧率范围与重处理能力的集合,它是 Camera 流设计与 Session 创建过程的核心决策依据。
整个框架中与 StreamConfigurationMap 直接关联的关键组件包括:
- CameraMetadata(native 层)
- 定义并填充
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS、ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS等字段。
- 定义并填充
- CameraCharacteristics(Java 层)
- 从 HAL metadata 映射到 Java 对象,由
CameraManager#getCameraCharacteristics()返回。
- 从 HAL metadata 映射到 Java 对象,由
- CameraDevice / CaptureSession 配置流程
- 应用层通过
getOutputSizes()等接口判断目标流是否受支持,并据此创建ImageReader、SurfaceTexture等输出对象,作为 Session 配置输入。
- 应用层通过
- StreamConfigurationMap(Java 封装类)
- 封装各类接口能力,包括:
getOutputSizes(int format)getOutputMinFrameDuration()isOutputSupportedFor(Class<?> klass)getValidOutputFormatsForInput()等
- 封装各类接口能力,包括:
- CameraCaptureSession 设备协商路径
- session 构建前,CameraFramework 会根据 StreamConfigurationMap 中的内容对输入流和输出流组合进行合法性校验,非法配置会直接抛出
IllegalArgumentException。
- session 构建前,CameraFramework 会根据 StreamConfigurationMap 中的内容对输入流和输出流组合进行合法性校验,非法配置会直接抛出
总结来说,StreamConfigurationMap 处于 framework 与 HAL 能力协商的关键中间层,是连接App × Framework × HAL的标准能力桥梁,其合理性直接决定了拍照、录像、预览、AI流等功能是否能够顺利启用。
二、能力声明入口:HAL 如何填充 stream 配置能力并传递给 framework
HAL 通过向系统上报静态 metadata 的方式,向上层暴露 Camera 的流配置能力。其核心字段包括:
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS
该字段是最关键的配置列表,格式如下:
typedef struct camera3_stream_configuration {
int32_t format; // 输出或输入格式,如 YUV_420_888、JPEG、RAW_SENSOR
uint32_t width; // 分辨率宽度
uint32_t height; // 分辨率高度
uint32_t isInput; // 0 表示输出,1 表示输入(如 reprocessing)
} camera3_stream_configuration_t;
HAL 层会在 get_camera_metadata() 时,将上述配置封装成一组 CameraMetadataEntry 条目,以静态 metadata 形式报告。
举例:
const int32_t available_stream_config[] = {
HAL_PIXEL_FORMAT_YCbCr_420_888, 1920, 1080, 0,
HAL_PIXEL_FORMAT_YCbCr_420_888, 1280, 720, 0,
HAL_PIXEL_FORMAT_BLOB, 4032, 3024, 0,
HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, 1920, 1080, 0,
};
- 其他辅助字段包括:
ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS:每个 format + size 对应的最小帧时间(影响帧率上限)ANDROID_SCALER_AVAILABLE_STALL_DURATIONS:JPEG 或 YUV reprocess 流的处理延迟ANDROID_REQUEST_AVAILABLE_CAPABILITIES:决定是否支持 YUV reprocessing、RAW 等能力ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP(AIDL)或reprocess_input_output_map(HIDL):用于构建输入流与可支持输出格式的关系
- 上报流程:
以 HIDL 模式为例,HAL 中定义的 ICameraProvider::getCameraDeviceInterface_V3_x() 实现最终通过 constructDefaultRequestSettings() 和 getCameraCharacteristics() 两条路径,将支持的 stream 配置能力写入 metadata 中传递到 framework。
framework 端接收到 metadata 后,会在 CameraMetadata::buildStreamConfigurationMap() 中逐项解析 stream 配置字段,最终封装为 StreamConfigurationMap 并挂载到 CameraCharacteristics 中供上层使用。
五、内部数据结构解析:Size 配置 × Format 映射 × Dynamic Range 支持方式
StreamConfigurationMap 的底层核心是一组高效封装的映射结构,支撑其各类能力查询函数。理解这些内部结构的组织方式,对于调试 camera 流配置问题、扩展新能力(如 HDR、10-bit)具有重要意义。
- Output Size × Format 映射结构
最基本的结构是基于 format 的 输出尺寸列表:
Map<Integer /*format*/, Size[] /*available sizes*/> mOutputFormats;
其中每个 format(如 ImageFormat.YUV_420_888、ImageFormat.JPEG)对应一组可支持的尺寸(Size 为 width × height 封装对象)。
数据来源是 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS 中的 isInput == 0 条目。解析时按照 format 分类聚合。
例如:
HAL 上报:
YUV_420_888, 1920×1080, output
YUV_420_888, 1280×720, output
JPEG, 4032×3024, output
构造成:
{
YUV_420_888 → [1920x1080, 1280x720],
JPEG → [4032x3024]
}
- Input Format 支持结构
对于支持输入流的 HAL,还需解析 isInput == 1 条目:
Set<Integer /*input formats*/> mInputFormats;
该结构用于支持 reprocessing 功能判断,决定是否可以使用 ImageWriter/ReprocessableCaptureSession。
- Input → Output format 映射表(Reprocess)
存在 ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP 字段时,将其构造成:
Map<Integer /*input format*/, int[] /*valid output formats*/> mInputOutputMap;
该映射用于快速判断:给定一个输入格式(如 YUV),能否构建出特定输出(如 JPEG)流。
- Min Frame Duration、Stall Duration 数据结构
Map<Format+Size, Long>类型,用于判断不同流的帧率上限与处理延迟:
mMinFrameDurations: Map<format+size, duration>
mStallDurations: Map<format+size, duration>
例如 JPEG 输出通常会有长时间 Stall,用于影响 Session 配置顺序、App 节奏控制。
- Dynamic Range 与色彩能力扩展(Android 13+)
自 Android 13 开始,Google 引入了对 HDR 类型(如 HLG、PQ)与 10-bit color format 的扩展支持。
对应字段包括:
ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILESANDROID_REQUEST_AVAILABLE_COLOR_SPACES
framework 中添加了对 StreamConfigurationMap#getHighResolutionOutputSizes() 和 getSupportedDynamicRanges() 的封装,用于 App 选择支持的高 bit-depth 输出格式。
结构上一般构建为:
Map<format, DynamicRange[]>
App 可通过 OutputConfiguration#setDynamicRangeProfile() 来定制输出要求,HAL 若支持将匹配所需格式并返回对应流配置。
六、典型问题场景分析:尺寸不支持、流类型冲突、format 配置失败案例
在 Camera 开发或调试过程中,StreamConfigurationMap 显式与隐式定义的能力限制常常成为出错源头,以下是典型的三类问题及定位方法:
场景一:输出尺寸不被支持
现象:
调用 ImageReader.newInstance(w, h, format) 后,CameraCaptureSession 创建失败,日志中报:
E CameraDevice: Stream configuration failed: unsupported size
根因排查:
- 使用
cameraCharacteristics.get(StreamConfigurationMap.class).getOutputSizes(format)获取支持列表。 - 核对分辨率是否在其中,特别注意是否使用了非常规尺寸(如非 16:9)。
解决建议:
- 替换为标准尺寸,如 1280x720、1920x1080。
- 若需求特殊,需在 HAL 层声明更多尺寸。
场景二:输入流与输出流类型冲突(如 Reprocess 配置错误)
现象:
创建 ReprocessableCaptureSession 时崩溃:
IllegalArgumentException: Input configuration not supported
根因排查:
- 调用
StreamConfigurationMap.getInputFormats()确认输入流支持。 - 检查输入与输出是否匹配
getValidOutputFormatsForInput()。
解决建议:
- 确保 input 格式为 YUV_420_888。
- 避免使用未声明支持 reprocess 的设备。
场景三:Format 配置失败(App 未做能力判断)
现象:
App 固定使用某 format(如 RAW_SENSOR),在部分平台上报错:
CameraAccessException: Stream configuration map does not support RAW_SENSOR
根因排查:
- 多数平台仅主摄或某些特定模块支持 RAW。
- HAL 没有上报
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS中的 RAW 条目。
解决建议:
- 使用
getOutputFormats()先行判断是否包含ImageFormat.RAW_SENSOR。 - 避免盲目申请高 bit-depth 输出。
总结:
- 所有流配置异常问题,最终都可追溯到
StreamConfigurationMap所声明的能力与调用配置的匹配问题。 - 推荐在 APP 层统一封装一套流能力判断逻辑,防止业务调用路径出现碎片化配置错误。
七、性能与兼容性建议:构建 Session 前的能力预判与流选型策略
在复杂场景下,尤其是涉及多摄、多格式、HDR/HDR10、Video + Preview + Capture 并存的业务配置中,合理设计流选型策略,提前预判设备能力,是保障稳定性的关键。以下是构建 CameraCaptureSession 之前进行能力评估与 stream 配置选型的建议:
- 避免“盲配”:所有输出流都应通过
StreamConfigurationMap验证
- 对每一个待创建的流(如 ImageReader / SurfaceTexture):
- 使用
getOutputSizes(format)确认尺寸支持; - 使用
getHighResolutionOutputSizes()判断高分辨率模式是否存在; - 对于 YUV/RAW,判断是否存在特殊限制(某些平台仅主摄支持)。
- 使用
- 视频流与拍照流组合时,优先采用平台推荐组合
- 多数平台会预定义
camera_profile.xml或硬编码推荐组合,如:- 1920x1080 视频 + 640x480 预览 + JPEG 4032x3024 拍照
- 建议参考
dumpsys media.camera中的availableStreamConfigurations区段,找出 HAL 报告的已测试组合
- 流格式选型与“组合压力”评估
- JPEG vs YUV: 拍照建议使用 JPEG,若需高吞吐处理,则选择 YUV + 软件编码
- 预览建议 SurfaceTexture/SurfaceView,避免
ImageReader影响帧率 - Reprocess 时需确保 inputFormat 与 outputFormat 配对支持
- 高分辨率与高帧率不可兼得
部分平台将 max resolution 与 max frame rate 配置为互斥能力:
- 4032x3024 @ 30fps:支持
- 4032x3024 @ 60fps:不支持
- 1920x1080 @ 60fps:支持
在 session 构建前判断:
long duration = getOutputMinFrameDuration(format, size);
if (duration > 0) {
long maxFps = 1e9 / duration;
}
- 尽量避免冷启动时就构建所有流
- 某些平台在 session 初始化时会根据 stream 类型一次性分配 buffer 和 pipeline
- 可拆分 session 创建节奏(先预览,后添加拍照)以减少 OOM 或构建失败风险
八、工程调试技巧:如何通过 dumpsys + HAL log + camera-profile.xml 还原 stream 匹配流程
当遇到 stream 创建失败、configureStreams 报错、或实际运行中流错配等问题时,建议采用如下组合工具还原设备配置与系统匹配链路:
- dumpsys media.camera
执行命令:
adb shell dumpsys media.camera -v
重点关注:
Camera ID对应条目下的:Stream Configuration MapMin Frame DurationStall DurationDynamic Range Profiles
Available Capabilities是否包含所需功能(如 RAW、REPROCESSING)
- HAL log / vendor log
- MTK 平台:
vendor.debug.camera.*日志中有StreamConfigParser、StreamFeatureMapping输出 - 高通平台:使用
adb shell logcat | grep QCamera3HardwareInterface
查看是否存在配置失败的日志,如:
[ERROR] configure_streams: unsupported resolution 3264x2448 for format 35
- camera-profile.xml 分析
部分平台在 /vendor/etc/camera/ 或 /vendor/etc/camera_profiles.xml 中定义 stream 默认组合。
查看内容:
<camera>
<streamComb>
<stream id="0" type="preview" format="YUV" size="1280x720" />
<stream id="1" type="video" format="YUV" size="1920x1080" />
<stream id="2" type="still" format="JPEG" size="4032x3024" />
</streamComb>
</camera>
这些组合直接影响 HAL 对 configureStreams 的支持度。
- 验证组合路径:
- 使用
CameraManager.getCameraCharacteristics()对照dumpsys报告的内容确认是否一致 - 若 app 层配置失败,优先考虑缩减流数量或尺寸进行回退测试
- 补充调试工具:
atrace --async_start camera:用于记录从 configure → request → result 的时序链perfetto:可视化 session 构建的线程瓶颈与内核中断响应延迟simplecamera / CTS Camera ITS:用于构造标准配置验证路径
总结建议:
在复杂 stream 配置场景下,必须构建一套稳定的“配置验证流程”,结合 framework 层能力查询、vendor HAL log 验证与 camera profile 预判策略,形成一套工程闭环,避免上线版本因设备差异出现 stream 配置崩溃。
314.StreamConfigurationMap实现逻辑与解析过程详解:相机流能力的声明、匹配与验证机制全景
http://114.132.213.38:6250/archives/1754200101220
评论