Skip to content

Commit 8695687

Browse files
refactor(uvc): Refactor UVC stream opening operations
Refactor UVC stream opening operations to following order: 1. Find and open underlaying USB device (and cache CFG descriptor) 2. Find interface number for requested format: bInterfaceNumber is needed for Control transfers during format negotiation 3. Negotiate the format: negotiated result is needed for correct size of frame buffers and for selecting of bandwidth in ISOC cameras 4. Allocate the frame buffers 5. Find the interface endpoint that fits our requirements and claim it: the endpoint descriptor is needed for proper USB transfer allocation 6. Allocate the USB transfer
1 parent b8e8c06 commit 8695687

9 files changed

Lines changed: 124 additions & 85 deletions

File tree

host/class/uvc/usb_host_uvc/private_include/uvc_descriptors_priv.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -38,9 +38,8 @@ esp_err_t uvc_desc_get_streaming_interface_num(
3838
/**
3939
* @brief Get Streaming Interface and Endpoint descriptors
4040
*
41-
* We go through all alternate interfaces and pick the one that offers endpoint with MPS that:
42-
* * Is lower than or equal to dwMaxPayloadTransferSize
43-
* * Has as few as possible extra transactions per microframe (HS only)
41+
* We go through all alternate interfaces and pick the one that offers endpoint with MPS
42+
* that is lower than or equal to dwMaxPayloadTransferSize
4443
*
4544
* @note The caller is responsible for dwMaxPayloadTransferSize fitting in the IN FIFO
4645
*

host/class/uvc/usb_host_uvc/private_include/uvc_frame_priv.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -19,10 +19,13 @@ extern "C" {
1919
/**
2020
* @brief Allocate frame buffers for UVC stream
2121
*
22+
* In case fb_size is 0, format negotiation (probe) must be done before calling this function,
23+
* because the frame size is taken from the negotiated format.
24+
*
2225
* @param[in] uvc_stream UVC stream handle
2326
* @param[in] nb_of_fb Number of frame buffers to allocate
24-
* @param[in] fb_size Size of 1 frame buffer in bytes
25-
* @param[in] fb_caps Memory capabilities of memory for frame buffers
27+
* @param[in] fb_size Size of 1 frame buffer in bytes, can be 0 for default
28+
* @param[in] fb_caps Memory capabilities of memory for frame buffers, can be 0 for MALLOC_CAP_DEFAULT
2629
* @param[in] user_frame_buffers Optional user-provided frame buffers. If not NULL, use these instead of allocating
2730
* @return
2831
* - ESP_OK: Success

host/class/uvc/usb_host_uvc/private_include/uvc_idf_version_priv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -11,7 +11,7 @@
1111

1212
// @todo fix the hard-coded number here: Should be taken from HAL FIFO config in future versions of esp-idf
1313
#if (CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_LINUX)
14-
#define MAX_MPS_IN 4096
14+
#define MAX_MPS_IN 4096 // Theoretically maximum 3 isochronous transaction per microframe, 3072 bytes
1515
#else
1616
// If FIFO is configured for bias IN, we have 608 bytes available.
1717
// However, configuring MPS > 596 causes USB transfer failures,

host/class/uvc/usb_host_uvc/private_include/uvc_types_priv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -44,6 +44,7 @@ struct uvc_host_stream_s {
4444
uint8_t bInterfaceNumber; // USB Video Streaming interface claimed by this stream. Needed for ISOC Stream start and CTRL transfers
4545
uint8_t bAlternateSetting; // Alternate setting for selected interface. Needed for ISOC Stream start
4646
uint8_t bEndpointAddress; // Streaming endpoint address. Needed for BULK Stream stop
47+
const usb_config_desc_t *cfg_desc; // Configuration descriptor of the device. Cached for faster access
4748

4849
// USB host related members
4950
usb_device_handle_t dev_hdl; // USB device handle

host/class/uvc/usb_host_uvc/uvc_control.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -37,8 +37,6 @@ static esp_err_t uvc_host_stream_control(uvc_host_stream_hdl_t stream_hdl, uvc_v
3737
uvc_stream_t *uvc_stream = (uvc_stream_t *)stream_hdl;
3838
uint8_t bmRequestType, bRequest;
3939
uint16_t wValue, wIndex, wLength;
40-
const usb_config_desc_t *cfg_desc;
41-
ESP_ERROR_CHECK(usb_host_get_active_config_descriptor(uvc_stream->constant.dev_hdl, &cfg_desc));
4240
esp_err_t ret = ESP_OK;
4341
const bool set = (req_code == UVC_SET_CUR) ? true : false;
4442

@@ -56,7 +54,7 @@ static esp_err_t uvc_host_stream_control(uvc_host_stream_hdl_t stream_hdl, uvc_v
5654
const uvc_frame_desc_t *frame_desc;
5755

5856
ESP_RETURN_ON_ERROR(
59-
uvc_desc_get_frame_format_by_format(cfg_desc, uvc_stream->constant.bInterfaceNumber, vs_format, &format_desc, &frame_desc),
57+
uvc_desc_get_frame_format_by_format(uvc_stream->constant.cfg_desc, uvc_stream->constant.bInterfaceNumber, vs_format, &format_desc, &frame_desc),
6058
TAG, "Could not find format that matches required format");
6159
UVC_CHECK(format_desc && frame_desc, ESP_ERR_NOT_FOUND);
6260

@@ -92,7 +90,7 @@ static esp_err_t uvc_host_stream_control(uvc_host_stream_hdl_t stream_hdl, uvc_v
9290
const uvc_format_desc_t *format_desc = NULL;
9391
const uvc_frame_desc_t *frame_desc = NULL;
9492
ESP_RETURN_ON_ERROR(
95-
uvc_desc_get_frame_format_by_index(cfg_desc, uvc_stream->constant.bInterfaceNumber, vs_control->bFormatIndex, vs_control->bFrameIndex, &format_desc, &frame_desc),
93+
uvc_desc_get_frame_format_by_index(uvc_stream->constant.cfg_desc, uvc_stream->constant.bInterfaceNumber, vs_control->bFormatIndex, vs_control->bFrameIndex, &format_desc, &frame_desc),
9694
TAG, "Could not find requested frame format");
9795

9896
vs_format->format = uvc_desc_parse_format(format_desc);

host/class/uvc/usb_host_uvc/uvc_descriptor_parsing.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ esp_err_t uvc_desc_get_streaming_intf_and_ep(
7373
const uint8_t num_of_alternate = usb_parse_interface_number_of_alternate(cfg_desc, bInterfaceNumber);
7474
uint16_t last_mps = 0; // Looking for maximum MPS: init to zero
7575
uint8_t last_mult = UINT8_MAX; // Looking for minimum: init to max
76+
77+
/* Number of alternate interfaces will be 0 for BULK cameras
78+
* that is why in the for loop below we go from 0 to num_of_alternate **inclusive**
79+
*/
7680
for (int i = 0; i <= num_of_alternate; i++) {
7781
// Check Interface desc
7882
intf_desc = usb_parse_interface_descriptor(cfg_desc, bInterfaceNumber, i, &offset);

host/class/uvc/usb_host_uvc/uvc_descriptor_printing.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -368,11 +368,9 @@ void uvc_host_desc_print(uvc_host_stream_hdl_t stream_hdl)
368368
{
369369
assert(stream_hdl);
370370
uvc_stream_t *uvc_stream = (uvc_stream_t *)stream_hdl;
371-
372371
const usb_device_desc_t *device_desc;
373-
const usb_config_desc_t *config_desc;
372+
374373
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_device_descriptor(uvc_stream->constant.dev_hdl, &device_desc));
375-
ESP_ERROR_CHECK_WITHOUT_ABORT(usb_host_get_active_config_descriptor(uvc_stream->constant.dev_hdl, &config_desc));
376374
usb_print_device_descriptor(device_desc);
377-
usb_print_config_descriptor(config_desc, &uvc_print_desc);
375+
usb_print_config_descriptor(uvc_stream->constant.cfg_desc, &uvc_print_desc);
378376
}

host/class/uvc/usb_host_uvc/uvc_frame.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -15,6 +15,7 @@
1515
#include "uvc_frame_priv.h"
1616
#include "uvc_types_priv.h"
1717
#include "uvc_check_priv.h"
18+
#include "uvc_critical_priv.h"
1819

1920
#include "freertos/FreeRTOS.h"
2021
#include "freertos/queue.h"
@@ -58,10 +59,14 @@ esp_err_t uvc_frame_allocate(uvc_stream_t *uvc_stream, int nb_of_fb, size_t fb_s
5859
// Use user-provided buffer (already validated in uvc_host_stream_open)
5960
this_data = user_frame_buffers[i];
6061
} else {
61-
// Allocate driver-managed buffer
62+
// In case the user did not fill the config, set it to default
63+
if (fb_size == 0) {
64+
fb_size = UVC_ATOMIC_LOAD(uvc_stream->dynamic.dwMaxVideoFrameSize);
65+
}
6266
if (fb_caps == 0) {
6367
fb_caps = MALLOC_CAP_DEFAULT; // In case the user did not fill the config, set it to default
6468
}
69+
// Allocate driver-managed buffer
6570
this_data = heap_caps_malloc(fb_size, fb_caps);
6671
if (this_data == NULL) {
6772
free(this_fb);

0 commit comments

Comments
 (0)