Skip to content

Commit 747a7ea

Browse files
committed
fix(uvc): add camera format print in basic_uvc_stream
1 parent 1bb9221 commit 747a7ea

File tree

5 files changed

+115
-61
lines changed

5 files changed

+115
-61
lines changed

host/class/uvc/usb_host_uvc/examples/basic_uvc_stream/main/basic_uvc_stream.c

Lines changed: 96 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,22 @@
3636
#define EXAMPLE_NUMBER_OF_STREAMS (1) // This example shows how to control multiple UVC streams. Set this to 1 if you camera offers only 1 stream
3737
#define EXAMPLE_USE_SDCARD (0) // SD card on P4 evaluation board will be initialized
3838

39+
#define UVC_DESC_DWFRAMEINTERVAL_TO_FPS(dwFrameInterval) (((dwFrameInterval) != 0) ? 10000000 / ((float)(dwFrameInterval)) : 0)
40+
3941
static const char *TAG = "UVC example";
4042
static QueueHandle_t rx_frames_queue[EXAMPLE_NUMBER_OF_STREAMS];
43+
static int device_count = 0;
4144
static bool dev_connected = false;
45+
static uvc_host_frame_info_t *frame_info_list[EXAMPLE_NUMBER_OF_STREAMS] = {NULL};
46+
static size_t frame_info_list_size[EXAMPLE_NUMBER_OF_STREAMS] = {0};
47+
48+
static const char *FORMAT_STR[] = {
49+
"FORMAT_UNDEFINED",
50+
"FORMAT_MJPEG",
51+
"FORMAT_YUY2",
52+
"FORMAT_H264",
53+
"FORMAT_H265",
54+
};
4255

4356
bool frame_callback(const uvc_host_frame_t *frame, void *user_ctx)
4457
{
@@ -63,6 +76,7 @@ static void stream_callback(const uvc_host_stream_event_data_t *event, void *use
6376
case UVC_HOST_DEVICE_DISCONNECTED:
6477
ESP_LOGI(TAG, "Device suddenly disconnected");
6578
dev_connected = false;
79+
device_count--;
6680
ESP_ERROR_CHECK(uvc_host_stream_close(event->device_disconnected.stream_hdl));
6781
break;
6882
case UVC_HOST_FRAME_BUFFER_OVERFLOW:
@@ -95,7 +109,7 @@ static void usb_lib_task(void *arg)
95109

96110
static void frame_handling_task(void *arg)
97111
{
98-
const uvc_host_stream_config_t *stream_config = (const uvc_host_stream_config_t *)arg;
112+
const uvc_host_stream_config_t *stream_config = (uvc_host_stream_config_t *)arg;
99113
QueueHandle_t frame_q = *((QueueHandle_t *)(stream_config->user_ctx));
100114
const int uvc_index = stream_config->usb.uvc_stream_index;
101115

@@ -153,52 +167,8 @@ static void frame_handling_task(void *arg)
153167
}
154168
}
155169

156-
static const uvc_host_stream_config_t stream_mjpeg_config = {
157-
.event_cb = stream_callback,
158-
.frame_cb = frame_callback,
159-
.user_ctx = &rx_frames_queue[0],
160-
.usb = {
161-
.vid = EXAMPLE_USB_DEVICE_VID,
162-
.pid = EXAMPLE_USB_DEVICE_PID,
163-
.uvc_stream_index = 0,
164-
},
165-
.vs_format = {
166-
.h_res = 720,
167-
.v_res = 1280,
168-
.fps = 15,
169-
.format = UVC_VS_FORMAT_MJPEG,
170-
},
171-
.advanced = {
172-
.number_of_frame_buffers = EXAMPLE_FRAME_COUNT,
173-
.frame_size = 0,
174-
.number_of_urbs = 4,
175-
.urb_size = 10 * 1024,
176-
},
177-
};
178-
179170
#if EXAMPLE_NUMBER_OF_STREAMS > 1
180-
static const uvc_host_stream_config_t stream_h265_config = {
181-
.event_cb = stream_callback,
182-
.frame_cb = frame_callback,
183-
.user_ctx = &rx_frames_queue[1],
184-
.usb = {
185-
.vid = EXAMPLE_USB_DEVICE_VID,
186-
.pid = EXAMPLE_USB_DEVICE_PID,
187-
.uvc_stream_index = 1,
188-
},
189-
.vs_format = {
190-
.h_res = 1280,
191-
.v_res = 720,
192-
.fps = 15,
193-
.format = UVC_VS_FORMAT_H265,
194-
},
195-
.advanced = {
196-
.number_of_frame_buffers = EXAMPLE_FRAME_COUNT,
197-
.frame_size = 0,
198-
.number_of_urbs = 4,
199-
.urb_size = 10 * 1024,
200-
},
201-
};
171+
202172
#endif // EXAMPLE_NUMBER_OF_STREAMS > 1
203173

204174
#if EXAMPLE_USE_SDCARD
@@ -279,6 +249,85 @@ void app_init_sdcard(void)
279249
}
280250
#endif // EXAMPLE_USE_SDCARD
281251

