# 探索视频示例应用程序

您可以使用 [Qualcomm IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/qimsdk_landing_page.html) 框架或 V4L2 接口在本地层使用视频功能。Qualcomm 提供基于 GStreamer 和 V4L2 的示例应用程序来运行视频示例用例。

## GStreamer 示例

[Qualcomm IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/qimsdk_landing_page.html) 包含用于视频播放的 GStreamer 示例应用程序。

Note

有关不同 SoC 上支持的示例 GStreamer 应用程序的信息，请参阅 [Multimedia 示例应用程序](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/example-applications.html#multimedia-sample-applications)。

有关 GStreamer 应用程序前提条件的信息，请参阅[运行视频和音频示例应用程序](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/audio-sample-applications.html)。

下表列出了方法和示例视频测试用例：

| 方法 | 用例 |
| --- | --- |
| 使用 `gst-launch-1-0` | [视频播放](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/video-playback-use-cases.html) |
| 使用 `gst-launch-1-0` | [音视频播放](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/audio-video-use-cases.html) |
| 使用 `gst-launch-1-0` | [视频录制](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/camera-and-video-encode.html) |
| 使用 GStreamer 应用程序 | [视频播放](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/gst-video-playback-example.html) |
|  |  |
|  |  |

## V4L2 示例

`iris_v4l2_test` 示例视频测试应用程序使用 Linux V4L2 接口模拟几种基本的编码器和解码器行为。有关详细信息，参见[示例 V4L2 应用程序](https://github.com/quic/v4l-video-test-app)。

Qualcomm Linux 支持以下视频 API：

- [GStreamer API](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#section-r53-mv3-n1c-eputla-02-23-24-1111-38-601)：Qualcomm GStreamer 插件兼容开源 GStreamer 框架。有关基于 GStreamer 的插件的更多信息，请参阅 [Qualcomm IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/qimsdk_landing_page.html)。
- [V4L2 APIs](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#section-nss-w1z-k1c-eputla-02-14-24-2315-20-633)：Adreno VPU 驱动程序遵循符合 V4L2 的标准调用流程。V4L2 API 部分提供了与 V4L2 API、命令、控件和事件相关的信息。

## 配置 GStreamer 和 V4L2 API

- Qualcomm 提供基于 GStreamer 的插件，您可以将其集成到您的媒体 pipeline 中。有关基于 GStreamer 的插件的信息，请参阅[配置 Qualcomm GStreamer 插件](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/qim-sdk-plugins.html)。
- Adreno VPU 驱动程序使用 V4L2 接口支持所有遵循 V4L2 指导的客户端的视频编码和解码。

### GStreamer API

有关 GStreamer 应用程序开发和 pipeline 创建的详细信息，参见 [Building an Application](https://gstreamer.freedesktop.org/documentation/application-development/basics/index.html)。

#### 配置 GStreamer API

有关为不同功能和相应插件配置 GStreamer 元素属性的信息，请参阅[配置 Qualcomm GStreamer 插件](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-50/qim-sdk-plugins.html)。

### V4L2 API

本节介绍解码器和编码器的 V4L2 设备节点、文件操作、命令、控件和事件。

#### VPU 驱动程序节点

设备在启动过程中注册 VPU 驱动程序并分配设备节点号。

- 解码器的 VPU 驱动程序节点：`/dev/video32`
- 编码器的 VPU 驱动程序节点：`/dev/video33`

#### V4L2 文件操作

Adreno VPU 驱动程序支持以下 V4L2 文件操作：

| 操作 | 说明 |
| --- | --- |
| `open` | 使用输入/输出控制 `ioctl` 命令打开用于与 VPU 驱动程序通信的视频设备文件描述符 (FD) |
| `close` | 在视频用例完成后关闭视频设备，并释放与视频设备相关的所有 VPU 驱动程序资源 |
| `poll` | 等待来自 VPU 驱动程序的事件 |
| `ioctl` | 向 VPU 设备发送命令或控件 |

#### 解码器和编码器的 V4L2 常用命令

对于视频解码器和编码器使用案例，VPU 驱动程序支持以下 `ioctl` 命令：

- `VIDIOC_ENUM_FMT`
- `VIDIOC_TRY_FMT`
- `VIDIOC_G_FMT`
- `VIDIOC_S_FMT`
- `VIDIOC_ENUM_FRAMESIZES`
- `VIDIOC_REQBUFS`
- `VIDIOC_QUERY_BUF`
- `VIDIOC_CREATE_BUF`
- `VIDIOC_PREPARE_BUF`
- `VIDIOC_QBUF`
- `VIDIOC_DQBUF`
- `VIDIOC_STREAMON`
- `VIDIOC_STREAMOFF`
- `VIDIOC_QUERYCAP`
- `VIDIOC_QUERYCTRL`
- `VIDIOC_QUERYMENU`
- `VIDIOC_SUBSCRIBE_EVENT`
- `VIDIOC_UNSUBSCRIBE_EVENT`
- `VIDIOC_G_SELECTION`
- `VIDIOC_G_CTRL`
- `VIDIOC_S_CTRL`

#### V4L2 视频解码器

本节提供有关 Adreno VPU 解码器设备节点、支持的控件、命令和事件的信息。有关打开 VPU 解码器节点的步骤，可参见 [VPU 驱动程序节点](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#p-lg1-3cs-s1c-eputla-03-13-24-1448-52-615)。

**解码器的 V4L2 ioctl 命令**

有关标准 `ioctl` 命令的说明，请参阅 [Video for Linux API Function Reference](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/user-func.html)。

除了[常用命令](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#v4l2commoncommands)之外，VPU 驱动程序还支持以下用于视频解码器用例的命令 `ioctl`：

- `VIDIOC_TRY_DECODER_CMD`
- `VIDIOC_DECODER_CMD`

如 [Memory-to-Memory Stateful Video Decoder Interface](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-decoder.html) 中所述，解码器支持视频解码器用例所需的所有强制性命令。

**解码器的 V4L2 开源控件**

有关标准开源控件的说明，参见 [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html)。

VPU 驱动程序支持视频解码器用例的以下开源控件：

| 控件 ID | 目的 | 动态/静态 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_PROFILE` | H.264 解码器 profile | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_PROFILE` | HEVC 解码器 profile | 静态 |
| `V4L2_CID_MPEG_VIDEO_VP9_PROFILE` | VP9 解码器 profile | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_LEVEL` | H.264 解码器 level | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_LEVEL` | HEVC 解码器 level | 静态 |
| `V4L2_CID_MPEG_VIDEO_VP9_LEVEL` | VP9 解码器 level | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_TIER` | HEVC 解码器 tier | 静态 |

解码器支持以下 V4L2 开源事件：

- `V4L2_EVENT_EOS`
- `V4L2_EVENT_SOURCE_CHANGE`
- `V4L2_EVENT_CTRL`

解码器支持以下 V4L2 命令：

- `V4L2_DEC_CMD_START`
- `V4L2_DEC_CMD_STOP`

#### V4L2 视频编码器

本节提供有关 Adreno VPU 编码器设备节点、支持的控件、命令和事件的信息。有关打开 VPU 编码器节点的步骤，可参见 [VPU 驱动程序节点](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#p-lg1-3cs-s1c-eputla-03-13-24-1448-52-615)。

**编码器的 V4l2 ioctl 命令**

有关标准 `ioctl` 命令的说明，请参阅 [Function Reference](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/user-func.html)。

除了[常用命令](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html#v4l2commoncommands)之外，VPU 驱动程序还支持以下用于编码用例的命令 `ioctl`：

- `VIDIOC_ENUM_FRAMEINTERVALS`
- `VIDIOC_S_SELECTION`
- `VIDIOC_S_PARM`
- `VIDIOC_G_PARM`
- `VIDIOC_TRY_ENCODER_CMD`
- `VIDIOC_ENCODER_CMD`

如 [Memory-to-Memory Stateful Video Encoder Interface](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-encoder.html) 中所述，编码器支持视频编码器用例所需的所有强制性命令。

**编码器的 V4L2 开源控件**

有关标准开源控件的说明，参见 [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html)。

VPU 驱动程序支持视频编码器使用案例的以下开源控件：

| 控件 ID | 目的 | 动态/静态 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_PROFILE` | H.264 编码器 profile | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_PROFILE` | HEVC 编码器 profile | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_LEVEL` | H.264 编码器 level | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_LEVEL` | HEVC 编码器 level | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_TIER` | H.264 编码器 tier | 静态 |
| `V4L2_CID_HFLIP` | 水平翻转 | 两者 |
| `V4L2_CID_VFLIP` | 垂直翻转 | 两者 |
| `V4L2_CID_ROTATE` | 旋转 | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEADER_MODE` | 标头模式 | 静态 |
| `V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR` | 带瞬时解码器刷新 (IDR) 帧的 SPS/PPS | 静态 |
| `V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME` | 请求强制同步帧 | 两者 |
| `V4L2_CID_MPEG_VIDEO_BITRATE` | 平均码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_BITRATE_PEAK` | 峰值码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_BITRATE_MODE` | 码率控制 | 静态 |
| `V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE` | 跳帧模式 | 静态 |
| `V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE` | RC 启用/禁用 | 静态 |
| `V4L2_CID_MPEG_VIDEO_GOP_SIZE` | 图片组大小 | 两者 |
| `V4L2_CID_MPEG_VIDEO_B_FRAMES` | B 帧 | 静态 |
| `V4L2_CID_MPEG_VIDEO_LTR_COUNT` | LTR 帧数 | 静态 |
| `V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES` | 使用 LTR | 两者 |
| `V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX` | 标记 LTR | 两者 |
| `V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID` | 设置层编码的基本层 ID | 静态 |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE` | Intra-refresh | 静态 |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD` | Intra-refresh 周期 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_MIN_QP` | H.264 最小量化参数 (QP) | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP` | HEVC 最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_MAX_QP` | H.264 最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP` | HEVC 最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP` | H.264 I 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP` | HEVC I 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP` | H.264 P 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP` | HEVC P 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP` | H.264 B 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP` | HEVC B 帧最小 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP` | H.264 I 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP` | HEVC I 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP` | H.264 P 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP` | HEVC P 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP` | H.264 B 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP` | HEVC B 帧最大 QP | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP` | HEVC I 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP` | H.264 I 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP` | HEVC P 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP` | H.264 P 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP` | HEVC B 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP` | H.264 B 帧 QP | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE` | HEVC Hier 编码类型 | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE` | H.264 Hier 编码类型 | 静态 |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING` | H.264 Hier 编码 | 静态 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER` | HEVC Hier 层数 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER` | H.264 Hier 层数 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR` | H.264 layer 0 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR` | HEVC layer 0 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR` | H.264 layer 1 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR` | HEVC layer 1 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR` | H.264 layer 2 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR` | HEVC layer 2 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR` | H.264 layer 3 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR` | HEVC layer 3 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR` | H.264 layer 4 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR` | HEVC layer 4 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR` | H.264 layer 5 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR` | HEVC layer 5 码率 | 两者 |
| `V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE` | H.264 熵模式 | 静态 |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE` | 编码 slice 模式 | 静态 |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES` | slice 中的最大字节数 | 静态 |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB` | slice 中的最大宏块数 | 静态 |

所有静态配置选项都在设置两个平面上的格式之后以及在任一平面上请求缓存之前进行设置。在两个平面上设置格式后调用动态参数。

有关 Codec 的 V4L2 控件的信息，请参阅 [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html)。

编码器支持的开源事件包括：

- `V4L2_EVENT_EOS`
- `V4L2_EVENT_CTRL`

编码器支持的开源命令包括：

- `V4L2_ENC_CMD_START`
- `V4L2_ENC_CMD_STOP`

#### 配置 V4L2 API

使用本节提供的 V4L2 控件 ID、接受格式、接受范围和示例代码信息，可配置和管理设备上的不同视频功能。

**B 帧编码**

您可以使用 `VIDIOC_S_CTRL` ioctl 系统调用配置 VPU 驱动程序以在编码器会话中设置 B 帧。在输出平面上设置 `VIDIOC_STREAMON` 之前，请先设置 B 帧编码配置。VPU 驱动程序仅支持使用分层编码的 B 帧编码。此功能不支持动态配置。

| H.264 和 HEVC codec 的控件 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_B_FRAMES` | 整型 | <ul class="simple"><br><li><p>{0, 1}</p></li><br><li><p>0：禁用 B 帧</p></li><br><li><p>1：启用单个 B 帧</p></li><br></ul> |

以下代码示例显示了单个 B 帧的静态配置：

v4l2_control control;
    int ret = 0;
    int bframes = 1;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
    control.value = bframes;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE;
    control.value = 0;// V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER;
    control.value = 1;//Enable 1 layer
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

**编码器初始 QP 覆盖**

您可以配置 VPU 驱动程序，将 I 帧、P 帧和 B 帧的初始帧量化参数 (QP) 覆盖为编码帧的预期值。您可以使用 `VIDIOC_S_CTRL` ioctl 系统调用进行覆盖。QP 覆盖功能还允许灵活地设置仅用于 I 帧、或仅 P 帧、或仅 B 帧、或仅 I 帧和 P 帧、或仅 P 帧和 B 帧或这些帧的组合。在输出平面上的 `VIDIOC_STREAMON` 之前设置编码器初始 QP 覆盖配置，并且仅适用于编码器会话。

| H.264 codec 的控制 ID | 接受的格式 | QP 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
|  |  |  |
|  |  |  |

| HEVC  codec 的控件 ID | 接受的格式 | QP 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QPI` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP` | 整型 | 符合 codec 标准的示例：<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>8 位为 1 到 51</p></li><br>> <li><p>10 位为 1 到 63（-12 至 51）</p></li><br>> </ul> |
|  |  |  |
|  |  |  |

以下代码示例显示了用于选择下列选项的静态配置参数：

- 40 作为 I 帧的初始 QP
- 35 作为 P 帧的初始 QP
- B 帧用于 H.264 会话

v4l2_control control;
    int ret = 0;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
    control.value = 40;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
    control.value = 35;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP;
    control.value = 35;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

**slice 编码**

可以将 VPU 驱动程序配置为使用 `VIDIOC_S_CTRL` ioctl 系统调用将单个帧编码为多个 slice 。每个 slice 的位数或每个切片的宏块数是 slice 边界。在输出平面的 `VIDIOC_STREAMON` 之前设置 slice 编码配置。slice 编码功能不支持动态配置，此配置仅适用于编码器会话。

| H.264 和 HEVC codec 的控件 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE` | enum<br><br><br><br>> <br>> <br>> `v4l2_mpeg_video_multi_slice_mode` | 符合 codec 标准的值：<br><br><br><br>> <br>> <br>> enum<br>> <br>> <br>> `v4l2_mpeg_video_multi_slice_mode` |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES` | 整型 | 512 - MAX\_BITRATE/8<br><br><br><br>> <br>> <br>> 单位：比特/秒 |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB` | 整型 | 1 到 36864<br><br><br><br>> <br>> <br>> 单位：宏块 |

以下代码示例展示了一个用于编码具有多个 slice 的帧，并将每个 slice 的最大宏块数设置为 400 的静态配置：

v4l2_control control;
    int ret = 0;
    v4l2_mpeg_video_multi_slice_mode slicemode = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE;
    control.value = slicemode;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB;
    control.value = 400;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

**Intra-refresh**

可以使用 `VIDIOC_S_CTRL` ioctl 系统调用将 VPU 驱动程序配置为启用 Intra-refresh 模式和 Intra-refresh 周期。在输出平面的 `VIDIOC_STREAMON` 之前设置 Intra-refresh 配置。您可以在会话期间动态更改 Intra-refresh 周期，此功能仅适用于编码器会话。

| H.264 和 HEVC codec 的控件 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE` | enum<br><br><br><br>> <br>> <br>> `v4l2_mpeg_video_intra_refresh_period_type` | `{V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM, V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC}`<br><br><br><br>> <br>> <br>> 随机模式：<br>> <br>> <br>> `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM`<br>> <br>> <br>> 循环模式：<br>> <br>> <br>> `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC` |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD` | 整型 | 将 Intra-refresh 周期设置为小于 I 帧间隔<br><br><br><br>> <br>> <br>> 单位：帧数 |

以下代码示例展示了为每 10 帧启用随机内部刷新的静态配置：

v4l2_control control;
    int ret = 0;
    v4l2_mpeg_video_intra_refresh_period_type refreshtype = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM;
    
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE;
    control.value = refreshtype;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD;
    control.value = 10;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

**旋转**

可以将 VPU 驱动程序配置为在使用 `VIDIOC_S_CTRL` 系统调用进行编码之前旋转输入帧。在输出平面的 `VIDIOC_STREAMON` 之前设置旋转配置。旋转功能不支持动态配置，仅适用于编码器会话。

| H264 和 HEVC codec 的控件 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_ROTATE` | 整型 | {90, 180, 270}<br><br><br><br>> <br>> <br>> 单位：度 |

以下代码示例展示了将输入帧旋转到 90 度的静态配置：

v4l2_control control;
    int ret = 0;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_ROTATE;
    control.value = 90;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

**帧 QP 范围**

可以使用 `VIDIOC_S_CTRL` ioctl 系统调用配置 VPU 驱动程序，以将 I 帧、P 帧和 B 帧的最小和最大帧 QP 范围参数设置为编码帧的预期值。设置输出平面上 `VIDIOC_STREAMON` 之前的帧 QP 范围配置。这些值对整个会话有效。不支持动态配置，帧 QP 功能仅适用于编码器会话。

| H.264 codec 的控制 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP` | 整型 | 符合 codec 标准的示例：8 位为 1 到 51 |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |

以下代码示例展示了静态配置参数，用于选择 40 作为 H.264 会话中 I 帧、P 帧和 B 帧的最大 QP，选择 10 作为最小 QP：

v4l2_control control;
    int ret = 0;
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP;
    control.value = 10;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP;
    control.value = 10;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP;
    control.value = 10;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP;
    control.value = 40;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP;
    control.value = 40;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    memset(&control, 0, sizeof(control));
    control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP;
    control.value = 40;
    ret = ioctl(mDriverFd, VIDIOC_S_CTRL, &control);// mDriverFd returned from open() system call
    if (ret) {
        return -1;
    }
    Copy to clipboard

如果需要为 I 帧、P 帧和 B 帧设置具有相同的最小和最大 QP 值，可以配置以下控件：

| H.264 codec 的控制 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_MIN_QP` | 整型 | 符合代码标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_H264_MAX_QP` | 整型 | 符合代码标准的示例：8 位为 1 到 51 |
|  |  |  |

| HEVC  codec 的控件 ID | 接受的格式 | 范围 |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP` | 整型 | 符合代码标准的示例：8 位为 1 到 51 |
| `V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP` | 整型 | 符合代码标准的示例：8 位为 1 到 51 |
|  |  |  |

## 后续步骤

- [排查视频故障](https://docs.qualcomm.com/doc/80-70022-20SC/topic/bring-up.html#concept-lkc-ny3-bzb)
- [视频规格](https://docs.qualcomm.com/doc/80-70022-20SC/topic/feature-descriptions.html#section-tmv-51x-k1c-eputla-02-14-24-1638-44-607)

Last Published: Nov 03, 2025

[Previous Topic
构建视频源组件](https://docs.qualcomm.com/bundle/publicresource/80-70022-20SC/topics/software.md) [Next Topic
排除视频故障](https://docs.qualcomm.com/bundle/publicresource/80-70022-20SC/topics/bring-up.md)

Source: [https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html](https://docs.qualcomm.com/doc/80-70022-20SC/topic/interfaces.html)