Skip to content

Commit 5e2f0a6

Browse files
josuahAlain Volmat
authored andcommitted
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 <[email protected]>
1 parent 9a93f3b commit 5e2f0a6

File tree

1 file changed

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

1 file changed

+32
-3
lines changed

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

Lines changed: 32 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 void 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 void 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 void 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) {
@@ -53,13 +79,16 @@ static void app_add_format(uint32_t pixfmt, uint32_t width, uint32_t height)
5379
/* Submit to UVC only the formats expected to be working (enough memory for the size, etc.) */
5480
static void app_add_filtered_formats(void)
5581
{
82+
const bool has_sup_fmts = app_has_supported_format();
83+
5684
for (int i = 0; video_caps.format_caps[i].pixelformat != 0; i++) {
5785
const struct video_format_cap *vcap = &video_caps.format_caps[i];
5886

59-
app_add_format(vcap->pixelformat, vcap->width_min, vcap->height_min);
87+
app_add_format(vcap->pixelformat, vcap->width_min, vcap->height_min, has_sup_fmts);
6088

6189
if (vcap->width_min != vcap->width_max || vcap->height_min != vcap->height_max) {
62-
app_add_format(vcap->pixelformat, vcap->width_max, vcap->height_max);
90+
app_add_format(vcap->pixelformat, vcap->width_max, vcap->height_max,
91+
has_sup_fmts);
6392
}
6493
}
6594
}

0 commit comments

Comments
 (0)