# APIs and sample applications

Qualcomm Linux supports the following video APIs:

- [GStreamer APIs](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#section-r53-mv3-n1c-eputla-02-23-24-1111-38-601): The Qualcomm GStreamer plugins are open-source GStreamer framework compliant. You can find information about various GStreamer based plugins in the [IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/overview.html).
- [V4L2 APIs](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#section-nss-w1z-k1c-eputla-02-14-24-2315-20-633): The Adreno VPU driver follows a standard V4L2-compliant call flow. You can find information on V4L2 APIs, commands, controls, and events in this section.

## GStreamer APIs

Qualcomm offers GStreamer-based plugins that can be integrated into your media pipeline. For more information on the GStreamer-based plugins, see [Qualcomm GST plugins](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/qim-sdk-plugins.html).

For more information on the GStreamer application development and pipeline creation, see [Building an Application](https://gstreamer.freedesktop.org/documentation/application-development/basics/index.html).

### Configure GStreamer APIs

For more information on the GStreamer element property for different features and respective plugins, see [Qualcomm GST plugins](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/qim-sdk-plugins.html).

## V4L2 APIs

The Adreno VPU driver is based on the V4L2 interface, and supports video encode and decode for all clients that adhere to the V4L2 guidance.

This section describes V4L2 device nodes, file operations, commands, controls, and events for decoder and encoder.

### VPU driver nodes

The VPU driver is registered during the boot up process and assigns the device node number.

- VPU driver node for decoder: `/dev/video32`
- VPU driver node for encoder: `/dev/video33`

### V4L2 file operations

The Adreno VPU driver supports the following V4L2 file operations:

| Operation | Description |
| --- | --- |
| `open` | Opens the video device file descriptor (FD) that is used to communicate with the VPU driver using the `ioctl` commands |
| `close` | Closes the video device upon the completion of a video use case, and releases all the VPU driver resources related to the video device |
| `poll` | Waits for the events from the VPU driver |
| `ioctl` | Sends commands or controls to the VPU device |

### V4L2 common commands for decoder and encoder

The following are the `ioctl` commands supported by the VPU driver for the video decoder and encoder use cases:

- `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 video decoder

The Adreno VPU decoder device node, supported controls, commands, and events are described in the following topics. For the procedure to open a VPU decoder node, see [VPU driver nodes](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#p-lg1-3cs-s1c-eputla-03-13-24-1448-52-615).

**V4L2 ioctl commands for decoder**

For descriptions of the standard `ioctl` commands, see [Video for Linux API Function Reference](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/user-func.html).

In addition to the [common commands](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#v4l2commoncommands), the following are the `ioctl` commands supported by the VPU driver for the video decoder use cases:

- `VIDIOC_TRY_DECODER_CMD`
- `VIDIOC_DECODER_CMD`

All the mandatory commands required for the video decoder use cases, as specified in the [Video Decoder Interface](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-decoder.html), are supported.

**V4L2 open-source controls for decoder**

For descriptions of the standard open-source controls, see [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html).

The following table lists the open-source controls supported by the VPU driver for the video decoder use cases:

| Control ID | Purpose | Dynamic/Static |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_PROFILE` | H.264 decoder profile | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_PROFILE` | HEVC decoder profile | Static |
| `V4L2_CID_MPEG_VIDEO_VP9_PROFILE` | VP9 decoder profile | Static |
| `V4L2_CID_MPEG_VIDEO_H264_LEVEL` | H.264 decoder level | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_LEVEL` | HEVC decoder level | Static |
| `V4L2_CID_MPEG_VIDEO_VP9_LEVEL` | VP9 decoder level | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_TIER` | HEVC decoder tier | Static |

The following are the supported V4L2 open-source events for the decoder:

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

The following are the supported V4L2 commands for the decoder:

- `V4L2_DEC_CMD_START`
- `V4L2_DEC_CMD_STOP`

### V4L2 video encoder

The Adreno VPU encoder device node, supported controls, commands, and events are described in the following topics. For the procedure to open a VPU encoder node, see [VPU driver nodes](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#p-lg1-3cs-s1c-eputla-03-13-24-1448-52-615).

**V4l2 ioctl commands for encoder**

For descriptions of the standard `ioctl` commands, see [Video for Linux API Function Reference](https://www.kernel.org/doc/html/v4.9/media/uapi/v4l/user-func.html).

In addition to the [common commands](https://docs.qualcomm.com/doc/80-70017-20/topic/interfaces.html#v4l2commoncommands), the following are the `ioctl` commands supported by the VPU driver for the encode use cases:

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

All the mandatory commands required for the video encoder use cases, as specified in the [Video Encoder Interface](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/dev-encoder.html), are supported.

**V4L2 open-source controls for encoder**

For descriptions of the standard open-source controls, see [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html).

The following table lists the supported open-source controls available in the VPU driver for the video encoder use cases:

| Control ID | Purpose | Dynamic/Static |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_PROFILE` | H.264 encoder profile | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_PROFILE` | HEVC encoder profile | Static |
| `V4L2_CID_MPEG_VIDEO_H264_LEVEL` | H.264 encoder level | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_LEVEL` | HEVC encoder level | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_TIER` | H.264 encoder tier | Static |
| `V4L2_CID_HFLIP` | Horizontal flip | Both |
| `V4L2_CID_VFLIP` | Vertical flip | Both |
| `V4L2_CID_ROTATE` | Rotation | Static |
| `V4L2_CID_MPEG_VIDEO_HEADER_MODE` | Header mode | Static |
| `V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR` | SPS/PPS with IDR frame | Static |
| `V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME` | Request force sync frame | Both |
| `V4L2_CID_MPEG_VIDEO_BITRATE` | Average bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_BITRATE_PEAK` | Peak bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_BITRATE_MODE` | Rate control | Static |
| `V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE` | Frame skip mode | Static |
| `V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE` | RC enable/disable | Static |
| `V4L2_CID_MPEG_VIDEO_GOP_SIZE` | Group-of-pictures size | Both |
| `V4L2_CID_MPEG_VIDEO_B_FRAMES` | B-frames | Static |
| `V4L2_CID_MPEG_VIDEO_LTR_COUNT` | LTR frame count | Static |
| `V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES` | Use LTR | Both |
| `V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX` | Mark LTR | Both |
| `V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID` | Set base layer ID for layer encode | Static |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE` | Intra-refresh | Static |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD` | Intra-refresh period | Both |
| `V4L2_CID_MPEG_VIDEO_H264_MIN_QP` | H.264 minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP` | HEVC minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_MAX_QP` | H.264 maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP` | HEVC maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP` | H.264 I-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP` | HEVC I-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP` | H.264 P-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP` | HEVC P-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP` | H.264 B-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP` | HEVC B-frame minimum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP` | H.264 I-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP` | HEVC I-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP` | H.264 P-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP` | HEVC P-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP` | H.264 B-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP` | HEVC B-frame maximum QP | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP` | HEVC I-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP` | H.264 I-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP` | HEVC P-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP` | H.264 P-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP` | HEVC B-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP` | H.264 B-frame QP | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE` | HEVC Hier coding type | Static |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE` | H.264 Hier coding type | Static |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING` | Enables H.264 Hier coding | Static |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER` | HEVC Hier layer count | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER` | H.264 Hier layer count | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR` | H.264 layer 0-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR` | HEVC layer 0-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR` | H.264 layer 1-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR` | HEVC layer 1-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR` | H.264 layer 2-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR` | HEVC layer 2-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR` | H.264 layer 3-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR` | HEVC layer 3-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR` | H.264 layer 4-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR` | HEVC layer 4-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR` | H.264 layer 5-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR` | HEVC layer 5-bit rate | Both |
| `V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE` | H.264 entropy mode | Static |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE` | Encode slice mode | Static |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES` | Maximum bytes in slice | Static |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB` | Maximum macroblocks in slice | Static |

Set all static configuration options after setting the formats on both the planes and before requesting buffers on either of the planes. The dynamic parameters can be called after setting the formats on both the planes.

For more information on the V4L2 controls for encoder, see [Codec Control Reference](https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/ext-ctrls-codec.html).

The following are the supported open-source events for encoder:

- `V4L2_EVENT_EOS`
- `V4L2_EVENT_CTRL`

The following are the supported open-source commands for encoder:

- `V4L2_ENC_CMD_START`
- `V4L2_ENC_CMD_STOP`

### Configure V4L2 APIs

The following information is about V4L2 control IDs, accepted format, ranges, and sample code for different features.

**B-frame encode**

You can configure the VPU driver to enable B-frames in an encoder session using the `VIDIOC_S_CTRL` ioctl system call. Set the B-frame encode configuration before the `VIDIOC_STREAMON` on an output plane. The VPU driver supports B-frame encode only with the Hierarchical coding. Dynamic configuration is not supported.

| Control ID for H.264 and HEVC codec | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_B_FRAMES` | Integer | <ul class="simple"><br><li><p>{0, 1}</p></li><br><li><p>0: Disable B-frame</p></li><br><li><p>1: Enable 1 B-frame</p></li><br></ul> |

The following code sample shows the static configuration to enable a single B-frame:

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

**Encoder initial QP override**

You can configure the VPU driver to override the initial frame Quantization Parameter (QP) for I, P, and B frames to an intended value of encoded frames. This override is performed using the `VIDIOC_S_CTRL` ioctl system call. The override also has the flexibility to set the initial frame QP for I-frame only, or P-frame only, or B-frame only, or I-frame and P-frame only, or P-frame and B-frame only or combinations of these frames. The encoder initial QP override configuration is set before the `VIDIOC_STREAMON` on an output plane and is only applicable to an encoder session.

| Control ID for H.264 codec | Accepted format | QP range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
|  |  |  |
|  |  |  |

| Control ID for HEVC codec | Accepted format | QP range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QPI` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP` | Integer | <br>Example according to the codec standard:<br><br><br><br>> <br>> <br>> <ul class="simple"><br>> <li><p>1 to 51 for 8‑bit</p></li><br>> <li><p>1 to 63 (-12 to 51) for 10‑bit</p></li><br>> </ul> |
|  |  |  |
|  |  |  |

The following code sample shows the static configuration parameter to choose the following:

- 40 as an initial QP for I-frame
- 35 as an initial QP for P-frame
- B-frame for H.264 session

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 encode**

You can configure the VPU driver to encode a single frame to multiple slices using the `VIDIOC_S_CTRL` ioctl system call. A slice boundary is specified as the number of bits per slice or the number of macroblocks per slice. The slice encode configuration is set before the `VIDIOC_STREAMON` on an output plane. Dynamic configuration is not supported in this feature, and this configuration is applicable only to an encoder session.

| Control ID for H.264 and HEVC | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE` | enum<br><br><br><br>> <br>> <br>> `v4l2_mpeg_video_multi_slice_mode` | Values according to the codec standard:<br><br><br><br>> <br>> <br>> enum<br>> <br>> <br>> `v4l2_mpeg_video_multi_slice_mode` |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES` | Integer | 512 - MAX\_BITRATE/8<br><br><br><br>> <br>> <br>> Unit: bits/second |
| `V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB` | Integer | 1 to 36864<br><br><br><br>> <br>> <br>> Unit: Macroblocks |

The following code sample shows the static configuration to encode frames with multiple slices and with the maximum number of macroblocks per slice set to 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**

You can configure the VPU driver to enable the intra-refresh mode and intra-refresh period using the `VIDIOC_S_CTRL` ioctl system call. The intra-refresh configuration is set before the `VIDIOC_STREAMON` on an output plane. It is to be noted that the intra-refresh period can be modified dynamically during the session and this feature is applicable only to an encoder session.

| Control ID for H.264 and HEVC | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE` | enum<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>Random mode:<br><br><br>`V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM`<br><br><br>Cyclic mode:<br><br><br>`V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC` |
| `V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD` | Integer | Set the intra-refresh period to be less than an I-frame interval<br><br><br>Unit: number of frames |

The following code sample shows the static configuration to enable the random intra refresh for every 10 frames:

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

**Rotation**

You can configure the VPU driver to rotate the input frame before encoding using the `VIDIOC_S_CTRL` ioctl system call. The rotation configuration is set before the `VIDIOC_STREAMON` on an output plane. The rotation feature does not support dynamic configuration and is applicable only to an encoder session.

| Control ID for H264 and HEVC | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_ROTATE` | Integer | {90, 180, 270}<br><br><br>Unit: degrees |

The following code sample shows the static configuration for rotating an input frame to 90 degrees:

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

**Frame QP range**

You can configure the VPU driver to set the minimum and maximum frame QP range parameters for I, P, and B frames to the intended values for encoded frames using the `VIDIOC_S_CTRL` ioctl system call. Set the frame QP range configuration before the `VIDIOC_STREAMON` on an output plane. The values are valid for an entire session. Dynamic configuration is not supported, and the frame QP feature is applicable only to an encoder session.

| Control ID for H.264 codec | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP` | <br>Integer | <br>Example according to the codec standard: 1 to 51 for 8‑bit |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |
|  |  |  |

The following code sample shows the static configuration parameter to choose 40 as the maximum QP and 10 as the minimum QP for the I, P, and B-frames in a H.264 session:

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

Alternatively, you can configure the following controls if you wish to have the same minimum and maximum QP value for I, P, and B-frames:

| Control ID for H.264 codec | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_H264_MIN_QP` | <br>Integer | <br>Example according to the code standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_H264_MAX_QP` | <br>Integer | <br>Example according to the code standard: 1 to 51 for 8‑bit |
|  |  |  |

| Control ID for HEVC codec | Accepted format | Range |
| --- | --- | --- |
| `V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP` | Integer | <br>Example according to the code standard: 1 to 51 for 8‑bit |
| `V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP` | Integer | <br>Example according to the code standard: 1 to 51 for 8‑bit |
|  |  |  |

## Sample applications

The video functionality can be effectively used at the native layer by using the the [IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/overview.html) framework or by using the V4L2 interfaces. Qualcomm provides GStreamer-based sample applications and V4L2 that enable you to run the sample use cases.

### GStreamer samples

The sample GStreamer applications for video playback are part of the [IM SDK](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/overview.html).
To understand more about the prerequisites for the GStreamer applications, see [Sample applications](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/audio-sample-applications.html).

The following table lists the methods and sample video test cases:

| Method | Use case |
| --- | --- |
| <br>Using `gst-launch-1-0` | [Video only playback](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/video-playback-use-cases.html) |
| <br>Using `gst-launch-1-0` | [Audio and video playback](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/audio-video-use-cases.html) |
| <br>Using `gst-launch-1-0` | [Video recording](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/camera-and-video-encode.html) |
| Using the GStreamer application | [Video playback and recording](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-50/gst-video-playback-example.html) |
|  |  |
|  |  |

### V4L2 samples

The `iris_v4l2_test` is a sample video test application that uses Linux V4L2 interfaces to simulate several basic encoder and decoder behaviors. For more information, see [sample V4L2 application](https://github.com/quic/v4l-video-test-app).

Last Published: Dec 30, 2024

[Previous Topic
Architecture and features](https://docs.qualcomm.com/bundle/publicresource/80-70017-20/topics/architecture.md) [Next Topic
Software](https://docs.qualcomm.com/bundle/publicresource/80-70017-20/topics/software.md)

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