06 · 统一 libcamerasrc 与架构定型:3A、CPU 归因与一次黑屏回归

本系列第 6 篇 | 2026-08 | 标签:libcamera、ISP/3A、性能归因、架构重构

这一篇是架构的定型篇:为什么最终删掉低延迟的 v4l2src 直采路径、统一走

libcamerasrc;"待机 CPU 60%" 怎么一步步归因到 libcamera IPA 的一个版本差异;

face_rec 怎么分两步完成订阅化迁移;以及一次"中途接入黑屏"的回归是怎么发生、

怎么修掉的。

决策:删掉低延迟路径,换 3A

第 2、4 篇里那条 ~8ms 的 v4l2src 直采路,被整体删除了 ------ 连同它的初始化脚本、

aux pipe 分支和各种 dmabuf 基准工具。

为什么?对讲场景的卖点是 3A(自动曝光/白平衡) :IMX335 无硬件 ISP,

裸 v4l2src 直采意味着没有 3A ------ 逆光、白炽灯下画面不可用。统一走

libcamerasrc 后,采集延迟从 ~8ms 变为 24~30ms (libcamera request 流转 +

IPA 跑 3A/AE 的固定开销),对对讲完全可接受。

架构取舍的通用判断式:牺牲可量化的延迟(24ms),换回不可量化的可用性
(逆光能看清人)
。延迟有探针盯着,画面质量没有数字,但用户一眼就能看出

"看不清"。当两个指标冲突时,先想清楚哪个没有退路。

CPU 归因三步法:"60% 到底花在哪"

统一之后,发布进程待机涨到 ~60% 单核。是泄漏?是死循环?还是本来就该这样?

归因过程值得完整复盘:

第一步:对照实验隔离变量

加了一个诊断开关:TESTPATTERN=1 时用 videotestsrc 替掉相机源,

其余管线完全不动。结果同样管线只剩 ~15% (还含一处软格式转换)。

→ 差额 ~45 个点全在 libcamerasrc 这一层。

第二步:算总账,回答"正不正常"

编码 + 三环广播整条链只占 ~1.5 成;IMX335 无硬件 ISP,软 ISP/3A 本来就要烧 CPU;

~60% 单核 ≈ 双核 A35 整机 30%,待机属正常,不是可优化项

结论先于深挖:如果总账算出来"正常",后面的源码级定位就只是求证而非抢救。

第三步:日志计数,定位到模块

打开 libcamera IPA 的 DEBUG 日志,统计 ISP update 次数:

我们这块自制板 ST 官方开发板
5 秒内 ISP update 次数 267(≈每帧) 9(仅启动收敛期)
每帧重写的内容 EXPOSURE + AWB(且 AWB 写的是同一个值) 参数变化才写

决定性证据:每帧无条件重写未变化的参数 。继续对照两版驱动 patch 的源码:

官方版 AWB 有防振荡检测(统计没变就直接 return),我们镜像里的旧版(evision 分支)

简单算法 fallback 缺这个检测 ,每帧无条件 applyProfile。ST 官方后来已修复,

升级 libcamera 即消除;顺带发现单文件替换 IPA 库会因 ABI 不匹配直接 abort,

只能整版升级。

方法论沉淀成一句话:性能问题先用对照开关把变量隔离,再用日志计数定位到模块,
最后才读源码找差异。
从现象到证据链的完整路径,比结论本身更值钱。

libcamerasrc 双 pad 广播:两个一踩就中招的细节

发布进程从单一 view-finder 编码扩展为双 pad:

复制代码
libcamerasrc ── 静态 src pad = view-finder(role=3)
                    └→ tee ─┬→ 编码链 → <stream>(H264)环
                            └→ <stream>_raw 环
             ── request src_%u pad = still-capture(role=1)
                    └→ DCMIPP 硬缩 128×128 → <stream>_det 环

细节一:caps 必须用显式 capsfilter 钉住gst_element_link_filtered 的 filter

不持久;libcamera 的协商靠向下游 peer 查询 caps ------ 只有 capsfilter 元件的 caps

属性能把 640×480 RGB16 / 128×128 RGB 真正传回去。(呼应第 3 篇:那边是插错转换元件

协商退化,这边是不钉 filter 根本协商不到想要的格式 ------ 同一个主题的两面。)

细节二:view-finder 必须用静态 src pad 。用 request pad(src_%u)的话,

静态 src 默认 role=video-recording 仍留在 pad 列表里,DCMIPP main pipe 被

