第49讲 Android13 Camera2 New APIs介绍:OutputConfiguration与Stream usecase配置实战
1. Android13 Camera2 多流输出适配OutputConfiguration 与 Stream usecase 到底解决了什么问题如果你在做 Android Camera2 开发大概率遇到过这种场景预览要一路流、拍照要一路流、录像还要一路流三路流同时开的时候要么帧率掉得厉害要么某一路直接创建失败。Android 13 之前我们能控制的只有 Surface 的尺寸和格式至于「这路流到底是给预览用的还是给录像用的」系统并不知道只能靠 HAL 自己猜。猜错了功耗和延迟就上去了。Android 13 在 Camera2 里补上了这块拼图核心是两个东西OutputConfiguration和Stream usecase。OutputConfiguration 是 Android 10 就引入的但 Android 13 给它加了 Mirror、Timestamp base、Dynamic range profile 这些新能力Stream usecase 则是 Android 13 真正落地的一个「语义标签」机制让你告诉底层「这路流是 PREVIEW、STILL_CAPTURE 还是 VIDEO_RECORD」。打个比方以前的 Surface 就像寄快递只写地址不写物品类型快递员只能按默认方式处理现在你可以标注「易碎」「冷藏」物流系统就能提前分配对应的资源。Stream usecase 就是这个「物品类型标签」它直接影响 ISP、Scaler 的资源分配策略。这篇面向的是已经在用 Camera2、准备在 Android 13 设备上适配多流输出的开发者。我会给出可直接复制的 OutputConfiguration 配置骨架、Stream usecase 的设置方式以及在真机上验证流组合是否生效的具体步骤。涉及的关键检索词包括 Android13 Camera2 OutputConfiguration 配置、Stream usecase 设置、SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS 查询等都会在代码里体现。需要先明确一点Stream usecase 不是所有设备都支持。你得先查REQUEST_AVAILABLE_CAPABILITIES里有没有REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE没有的话设了也白设系统会忽略。这个判断逻辑我会在第三节的代码里写清楚。另外多流组合不是随便配的。Android 13 提供了SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS这个静态属性它告诉你「哪些 usecase 组合是设备一定支持的」。你按它给的组合去配成功率最高自己乱配可能创建 Session 时直接抛异常。这是本篇要重点讲的部分。2. TaoToken 前置准备用模型对话快速核对 Camera2 API 签名与常量Camera2 的 API 签名和常量值经常记混尤其是 Android 13 新增的这一批。我自己的做法是在写代码前先用模型对话把关键 API 的签名和常量对照一遍避免编译期才发现参数类型不对。TaoToken 的模型对话入口在这里https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。你可以直接问它「Android 13 OutputConfiguration setStreamUseCase 的参数类型是什么」「SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD 的常量值是多少」这类问题它会给出对应的 API 说明。为什么要在写 Camera2 代码前做这一步因为 Android 13 的 Camera2 新增 API 有几个坑第一setStreamUseCase(long)的参数是 long不是 int。很多人习惯性写 int编译不过。这个 long 值来自SCALER_AVAILABLE_STREAM_USE_CASES_*常量。第二setDynamicRangeProfile(long)也是 long而且它和 output format 强绑定——只有ImageFormat.YCBCR_P010或ImageFormat.PRIVATE才能设 10bit HDR profile。你如果拿一个 YUV_420_888 的 Surface 去设 HLG10运行时会报错。第三setMirrorMode(int)只影响 Buffer 的 Transform matrix不会真的去翻转像素数据。这个语义如果理解错了后面显示方向对不上会排查很久。用模型对话把这些签名和约束先过一遍比直接翻 AOSP 源码快得多。我试过把一段报错的堆栈贴进去问它能定位到是哪个 setter 的参数类型或取值不对。拿到确认后的 API 信息再回到 Android Studio 里写代码编译一次过的概率会高很多。这一步不涉及任何环境配置就是纯查证几分钟的事。如果你后面要做的是长期编码或者 Agent 类的自动化任务可以考虑 Coding Planhttps://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。但就本篇这个场景模型对话足够用了。3. 可复制配置OutputConfiguration 与 Stream usecase 代码骨架这一节给出完整的配置代码。核心思路是先查设备支持哪些 usecase再按 mandatory 组合去配 OutputConfiguration最后创建 Session。先看能力查询部分。这段代码判断设备是否支持 Stream usecase并拿到支持的 usecase 列表// 查询设备是否支持 Stream usecase CameraCharacteristics characteristics cameraManager.getCameraCharacteristics(cameraId); int[] capabilities characteristics.get( CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); boolean supportStreamUseCase false; if (capabilities ! null) { for (int cap : capabilities) { if (cap CameraCharacteristics .REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE) { supportStreamUseCase true; break; } } } // 拿到当前 Camera 支持的 stream usecase 列表 long[] availableUseCases null; if (supportStreamUseCase) { availableUseCases characteristics.get( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES); }接下来是查询 mandatory 组合。这个属性返回的是一个 long 数组每两个一组表示一个组合或者按文档定义的编码方式解析。实际使用时最稳妥的做法是遍历它找到包含你需要的 usecase 的组合// 查询设备一定支持的 usecase 组合 long[] mandatoryCombinations characteristics.get( CameraCharacteristics.SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS);然后是核心的 OutputConfiguration 配置。假设我们要配三路流预览、拍照、录像。每路流创建一个 OutputConfiguration设置对应的 usecase// 预览流尺寸 1920x1080PRIVATE 格式 SurfaceTexture previewTexture new SurfaceTexture(0); previewTexture.setDefaultBufferSize(1920, 1080); Surface previewSurface new Surface(previewTexture); OutputConfiguration previewConfig new OutputConfiguration(previewSurface); if (supportStreamUseCase) { previewConfig.setStreamUseCase( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW); } // 拍照流尺寸 4032x3024JPEG 格式 ImageReader stillReader ImageReader.newInstance( 4032, 3024, ImageFormat.JPEG, 2); OutputConfiguration stillConfig new OutputConfiguration( stillReader.getSurface()); if (supportStreamUseCase) { stillConfig.setStreamUseCase( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE); } // 录像流尺寸 1920x1080PRIVATE 格式 MediaRecorder recorder new MediaRecorder(); // ... recorder 配置省略 ... OutputConfiguration recordConfig new OutputConfiguration( recorder.getSurface()); if (supportStreamUseCase) { recordConfig.setStreamUseCase( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD); }如果你要做 10bit HDR 输出需要额外设置 dynamic range profile并且 format 必须是 YCBCR_P010 或 PRIVATE// 10bit HDR 输出流 ImageReader hdrReader ImageReader.newInstance( 1920, 1080, ImageFormat.YCBCR_P010, 2); OutputConfiguration hdrConfig new OutputConfiguration( hdrReader.getSurface()); if (supportStreamUseCase) { hdrConfig.setStreamUseCase( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD); } // 设置 HDR profile需先确认设备支持 DynamicRangeProfiles profiles characteristics.get( CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES); if (profiles ! null profiles.getSupportedProfiles() .contains(DynamicRangeProfiles.HLG10)) { hdrConfig.setDynamicRangeProfile(DynamicRangeProfiles.HLG10); }最后创建 Session。注意这里用的是SessionConfiguration它接受 OutputConfiguration 列表ListOutputConfiguration outputConfigs new ArrayList(); outputConfigs.add(previewConfig); outputConfigs.add(stillConfig); outputConfigs.add(recordConfig); SessionConfiguration sessionConfig new SessionConfiguration( SessionConfiguration.SESSION_REGULAR, outputConfigs, new HandlerExecutor(backgroundHandler), new CameraCaptureSession.StateCallback() { Override public void onConfigured(CameraCaptureSession session) { // Session 创建成功可以下发请求了 } Override public void onConfigureFailed(CameraCaptureSession session) { // 配置失败检查流组合是否被支持 } }); cameraDevice.createCaptureSession(sessionConfig);这段代码里setStreamUseCase和setDynamicRangeProfile都做了能力判断不支持就跳过不会因为设了不支持的 usecase 而崩溃。这是适配多机型的关键。4. 真机验证确认流组合与输出配置是否生效代码写完只是第一步真正要确认的是「设备到底认不认你配的 usecase」。这一节给出真机验证的具体步骤。第一步打印设备支持的 usecase 列表。在onOpened回调里加日志long[] useCases characteristics.get( CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES); if (useCases ! null) { for (long uc : useCases) { Log.d(TAG, supported usecase: Long.toHexString(uc)); } }对照日志里的值确认你用的PREVIEW、STILL_CAPTURE、VIDEO_RECORD是否在列表里。如果某个不在说明这台设备不支持该 usecase你设了也会被忽略。第二步验证 Session 是否创建成功。如果onConfigureFailed被调用大概率是流组合不被支持。这时候去查SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS看你的组合是否在 mandatory 列表里。不在的话换一个 mandatory 支持的组合再试。第三步验证 usecase 是否真的生效。最直接的方法是抓CaptureResult看CaptureResult里有没有对应的 usecase 回传。不过更实用的方法是看功耗和帧率设置VIDEO_RECORDusecase 后录像流的帧率应该更稳定掉帧更少设置PREVIEWusecase 后预览延迟应该更低。第四步验证 Mirror 和 Timestamp base。Mirror 只影响 Transform matrix你可以通过OutputConfiguration.getMirrorMode()确认设置是否被接受。Timestamp base 则可以通过对比不同流的 timestamp 来验证// 在 onCaptureCompleted 里打印 timestamp Log.d(TAG, stream timestamp: result.get(CaptureResult.SENSOR_TIMESTAMP));如果设置了TIMESTAMP_BASE_SENSOR那 timestamp 应该和 sensor 的时间基准一致设置TIMESTAMP_BASE_REALTIME则和系统实时时钟对齐。第五步验证 10bit HDR。设置DynamicRangeProfile.HLG10后检查输出 buffer 的 format 是否为YCBCR_P010。如果是说明 HDR 流配置生效了。同时可以对比 HDR 和 SDR 流的画面亮度范围HDR 流的高光细节应该更丰富。实测下来最容易出问题的是流组合。很多设备虽然支持单个 usecase但不支持你想要的组合。所以第三步的 mandatory 组合查询一定要做别跳过。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth这一节整理几个在配置过程中可能遇到的报错以及对应的排查方向。报错一IllegalArgumentException: stream use case not supported这个报错通常出现在setStreamUseCase时传了一个设备不支持的 usecase。排查方法先打印SCALER_AVAILABLE_STREAM_USE_CASES确认你用的常量在列表里。如果不在就不要设或者换一个支持的。报错二onConfigureFailed被调用但没有明确异常信息这是流组合不被支持。排查方法查SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS把你的组合和 mandatory 列表对比。如果组合不在列表里尝试减少流数量或者换用 mandatory 支持的组合。报错三local proxy failed或网络请求相关错误如果你在查 API 文档或调用模型对话时遇到local proxy failed先检查网络配置。TaoToken 的 API 入口是 https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 确认请求地址没有拼错。如果是 401说明 API Key 无效或过期去 API Keys 页面重新生成https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。报错四reading choices相关错误这个通常出现在解析模型返回结果时。如果你用模型对话查 API 签名返回的 JSON 里choices字段解析失败检查一下请求的 model 参数是否正确以及返回内容是否被截断。报错五OAuth 相关错误如果你用的是需要 OAuth 的接入方式检查 token 是否过期。OAuth 流程的配置可以参考接入文档https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。报错六setDynamicRangeProfile抛异常这个报错的原因是 output format 不是YCBCR_P010或PRIVATE。排查方法检查创建 ImageReader 时用的 format必须是这两个之一才能设 HDR profile。报错七Mirror 设置后画面方向不对Mirror 只影响 Transform matrix不会翻转像素。如果你在显示端没有正确处理 Transform matrix画面方向就会不对。排查方法检查显示端的 matrix 应用逻辑确保它读取了 OutputConfiguration 的 mirror mode。6. 语义一致 CTA继续深入 Camera2 与 Android13 适配Camera2 的适配工作很多时候卡在「设备支持什么」和「我配了什么」之间的信息差上。Android 13 的 OutputConfiguration 和 Stream usecase 把一部分控制权交回给了开发者但也要求开发者更清楚设备的能力边界。如果你在配置过程中需要反复核对 API 签名、常量值、报错含义用模型对话会省很多时间https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。把报错堆栈贴进去它能帮你定位到具体的 setter 或参数。需要生成 API Key 的话入口在这里https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。接入文档里有完整的请求示例和参数说明https://taotoken.net/api?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。最后给一个实用建议在真机验证时先把SCALER_MANDATORY_USE_CASE_STREAM_COMBINATIONS打印出来按它给的组合去配成功率最高。自己组合的流即使单个 usecase 都支持也可能因为资源冲突而创建失败。这个属性是 Android 13 给开发者的「安全组合清单」别浪费它。

