3. Camx XML 配置体系:层次结构与 Schema 验证

Camx 的 XML 配置体系是整个 Pipeline 的“骨架”与“神经”。它通过一套严格分层的 XML 文件,将硬件 ISP 能力、算法节点、数据流路径和业务场景(Usecase)解耦并组合。本章深入剖析 XML 配置文件的层次结构,并讲解如何通过 Schema 与 DTD 保证配置的合法性。

3.1 XML 配置文件的层次结构

Camx XML 配置体系遵循 Usecase → Pipeline → Node → Port → Link 的五层模型。每一层都定义了特定的语义和约束,共同构成一个可执行的 Camera 会话。

核心原则: 上层(Usecase)定义“做什么”,下层(Node/Port/Link)定义“怎么做”。Pipeline 是连接业务逻辑与硬件/算法执行的桥梁。

3.1.1 五层模型详解

层级 XML 标签/属性 职责描述 典型示例
Usecase <Usecase> 定义顶层业务场景,如预览、拍照、录像。它引用一个或多个 Pipeline,并配置会话参数(如帧率、分辨率)。 UsecasePreview, UsecaseSnapshot
Pipeline <Pipeline> 描述一条完整的数据处理链路,包含多个 Node 及其连接关系。Pipeline 是资源分配和调度的基本单位。 PipelinePreview, PipelineZSL
Node <Node> 代表一个具体的处理单元,可以是硬件 ISP 模块(如 IFE, BPS)或软件算法(如 SWMF, SWCrop)。 NodeIFE, NodeBPS, NodeSWMF
Port <InputPort> / <OutputPort> 定义 Node 的数据输入/输出接口,包括数据类型(Image, Meta)、格式(YUV, RAW)和缓冲区要求。 PortInputFull, PortOutputDS
Link <Link> 显式连接上游 Node 的 OutputPort 到下游 Node 的 InputPort,形成数据流路径。 LinkIFEToBPS

3.1.2 层次结构关系图

下图展示了从 Usecase 到 Link 的完整层级关系,以及它们如何组合成一个可运行的 Camera 配置。

Camx XML 五层配置层次结构 Usecase (业务场景) Pipeline (处理管线) Node (处理节点) Port (输入/输出端口) Link (连接关系) 说明:Usecase 引用 Pipeline,Pipeline 包含多个 Node,Node 通过 Port 暴露接口,Link 将 Port 连接成完整数据流。 配置解析器按此层次自顶向下加载,最终生成可执行的 Camx Pipeline 图。

3.2 核心 XML 元素详解

3.2.1 Usecase 定义

Usecase 是配置的入口点。一个典型的 Usecase 定义包含会话参数和引用的 Pipeline 列表。

<Usecase name="UsecasePreview">
    <Session>
        <StreamConfig>
            <Stream dimension="1920x1080" format="NV12" dataspace="0" />
        </StreamConfig>
        <PipelineRef name="PipelinePreview" />
        <PipelineRef name="PipelineMeta" />
    </Session>
</Usecase>

3.2.2 Pipeline 与 Node 组合

Pipeline 内部通过 <Node> 标签组织处理单元。每个 Node 必须指定其类型(HW/SW)和绑定的具体实现。

<Pipeline name="PipelinePreview">
    <Node name="NodeIFE" type="HW" hwBlock="IFE">
        <InputPort name="PortInput" format="RAW10" />
        <OutputPort name="PortFull" format="NV12" dimension="1920x1080" />
        <OutputPort name="PortDS" format="NV12" dimension="640x480" />
    </Node>
    <Node name="NodeBPS" type="HW" hwBlock="BPS">
        <InputPort name="PortInput" format="NV12" />
        <OutputPort name="PortOutput" format="NV12" />
    </Node>
    <Link fromNode="NodeIFE" fromPort="PortFull" toNode="NodeBPS" toPort="PortInput" />
</Pipeline>

3.2.3 Port 与 Link 的精细控制

Port 定义不仅包含格式,还可以配置缓冲区数量、对齐要求等性能相关属性。Link 则负责将数据路径显式化。

性能调优提示: 在 Port 上配置 bufferCount="4" 可以增加流水线深度,掩盖硬件延迟;但会增加内存占用。在 Link 上配置 enableFence="true" 可以启用硬件 fence 同步,减少 CPU 轮询开销。

