Skip to content

Commit 3aca32e

Browse files
committed
samples: usb: uvc: add filtering of the format
The UVC class now lets the application select the format list sent to the host. Leverage this in the sample to filter out any format that is not expected to work (buffer too big, rarely supported formats). Signed-off-by: Josuah Demangeon <me@josuah.net>
1 parent 982e54f commit 3aca32e

File tree

1 file changed

+33
-3
lines changed
  • samples/subsys/usb/uvc/src

1 file changed

+33
-3
lines changed

samples/subsys/usb/uvc/src/main.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,28 @@ const static struct device *const video_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_cam
2323
/* Format capabilities of video_dev, used everywhere through the sample */
2424
static struct video_caps video_caps = {.type = VIDEO_BUF_TYPE_OUTPUT};
2525

26-
static int app_add_format(uint32_t pixfmt, uint32_t width, uint32_t height)
26+
/* Pixel formats present in one of the UVC 1.5 standard */
27+
static bool app_is_supported_format(uint32_t pixfmt)
28+
{
29+
return pixfmt == VIDEO_PIX_FMT_JPEG ||
30+
pixfmt == VIDEO_PIX_FMT_YUYV ||
31+
pixfmt == VIDEO_PIX_FMT_NV12;
32+
}
33+
34+
static bool app_has_supported_format(void)
35+
{
36+
const struct video_format_cap *fmts = video_caps.format_caps;
37+
38+
for (int i = 0; fmts[i].pixelformat != 0; i++) {
39+
if (app_is_supported_format(fmts[i].pixelformat)) {
40+
return true;
41+
}
42+
}
43+
44+
return false;
45+
}
46+
47+
static int app_add_format(uint32_t pixfmt, uint32_t width, uint32_t height, bool has_sup_fmts)
2748
{
2849
struct video_format fmt = {
2950
.pixelformat = pixfmt,
@@ -33,6 +54,11 @@ static int app_add_format(uint32_t pixfmt, uint32_t width, uint32_t height)
3354
};
3455
int ret;
3556

57+
/* If the system has any standard pixel format, only propose them to the host */
58+
if (has_sup_fmts && !app_is_supported_format(pixfmt)) {
59+
return;
60+
}
61+
3662
/* Set the format to get the size */
3763
ret = video_set_format(video_dev, &fmt);
3864
if (ret != 0) {
@@ -58,16 +84,20 @@ static int app_add_format(uint32_t pixfmt, uint32_t width, uint32_t height)
5884
/* Submit to UVC only the formats expected to be working (enough memory for the size, etc.) */
5985
static int app_add_filtered_formats(void)
6086
{
87+
const bool has_sup_fmts = app_has_supported_format();
88+
6189
for (int i = 0; video_caps.format_caps[i].pixelformat != 0; i++) {
6290
const struct video_format_cap *vcap = &video_caps.format_caps[i];
6391

64-
ret = app_add_format(vcap->pixelformat, vcap->width_min, vcap->height_min);
92+
ret = app_add_format(vcap->pixelformat, vcap->width_min, vcap->height_min,
93+
has_sup_fmts);
6594
if (ret != 0) {
6695
return ret;
6796
}
6897

6998
if (vcap->width_min != vcap->width_max || vcap->height_min != vcap->height_max) {
70-
ret = app_add_format(vcap->pixelformat, vcap->width_max, vcap->height_max);
99+
ret = app_add_format(vcap->pixelformat, vcap->width_max, vcap->height_max,
100+
has_sup_fmts);
71101
if (ret != 0) {
72102
return ret;
73103
}

0 commit comments

Comments
 (0)