From 1a7259649ba388e8e0a58383f6fa13066cb62cc1 Mon Sep 17 00:00:00 2001 From: sakimisu <1203593632@qq.com> Date: Fri, 25 Aug 2023 21:36:27 +0800 Subject: [PATCH] standardize video control api --- class/video/usbh_video.c | 122 ++++++++++++++++++++++++++++----------- class/video/usbh_video.h | 9 ++- 2 files changed, 92 insertions(+), 39 deletions(-) diff --git a/class/video/usbh_video.c b/class/video/usbh_video.c index 1a4e07b8..8521d26c 100644 --- a/class/video/usbh_video.c +++ b/class/video/usbh_video.c @@ -53,32 +53,45 @@ static void usbh_video_class_free(struct usbh_video *video_class) memset(video_class, 0, sizeof(struct usbh_video)); } -int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len) +int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len) { struct usb_setup_packet *setup = video_class->hport->setup; int ret; + uint8_t retry; setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = VIDEO_REQUEST_GET_CUR; + setup->bRequest = request; setup->wValue = cs << 8; setup->wIndex = (entity_id << 8) | intf; setup->wLength = len; - ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf); - if (ret < 0) { - return ret; + retry = 0; + while (1) { + ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf); + if (ret > 0) { + break; + } + retry++; + + if (retry == 3) { + return ret; + } } - memcpy(buf, g_video_buf, len); + + if (buf) { + memcpy(buf, g_video_buf, len); + } + return ret; } -int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len) +int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len) { struct usb_setup_packet *setup = video_class->hport->setup; int ret; setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE; - setup->bRequest = VIDEO_REQUEST_SET_CUR; + setup->bRequest = request; setup->wValue = cs << 8; setup->wIndex = (entity_id << 8) | intf; setup->wLength = len; @@ -86,13 +99,13 @@ int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t ent memcpy(g_video_buf, buf, len); ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf); - usb_osal_msleep(5); + usb_osal_msleep(50); return ret; } int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class) { - return usbh_video_get_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); + 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) @@ -100,7 +113,8 @@ int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t fo video_class->probe.bFormatIndex = formatindex; video_class->probe.bFrameIndex = frameindex; video_class->probe.dwMaxPayloadTransferSize = 0; - return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26); + video_class->probe.dwFrameInterval = 333333; + 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); } int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex) @@ -108,7 +122,8 @@ 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; - return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26); + 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); } int usbh_video_open(struct usbh_video *video_class, @@ -125,6 +140,7 @@ int usbh_video_open(struct usbh_video *video_class, bool found = false; uint8_t formatidx = 0; uint8_t frameidx = 0; + uint8_t step; if (video_class->is_opened) { return -EMFILE; @@ -152,31 +168,65 @@ int usbh_video_open(struct usbh_video *video_class, return -EINVAL; } + /* Open video step: + * Get CUR request (probe) + * Set CUR request (probe) + * Get CUR request (probe) + * Get MAX request (probe) + * Get MIN request (probe) + * Get CUR request (probe) + * Set CUR request (commit) + * + */ + step = 0; ret = usbh_videostreaming_get_cur_probe(video_class); if (ret < 0) { - return ret; - } - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); - if (ret < 0) { - return ret; - } - ret = usbh_videostreaming_get_cur_probe(video_class); - if (ret < 0) { - return ret; - } - ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); - if (ret < 0) { - return ret; - } - ret = usbh_videostreaming_get_cur_probe(video_class); - if (ret < 0) { - return ret; - } - ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx); - if (ret < 0) { - return ret; + goto errout; } + step = 1; + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + if (ret < 0) { + goto errout; + } + + step = 2; + ret = usbh_videostreaming_get_cur_probe(video_class); + if (ret < 0) { + goto errout; + } + + step = 3; + ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MAX, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26); + if (ret < 0) { + goto errout; + } + + step = 4; + ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MIN, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26); + if (ret < 0) { + goto errout; + } + + step = 5; + ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx); + if (ret < 0) { + goto errout; + } + + step = 6; + ret = usbh_videostreaming_get_cur_probe(video_class); + if (ret < 0) { + goto errout; + } + + step = 7; + ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx); + if (ret < 0) { + goto errout; + } + + step = 8; setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE; setup->bRequest = USB_REQUEST_SET_INTERFACE; setup->wValue = altsetting; @@ -185,7 +235,7 @@ int usbh_video_open(struct usbh_video *video_class, ret = usbh_control_transfer(video_class->hport->ep0, setup, NULL); if (ret < 0) { - return ret; + goto errout; } ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc; @@ -203,6 +253,10 @@ int usbh_video_open(struct usbh_video *video_class, video_class->is_opened = true; video_class->current_format = format_type; return ret; + +errout: + USB_LOG_ERR("Fail to open video in step %u\r\n", step); + return ret; } int usbh_video_close(struct usbh_video *video_class) diff --git a/class/video/usbh_video.h b/class/video/usbh_video.h index a9df365a..fe44bf77 100644 --- a/class/video/usbh_video.h +++ b/class/video/usbh_video.h @@ -25,6 +25,8 @@ struct usbh_video_format { struct usbh_videostreaming { uint32_t bufoffset; uint32_t buflen; + uint16_t width; + uint16_t heigth; void (*video_one_frame_callback)(struct usbh_videostreaming *stream); }; @@ -52,11 +54,8 @@ struct usbh_video { extern "C" { #endif -int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len); -int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len); -int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class); -int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex); -int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex); +int usbh_video_get_cur(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len); +int usbh_video_set_cur(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len); int usbh_video_open(struct usbh_video *video_class, uint8_t format_type,