默认配置占掉,still-capture 直接撞车,报 Main pipe already allocated

板上验证:640×480 RGB565 + 128×128 BGR888 双流同出,det 环满帧写入,

人脸识别同时跑不互斥。

face_rec 订阅化:分两步走

重构期间 face_rec 曾短暂回到自己开相机的老路(双 pad 广播还没就绪)。

就绪后按步迁移,而不是一把梭:

  • 第一步 :只订 <stream>_det 环。删整条相机管线,起订阅线程
    (200ms 重试挂环、5 秒无帧自动重挂 ------ 抄推流订阅器的模式)。det 字节 =
    DCMIPP 直出 128×128 RGB24,零转换直接喂 BlazeFace 。此步识别/显示先禁用,
    只做检测 + 发框 ------ 先在板上验证"共享 IMX335 不互斥、30fps 满帧订阅"再继续。
  • 第二步 :补订 <stream>_raw 环恢复识别 + 上屏,阈值对齐官方 int8 标定值 0.40
    (第 3 篇讲过的量化压扁问题)。

分步策略的核心:每一步都让一个可观测的最小闭环跑通,失败时知道是哪一步引入的。

回归:一颗丢掉的 config-interval=-1

双 pad 重构把管线改成元素式写法时,把 h264parse config-interval=-1 弄丢了。

后果链:

复制代码
config-interval 默认 0 → SPS/PPS 只在流开始发一次
→ 关键帧不再自包含(SPS+PPS+IDR 缺前两个)
→ WebRTC 中途接入 / 强制 IDR 之后黑屏

最迷惑的地方:启动链路一切正常 (第一帧本来就带参数集),

只有"中途接入"这个动作复现。这正是第 4 篇强调的关键帧自包含约束 ------

它不是优化项,是正确性前提。

教训:改管线写法时,逐属性 diff 新旧两端 。这类属性错误不报错,

只在你依赖它的场景下坏。

附:KVS SDK 的 UINT8 回绕

公网联调时 offer 直接失败,报 ICE 值缺失。根因在 SDK 内部:

浏览器 offer 里多余的 a=rtcp-fb 行把单个媒体段的属性数顶过了上限(256),

而 SDK 用 UINT8 计数 ,溢出后回绕覆盖,把 a=ice-ufrag/a=ice-pwd

盖掉了。修法:处理 offer 前剥掉多余属性行。

同一时期还修了 .local(mDNS)候选的阻塞问题:跨网时浏览器的 host 候选

必然解不出,但每条域名解析卡 ~4 秒超时,把队列里真正有用的 relay/srflx
候选堵住 → 首帧 ~10s
。解法:按网络模式分流,relay 模式直接丢 .local

第三方 SDK 的坑往往不在文档里,在计数器类型和超时路径里 ------ 出现"不可能的报错"

时,去读它的错误码生成逻辑。

重构后的验收基线

读数 局域网 公网 5G
呼叫→首帧渲染 ~120ms ~690ms
稳态 RTT / fps / 丢帧 2ms / 30 / +0 88ms / 29 / +0

采集延迟 24~30ms 由 libcamerasrc 固定开销主导,端到端零丢帧 ------ 重构无回归,

架构定型。


下一篇:07 · 补齐对讲的另一半

------ 麦克风上行、强制 IDR 的反向通道选型、音频 PTS 坑。

相关推荐
醉颜凉1 小时前
Elasticsearch核心架构:集群(Cluster)原理详解与核心作用
elasticsearch·架构·jenkins
qyyyyy5701 小时前
芯片 Application Note PDF 怎么读?参考电路、BOM 和调试波形翻译实战
嵌入式硬件·设计模式·机器翻译·web application
Romantic_love_1 小时前
理解USART真实收发过程
开发语言·stm32·单片机·学习
RisunJan1 小时前
HarmonyOS 架构精读:从系统分层到应用模型
华为·架构·harmonyos
songgeb2 小时前
UITableView 局部刷新 Crash:Invalid update
ios·架构
bluesky9612222 小时前
malloc 和 realloc C/C++
c语言·c++·算法
天空'之城2 小时前
单片机基础核心知识点汇总(十九)
单片机·嵌入式硬件
恒锐丰科技林技术员2 小时前
SS6635E:高性价比 30V 桥式直流电机驱动芯片解析
经验分享·嵌入式硬件·硬件工程
LCG元2 小时前
STM32 FreeRTOS 多任务实战:信号量同步、互斥量保护与优先级反转排查
stm32·单片机·嵌入式硬件