@@ -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. */
385385static 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
0 commit comments