首页 / 资讯中心 / 文章详情

MTK Camera Metadata Size配置详解:从原理到实战排查

MTK Camera Metadata Size配置详解:从原理到实战排查 ★ FEATURED ARTICLE
直接把“配置size”这件事讲透。这篇文章不打算从头讲MTK camera整体架构那些HAL层怎么流转、pipeline怎么构建网上文档不少但唯独“metadata里的size到底怎么配、配错了会发生什么、为什么这么配”这件事很少有人掰开揉碎讲清楚。我结合自己做camera HAL和tuning相关工作的实际经验把这块内容完整梳理一遍。1. metadata文件中size配置的整体设计思路1.1 先搞清楚metadata文件在整个相机体系里的位置MTK camera的metadata文件实际指的是camera_custom_*系列配置以及HAL层用到的各类静态metadata、动态metadata模板。不同平台、不同版本文件组织方式有差异但核心逻辑是一致的metadata就是相机硬件能力和软件行为之间的“契约书”。这份“契约书”里写了sensor支持哪些尺寸、哪些帧率、哪些能力也写了ISP pipeline应该怎么配buffer、怎么切场景、怎么限制stream。而size这个字段几乎是整个metadata体系里最基础又最容易被误解的参数。我记得刚接触MTK平台时看到imgsensor_size、capture_size、video_size、preview_size这些字段以为只是简单的分辨率枚举。后来深入发现完全不是这么回事——这里的size不只是分辨率它背后关联着buffer分配、ISP吞吐、sensor裁剪、FOV计算、stretch/blending等一系列硬件行为。配错了size轻则预览变形重则直接黑屏或crash。1.2 size在metadata中存在的形式与作用域在MTK的metadata体系里size出现的形态大致有这几类形态典型字段作用sensor原生分辨率sensor_size_full定义sensor输出最大分辨率各场景裁剪尺寸capture_size/preview_size/video_size定义不同场景下实际使用的输出尺寸buffer配置尺寸buffer_size/max_payload_size定义buffer分配大小JPEG编码相关jpeg_size/thumb_size定义编码输出及缩略图尺寸3A统计相关ae_size/af_size/awb_size定义3A算法的统计窗口尺寸这些size不是孤立存在的它们之间有明确的层级关系。比如preview_size不能超过sensor实际输出的最大尺寸capture_size和video_size之间可能存在restriction比如4K录像时不能同时支持某些尺寸的预览。1.3 为什么单独要把size拿出来做“解读”很多人在MTK平台做二次开发时第一个遇到的红线问题就是size配置。原因有三第一size错误的表现极具迷惑性。有时候画面只是轻微裁切有时候是绿屏有时候是stall有时候又是某些sensor模式下完全打不开相机问题定位链路很长。第二size之间不是简单的包含关系。很多size字段之间的限制是隐式的比如video_stable_size和capture_size之间就有联动如果只看单字段配当时可能正常但切换场景就崩。第三定制项目里最常见的需求就是改size。做前摄打孔、做高分辨率预览、做特殊比例视频都需要动这些配置但改起来牵一发动全身。所以这篇文章的核心思路就是把size相关的配置项逐条讲清楚把它们之间的逻辑关系串起来然后结合实操给出一套可复用的排查方法。2. 核心数据结构与配置项逐一拆解2.1 sensor output size与scenario size的关系MTK的camera hal中每个sensor都有一个SENSOR_OUTPUT_SIZE相关的结构体定义。这里面的第一个坑就是sensor output size不等于你最终拿到的预览或拍照分辨率。sensor output size是sensor硬件层面能输出的最大尺寸它决定了后续所有尺寸的上限。而scenario sizepreview/capture/video是ISP处理之后、送到不同模块的尺寸。举个例子某款48M sensorsensor output size可能是8000x6000但capture_size实际配的是4000x3000preview_size配的是1920x1080。中间多出来的尺寸到哪里去了是被ISP做了binning或者裁剪。这里有一个关键的机制需要理解当MTK平台设置capture_size小于sensor output size时HAL层会做两种处理之一——如果sensor有binning模式就切换到对应的binning输出如果没有合适的binning档位就保留sensor全尺寸输出后续用ISP裁剪。这两种方式的功耗、帧率、FOV都不一样。所以配置size时不能只看数值本身还要确认sensor驱动里注册的binning table是否覆盖了目标尺寸。我在一个项目里就遇到过sensor只注册了2x2 binning和4x4 binningmetadata里却把video_size配成了介于两者之间的尺寸结果HAL在切换时找不到匹配档位直接回退到全尺寸再裁剪导致FOV变小且功耗异常。2.2 buffer size相关字段的隐含约束MTK metadata中buffer相关的size配置有几个容易踩坑的地方。第一个是max_payload_size。这个名字看起来像个通用容量实际上在MTK的实现里它是用来约束HAL层申请buffer时的大小预算。如果配小了大分辨率场景下buffer会申请失败如果配大了内存占用无谓增加尤其在多路并发时OOM风险会明显升高。第二个是buffer_count。这个虽然不叫size但和size强相关——每个buffer的size决定了单块内存大小buffer count决定了这个大小乘以几。在配置metadata时往往只改了单块size而忘了调count导致应用层开出的buffer数量不足出现帧率不稳定或者丢帧。我自己的习惯是在改任何size字段之前先列一张全局buffer预算表把所有streampreview、record、capture、depth等的size和count乘一遍看总内存是否在平台限制范围内。2.3 JPEG与thumbnail的size联动逻辑拍照场景下jpeg_size和thumb_size是最容易配出问题的两个字段。它们的逻辑关系是jpeg_size定义主图的编码尺寸和存储上限thumb_size定义缩略图的尺寸通常由jpeg_size推导而来但也可以独立配置某些平台上thumb_size的宽高比必须和jpeg_size一致否则生成相册缩略图时会有拉伸这里有一个实操层面的经验在MTK平台上配置thumb_size时建议遵循“等比缩放”原则不要直接用目标宽高去填否则JpegEncoder在生成EXIF缩略图时会做额外的scale增加编码耗时。实测下来在4:3的主图比例下缩略图也保持4:3编码耗时差异可以达到20%左右。2.4 3A统计窗口size对算法的影响ae_size、af_size、awb_size这几个字段容易被忽略因为它们不直接影响输出画面。但它们决定3A算法的统计窗口大小——统计窗口越大算法获得的信息越多收敛越准确但功耗和耗时也会增加。这个size最终会映射到ISP的统计引擎配置上配置过小会出现曝光收敛慢、白平衡偏色、对焦犹豫等问题。值得注意的是统计窗口size和最终输出size可以不同有些平台甚至建议统计窗口固定为某个尺寸避免不同场景切换导致的3A扰动。我在实际项目里遇到过一个问题预览尺寸从1080p改成720p后发现暗光下对焦变慢了查了很久最后定位到是因为af_size跟着preview size联动更新后变小了统计信息不足。后来把af_size固定住问题就消失了。3. size配置的具体操作流程与参数计算3.1 从sensor datasheet到metadata size的推导链路拿到一颗新sensor配置metadata size的完整链路是这样的第一步确认sensor的datasheet中输出的所有分辨率模式包括全尺寸、binning尺寸、裁剪窗口、各分辨率下的帧率限制。第二步明确产品需求列出所有要支持的场景预览、拍照、1080p录像、4K录像等每个场景的目标分辨率和帧率。第三步建立尺寸映射表把sensor输出模式和场景分辨率对应起来。这一步是核心需要遵循几个原则每个场景优先选择sensor原生支持的尺寸避免额外的ISP scale如果sensor不支持目标尺寸选择大于目标尺寸的档位再通过ISP裁剪帧率不达标的档位直接排除第四步把映射表填进metadata同时更新相关的联动字段比如FOV、crop region、3A窗口。这个流程看着简单但每一步都有细节坑。举个计算例子假设sensor datasheet给出全尺寸8000x6000最大帧率15fps2x2 binning4000x3000最大帧率30fps4x4 binning2000x1500最大帧率60fps产品需求是预览1920x1080 30fps录像3840x2160 30fps拍照8000x6000那么怎么配重点看录像和预览。录像3840x2160不能直接落在sensor原生档位上。如果从8000x6000出需要像素处理量是8000x6000x30明显超过sensor输出能力而且sensor全尺寸只有15fps这条路走不通。如果从4000x3000出做一次ISP缩放4000x300030fps可行。所以video_size应该选4000x3000的档位。预览1920x1080两个选择从4000x3000做ISP裁剪或者从2000x1500做ISP缩放。从功耗角度选择2000x1500更合理因为像素量小。但注意2000x1500的比例是4:3输出1920x1080需要裁剪FOV会有损失。如果产品不能接受FOV损失就要改用4000x3000档位。这一步是典型的“每个选择背后都有代价”的case。3.2 实操中修改metadata size的推荐步骤以我常用的修改流程为例大致分六步备份原始metadata文件这一步不可省略。MTK的camera配置经常有隐性依赖一旦改崩还原配置能省下大量排查时间。全局搜索所有size相关字段先画出“现状地图”。我一般会把每个size字段当前值、所属场景、关联字段做成一张表改之前心里有数。按照上一节的推导链路确定目标值。注意同时更新scenario size、对应的buffer size、FOV相关配置。改完配置后先做静态检查。用MTK提供的工具解析metadata看是否有冲突项或超范围项。没有工具时可以写一个简单的解析脚本把各个size字段提取出来按约束关系做一次逻辑校验。上机验证基础功能。包括预览是否正常、缩放是否平滑、拍照是否出图、录像是否卡顿。这个阶段先不用做深度测试确认能跑通就行。做全场景回归重点覆盖切换场景预览到录像、录像到拍照时的稳定性以及前后摄切换、暗光环境。这套流程我用了很多年最大的价值不是“改得准”而是“能回退”。颜色、清晰度、功耗类问题都可能与size改动相关能快速定位到改动点效率完全不同。3.3 具体场景中的参数选择思路高像素拍照场景如果产品主打高像素拍照capture_size要配成sensor全尺寸但这会带来两个问题拍照瞬间内存压力大、快门延迟高。我通常的做法是保留capture_size为全尺寸但将拍照流程拆成两段——先预览占用低分辨率buffer按下快门时再分配全尺寸buffer。这个方案在metadata不需要额外配置只需要HAL层buffer管理配合。视频防抖场景开了EIS之后实际输出尺寸会小于sensor裁切后的尺寸因为需要预留防抖移动空间。MTK平台在metadata中有一个video_stable_size的字段专门处理这个场景。配这个字段时通常是目标视频尺寸的1.1倍左右具体系数取决于防抖最大补偿角度。超高帧率场景像720p240fps这种需求关键在sensor的binning档位是否能支撑。如果sensor最高只支持120fpsmetadata配了240fps也跑不起来HAL会按最高可用帧率兜底。这种问题在项目前期最好就通过sizeframeRate联合检查排除。4. 常见问题与排查技巧实录4.1 预览画面裁切比例不对这个问题出现的概率极高尤其在定制前摄或者特殊屏幕比例的项目里。先看metadata里的crop相关字段和FOV相关配置。多数情况下是因为改大了sensor_size_full或者改小了preview_size但crop region没有同步更新。MTK的crop region是相对sensor full size的比例坐标如果sensor full size改了crop坐标的绝对数值必须跟着变。实操排查建议先在HAL log里搜crop、CropRegion关键字确认HAL计算出的实际crop值是否在sensor输出范围内。如果crop值越界通常是metadata里的sensor full size和sensor driver注册的输出尺寸不一致。还有一个隐蔽问题部分MTK版本存在“二次crop”逻辑即ISP先crop到scenario size再做一次display crop。两层crop的size配置在不同字段里改了一层忘了另一层就会出现比例对但FOV偏小的情况。4.2 切到录像模式黑屏或crash这个问题通常和video size配置有关。黑屏的本质是video stream的buffer没分配成功或者sensor mode切不过来。从size角度排查优先确认三件事video_size是否在sensor binning档位支持范围内对应buffer size是否足够大video和preview的buffer总数是否超出平台内存限制我有一个快速定位技巧抓HAL的buffer alloc log看requestBuffer的返回值。如果返回的是buffer size不足类错误就直接查max_payload_size和buffer_size如果返回的是内存分配失败就要查总内存预算而不是单一size字段。实战中遇到过一个案例项目在1080p预览正常一切到4K录像就crashlog显示是buffer alloc失败。全局查下来video_size配的是3840x2160max_payload_size也够但buffer_count只有3而sensor在4K模式下需要4个buffer才能稳定跑帧缺一个就崩。这个案例说明size和count必须一起看单独看哪个都容易误判。4.3 拍照出图尺寸和预期不符出图尺寸不对一般是capture_size和sensor output size的匹配问题。HAL的逻辑是如果capture size正好等于某档binning输出尺寸就切到对应sensor mode否则用当前mode做ISP resize。问题是很多定制项目里capture_size往往填的是产品需求分辨率比如4000x3000而sensor刚好又没有这一档原生输出就会走ISP resize路径。虽然图能出来但分辨率信息、FOV可能都变了。检查方法很直接抓sensor mode切换的log看拍照瞬间sensor是否切换了mode以及当前mode是否等于capture size。如果sensor mode一直没切说明匹配逻辑没有触发。一个比较容易忽略的细节是某些平台的capture size匹配是精确匹配不是范围匹配。比如sensor有4000x3000这一档但metadata写成4000x3004匹配会失败。别看就差4个像素sensor mode就是切不过去。我在这上面栽过一次后来统计了sensor驱动里所有mclk/pclk对应的输出尺寸逐一对照metadata发现这类问题全部可以通过脚本预先检查出来。4.4 暗光下噪点明显或对焦慢size配置对画质的影响常被低估。暗光场景下如果preview_size设置了过大ISP为了维持帧率会拉高gain噪点就会明显变多。这种情况不是sensor的问题是metadata配置的问题。我踩过的一个具体场景某项目用同一款sensorA版本把预览配成全尺寸8000x6000再缩到屏幕分辨率B版本用binning档位4000x3000。同样的暗光环境A版本画面噪点明显更多而且预览帧率只有B版本的一半。原因就是A版本让ISP一路高负荷工作没有利用sensor binning在灵敏度上的优势。改动建议暗光场景优先选低分辨率binning档位作为preview_size但要注意画面解析力不能牺牲太多。实际操作中是取一个平衡点——拿产品主打场景分别用不同档位出图对比选色彩、噪点、清晰度综合最优的。4.5 一个容易忽略的内存相关事项改大的size必然带来更大的内存占用。多路并发前后摄同时工作、双景录像、画中画时尤其要关注总buffer大小。MTK平台一般有一个整体buffer预算配置不在metadata里但在camera service或者HAL的config文件中。很多项目改完metadata后出现OOM就是只改了单路的size没看整机内存预算。我的建议是每次改完size配置后做一次全场景内存估算再跑一遍压力测试不要只验证功能正常就完事。5. 配置size时要记住的几条原则做了这么多MTK camera项目总结下来配置size的核心原则其实就几条第一一切size配置从sensor的实际能力出发。脱离datasheet谈size配置等于闭眼开车。第二size是“牵一发动全身”的配置项。改了一个size必须检查FOV、crop、buffer、3A window、sensor mode这些联动项。第三binning优先于ISP resize。硬件binning在功耗、帧率、暗光表现上都优于ISP后期缩放能走binning就不要走resize。第四验证要在真实场景下做。尺寸改完常规预览、拍照、录像都过了不代表暗光、切换、多路并发也没问题。MTK platform的很多size问题要特定条件才能触发必须把场景覆盖做全。第五保留完整的修改记录。camera的size配置牵涉面广哪个版本、哪些字段改过尽量留痕。我见过太多次排了一两周的疑难问题最后发现是某次size字段改回来时漏改了一个关联项。我个人在实际操作中最深的体会是MTK camera的size配置看起来只是填几个数字实际上是一个涉及sensor硬件、ISP pipeline、内存管理、3A算法、编码模块的系统工程。把它的逻辑链条梳理清楚比背各种平台上的字段名和默认值重要得多项目也少踩很多坑。希望这篇解读能给正在调试MTK camera size的同行一些参考少走一些我走过的弯路。
阅读完成 · 觉得有帮助?
咨询建站