252+
static void start_uvc_frame_handling_tasks(void)
253+
{
254+
uvc_host_stream_config_t _stream_config = {
255+
.event_cb = stream_callback,
256+
.frame_cb = frame_callback,
257+
.user_ctx = &rx_frames_queue[0],
258+
.usb = {
259+
.vid = EXAMPLE_USB_DEVICE_VID,
260+
.pid = EXAMPLE_USB_DEVICE_PID,
261+
.uvc_stream_index = 0,
262+
},
263+
.vs_format = {
264+
.h_res = frame_info_list[0][0].h_res,
265+
.v_res = frame_info_list[0][0].v_res,
266+
.fps = UVC_DESC_DWFRAMEINTERVAL_TO_FPS(frame_info_list[0][0].default_interval),
267+
.format = UVC_VS_FORMAT_MJPEG,
268+
},
269+
.advanced = {
270+
.number_of_frame_buffers = EXAMPLE_FRAME_COUNT,
271+
.frame_size = 0,
272+
.number_of_urbs = 4,
273+
.urb_size = 10 * 1024,
274+
},
275+
};
276+
static uvc_host_stream_config_t stream_mjpeg_config;
277+
memcpy(&stream_mjpeg_config, &_stream_config, sizeof(uvc_host_stream_config_t));
278+
BaseType_t task_created = xTaskCreatePinnedToCore(frame_handling_task, "mjpeg_handling", 4096, (void *)&stream_mjpeg_config, EXAMPLE_USB_HOST_PRIORITY - 2, NULL, tskNO_AFFINITY);
279+
assert(task_created == pdTRUE);
280+
281+
#if EXAMPLE_NUMBER_OF_STREAMS > 1
282+
vTaskDelay(pdMS_TO_TICKS(1000));
283+
_stream_config.usb.uvc_stream_index = 1;
284+
_stream_config.vs_format.h_res = frame_info_list[1][0].h_res;
285+
_stream_config.vs_format.v_res = frame_info_list[1][0].v_res;
286+
_stream_config.vs_format.fps = UVC_DESC_DWFRAMEINTERVAL_TO_FPS(frame_info_list[1][0].default_interval);
287+
_stream_config.vs_format.format = UVC_VS_FORMAT_H265;
288+
_stream_config.user_ctx = &rx_frames_queue[1];
289+
static uvc_host_stream_config_t stream_h265_config;
290+
memcpy(&stream_h265_config, &_stream_config, sizeof(uvc_host_stream_config_t));
291+
task_created = xTaskCreatePinnedToCore(frame_handling_task, "h265_handling", 4096, (void *)&stream_h265_config, EXAMPLE_USB_HOST_PRIORITY - 3, NULL, tskNO_AFFINITY);
292+
assert(task_created == pdTRUE);
293+
#endif // EXAMPLE_NUMBER_OF_STREAMS > 1
294+
}
295+
296+
static void uvc_event_cb(const uvc_host_driver_event_data_t *event, void *user_ctx)
297+
{
298+
switch (event->type) {
299+
case UVC_HOST_DRIVER_EVENT_DEVICE_CONNECTED: {
300+
ESP_LOGI(TAG, "Device connected, addr: %d, stream index: %d", event->device_connected.dev_addr, event->device_connected.uvc_stream_index);
301+
int stream_index = event->device_connected.uvc_stream_index;
302+
if (stream_index >= EXAMPLE_NUMBER_OF_STREAMS) {
303+
ESP_LOGW(TAG, "Stream index %d is out of range. Max supported is %d", stream_index, EXAMPLE_NUMBER_OF_STREAMS - 1);
304+
break;
305+
}
306+
device_count++;
307+
if (device_count > 1) {
308+
ESP_LOGW(TAG, "Multiple devices connected. ignoring additional devices.");
309+
break;
310+
}
311+
312+
frame_info_list_size[stream_index] = event->device_connected.frame_info_num;
313+
frame_info_list[stream_index] = calloc(frame_info_list_size[stream_index], sizeof(uvc_host_frame_info_t));
314+
assert(frame_info_list[stream_index]);
315+
uvc_host_get_frame_list(event->device_connected.dev_addr, stream_index, (uvc_host_frame_info_t (*)[])frame_info_list[stream_index], &frame_info_list_size[stream_index]);
316+
for (int i = 0; i < frame_info_list_size[stream_index]; i++) {
317+
ESP_LOGI(TAG, "Camera format: %s %d*%d@%.1ffps",
318+
FORMAT_STR[frame_info_list[stream_index][i].format],
319+
frame_info_list[stream_index][i].h_res,
320+
frame_info_list[stream_index][i].v_res,
321+
UVC_DESC_DWFRAMEINTERVAL_TO_FPS(frame_info_list[stream_index][i].default_interval));
322+
}
323+
start_uvc_frame_handling_tasks();
324+
break;
325+
}
326+
default:
327+
break;
328+
}
329+
}
330+
282331
/**
283332
* @brief Main application
284333
*/
@@ -311,15 +360,7 @@ void app_main(void)
311360
.driver_task_priority = EXAMPLE_USB_HOST_PRIORITY + 1,
312361
.xCoreID = tskNO_AFFINITY,
313362
.create_background_task = true,
363+
.event_cb = uvc_event_cb,
314364
};
315365
ESP_ERROR_CHECK(uvc_host_install(&uvc_driver_config));
316-
317-
task_created = xTaskCreatePinnedToCore(frame_handling_task, "mjpeg_handling", 4096, (void *)&stream_mjpeg_config, EXAMPLE_USB_HOST_PRIORITY - 2, NULL, tskNO_AFFINITY);
318-
assert(task_created == pdTRUE);
319-
320-
#if EXAMPLE_NUMBER_OF_STREAMS > 1
321-
vTaskDelay(pdMS_TO_TICKS(1000));
322-
task_created = xTaskCreatePinnedToCore(frame_handling_task, "h265_handling", 4096, (void *)&stream_h265_config, EXAMPLE_USB_HOST_PRIORITY - 3, NULL, tskNO_AFFINITY);
323-
assert(task_created == pdTRUE);
324-
#endif // EXAMPLE_USE_SDCARD
325366
}

