Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 99 additions & 21 deletions Runner/suites/Multimedia/Video/README_Video.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,28 @@ Video scripts automates the validation of video encoding and decoding capabiliti
## Features

- V4L2 driver level test
- Encoding YUV to H264 bitstream
- Decoding H264 bitstream to YUV
- Encoding YUV to H264/H265 bitstream
- Decoding H264/H265/VP9 bitstream to YUV
- Compatible with Yocto-based root filesystem
- Supports both encode and decode test modes.
- Parses and runs multiple JSON config files.
- Automatically fetches missing input clips from a predefined URL.
- Supports timeout, repeat, dry-run, and JUnit XML output.
- Performs dmesg scanning for kernel errors.
- Generates summary reports.

## Prerequisites

Ensure the following components are present in the target Yocto build:

- `iris_v4l2_test` (available in /usr/bin/) - this test app can be compiled from https://github.com/quic/v4l-video-test-app
- input json file for iris_v4l2_test app
- input json config files for encode/decode tests
- input bitstream for decode script
- input YUV for encode script
- Write access to root filesystem (for environment setup)
- POSIX shell utilities: grep, sed, awk, find, sort
- Optional: run_with_timeout function from functestlib.sh
- Internet access (for fetching missing clips)

## Directory Structure

Expand All @@ -31,12 +40,16 @@ Runner/
├── suites/
│ ├── Multimedia/
│ │ ├── Video/
│ │ │ ├── iris_v4l2_video_encode/
│ │ │ │ ├── H264Encoder.json
│ │ │ ├── Video_V4L2_Runner/
│ │ │ │ ├── h264Decoder.json
│ │ │ │ ├── h265Decoder.json
│ │ │ │ ├── vp9Decoder.json
│ │ │ │ ├── h264Encoder.json
│ │ │ │ ├── h265Encoder.json
│ │ │ │ ├── run.sh
│ │ │ ├── iris_v4l2_video_decode/
│ │ │ │ ├── H264Decoder.json
│ │ │ ├── run.sh
│ │ │ ├── README_Video.md
├── utils/
│ ├── lib_video.sh
```

## Usage
Expand All @@ -55,24 +68,89 @@ git clone <this-repo>
cd <this-repo>
scp -r Runner user@target_device_ip:<Path in device>
ssh user@target_device_ip
cd <Path in device>/Runner && ./run-test.sh iris_v4l2_video_encode
cd <Path in device>/Runner && ./run-test.sh Video_V4L2_Runner
```
Sample output:
```
sh-5.2# cd <Path in device>/Runner && ./run-test.sh iris_v4l2_video_encode
[Executing test case: <Path in device>/Runner/suites/Multimedia/Video/iris_v4l2_video_encode] 1980-01-08 22:22:15 -
[INFO] 1980-01-08 22:22:15 - -----------------------------------------------------------------------------------------
[INFO] 1980-01-08 22:22:15 - -------------------Starting iris_v4l2_video_encode Testcase----------------------------
[INFO] 1980-01-08 22:22:15 - Checking if dependency binary is available
[PASS] 1980-01-08 22:22:15 - Test related dependencies are present.
...
[PASS] 1980-01-08 22:22:17 - iris_v4l2_video_encode : Test Passed
[INFO] 1980-01-08 22:22:17 - -------------------Completed iris_v4l2_video_encode Testcase----------------------------
sh-5.2# ./run-test.sh Video_V4L2_Runner
[Executing test case: Video_V4L2_Runner] 2025-09-02 05:08:36 -
[INFO] 2025-09-02 05:08:36 - ----------------------------------------------------------------------
[INFO] 2025-09-02 05:08:36 - ------------------ Starting Video_V4L2_Runner (generic runner) ----------------
[INFO] 2025-09-02 05:08:36 - === Initialization ===
[INFO] 2025-09-02 05:08:36 - TIMEOUT=60s STRICT=0 DMESG_SCAN=1 SUCCESS_RE=SUCCESS
[INFO] 2025-09-02 05:08:36 - LOGLEVEL=15
[INFO] 2025-09-02 05:08:36 - REPEAT=1 REPEAT_DELAY=0s REPEAT_POLICY=all
[INFO] 2025-09-02 05:08:36 - No config argument passed, searching for JSON files in ./Runner/suites/Multimedia/Video/
[INFO] 2025-09-02 05:08:36 - Configs to run:
- ./Runner/suites/Multimedia/Video/Video_V4L2_Runner/h264Decoder.json
- ./Runner/suites/Multimedia/Video/Video_V4L2_Runner/h264Encoder.json
- ./Runner/suites/Multimedia/Video/Video_V4L2_Runner/h265Decoder.json
- ./Runner/suites/Multimedia/Video/Video_V4L2_Runner/h265Encoder.json
- ./Runner/suites/Multimedia/Video/Video_V4L2_Runner/vp9Decoder.json
[INFO] 2025-09-02 05:08:37 - No relevant, non-benign errors for modules [oom|memory|BUG|hung task|soft lockup|hard lockup|rcu|page allocation failure|I/O error] in recent dmesg.
[PASS] 2025-09-02 05:08:37 - [Decode1] PASS (1/1 ok)
[INFO] 2025-09-02 05:08:39 - No relevant, non-benign errors for modules [oom|memory|BUG|hung task|soft lockup|hard lockup|rcu|page allocation failure|I/O error] in recent dmesg.
[PASS] 2025-09-02 05:08:39 - [Encode1] PASS (1/1 ok)
[INFO] 2025-09-02 05:08:55 - No relevant, non-benign errors for modules [oom|memory|BUG|hung task|soft lockup|hard lockup|rcu|page allocation failure|I/O error] in recent dmesg.
[PASS] 2025-09-02 05:08:55 - [Decode2] PASS (1/1 ok)
[INFO] 2025-09-02 05:08:57 - No relevant, non-benign errors for modules [oom|memory|BUG|hung task|soft lockup|hard lockup|rcu|page allocation failure|I/O error] in recent dmesg.
[PASS] 2025-09-02 05:08:57 - [Encode2] PASS (1/1 ok)
[INFO] 2025-09-02 05:09:01 - No relevant, non-benign errors for modules [oom|memory|BUG|hung task|soft lockup|hard lockup|rcu|page allocation failure|I/O error] in recent dmesg.
[PASS] 2025-09-02 05:09:01 - [Decode3] PASS (1/1 ok)
[INFO] 2025-09-02 05:09:01 - Summary: total=5 pass=5 fail=0 skip=0
[PASS] 2025-09-02 05:09:01 - Video_V4L2_Runner: PASS
[PASS] 2025-09-02 05:09:01 - Video_V4L2_Runner passed

[INFO] 2025-09-02 05:09:01 - ========== Test Summary ==========
PASSED:
Video_V4L2_Runner

FAILED:
None

SKIPPED:
None
[INFO] 2025-09-02 05:09:01 - ==================================
```
3. Results will be available in the `Runner/suites/Multimedia/Video/` directory under each usecase folder.

