diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c index 077b6bb9..4aa330e2 100644 --- a/class/video/usbh_video.c +++ b/class/video/usbh_video.c @@ -122,12 +122,12 @@ int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class) return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); } -int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex) +int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwFrameInterval) { video_class->probe.bFormatIndex = formatindex; video_class->probe.bFrameIndex = frameindex; video_class->probe.dwMaxPayloadTransferSize = 0; - video_class->probe.dwFrameInterval = 333333; + video_class->probe.dwFrameInterval = dwFrameInterval; return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); } @@ -136,7 +136,6 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls)); video_class->commit.bFormatIndex = formatindex; video_class->commit.bFrameIndex = frameindex; - video_class->commit.dwFrameInterval = 333333; return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26); } @@ -154,6 +153,7 @@ int usbh_video_open(struct usbh_video *video_class, bool found = false; uint8_t formatidx = 0; uint8_t frameidx = 0; + uint32_t dwDefaultFrameInterval; uint8_t step; if (!video_class || !video_class->hport) { @@ -172,6 +172,7 @@ int usbh_video_open(struct usbh_video *video_class, if ((wWidth == video_class->format[i].frame[j].wWidth) && (wHeight == video_class->format[i].frame[j].wHeight)) { frameidx = j + 1; + dwDefaultFrameInterval = video_class->format[i].frame[j].dwDefaultFrameInterval; found = true; break; } @@ -204,7 +205,7 @@ int usbh_video_open(struct usbh_video *video_class, } step = 1; - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval); if (ret < 0) { goto errout; } @@ -228,7 +229,7 @@ int usbh_video_open(struct usbh_video *video_class, } step = 5; - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx, dwDefaultFrameInterval); if (ret < 0) { goto errout; } @@ -246,26 +247,30 @@ int usbh_video_open(struct usbh_video *video_class, } step = 8; - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = altsetting; - setup->wIndex = video_class->data_intf; - setup->wLength = 0; + if (!video_class->is_bulk) { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = altsetting; + setup->wIndex = video_class->data_intf; + setup->wLength = 0; - ret = usbh_control_transfer(video_class->hport, setup, NULL); - if (ret < 0) { - goto errout; - } + ret = usbh_control_transfer(video_class->hport, setup, NULL); + if (ret < 0) { + goto errout; + } - ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc; - mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; - mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; - if (ep_desc->bEndpointAddress & 0x80) { - video_class->isoin_mps = mps * (mult + 1); - USBH_EP_INIT(video_class->isoin, ep_desc); + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc; + mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; + mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; + if (ep_desc->bEndpointAddress & 0x80) { + video_class->isoin_mps = mps * (mult + 1); + USBH_EP_INIT(video_class->isoin, ep_desc); + } else { + return -USB_ERR_NODEV; + } } else { - video_class->isoout_mps = mps * (mult + 1); - USBH_EP_INIT(video_class->isoout, ep_desc); + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc; + USBH_EP_INIT(video_class->bulkin, ep_desc); } USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting); @@ -292,54 +297,62 @@ int usbh_video_close(struct usbh_video *video_class) video_class->is_opened = false; - if (video_class->isoin) { - video_class->isoin = NULL; + if (video_class->is_bulk) { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_ENDPOINT; + setup->bRequest = USB_REQUEST_CLEAR_FEATURE; + setup->wValue = USB_FEATURE_ENDPOINT_HALT; + setup->wIndex = video_class->bulkin->bEndpointAddress; + setup->wLength = 0; + } else { + setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; + setup->bRequest = USB_REQUEST_SET_INTERFACE; + setup->wValue = 0; + setup->wIndex = video_class->data_intf; + setup->wLength = 0; } - if (video_class->isoout) { - video_class->isoout = NULL; - } - - setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = USB_REQUEST_SET_INTERFACE; - setup->wValue = 0; - setup->wIndex = video_class->data_intf; - setup->wLength = 0; - ret = usbh_control_transfer(video_class->hport, setup, NULL); if (ret < 0) { return ret; } + return ret; } void usbh_video_list_info(struct usbh_video *video_class) { struct usb_endpoint_descriptor *ep_desc; - uint8_t mult; - uint16_t mps; USB_LOG_INFO("============= Video device information ===================\r\n"); USB_LOG_RAW("bcdVDC:%04x\r\n", video_class->bcdVDC); - USB_LOG_RAW("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings); + USB_LOG_RAW("Num of altsettings:%u (%s mode)\r\n", video_class->num_of_intf_altsettings, video_class->num_of_intf_altsettings == 1 ? "bulk" : "iso"); - for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) { - if (i == 0) { - USB_LOG_RAW("Ingore altsetting 0\r\n"); - continue; + video_class->is_bulk = video_class->num_of_intf_altsettings == 1 ? true : false; + + if (video_class->is_bulk) { + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[0].ep[0].ep_desc; + USB_LOG_RAW("Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", + ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), + ep_desc->bInterval, + USB_GET_MULT(ep_desc->wMaxPacketSize)); + } else { + for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) { + if (i == 0) { + USB_LOG_RAW("Ingore altsetting 0\r\n"); + continue; + } + ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc; + + USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", + i, + ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + USB_GET_MAXPACKETSIZE(ep_desc->wMaxPacketSize), + ep_desc->bInterval, + USB_GET_MULT(ep_desc->wMaxPacketSize)); } - ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc; - - mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT; - mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK; - - USB_LOG_RAW("Altsetting:%u, Ep=%02x Attr=%02u Mps=%d Interval=%02u Mult=%02u\r\n", - i, - ep_desc->bEndpointAddress, - ep_desc->bmAttributes, - mps, - ep_desc->bInterval, - mult); } USB_LOG_RAW("bNumFormats:%u\r\n", video_class->num_of_formats); @@ -350,9 +363,10 @@ void usbh_video_list_info(struct usbh_video *video_class) USB_LOG_RAW(" Resolution:\r\n"); for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) { USB_LOG_RAW(" FrameIndex:%u\r\n", j + 1); - USB_LOG_RAW(" wWidth: %d, wHeight: %d\r\n", - video_class->format[i].frame[j].wWidth, - video_class->format[i].frame[j].wHeight); + USB_LOG_RAW(" wWidth: %d, wHeight: %d, fps: %d\r\n", + video_class->format[i].frame[j].wWidth, + video_class->format[i].frame[j].wHeight, + (1000 / (video_class->format[i].frame[j].dwDefaultFrameInterval / 10000))); } } @@ -438,12 +452,14 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf) video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->wHeight; + video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_uncompressed_descriptor *)p)->dwDefaultFrameInterval; break; case VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE: frame_index = p[DESC_bFrameIndex]; video_class->format[format_index - 1].frame[frame_index - 1].wWidth = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wWidth; video_class->format[format_index - 1].frame[frame_index - 1].wHeight = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->wHeight; + video_class->format[format_index - 1].frame[frame_index - 1].dwDefaultFrameInterval = ((struct video_cs_if_vs_frame_mjpeg_descriptor *)p)->dwDefaultFrameInterval; break; default: break; @@ -476,12 +492,6 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf) struct usbh_video *video_class = (struct usbh_video *)hport->config.intf[intf].priv; if (video_class) { - if (video_class->isoin) { - } - - if (video_class->isoout) { - } - if (hport->config.intf[intf].devname[0] != '\0') { usb_osal_thread_schedule_other(); USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname); diff --git a/class/video/usbh_video.h b/class/video/usbh_video.h index dac5792c..9edce49b 100644 --- a/class/video/usbh_video.h +++ b/class/video/usbh_video.h @@ -14,6 +14,7 @@ struct usbh_video_resolution { uint16_t wWidth; uint16_t wHeight; + uint32_t dwDefaultFrameInterval; }; struct usbh_video_format { @@ -40,7 +41,7 @@ struct usbh_videostreaming { struct usbh_video { struct usbh_hubport *hport; struct usb_endpoint_descriptor *isoin; /* ISO IN endpoint */ - struct usb_endpoint_descriptor *isoout; /* ISO OUT endpoint */ + struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ uint8_t ctrl_intf; /* interface number */ uint8_t data_intf; /* interface number */ @@ -48,9 +49,9 @@ struct usbh_video { struct video_probe_and_commit_controls probe; struct video_probe_and_commit_controls commit; uint16_t isoin_mps; - uint16_t isoout_mps; bool is_opened; uint8_t current_format; + bool is_bulk; uint16_t bcdVDC; uint8_t num_of_intf_altsettings; uint8_t num_of_formats;