host/class/uvc/usb_host_uvc/examples/basic_uvc_stream/sdkconfig.defaults

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
# This file was generated using idf.py save-defconfig. It can be edited manually.
22
# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration
33
#
4-
CONFIG_IDF_TARGET="esp32p4"
5-
CONFIG_ESP32P4_REV_MIN_0=y
6-
CONFIG_RTC_CLK_SRC_EXT_CRYS=y
7-
CONFIG_RTC_CLK_CAL_CYCLES=1024
4+
CONFIG_FREERTOS_HZ=1000
5+
CONFIG_COMPILER_OPTIMIZATION_PERF=y
86
CONFIG_SPIRAM=y
9-
CONFIG_SPIRAM_SPEED_200M=y
7+
108
CONFIG_LOG_COLORS=y
119
CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=4096
1210
CONFIG_USB_HOST_HW_BUFFER_BIAS_IN=y
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y
1+
2+
CONFIG_ESP32P4_REV_MIN_0=y
3+
CONFIG_RTC_CLK_SRC_EXT_CRYS=y
4+
CONFIG_RTC_CLK_CAL_CYCLES=1024
5+
CONFIG_SPIRAM_SPEED_200M=y
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
3+
CONFIG_SPIRAM_SPEED_80M=y
4+
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
5+
CONFIG_SPIRAM_RODATA=y
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
3+
CONFIG_SPIRAM_MODE_OCT=y
4+
CONFIG_SPIRAM_SPEED_80M=y
5+
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
6+
CONFIG_SPIRAM_RODATA=y

0 commit comments

Comments
 (0)