4. Results will be available in the `Runner/suites/Multimedia/Video/Video_V4L2_Runner` directory.

## Common Options

| Option | Description |
|--------|-------------|

| `--extract-input-clips true|false` | Auto-fetch missing clips (default: true) |
| `--stack auto|upstream|downstream|base|overlay|up|down` | Select video stack |
| `--platform lemans|monaco|kodiak` | Specify platform for validation |
| `--downstream-fw PATH` | Path to downstream firmware (Kodiak-specific) |
| `--force` | Force stack switch or firmware override |
| `--verbose` | Enable verbose logging |
| `--config path.json` | Run a specific config file |
| `--dir DIR` | Directory to search for configs |
| `--pattern GLOB` | Filter configs by glob pattern |
| `--timeout S` | Timeout per test (default: 60s) |
| `--strict` | Fail on critical dmesg errors |
| `--no-dmesg` | Disable dmesg scanning |
| `--max N` | Run at most N tests |
| `--stop-on-fail` | Stop on first failure |
| `--loglevel N` | Set log level for `iris_v4l2_test` |
| `--repeat N` | Repeat each test N times |
| `--repeat-delay S` | Delay between repeats |
| `--repeat-policy | all or any |
| `--junit FILE` | Output JUnit XML to file |
| `--dry-run` | Show commands without executing |

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to include a few more examples showing how a user can launch using these CLI parameters.


## Notes

- The script does not take any arguments.
- The script auto-detects encode/decode mode based on config filename.
- It validates the presence of required libraries before executing tests.
- If any critical tool is missing, the script exits with an error message.
- If any critical tool is missing, the script exits with an error message.
- Missing input clips are fetched from:
https://github.com/qualcomm-linux/qcom-linux-testkit/releases/download/IRIS-Video-Files-v1.0/video_clips_iris.tar.gz

## License

SPDX-License-Identifier: BSD-3-Clause-Clear
(C) Qualcomm Technologies, Inc. and/or its subsidiaries.
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
"ExecutionMode": "Sequential",
"TestCases": [
{
"Name" : "Decoder Testcase",
"Name" : "H264 Decoder Testcase",
"TestConfigs" : {
"Domain": "Decoder",
"InputPath": "./simple_AVC_720p_10fps_90frames.264",
"InputPath": "./720p_AVC.h264",
"NumFrames": -1,
"CodecName": "AVC",
"PixelFormat": "NV12",
"Width": 1280,
"Height": 720,
"Outputpath": "./output_simple_nv12_720p_90frms.yuv",
"Outputpath": "./720p_AVC.yuv",
"InputBufferCount": 16,
"OutputBufferCount": 16
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
"Name" : "Encoder Testcase",
"TestConfigs" : {
"Domain": "Encoder",
"InputPath": "./simple_nv12_720p_90frms.yuv",
"InputPath": "./90frames_yuv.yuv",
"NumFrames": -1,
"CodecName": "AVC",
"PixelFormat": "NV12",
"Width": 1280,
"Height": 720,
"Outputpath": "./output_simple_AVC_720p_10fps.h264",
"Outputpath": "./Enc_AVC_720p.h264",
"InputBufferCount": 32,
"OutputBufferCount": 32,
"OperatingRate": 10,
Expand Down
21 changes: 21 additions & 0 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/h265Decoder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"ExecutionMode": "Sequential",
"TestCases": [
{
"Name": "HEVC Decoder TestCase",
"TestConfigs": {
"Domain": "Decoder",
"InputPath": "./720x1280_hevc.h265",
"NumFrames": -1,
"CodecName": "HEVC",
"PixelFormat": "NV12",
"Width": 1280,
"Height": 720,
"Outputpath": "./720x1280_hevc.yuv",
"InputBufferCount": 16,
"OutputBufferCount": 16,
"UseMinBufferCtrl": false
}
}
]
}
102 changes: 102 additions & 0 deletions Runner/suites/Multimedia/Video/Video_V4L2_Runner/h265Encoder.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"ExecutionMode": "Sequential",
"TestCases": [
{
"Name": "HEVC Encode TestCase",
"TestConfigs": {
"VideoDevice": "/dev/video1",
"Domain": "Encoder",
"InputPath": "./60frames_yuv.yuv",
"NumFrames": 60,
"CodecName": "HEVC",
"PixelFormat": "NV12",
"Width": 1280,
"Height": 720,
"Outputpath": "./Enc_HEVC__Main_1280_720.265",
"UseMinBufferCtrl": false,
"InputBufferCount": 32,
"OutputBufferCount": 32,
"OperatingRate": 30,
"FrameRate": 30,
"StaticControls": [
{
"Id": "Profile",
"Vtype": "String",
"Value": "MAIN"
},
{
"Id": "Level",
"Vtype": "String",
"Value": "5.0"
},
{
"Id": "FrameRC",
"Vtype": "Int",
"Value": 1
},
{
"Id": "BitRate",
"Vtype": "Int",
"Value": 3662400
},
{
"Id": "BitRateMode",
"Vtype": "String",
"Value": "VBR"
},
{
"Id": "PrefixHeaderMode",
"Vtype": "String",
"Value": "JOINED"
},
{
"Id": "Tier",
"Vtype": "String",
"Value": "HIGH"
},
{
"Id": "GOPSize",
"Vtype": "Int",
"Value": 59
},
{
"Id": "MultiSliceMode",
"Vtype": "String",
"Value": "SINGLE"
},
{
"Id": "MinIQP",
"Vtype": "Int",
"Value": 10
},
{
"Id": "MinPQP",
"Vtype": "Int",
"Value": 10
},
{
"Id": "MinBQP",
"Vtype": "Int",
"Value": 10
},
{
"Id": "MaxIQP",
"Vtype": "Int",
"Value": 51
},
{
"Id": "MaxPQP",
"Vtype": "Int",
"Value": 51
},
{
"Id": "MaxBQP",
"Vtype": "Int",
"Value": 51
}
],
"DynamicControls": []
}
}
]
}
Loading
Loading