相关新闻

AI编程工具对比分析:OpenClaw、Codex、Trae与Claude Code 配 TaoToken 统一 Key 接入实践

AI编程工具对比分析:OpenClaw、Codex、Trae与Claude Code 配 TaoToken 统一 Key 接入实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 22:04:15 阅读更多 →
AI Agent 的记忆系统:从必要性到工程实践——用 TaoToken 统一 Key 打通 Cursor 与 Claude Code 配置

AI Agent 的记忆系统:从必要性到工程实践——用 TaoToken 统一 Key 打通 Cursor 与 Claude Code 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 22:04:15 阅读更多 →
用Flutter开发跨平台鸿蒙养花APP,浇水提醒与植物识别实现指南

用Flutter开发跨平台鸿蒙养花APP,浇水提醒与植物识别实现指南

第一次听到“用 Flutter 养花”这个需求时,我以为是句玩笑。直到朋友在阳台摆了几排多肉,出差一周回来,死了大半,他说想做个 APP:拍照能识别植物品种,该浇水的时候能提醒一句。恰好那阵子我们团队正在把一套…

2026/9/30 22:03:14 阅读更多 →

最新新闻

一键开关机芯片选型的四大工程生死线

一键开关机芯片选型的四大工程生死线

1. 为什么“一键开关机”不是按个按钮那么简单?你拆过那些带“长按3秒开机、短按关机”的智能设备吗?比如某款国产便携式示波器、某品牌工业手持终端,或者你自己焊的STM32开发板——表面看就是个按键控制电源通断,但实际一上电就死…