3.3 XML Schema 与 DTD 验证

为了保证 XML 配置的合法性和一致性,Camx 引入了两套验证机制:XML Schema (XSD) 和 DTD。它们定义了 XML 文档的结构、数据类型和约束规则。

3.3.1 Schema vs DTD 对比

对比维度 XML Schema (XSD) DTD
语法 基于 XML 语法,本身是 XML 文档 非 XML 语法,使用 EBNF 表示法
数据类型 支持丰富的数据类型(int, string, enum, pattern) 仅支持 #PCDATA, EMPTY, ANY 等简单类型
命名空间 原生支持命名空间,适合大型系统 不支持命名空间
约束能力 可定义元素出现次数、顺序、唯一性、外键引用 仅能定义元素出现次数和顺序
Camx 用途 用于验证 运行时配置(如 Usecase/Pipeline 定义) 用于验证 静态元数据(如传感器能力描述)

3.3.2 Schema 验证流程

Camx 在初始化阶段会加载 XSD 文件,对用户提供的 XML 配置进行严格校验。校验失败会导致 Pipeline 创建失败,并输出详细的错误日志。

<!-- 简化的 Camx Pipeline Schema 片段 -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Pipeline">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Node" type="NodeType" maxOccurs="unbounded"/>
                <xs:element name="Link" type="LinkType" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
            <xs:attribute name="name" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="NodeType">
        <xs:sequence>
            <xs:element name="InputPort" type="PortType" minOccurs="0" maxOccurs="unbounded"/>
            <xs:element name="OutputPort" type="PortType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="name" type="xs:string" use="required"/>
        <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>

    <xs:complexType name="LinkType">
        <xs:attribute name="fromNode" type="xs:string" use="required"/>
        <xs:attribute name="fromPort" type="xs:string" use="required"/>
        <xs:attribute name="toNode" type="xs:string" use="required"/>
        <xs:attribute name="toPort" type="xs:string" use="required"/>
    </xs:complexType>
</xs:schema>

3.3.3 常见验证错误与排查

  • Schema 验证失败: 检查 XML 元素顺序是否与 Schema 定义一致;检查必填属性是否缺失。
  • Port 类型不匹配: Link 连接的 fromPort 和 toPort 的 format 属性必须兼容(如 NV12→NV12,或 RAW10→NV12 需要显式转换节点)。
  • Node 引用未定义: Link 中引用的 fromNode/toNode 必须在当前 Pipeline 中已定义。
  • DTD 实体未声明: 使用 DTD 时,所有引用的实体(如 &sensor_name;)必须在 DTD 中预先定义。
避坑指南: 不要手动修改 Schema 文件来绕过验证。正确的做法是调整 XML 配置以符合 Schema 约束。绕过验证可能导致运行时 Pipeline 挂死或硬件超时,且问题极难定位。

3.4 配置验证与调试工具

Camx 提供了一套命令行工具和运行时日志机制,帮助开发者验证和调试 XML 配置。

3.4.1 离线验证工具

在编译阶段,可以使用 camx_xml_validator 工具对 XML 进行离线验证:

# 使用 Schema 验证 Pipeline 配置
camx_xml_validator --schema camx_pipeline.xsd --xml my_pipeline.xml

# 使用 DTD 验证传感器元数据
camx_xml_validator --dtd sensor_meta.dtd --xml sensor_config.xml

3.4.2 运行时日志分析

当 XML 配置加载失败时,Camx 会在 dmesg 或 logcat 中输出关键错误信息。常见日志关键字包括:

  • CamxXML: Schema validation failed — Schema 校验失败
  • CamxXML: Unknown node type — Node 类型未注册
  • CamxXML: Port link mismatch — Port 连接格式不兼容
  • CamxXML: Pipeline graph cycle detected — Pipeline 中存在环路

3.5 本章小结

Camx XML 配置体系通过 Usecase → Pipeline → Node → Port → Link 的五层结构,实现了业务场景与硬件/算法能力的灵活组合。XML Schema 和 DTD 提供了双重验证保障,确保配置的合法性和一致性。掌握这一体系,是进行后续 Pipeline 性能调优和定制化开发的基础。