> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# qtimlmetaparser

> 将 GStreamer 缓冲区中的 ML 推理元数据序列化为文本。

# 概述

`qtimlmetaparser` 是一个 GStreamer 元素，用于将机器学习元数据转换为人类可读且可移植的文本表示。其主要目的是将附加在 GStreamer 缓冲区上的推理结果转换为 **UTF-8 编码文本**，使元数据更易于查看、记录、存储或转发到外部系统。

无论输入格式如何，`qtimlmetaparser` 都专注于提取相关的内部 ML 元数据并将其转换为标准化的文本表示。

### 运行时解析器架构

`qtimlmetaparser` 内部不实现元数据转换逻辑。相反，它作为一个轻量级封装器，在运行时动态加载解析器模块，并将实际的元数据转换工作委托给该模块。这种设计使该元素具备可扩展性，无需修改核心元素实现即可支持不同的输出格式。

当前支持的一个运行时模块是 JSON 解析器模块（`ml-meta-parser-json`）。该模块遍历受支持的 ML 元数据结构，并将其序列化为 JSON 文档。生成的 JSON 输出随后可供下游应用或外部组件用于：

* 日志记录与调试
* 结果归档
* 分析流水线
* 进程间通信
* 与非 GStreamer 软件栈集成

通过将解析后端与元素本身分离，`qtimlmetaparser` 提供了一种灵活的机制，可将 ML 元数据转换为适合开发者查看和系统级集成的可移植文本格式。

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/IMSDK/plugin-reference/images/metaparser0.png" alt="qtimetamux_workflow" />

## 示例流水线