2026/9/30 22:37:36 阅读更多 →
吃透这篇!网络安全渗透测试大厂面试通关指南

吃透这篇!网络安全渗透测试大厂面试通关指南

人人都有一个进大厂的梦想,而进大厂的门槛也可想而知,所以这里整理了一份安全大厂的面试大全,看完文章如果对你有帮助的话希望能够点赞 收藏 关注!感谢! 一、渗透测试面试题,包含大量渗透技巧 1. 拿到一…

2026/9/30 22:37:36 阅读更多 →
人才风控系统治理指南:模型验证与误报监控

人才风控系统治理指南:模型验证与误报监控

人才风控系统的模型验证与误报监控,应形成持续闭环:先定义模型用途、基线样本、指标口径和责任人,再设置触发阈值、抽检方法、人工复核、问题分级和整改期限。每次结果都要追溯到输入数据、规则或模型版本及人工决定;误报不能只靠…

2026/9/30 22:37:36 阅读更多 →
内容发了也收录了,AI 为什么还是不引用你?

内容发了也收录了,AI 为什么还是不引用你?

运营小陈上个月发了 40 篇稿,收录查询显示全部被抓取。她让客服在豆包里问了行业里的十个常见问题,答案里一次都没出现自己公司。收录正常,引用为零——她卡在了大多数人都没意识到的那一步。 问题不在收录,在于2026 年 8-9 月这…

2026/9/30 22:36:35 阅读更多 →
热导气体分析仪XEFD-TCD防爆型维修与备件替代实战经验

热导气体分析仪XEFD-TCD防爆型维修与备件替代实战经验

这几年在装置现场最常遇到的尴尬场面,就是一大批“老黄牛”仪表还在服役,可厂家备件已经悄悄退出了常规供应。Emerson X-Stream XEFD-TCD 防爆型热导气体分析仪就是这么一台让我又爱又恨的设备。装置是十几年前的老装置,DCS 都升级过好几轮&a…

2026/9/30 22:36:35 阅读更多 →
CST电磁仿真零基础入门:从矩形波导到时域求解器的实战路线

CST电磁仿真零基础入门:从矩形波导到时域求解器的实战路线

先说个现象:每次有年轻人问我CST怎么入门,我第一反应不是甩教程链接,而是先反问一句——你知道你要仿的对象,在物理上到底发生了什么吗?CST这类三维电磁场仿真工具,在高速仿真领域几乎是标配。信号速率上到…

2026/9/30 22:36:35 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/30 15:27:04 阅读更多 →