Skip to content

Commit 68e5c16

Browse files
committed
tests: drivers: video: sw_stats: add tests for VIDEO_SW_DRIVER
Test it by filling a buffer manually with test data and verify that the statistics produced are matching. Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 41dd03d commit 68e5c16

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(drivers_video_sw_stats)
6+
7+
target_sources(app PRIVATE src/main.c)

tests/drivers/video/sw_stats/prj.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CONFIG_LOG=y
2+
CONFIG_VIDEO_LOG_LEVEL_DBG=y
3+
CONFIG_ZTEST=y
4+
CONFIG_VIDEO=y
5+
CONFIG_VIDEO_SW_STATS=y
6+
CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=16384
7+
CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=1
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2025 tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/ztest.h>
8+
#include <zephyr/drivers/video.h>
9+
#include <zephyr/drivers/video-controls.h>
10+
#include <zephyr/pixel/print.h>
11+
12+
#define WIDTH 640
13+
#define HEIGHT 480
14+
15+
uint8_t rggb8frame[WIDTH * HEIGHT * 1];
16+
uint16_t rgb24hist[(1 << 4) * 3];
17+
18+
ZTEST(video_sw_stats, test_video_sw_stats)
19+
{
20+
const struct device *dev = device_get_binding("VIDEO_SW_STATS");
21+
struct video_buffer *vbufp;
22+
struct video_stats_channels chan = {
23+
.base.flags = VIDEO_STATS_CHANNELS_RGB
24+
};
25+
struct video_stats_histogram hist = {
26+
.base.flags = VIDEO_STATS_HISTOGRAM_RGB,
27+
.buckets = rgb24hist,
28+
.num_buckets = ARRAY_SIZE(rgb24hist),
29+
};
30+
struct video_buffer vbuf = {
31+
.buffer = rggb8frame,
32+
.size = sizeof(rggb8frame),
33+
.bytesused = sizeof(rggb8frame),
34+
};
35+
struct video_format fmt = {
36+
.pixelformat = VIDEO_PIX_FMT_RGGB8,
37+
.width = WIDTH,
38+
.pitch = WIDTH * video_bits_per_pixel(VIDEO_PIX_FMT_RGGB8) / BITS_PER_BYTE,
39+
.height = HEIGHT,
40+
};
41+
42+
zexpect_not_null(dev);
43+
zexpect_true(device_is_ready(dev));
44+
45+
/* Load test data on the buffer: upper half completely white */
46+
47+
memset(rggb8frame, 0xff, sizeof(rggb8frame) / 2);
48+
49+
zexpect_ok(video_set_format(dev, VIDEO_EP_IN, &fmt));
50+
51+
/* Test loading a buffer into the device */
52+
53+
zexpect_ok(video_enqueue(dev, VIDEO_EP_IN, &vbuf));
54+
55+
/* Test collecting image statistics out of this buffer */
56+
57+
zexpect_ok(video_get_stats(dev, VIDEO_EP_IN, &chan.base));
58+
zexpect_ok(video_get_stats(dev, VIDEO_EP_IN, &hist.base));
59+
60+
/* Test collecting image statistics out of this buffer */
61+
62+
zexpect_ok(video_dequeue(dev, VIDEO_EP_IN, &vbufp, K_NO_WAIT));
63+
zexpect_not_null(vbufp);
64+
65+
/* Check the statistics content of channel averages */
66+
67+
zexpect_equal(chan.base.flags & VIDEO_STATS_CHANNELS_RGB, VIDEO_STATS_CHANNELS_RGB);
68+
zexpect_within(chan.rgb[0], 0xff / 2, 10, "%u is average", chan.rgb[0]);
69+
zexpect_within(chan.rgb[1], 0xff / 2, 10, "%u is average", chan.rgb[1]);
70+
zexpect_within(chan.rgb[2], 0xff / 2, 10, "%u is average", chan.rgb[2]);
71+
72+
/* Check the channel averagres */
73+
74+
zexpect_equal(hist.base.flags & VIDEO_STATS_HISTOGRAM_RGB, VIDEO_STATS_HISTOGRAM_RGB);
75+
zexpect_not_equal(hist.num_buckets, 0, "The histogram size must not be zero.");
76+
zexpect_not_equal(hist.num_values, 0, "The histogram must not be empty.");
77+
78+
/* Check the histograms */
79+
80+
zexpect_within(hist.buckets[0], hist.num_values / 2, 10,
81+
"Half of the image is filled with 0x00");
82+
83+
zexpect_within(hist.buckets[hist.num_buckets - 1], hist.num_values / 2, 10,
84+
"Half of the image is filled with 0xff");
85+
86+
for (size_t i = hist.num_buckets * 0 / 3 + 1; i < hist.num_buckets * 1 / 3 - 1; i++) {
87+
zexpect_equal(hist.buckets[i], 0, "%u: Only 0x00 or 0xff for the red channel", i);
88+
}
89+
90+
for (size_t i = hist.num_buckets * 1 / 3 + 1; i < hist.num_buckets * 2 / 3 - 1; i++) {
91+
zexpect_equal(hist.buckets[i], 0, "%u: Only 0x00 or 0xff in the green channel", i);
92+
}
93+
94+
for (size_t i = hist.num_buckets * 2 / 3 + 1; i < hist.num_buckets * 3 / 3 - 1; i++) {
95+
zexpect_equal(hist.buckets[i], 0, "%u: Only 0x00 or 0xff in the blue channel", i);
96+
}
97+
}
98+
99+
ZTEST_SUITE(video_sw_stats, NULL, NULL, NULL, NULL, NULL);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025 tinyVision.ai Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
tests:
5+
drivers.video.sw_stats:
6+
tags:
7+
- drivers
8+
- video
9+
platform_allow: native_sim

0 commit comments

Comments
 (0)