十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ESP32-S2/S3 USB Host 多媒体流驱动 usb_stream 使用指南:UVC 摄像头与 UAC 音频的读、写与控制

ESP32-S2/S3 USB Host 多媒体流驱动 usb_stream 使用指南:UVC 摄像头与 UAC 音频的读、写与控制 ESP32-S2/S3 USB Host 多媒体流驱动 usb_stream 使用指南UVC 摄像头与 UAC 音频的读、写与控制【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution导读usb_stream是 ESP-IoT-Solution 仓库中基于 ESP32-S2/ESP32-S3 USB Host 能力的 UVC UAC 主机驱动组件用于从 USB 外设读取、写入和控制多媒体数据流。它同时支持一路 UVC 摄像头视频流、一路 UAC 麦克风输入流和一路 UAC 扬声器输出流。阅读本文后你将掌握该组件的硬件选型要求、UVC/UAC 配置参数含义、完整的初始化与启动调用流程、流控挂起/恢复、音量/静音用法以及 ESP32-S2 ECO0 芯片上的 SPI 屏幕抖动问题与软件规避方案。组件概述与核心特性usb_stream是一个位于 components/usb/usb_stream 的独立组件通过 ESP32-S2/ESP32-S3 的 USB-OTG 外设以主机Host身份驱动外接 USB 设备。它面向三类多媒体设备UVCUSB Video Class摄像头通过 UVC Stream 接口获取 MJPEG 视频流同时支持等时Isochronous和批量Bulk两种传输模式UACUSB Audio Class麦克风通过 UAC Stream 接口接收音频采样数据IN 流UAC 扬声器通过 UAC Stream 接口发送音频数据OUT 流并可通过 UAC Control 接口控制音量、静音等特性。从组件源码看其能力还包括自动解析设备的配置描述符Configuration Descriptor按用户参数自动匹配接口、端点与格式支持 UVC/UAC 各路数据流分别挂起suspend与恢复resume提供描述符打印、USB 枚举失败重试、任务优先级/核心/栈大小可配置见 components/usb/usb_stream/Kconfig内部采用 FreeRTOS 任务 Ringbuffer URB 队列的流水线架构见 usb_stream.c。注意按 README.md 的说明对于 ESP-IDF V5.3.3 及以上版本如果启用 UVC建议同时开启Component config → USB-OTG → Hardware FIFO size biasing中的Bias IN选项以确保等时传输 FIFO 容量足够。硬件与设备选型要求开发板任何带有 USB Host 口的 ESP32-S2 / ESP32-S3 开发板均可使用但该 USB 口必须能够向外输出 5V 电压因为绝大多数 USB 摄像头、USB 耳机、USB 声卡需要总线供电。UVC 摄像头要求摄像头必须兼容USB 1.1 Full-Speed全速模式摄像头必须自带MJPEG硬件压缩输出ESP32 侧不进行 JPEG 编码用户可以通过uvc_streaming_config手动指定摄像头接口号、传输模式等时/批量和图像帧参数等时传输模式接口的最大包大小Max Packet Size, MPS应不超过 512 字节图像数据流 USB 传输总带宽应小于4 Mbps500 KB/s批量传输模式图像数据流 USB 传输总带宽应小于8.8 Mbps1100 KB/s批量模式可支持更高的带宽上限其它特殊摄像头的兼容性要求请参考示例程序的 README。UAC 设备要求音频功能必须兼容UAC 1.0 协议Audio Class 1.0即全速等时音频用户需要通过uac_streaming_config手动指定扬声器/麦克风的采样率、位宽等参数。UVC 与 UAC 同时使用UVC 和 UAC 功能可以单独启用例如只配置 UAC 驱动一个 USB 耳机/音箱或只配置 UVC 驱动一个 USB 摄像头如需同时启用 UVC UAC当前驱动仅支持同时含有摄像头与音频接口的复合设备Composite Device不支持分别连接两个独立设备一台摄像头 一台声卡的组合。快速接入与示例工程通过组件管理器添加依赖在任意 ESP-IDF 工程中使用组件管理器添加依赖CMake 阶段会自动下载该组件idf.py add-dependency espressif/usb_stream*从示例模板创建工程组件注册表提供了三个官方示例与本仓库 examples/usb/host 下的工程对应可用以下命令从模板创建# USB 摄像头 麦克风 扬声器USB Camera Audio含 Web 控制台 idf.py create-project-from-example espressif/usb_stream*:usb_camera_mic_spk # USB 摄像头本地 LCD 显示 idf.py create-project-from-example espressif/usb_stream*:usb_camera_lcd_display # USB 音频播放器 idf.py create-project-from-example espressif/usb_stream*:usb_audio_player示例下载到当前目录后即可进入目录编译烧录。若执行create-project-from-example时报CMakeLists.txt not found in project directory错误说明 idf-component-manager 版本过旧请先在 ESP-IDF 环境中执行pip install -U idf-component-manager升级。示例工程结构以 usb_camera_mic_spk 为例仓库内的 examples/usb/host/usb_camera_mic_spk 是一个浏览器 Web 控制的 AV 演示工程其main目录划分清晰main.c应用入口app_usb_host.c/.h初始化 USB Host并通过fifo_settings_custom自定义 DWC 硬件 FIFO 分配解决高采样率 UAC 端点 MPS 超限问题app_uvc_manager.c/.hUVC 摄像头配置、分辨率选择与预览app_uac_manager.c/.hUAC 麦克风/扬声器格式选择、静音、音量控制app_web.c/.h、app_wifi.c/.hSoftAP默认 SSIDUSB-AV-DEMO与 Web 控制台。编译命令为idf.py set-target TARGET # esp32s2 / esp32s3 / esp32p4 等 idf.py -p PORT flash monitor提示在该示例的 README 中说明若日志出现EP MPS exceeds supported limit端点 MPS 超过当前 FIFO 配置上限导致ESP_ERR_NOT_SUPPORTED需要针对目标设备调整fifo_settings_custom或选择较低带宽的 UAC 格式。配置参数详解UVC 配置结构 uvc_config_tuvc_config_t uvc_config { .frame_width 320, // mjpeg 图像宽度像素例如 320 .frame_height 240, // mjpeg 图像高度像素例如 240 .frame_interval FPS2INTERVAL(15), // 帧间隔100µs 单位例如 15fps .xfer_buffer_size 32 * 1024, // 单帧图像大小需按实际测试确定320*240 一般小于 35KB .xfer_buffer_a pointer_buffer_a, // USB 传输内部缓冲区 A .xfer_buffer_b pointer_buffer_b, // USB 传输内部缓冲区 B双缓冲 .frame_buffer_size 32 * 1024, // 单帧图像缓冲大小需按实际测试确定 .frame_buffer pointer_frame_buffer, // 图像帧缓冲 .frame_cb camera_frame_cb, // 摄像头回调可在其中阻塞 .frame_cb_arg NULL, // 摄像头回调参数 };各字段含义与约束依据 components/usb/usb_stream/include/usb_stream.h字段含义说明frame_width/frame_height期望图像宽高像素可设为FRAME_RESOLUTION_ANY__UINT16_MAX__匹配任意分辨率frame_interval帧间隔100ns 单位用宏FPS2INTERVAL(fps)转换如FPS2INTERVAL(15)表示 15fps源码同时提供FRAME_INTERVAL_FPS_5/10/15/20/30等预设宏xfer_buffer_size单块传输缓冲大小必须大于一帧图像大小内部使用双缓冲A/B交替接收xfer_buffer_a/b传输缓冲区指针建议使用MALLOC_CAP_DMA内存参考测试代码heap_caps_malloc(..., MALLOC_CAP_DMA)frame_buffer_size/frame_buffer帧缓冲大小与指针用于拼装完整 MJPEG 帧frame_cb/frame_cb_arg帧回调与参数新帧就绪后触发回调运行在独立任务上下文允许阻塞如解码、送显xfer_type可选传输模式UVC_XFER_ISOC等时或UVC_XFER_BULK批量多数摄像头为等时模式批量模式带宽更高format_index/frame_index可选格式索引 / 帧索引用于跳过描述符解析直接指定interface/interface_alt可选流接口号 / 备用接口号备用接口用于选择 MPS批量模式固定为 0ep_addr/ep_mps可选端点地址 / 端点 MPS跳过描述符解析时手动指定flags可选行为控制标志支持FLAG_UVC_SUSPEND_AFTER_START启动后立即挂起 UVC等从 test_apps/main/test_usb_stream.c 可以看到传输缓冲区按目标芯片区分大小ESP32-S2 为 45KB、ESP32-S3 为 55KB且要求xfer_buffer_size frame_buffer_size。UAC 配置结构 uac_config_tuac_config_t uac_config { .mic_bit_resolution 16, // 麦克风采样位宽bit .mic_samples_frequence 16000, // 麦克风采样率Hz .spk_bit_resolution 16, // 扬声器采样位宽bit .spk_samples_frequence 16000, // 扬声器采样率Hz .spk_buf_size 16000, // 扬声器发送缓冲大小需为 spk_ep_mps 的整数倍 .mic_buf_size 0, // 麦克风接收缓冲大小不使用为 0否则需为 mic_min_bytes 的整数倍 .mic_cb mic_frame_cb, // 麦克风回调禁止阻塞 .mic_cb_arg NULL, // 麦克风回调参数 };关键字段补充说明同样以头文件为准spk_ch_num/mic_ch_num扬声器/麦克风通道数可设UAC_CH_ANY0匹配任意通道数mic_bit_resolution/spk_bit_resolution位宽可设UAC_BITS_ANY__UINT16_MAX__匹配任意位宽mic_samples_frequence/spk_samples_frequence采样率可设UAC_FREQUENCY_ANY__UINT32_MAX__匹配任意采样率spk_buf_size扬声器发送 Ringbuffer 大小必须为 spk 端点 MPS 的整数倍mic_buf_size麦克风接收缓冲大小0 表示不使用配合uac_mic_streaming_read轮询否则需为mic_min_bytes的整数倍mic_cb麦克风数据回调一定不能阻塞否则影响后续帧的接收可选项mic_interface/mic_ep_addr/mic_ep_mps、spk_interface/spk_ep_addr/spk_ep_mps、ac_interface、mic_fu_id/spk_fu_id手动指定接口、端点与特性单元Feature UnitID用于跳过描述符解析以加快启动速度。编程流程配置 → 启动 → 回调 → 控制 → 停止完整的使用流程如下对应 usb_stream.h 的公开 API1. 配置驱动调用uvc_streaming_config(uvc_config)配置 UVC 驱动设备同时支持音频时调用uac_streaming_config(uac_config)配置 UAC 驱动。普通使用场景只需指定上述必选参数可选项置 0驱动会从设备描述符中自动查找正确值如需快速启动Quick Start则需手动指定全部参数以跳过获取与解析描述符的步骤。两个接口在数据流已运行时返回ESP_ERR_INVALID_STATE参数非法返回ESP_ERR_INVALID_ARG。2. 启动数据流esp_err_t usb_streaming_start(void);调用后驱动会创建内部任务处理 USB 数据并响应设备连接与协议协商。返回ESP_ERR_INVALID_STATE未配置或已在运行、ESP_FAIL启动失败或ESP_OK。可选地可在启动前注册设备连接状态回调esp_err_t usb_streaming_state_register(state_callback_t cb, void *user_ptr);回调在STREAM_CONNECTED/STREAM_DISCONNECTED时被调用仅支持注册一个回调后注册的覆盖先前的需在启动前注册。此外usb_streaming_connect_wait(timeout_ms)可阻塞等待设备连接。3. 描述符匹配与回调触发启动后主机根据用户参数匹配已连接设备的描述符设备不满足配置要求时驱动会打印警告。匹配成功后主机持续接收 IN 流UVC 视频与 UAC 麦克风UVC 帧回调每收到一帧完整 MJPEG 图像触发一次。回调运行在独立任务上下文sample_proc可以阻塞例如在回调中执行 JPEG 解码或写入显示缓冲。测试代码中回调会打印frame_format、sequence、width、height、data_bytes等信息UAC 麦克风回调收到mic_min_bytes字节数据后触发禁止阻塞否则会影响下一帧接收如需阻塞处理应改用uac_mic_streaming_read轮询模式替代回调模式。回调中的实际数据结构见头文件mic_frame_t携带data、data_bytes、bit_resolution、samples_frequenceUVC 回调帧包含frame_formatMJPEG 等、sequence、width、height、data_bytes。4. 发送扬声器数据OUT 流esp_err_t uac_spk_streaming_write(void *data, size_t data_bytes, size_t timeout_ms);用户将音频数据写入内部 Ringbuffer主机在 USB 空闲时取出数据发送 OUT 流。Ringbuffer 满时返回ESP_ERR_TIMEOUT。5. 流控与音频控制esp_err_t usb_streaming_control(usb_stream_t stream, stream_ctrl_t ctrl_type, void *ctrl_value);streamSTREAM_UVC、STREAM_UAC_SPK、STREAM_UAC_MICctrl_typeCTRL_SUSPEND/CTRL_RESUME挂起/恢复ctrl_value为 NULL、CTRL_UAC_MUTE静音ctrl_value为 false/true、CTRL_UAC_VOLUME音量ctrl_value为 0~100若当前设备不支持该控制类型返回ESP_ERR_NOT_SUPPORTED。音量/静音通过 UAC Control 接口的特性单元Feature Unit实现源码中定义了UAC_FU_MUTE_CONTROL、UAC_FU_VOLUME_CONTROL等控制选择子并将音量范围映射到 0~100见 usb_stream.c 中的UAC_SPK_VOLUME_MAX/MIN/STEP。在测试用例 test_usb_stream.c 的状态回调中可以看到典型组合用法设备连接后先查询分辨率列表再依次恢复 UVC/扬声器/麦克风流然后设置扬声器和麦克风的静音与音量CTRL_UAC_VOLUME传 30。6. 动态调整参数uvc_frame_size_list_get/uac_frame_size_list_get查询当前已连接设备的支持分辨率/音频格式列表传 NULL 仅获取列表大小uvc_frame_size_reset(width, height, interval)/uac_frame_size_reset(stream, ch_num, bit_resolution, samples_frequence)在挂起状态下修改参数恢复后生效。7. 停止数据流esp_err_t usb_streaming_stop(void);停止后内部任务被删除USB 资源URB、管道、事件队列等被完全释放返回ESP_ERR_TIMEOUT表示停止等待超时。Kconfig 可调参数组件提供丰富的 menuconfig 选项Component config → USB Stream见 Kconfig常用项如下配置项默认值说明CTRL_TRANSFER_DATA_MAX_BYTES1024控制传输最大数据长度64~2048 字节USB_STREAM_QUICK_STARTn快速启动模式跳过描述符解析UVC_PRINT_DESC/UVC_PRINT_DESC_VERBOSEy / n枚举时打印描述符信息 / 详细模式USB_PROC_TASK_PRIORITY/CORE/STACK_SIZE5 / 按芯片 / 3072USB 处理任务优先级1~25、核与栈大小USB_WAITING_AFTER_CONN_MS50设备连接后的枚举延时msUSB_CTRL_XFER_TIMEOUT_MS1000控制传输超时msUSB_ENUM_FAILED_RETRY/COUNT/DELAY_MSy / 10 / 200枚举失败重试开关、次数与间隔SAMPLE_PROC_TASK_PRIORITY/CORE/STACK_SIZE2 / 0 / 3072UVC 帧处理任务配置CORE 为 -1 时不绑定核UVC_CHECK_HEADER_EOFy校验 payload 头 EOF 位确认整帧接收完成UVC_DROP_NO_EOF_FRAME/UVC_DROP_OVERFLOW_FRAMEn / y丢弃无 EOF 帧 / 溢出帧NUM_BULK_STREAM_URBS/NUM_BULK_BYTES_PER_URB2 / 2048批量模式 URB 数量与单次传输字节数NUM_ISOC_UVC_URBS/NUM_PACKETS_PER_URB3 / 4等时模式 UVC URB 数量与每 URB 包数NUM_ISOC_SPK_URBS/NUM_ISOC_MIC_URBS3 / 3扬声器/麦克风等时 URB 数量UAC_MIC_CB_MIN_MS_DEFAULT16麦克风回调最小间隔ms1~32UAC_SPK_ST_MAX_MS_DEFAULT16扬声器单次最大发送时长ms1~32UAC_MIC_PACKET_COMPENSATIONn麦克风丢包时补数据UAC_SPK_PACKET_COMPENSATION/CONTINUOUS/TIMEOUT_MS/SIZE_MSy / y / 80 / 10扬声器缓冲空时补零策略、持续补零、超时与补零时长已知问题与规避方案ESP32-S2 ECO0 SPI 屏幕抖动在最早版本的 ESP32-S2ECO0芯片上USB 传输可能污染 SPI 数据导致 SPI 屏幕与 USB 摄像头同时工作时出现画面抖动。ESP32-S2 新版本ECO1以及 ESP32-S3 均不存在该 Bug。软件规避方案如下修改 IDF 内部文件属于芯片级 workaround在components/hal/esp32s2/include/hal/spi_ll.h中新增查询发送 FIFO 计数函数static inline uint32_t spi_ll_tx_get_fifo_cnt(spi_dev_t *hw) { return hw-dma_out_status.out_fifo_cnt; }修改spi_new_trans实现在真正 kick off 传输前等待数据确实已写入发送 FIFO再启动传输// 该函数用于发送新事务运行在 ISR 或任务中。 // 配置事务相关的寄存器和 DMA或非 DMA 的 FIFO使用的链表。 static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_t *trans_buf) { //................... spi_hal_setup_trans(hal, hal_dev, hal_trans); spi_hal_prepare_data(hal, hal_dev, hal_trans); //Call pre-transmission callback, if any if (dev-cfg.pre_cb) dev-cfg.pre_cb(trans); #if 1 //USB Bug workaround while (trans-length spi_ll_tx_get_fifo_cnt(SPI_LL_GET_HW(host-id)) 0) { __asm__ __volatile__(nop); __asm__ __volatile__(nop); __asm__ __volatile__(nop); } #endif //Kick off transfer spi_hal_user_start(hal); }其原理是在 USB 污染发生时发送 FIFO 计数可能短暂为 0此时忙等几个 NOP 周期让 FIFO 数据稳定后再启动 DMA 传输从而避免 SPI 数据被 USB 传输干扰。总结usb_stream为 ESP32-S2/ESP32-S3 提供了一套完整的多媒体 USB Host 解决方案一条 UVC 摄像头流 一条 UAC 麦克风流 一条 UAC 扬声器流可同时工作支持等时/批量传输、描述符自动解析、分路挂起/恢复、音量与静音控制并有配套的 Web 控制台示例、LCD 显示示例与音频播放示例。开发者只需配置uvc_config_t/uac_config_t结构体按配置 → 启动 → 回调处理 → 控制 → 停止的流程调用 API即可快速接入 USB 摄像头与音频设备若使用早期 ESP32-S2 ECO0 芯片并配合 SPI 屏幕可参考上文给出的软件规避补丁。【免费下载链接】esp-iot-solutionEspressif IoT Library. IoT Device Drivers, Documentations and Solutions.项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表