<Steps>
  <Step title="下载所需文件">
    | 文件            | 下载                                                                                                                           | 保存为                         |
    | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
    | YOLOX W8A8 模型 | [Qualcomm AI Hub — YOLOX](https://aihub.qualcomm.com/iot/models/yolox)                                                       | `yolo_x_w8a8.tflite`        |
    | 检测标签          | <a href="/SDKs/IMSDK/labels/yolov8.json" download="yolov8.json">yolov8.json</a>                                              | `yolov8.json`               |
    | 示例视频          | <a href="https://github.com/qualcomm/sample-apps-for-qualcomm-linux/raw/refs/heads/main/artifacts/videos/video.mp4">输入视频</a> | `Draw_1080p_180s_30FPS.mp4` |
  </Step>

  <Step title="将文件复制到设备">
    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      # Replace $HOME to the appropriate device path before running the commands.
      # For QLI:    /root
      # For Ubuntu: /home/ubuntu
      # Modify this based on your platform and ensure files are copied to the correct location on the device.
      # Run from your host machine — replace <user> and <device-ip>

      ssh <user>@<device-ip> "mkdir -p $HOME/{models,labels,media,media/output}"
      scp yolo_x_w8a8.tflite          <user>@<device-ip>:$HOME/models/
      scp yolov8.json                  <user>@<device-ip>:$HOME/labels/
      scp Draw_1080p_180s_30FPS.mp4   <user>@<device-ip>:$HOME/media/
      ```
    </CodeGroup>
  </Step>

  <Step title="连接到设备">
    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      # Run from your host machine — replace <user> and <device-ip>
      ssh <user>@<device-ip>
      ```
    </CodeGroup>
  </Step>

  <Step title="设置环境变量">
    在设备上运行以下命令

    ```bash theme={null}
    export MODEL_NAME=yolo_x_w8a8.tflite
    export LABELS_NAME=yolov8.json
    export SRC_VIDEO_NAME=Draw_1080p_180s_30FPS.mp4
    ```
  </Step>

  <Step title="运行流水线">
    ```bash theme={null}
    gst-launch-1.0 -e --gst-debug=2 \
    filesrc location=$HOME/media/$SRC_VIDEO_NAME ! qtdemux ! h264parse ! \
    v4l2h264dec capture-io-mode=4 output-io-mode=4 ! video/x-raw,format=NV12 ! queue ! \
    tee name=t ! qtimetamux name=obj_mux ! qtivoverlay ! waylandsink fullscreen=true sync=false \
    t. ! queue ! qtimlvconverter ! queue ! \
    qtimltflite model=$HOME/models/$MODEL_NAME delegate=external external-delegate-path=libQnnTFLiteDelegate.so \
      external-delegate-options="QNNExternalDelegate,backend_type=htp,log_level=(string)1;" ! queue ! \
    qtimlpostprocess module=yolov8 labels=$HOME/labels/$LABELS_NAME \
      settings="{\"confidence\": 51.0}" ! text/x-raw ! queue ! obj_mux.
    ```
  </Step>
</Steps>

# 层次结构

[GObject](https://docs.gtk.org/gobject/)<br />
   <Icon icon="arrow-turn-down-right" iconType="solid" />[GstObject](https://gstreamer.freedesktop.org/documentation/gstreamer/gstobject.html?gi-language=c)<br />
      <Icon icon="arrow-turn-down-right" iconType="solid" />[GstElement](https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html?gi-language=c)<br />
         <Icon icon="arrow-turn-down-right" iconType="solid" />[GstBaseTransform](https://gstreamer.freedesktop.org/documentation/base/gstbasetransform.html?gi-language=c)<br />
            <Icon icon="arrow-turn-down-right" iconType="solid" />qtimlmetaparser

# Pad 模板

### sink

| 能力                 |                |
| ------------------ | -------------- |
| `image/jpeg`       | `format: NA`   |
| `video/x-raw(ANY)` | `format: NA`   |
| `text/x-raw`       | `format: utf8` |
| 可用性：*Always*       |                |
| 方向：*sink*          |                |

### src

| 能力           |                |
| ------------ | -------------- |
| `text/x-raw` | `format: utf8` |
| 可用性：*Always* |                |
| 方向：*source*  |                |

# 元素属性

| 属性              | 描述                                                                                                                                                                                                                                                                                               |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `module`        | 用于解析元数据的模块名称。<br /><br />`Type: Enum `<br />`Default: 0, "none"`<br />`Range:`<br />    `(0): none - No module, default invalid mode`<br />    `(1): json - ml-meta-parser-json`<br />`Flags: readable/writable (changeable only in NULL or READY state)` `Example: module="json" (or) module=1` |
| `module-params` | 特定于所选模块的参数，用于解析缓冲区元数据。格式为 GstStructure 字符串。<br /><br />`Type: String`<br />`Default: params`<br />`Flags: readable/writable`                                                                                                                                                                     |

## 内部架构

`qtimlmetaparser` 采用三层架构组织，包括：

1. GStreamer 元素
2. 动态模块加载器
3. 解析器模块

这种职责分离使元素保持轻量、简化了可扩展性，并使元数据转换逻辑能够独立于 GStreamer 集成层进行演进。

### GStreamer 元素

在最顶层，`qtimlmetaparser` 以标准 GStreamer 元素的形式暴露，包含两个 pad：

* **Sink pad** <br />
  接收来自上游元素的输入缓冲区。支持的缓冲区类型包括 JPEG 图像、原始视频帧和 UTF-8 文本缓冲区。

* **Source pad** <br />
  生成与输入缓冲区关联的机器学习元数据的 UTF-8 编码、人类可读的文本表示。

### 动态模块加载器

模块加载器提供了 GStreamer 元素与解析器后端之间的抽象层。其作用是在运行时从共享对象加载解析器实现，并向元素暴露一个小巧且稳定的接口。

这种设计带来两个关键优势：

* **可扩展性** <br />
  无需更改核心元素实现即可添加新的元数据转换后端。

* **简化的模块开发** <br />
  解析器后端只需实现预定义的模块接口。它不需要实现为 GStreamer 元素，也无需包含任何流水线特定的逻辑。

通过将解析器逻辑与元素解耦，加载器实现了一种模块化架构，使转换格式可以独立添加、替换或更新。

### 解析器模块实现

解析器模块实现定义了如何遍历、解释机器学习元数据并将其转换为 UTF-8 文本。

每个模块负责将受支持的元数据结构转换为适合下游消费的可移植文本表示。

以下部分提供了有关**模块系统**和解析器模块接口的更多详细信息。

## 模块系统

`qtimlmetaparser` 使用轻量级运行时模块系统，将元数据序列化工作委托给运行时加载的共享库。这样无需修改元素即可添加新的输出格式。

解析器模块负责将附加在输入缓冲区上的受支持 ML 元数据转换为 UTF-8 文本输出。

典型的元数据类别包括：

**目标检测**— 标签、置信度、颜色以及归一化边界框
**关键点 / 姿态** — 关键点及可选连接
**文本** — OCR 输出、字幕或其他文本注释，包括 VLM 结果
**分类** — 来自图像或音频分类的标签和分数

## JSON 模块

当前支持的解析器模块是 JSON 模块。它通过元素的 module 属性选择：

```bash theme={null}
qtimlmetaparser module=json
```

JSON 模块将附加在输入缓冲区上的 ML 元数据序列化为 JSON 文本输出。这使得下游元素可以存储、显示或传输推理结果，而无需直接解析 GStreamer 元数据。

该模块还通过 module-params 属性支持 attach-frame 参数。当针对 JPEG 输入缓冲区启用时，模块会映射输入缓冲区，对 JPEG 数据进行 Base64 编码，并将其嵌入到生成的 JSON 输出中。

```bash theme={null}
qtimlmetaparser module=json module-params="params,attach-frame=true"
```

这样，推理元数据及对应的帧快照可以承载在单个 JSON 负载中。如果输入缓冲区不是 JPEG 编码的，即使 attach-frame=true 也不会附加帧，输出仅包含序列化的元数据。

### JSON 输出示例

以下示例展示了序列化为 object\_detection 数组的目标检测元数据，以及附加的 Base64 编码 JPEG 缓冲区。为便于阅读，缓冲区内容已截断。

```json theme={null}
{
  "object_detection": [
    {
      "label": "person",
      "confidence": 84.00863647460938,
      "color": 16711935,
      "rectangle": {
        "x": 0.26145833333333335,
        "y": 0.3037037037037037,
        "width": 0.10520833333333333,
        "height": 0.4824074074074074
      }
    },
    {
      "label": "person",
      "confidence": 84.00863647460938,
      "color": 16711935,
      "rectangle": {
        "x": 0.371875,
        "y": 0.33055555555555555,
        "width": 0.0703125,
        "height": 0.45555555555555555
      }
    }
  ],
  "buffer_base64": "/9j/4AAQSkZJRgABAQAAAQABAA...",
  "parameters": {
    "timestamp": "3403400000"
  }
}
```

### 模块参数

<ResponseField name="attach-frame" type="Boolean">
  启用后将映射输入缓冲区并对数据进行 Base64 编码，以便与元数据一起嵌入。仅对 JPEG 输入有效<br />

  标志：*readable, writable*<br />
  默认值：`false`
</ResponseField>

# 处理流程

**Caps 协商** <br />
在流水线设置期间，qtimlmetaparser 与相邻元素协商受支持的 sink 和 source caps。sink pad 接受多种输入类型，包括原始视频、JPEG 和 UTF-8 文本，而 source pad 始终生成 UTF-8 文本。

**属性解析与配置** <br />
Caps 协商完成后，元素会选择 module 属性指定的解析器模块，动态加载它，并为该流创建模块实例。

元素根据 sink caps 确定输入类型，在适用时提取宽度和高度，并将这些信息与用户提供的 module-params 结合。生成的配置在缓冲区处理开始前传递给模块。

**分配与缓冲区准备** <br />
对于原始视频输入，元素在分配协商期间请求 video meta 支持，以在流水线中保留元数据。

对于每个输入缓冲区，元素会为生成的文本分配对应的输出缓冲区。输入时间戳会被保留。如果输入缓冲区被标记为 GAP，元素会将 GAP 状态向下游传播。

**模块执行** <br />
对于每个缓冲区，元素调用所选模块，将附加的 ML 元数据转换为 UTF-8 文本。

使用 json 模块时，它会将受支持的元数据序列化为 JSON 文档。根据配置，它还可以嵌入 Base64 编码的 JPEG 帧数据以及时间戳等附加参数。

序列化后的 UTF-8 输出随后被写入输出缓冲区。

**输出** <br />
元素在 source pad 上以 text/x-raw 形式将输出缓冲区推送到下游。

# 用法

本示例演示了使用 YOLO 检测模型的基本实时摄像头推理流水线。来自 ISP 摄像头的视频帧由推理分支处理，生成的 AI 元数据通过 qtimetamux 元素附加到对应的视频缓冲区。附加的元数据随后由 qtimlmetaparser 解析，序列化为 JSON 格式，并写入文件以供存储或进一步处理。

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/IMSDK/plugin-reference/images/metaparser0.png" alt="qtimetamux_workflow" />

## 主缓冲区、元数据同步与延迟控制

该插件设计为具有一个接收主视频或音频缓冲区的**单一主 sink pad**，以及多个收集 ML 后处理结果或 CV 运动矢量的**辅助数据 pad**。到达辅助 pad 的数据可以字符串或 blob 形式提供，并被解析为结构化表示。解析完成后，插件将每个数据缓冲区与其对应的主媒体帧匹配，并将结果作为 **GstMeta** 附加。

### 异步模式（Async Mode）

这是默认的同步模式。不执行基于时间戳的匹配。相反，元数据缓冲区以严格的 **1:1 顺序**与主帧关联：

* 第 N 个传入的视频/音频帧会被保留，直到**所有**数据 pad 都收到第 N 个数据缓冲区。
* 一旦该帧所需的所有数据都可用，元数据即被附加。
* 随后将丰富后的缓冲区推送到下游。

当媒体缓冲区和元数据缓冲区以固定、可预测的顺序产生时，此模式非常适用。

### 同步模式（Sync Mode）

在同步模式下，插件执行**基于时间戳的同步**。每个传入的主帧最多保留 `1 / framerate` 秒（视频）或 `1 / rate` 秒（音频）的有限时间窗口。例如，在 30 fps 时，帧可能会被保留约 **33.3 ms**。

在此保留期间，插件等待其辅助 pad 上时间戳与主帧时间戳匹配的数据缓冲区：

* 如果所有预期的数据缓冲区都在时间窗口内到达，则在转发前将其附加。
* 如果一个或多个辅助 pad 未能及时提供匹配的缓冲区，则仅附加成功匹配的元数据，并将主缓冲区释放到下游。

### 延迟控制

在某些用例中，同步模式下的默认保留时间可能过短 — 特别是当元数据生成耗时超出预期时。`latency` 属性通过接受以**纳秒**为单位的整数值来延长等待时间，使插件在转发主帧之前能够等待更长时间以接收迟到的数据缓冲区。

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/SDKs/IMSDK/plugin-reference/images/qtimetamux_latency_control.png" alt="qtimetamux_latency_control" />

<Steps>
  <Step title="下载所需文件">
    | 文件      | 下载                                                              | 保存为                           |
    | ------- | --------------------------------------------------------------- | ----------------------------- |
    | YOLO 模型 | [Qualcomm Yolo 模型](https://aihub.qualcomm.com/iot/models/yolox) | `yolov8_det_quantized.tflite` |
    | YOLO 标签 | [labels](https://qimsdk.mintlify.io/labels/yolov8.json)         | `yolov8.json`                 |
  </Step>

  <Step title="将文件复制到设备">
    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      ssh <user>@<device-ip> "mkdir -p $HOME/{models,labels,media}"
      scp yolov8_det_quantized.tflite <user>@<device-ip>:$HOME/models/
      scp yolov8.json                <user>@<device-ip>:$HOME/labels/
      ```
    </CodeGroup>
  </Step>

  <Step title="连接到设备">
    <CodeGroup>
      ```bash SCP (SSH) theme={null}
      ssh <user>@<device-ip>
      ```
    </CodeGroup>
  </Step>

  <Step title="设置环境变量">
    在设备上运行以下命令

    ```bash theme={null}
    mkdir -p $HOME/{models,labels,media}
    ```
  </Step>

  <Step title="运行流水线">
    ```bash theme={null}
    gst-launch-1.0 -e --gst-debug=2 \
    qticamsrc ! video/x-raw,width=1920,height=1080 ! queue ! \
    tee name=t ! queue ! \
    qtimetamux name=metamux ! queue ! \
    qtimlmetaparser module=json ! filesink location=$HOME/media/meta.json \
    t. ! queue ! \
    qtimlvconverter ! queue ! \
    qtimltflite delegate=external external-delegate-path=libQnnTFLiteDelegate.so external-delegate-options="QNNExternalDelegate,backend_type=htp;" model=$HOME/models/yolov8_det_quantized.tflite ! queue ! \
    qtimlpostprocess results=10 module=yolov8 labels=$HOME/models/yolov8.json settings="{\"confidence\": 70.0}" ! text/x-raw ! queue ! \
    metamux.
    ```
  </Step>
</Steps>
