Skip to content

Commit e91b764

Browse files
author
Alain Volmat
committed
usb: uvc: use struct uvc_frame_descriptor in most of function parameters
This commit prepares introduction of the UVC Frame Based support by using the struct uvc_frame_descriptor as parameter of most of the UVC functions. struct uvc_frame_descriptor contains the common fields for all supported frame type and then depending on the DescriptorSubtype the pointer is casted in the correct struct definition. Signed-off-by: Alain Volmat <[email protected]>
1 parent b35e786 commit e91b764

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

subsys/usb/device_next/class/usbd_uvc.c

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ static const struct uvc_control_map uvc_control_map_xu[] = {
384384
/* Get the format and frame descriptors selected for the given VideoStreaming interface. */
385385
static void uvc_get_vs_fmtfrm_desc(const struct device *dev,
386386
struct uvc_format_descriptor **const format_desc,
387-
struct uvc_frame_discrete_descriptor **const frame_desc)
387+
struct uvc_frame_descriptor **const frame_desc)
388388
{
389389
const struct uvc_config *cfg = dev->config;
390390
struct uvc_data *data = dev->data;
@@ -407,7 +407,7 @@ static void uvc_get_vs_fmtfrm_desc(const struct device *dev,
407407

408408
*frame_desc = NULL;
409409
for (i++; i < ARRAY_SIZE(cfg->desc->if1_fmts); i++) {
410-
struct uvc_frame_discrete_descriptor *desc = &cfg->desc->if1_fmts[i].frm_disc;
410+
struct uvc_frame_descriptor *desc = &cfg->desc->if1_fmts[i].frm;
411411

412412
LOG_DBG("Walking through frame %u, subtype %u, index %u, ptr %p",
413413
i, desc->bDescriptorSubtype, desc->bFrameIndex, desc);
@@ -537,22 +537,34 @@ static int uvc_get_vs_probe_frame_interval(const struct device *dev, struct uvc_
537537
{
538538
struct uvc_data *data = dev->data;
539539
struct uvc_format_descriptor *format_desc;
540-
struct uvc_frame_discrete_descriptor *frame_desc;
541-
int max;
540+
struct uvc_frame_descriptor *frame_desc;
541+
int min, max, max_id;
542542

543543
uvc_get_vs_fmtfrm_desc(dev, &format_desc, &frame_desc);
544544
if (format_desc == NULL || frame_desc == NULL) {
545545
LOG_DBG("Selected format ID or frame ID not found");
546546
return -EINVAL;
547547
}
548548

549+
if (frame_desc->bDescriptorSubtype == UVC_VS_FRAME_UNCOMPRESSED ||
550+
frame_desc->bDescriptorSubtype == UVC_VS_FRAME_MJPEG) {
551+
struct uvc_frame_discrete_descriptor *desc =
552+
(struct uvc_frame_discrete_descriptor *)frame_desc;
553+
554+
min = sys_cpu_to_le32(desc->dwFrameInterval[0]);
555+
max_id = desc->bFrameIntervalType - 1;
556+
max = sys_cpu_to_le32(desc->dwFrameInterval[max_id]);
557+
} else {
558+
LOG_DBG("Invalid frame type");
559+
return -EINVAL;
560+
}
561+
549562
switch (request) {
550563
case UVC_GET_MIN:
551-
probe->dwFrameInterval = sys_cpu_to_le32(frame_desc->dwFrameInterval[0]);
564+
probe->dwFrameInterval = min;
552565
break;
553566
case UVC_GET_MAX:
554-
max = frame_desc->bFrameIntervalType - 1;
555-
probe->dwFrameInterval = sys_cpu_to_le32(frame_desc->dwFrameInterval[max]);
567+
probe->dwFrameInterval = max;
556568
break;
557569
case UVC_GET_RES:
558570
probe->dwFrameInterval = sys_cpu_to_le32(1);
@@ -599,7 +611,7 @@ static int uvc_get_vs_format_from_desc(const struct device *dev, struct video_fo
599611
{
600612
struct uvc_data *data = dev->data;
601613
struct uvc_format_descriptor *format_desc = NULL;
602-
struct uvc_frame_discrete_descriptor *frame_desc;
614+
struct uvc_frame_descriptor *frame_desc;
603615

604616
/* Update the format based on the probe message from the host */
605617
uvc_get_vs_fmtfrm_desc(dev, &format_desc, &frame_desc);
@@ -1449,7 +1461,7 @@ static int uvc_compare_frmival_desc(const void *const a, const void *const b)
14491461
return ib - ia;
14501462
}
14511463

1452-
static void uvc_set_vs_bitrate_range(struct uvc_frame_discrete_descriptor *const desc,
1464+
static void uvc_set_vs_bitrate_range(struct uvc_frame_descriptor *const desc,
14531465
const uint64_t frmival_nsec,
14541466
const struct video_format *const fmt)
14551467
{
@@ -1475,22 +1487,30 @@ static void uvc_set_vs_bitrate_range(struct uvc_frame_discrete_descriptor *const
14751487
desc->dwMaxBitRate = sys_cpu_to_le32(bitrate_max);
14761488
}
14771489

1478-
static int uvc_add_vs_frame_interval(struct uvc_frame_discrete_descriptor *const desc,
1490+
static int uvc_add_vs_frame_interval(struct uvc_frame_descriptor *const desc,
14791491
const struct video_frmival *const frmival,
14801492
const struct video_format *const fmt)
14811493
{
1482-
int i = desc->bFrameIntervalType;
1494+
if (desc->bDescriptorSubtype == UVC_VS_FRAME_UNCOMPRESSED ||
1495+
desc->bDescriptorSubtype == UVC_VS_FRAME_MJPEG) {
1496+
struct uvc_frame_discrete_descriptor *frame_desc =
1497+
(struct uvc_frame_discrete_descriptor *)desc;
1498+
1499+
if (frame_desc->bFrameIntervalType >= CONFIG_USBD_VIDEO_MAX_FRMIVAL) {
1500+
LOG_WRN("Out of descriptors, raise CONFIG_USBD_VIDEO_MAX_FRMIVAL above %u",
1501+
CONFIG_USBD_VIDEO_MAX_FRMIVAL);
1502+
return -ENOMEM;
1503+
}
14831504

1484-
if (i >= CONFIG_USBD_VIDEO_MAX_FRMIVAL) {
1485-
LOG_WRN("Out of descriptors, raise CONFIG_USBD_VIDEO_MAX_FRMIVAL above %u",
1486-
CONFIG_USBD_VIDEO_MAX_FRMIVAL);
1487-
return -ENOMEM;
1505+
frame_desc->dwFrameInterval[frame_desc->bFrameIntervalType] =
1506+
sys_cpu_to_le32(video_frmival_nsec(frmival) / 100);
1507+
frame_desc->bFrameIntervalType++;
1508+
frame_desc->bLength += sizeof(uint32_t);
1509+
} else {
1510+
LOG_DBG("Invalid frame type");
1511+
return -EINVAL;
14881512
}
14891513

1490-
desc->dwFrameInterval[i] = sys_cpu_to_le32(video_frmival_nsec(frmival) / 100);
1491-
desc->bFrameIntervalType++;
1492-
desc->bLength += sizeof(uint32_t);
1493-
14941514
uvc_set_vs_bitrate_range(desc, video_frmival_nsec(frmival), fmt);
14951515

14961516
return 0;
@@ -1502,7 +1522,7 @@ static int uvc_add_vs_frame_desc(const struct device *dev,
15021522
{
15031523
const struct uvc_config *cfg = dev->config;
15041524
struct uvc_data *data = dev->data;
1505-
struct uvc_frame_discrete_descriptor *desc;
1525+
struct uvc_frame_descriptor *desc;
15061526
struct video_frmival_enum fie = {.format = fmt};
15071527
int first_err = 0;
15081528
int ret;
@@ -1513,17 +1533,17 @@ static int uvc_add_vs_frame_desc(const struct device *dev,
15131533
LOG_INF("Adding frame descriptor #%u for %ux%u",
15141534
format_desc->bNumFrameDescriptors + 1, fmt->width, fmt->height);
15151535

1516-
desc = &uvc_new_fmt_desc(dev)->frm_disc;
1536+
desc = &uvc_new_fmt_desc(dev)->frm;
15171537
if (desc == NULL) {
15181538
return -ENOMEM;
15191539
}
15201540

1521-
desc->bLength = sizeof(*desc) - CONFIG_USBD_VIDEO_MAX_FRMIVAL * sizeof(uint32_t);
1541+
desc->bLength = sizeof(struct uvc_frame_discrete_descriptor) -
1542+
CONFIG_USBD_VIDEO_MAX_FRMIVAL * sizeof(uint32_t);
15221543
desc->bDescriptorType = USB_DESC_CS_INTERFACE;
15231544
desc->bFrameIndex = format_desc->bNumFrameDescriptors + 1;
15241545
desc->wWidth = sys_cpu_to_le16(fmt->width);
15251546
desc->wHeight = sys_cpu_to_le16(fmt->height);
1526-
desc->dwMaxVideoFrameBufferSize = sys_cpu_to_le32(fmt->size);
15271547
desc->bDescriptorSubtype = (format_desc->bDescriptorSubtype == UVC_VS_FORMAT_UNCOMPRESSED)
15281548
? UVC_VS_FRAME_UNCOMPRESSED : UVC_VS_FRAME_MJPEG;
15291549
desc->dwMinBitRate = sys_cpu_to_le32(UINT32_MAX);
@@ -1561,21 +1581,33 @@ static int uvc_add_vs_frame_desc(const struct device *dev,
15611581
fie.index++;
15621582
}
15631583

1564-
/* If no frame intrval supported, default to 30 FPS */
1565-
if (desc->bFrameIntervalType == 0) {
1566-
struct video_frmival frmival = {.numerator = 1, .denominator = 30};
1584+
if (desc->bDescriptorSubtype == UVC_VS_FRAME_UNCOMPRESSED ||
1585+
desc->bDescriptorSubtype == UVC_VS_FRAME_MJPEG) {
1586+
struct uvc_frame_discrete_descriptor *frame_desc =
1587+
(struct uvc_frame_discrete_descriptor *)desc;
15671588

1568-
ret = uvc_add_vs_frame_interval(desc, &frmival, fmt);
1569-
if (ret != 0 && first_err == 0) {
1570-
first_err = ret;
1589+
frame_desc->dwMaxVideoFrameBufferSize = sys_cpu_to_le32(fmt->size);
1590+
1591+
/* If no frame intrval supported, default to 30 FPS */
1592+
if (frame_desc->bFrameIntervalType == 0) {
1593+
struct video_frmival frmival = {.numerator = 1, .denominator = 30};
1594+
1595+
ret = uvc_add_vs_frame_interval(desc, &frmival, fmt);
1596+
if (ret != 0 && first_err == 0) {
1597+
first_err = ret;
1598+
}
15711599
}
1572-
}
15731600

1574-
/* UVC requires the frame intervals to be sorted, but not Zephyr */
1575-
qsort(desc->dwFrameInterval, desc->bFrameIntervalType,
1576-
sizeof(*desc->dwFrameInterval), uvc_compare_frmival_desc);
1601+
/* UVC requires the frame intervals to be sorted, but not Zephyr */
1602+
qsort(frame_desc->dwFrameInterval, frame_desc->bFrameIntervalType,
1603+
sizeof(*frame_discrete_desc->dwFrameInterval), uvc_compare_frmival_desc);
1604+
1605+
frame_desc->dwDefaultFrameInterval = frame_desc->dwFrameInterval[0];
1606+
} else {
1607+
LOG_DBG("Invalid frame type");
1608+
return -EINVAL;
1609+
}
15771610

1578-
desc->dwDefaultFrameInterval = desc->dwFrameInterval[0];
15791611
format_desc->bNumFrameDescriptors++;
15801612
cfg->desc->if1_hdr.wTotalLength += desc->bLength;
15811613

subsys/usb/device_next/class/usbd_uvc.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,7 @@ struct uvc_frame_descriptor {
385385
uint16_t wHeight;
386386
uint32_t dwMinBitRate;
387387
uint32_t dwMaxBitRate;
388-
uint32_t dwMaxVideoFrameBufferSize;
389-
uint32_t dwDefaultFrameInterval;
390-
uint8_t bFrameIntervalType;
391-
/* Other fields depending on bFrameIntervalType value */
388+
/* Other fields depending on bDescriptorSubtype value */
392389
} __packed;
393390

394391
struct uvc_frame_continuous_descriptor {

0 commit comments

Comments
 (0)