Add support for setting a custom device name and per-board serial number for UVC

This commit is contained in:
Lorow
2025-06-17 22:20:20 +02:00
parent 39002e2335
commit ec4369df7f
17 changed files with 2740 additions and 102 deletions

View File

@@ -0,0 +1,155 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#include "uvc_frame_config.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Board Specific Configuration
//--------------------------------------------------------------------+
#ifdef CONFIG_TINYUSB_RHPORT_HS
# define CFG_TUSB_RHPORT1_MODE OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED
#else
# define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE | OPT_MODE_FULL_SPEED
#endif
//--------------------------------------------------------------------
// Common Configuration
//--------------------------------------------------------------------
// defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
#ifndef ESP_PLATFORM
#define ESP_PLATFORM 1
#endif
#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS OPT_OS_FREERTOS
#endif
// Espressif IDF requires "freertos/" prefix in include path
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4)
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
#ifndef CFG_TUSB_DEBUG
#define CFG_TUSB_DEBUG 0
#endif
// Enable Device stack
#define CFG_TUD_ENABLED 1
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//------------- CLASS -------------//
// The number of video control interfaces
// The number of video streaming interfaces
#if CONFIG_UVC_SUPPORT_TWO_CAM
#define CFG_TUD_VIDEO 2
#define CFG_TUD_VIDEO_STREAMING 2
#else
#define CFG_TUD_VIDEO 1
#define CFG_TUD_VIDEO_STREAMING 1
#endif
// video streaming endpoint size
#ifdef UVC_CAM1_BULK_MODE
#if CONFIG_TINYUSB_RHPORT_HS
#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 512
#else
#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 64
#endif
#define CFG_TUD_CAM1_VIDEO_STREAMING_BULK 1
#else
#define CFG_TUD_CAM1_VIDEO_STREAMING_BULK 0
#if CONFIG_TINYUSB_RHPORT_HS
#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 1023
#else
#define CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE 512
#endif
#endif
#define CFG_EXAMPLE_VIDEO_DISABLE_MJPEG (!FORMAT_MJPEG)
#if CONFIG_UVC_SUPPORT_TWO_CAM
#ifdef UVC_CAM2_BULK_MODE
#if CONFIG_TINYUSB_RHPORT_HS
#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 512
#else
#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 64
#endif
#define CFG_TUD_CAM2_VIDEO_STREAMING_BULK 1
#else
#define CFG_TUD_CAM2_VIDEO_STREAMING_BULK 0
#if CONFIG_TINYUSB_RHPORT_HS
#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 1023
#else
#define CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE 512
#endif
#endif
#endif
#if CONFIG_UVC_SUPPORT_TWO_CAM
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE (CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE > CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE?CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE:CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE)
#else
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE
#endif
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */

View File

@@ -0,0 +1,343 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2023 Espressif
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include "tusb.h"
#include "usb_descriptors.h"
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
// Use Interface Association Descriptor (IAD) for Video
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = CONFIG_TUSB_VID,
.idProduct = CONFIG_TUSB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const *tud_descriptor_device_cb(void)
{
return (uint8_t const *)&desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
#if CFG_TUD_CAM1_VIDEO_STREAMING_BULK
#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(4))
#elif CONFIG_FORMAT_H264_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(4))
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN)
#elif CONFIG_FORMAT_H264_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN)
#else
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN)
#endif
#endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#else
#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(4))
#elif CONFIG_FORMAT_H264_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(4))
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN)
#elif CONFIG_FORMAT_H264_CAM1
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN)
#else
#define TUD_CAM1_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN)
#endif
#endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#endif // CFG_TUD_CAM1_VIDEO_STREAMING_BULK
#if CONFIG_UVC_SUPPORT_TWO_CAM
#if CFG_TUD_CAM2_VIDEO_STREAMING_BULK
#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(4))
#elif CONFIG_FORMAT_H264_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(4))
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN)
#elif CONFIG_FORMAT_H264_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN)
#else
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN)
#endif
#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#else
#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(4))
#elif CONFIG_FORMAT_H264_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(4))
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN)
#elif CONFIG_FORMAT_H264_CAM2
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN)
#else
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN (TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN)
#endif
#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#endif // CFG_TUD_CAM2_VIDEO_STREAMING_BULK
#else
#define TUD_CAM2_VIDEO_CAPTURE_DESC_LEN 0
#endif
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CAM1_VIDEO_CAPTURE_DESC_LEN + TUD_CAM2_VIDEO_CAPTURE_DESC_LEN)
#define EPNUM_CAM1_VIDEO_IN 0x81
#if CONFIG_UVC_SUPPORT_TWO_CAM
#define EPNUM_CAM2_VIDEO_IN 0x82
#endif
uint8_t const desc_fs_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 500),
// IAD for Video Control
#if CFG_TUD_CAM1_VIDEO_STREAMING_BULK
#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#else
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#else
#if CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN, CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM1
TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#else
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM1_VIDEO_IN,
UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE,
CFG_TUD_CAM1_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#endif // CONFIG_UVC_CAM1_MULTI_FRAMESIZE
#endif // CFG_TUD_CAM1_VIDEO_STREAMING_BULK
#if CONFIG_UVC_SUPPORT_TWO_CAM
#if CFG_TUD_CAM2_VIDEO_STREAMING_BULK
#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#else
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#else
#if CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#if CONFIG_FORMAT_MJPEG_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN, CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#else
#if CONFIG_FORMAT_MJPEG_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#elif CONFIG_FORMAT_H264_CAM2
TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(4, ITF_NUM_VIDEO_CONTROL_2, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#else
TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(4, ITF_NUM_VIDEO_CONTROL, EPNUM_CAM2_VIDEO_IN,
UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE,
CFG_TUD_CAM2_VIDEO_STREAMING_EP_BUFSIZE),
#endif
#endif // CONFIG_UVC_CAM2_MULTI_FRAMESIZE
#endif // CFG_TUD_CAM2_VIDEO_STREAMING_BULK
#endif
};
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
{
(void)index; // for multiple configurations
return desc_fs_configuration;
}
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const *string_desc_arr[] = {
(const char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
CONFIG_TUSB_MANUFACTURER, // 1: Manufacturer
CONFIG_TUSB_PRODUCT, // 2: Product
CONFIG_TUSB_SERIAL_NUM, // 3: Serials, should use chip ID, overridden with get_serial_number()
"UVC CAM1", // 4: UVC Interface, default, because we're overriding it get_uvc_device_name(), but we still have to keep the structure
#if CONFIG_UVC_SUPPORT_TWO_CAM
"UVC CAM2", // 5: UVC Interface
#endif
};
static uint16_t _desc_str[32];
__attribute__((weak)) const char *get_uvc_device_name(void)
{
// ETVR Override, by default we're reporting ourselves as this, users can override it
return "UVC OpenIris Camera";
}
__attribute__((weak)) const char *get_serial_number(void)
{
// ETVR Override, by default we're reporting ourselves as the predefined serial number
// this should get overwritten with a better implementation
return CONFIG_TUSB_SERIAL_NUM;
}
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
printf("am I being asked for this?");
(void)langid;
uint8_t chr_count;
if (index == 0)
{
memcpy(&_desc_str[1], string_desc_arr[0], 2);
chr_count = 1;
}
else
{
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])))
{
return NULL;
}
const char *str = string_desc_arr[index];
if (index == 3)
str = get_serial_number();
if (index == 4)
str = get_uvc_device_name();
if (str == NULL)
str = string_desc_arr[index];
// Cap at max char
chr_count = (uint8_t)strlen(str);
if (chr_count > 31)
{
chr_count = 31;
}
// Convert ASCII string into UTF-16
for (uint8_t i = 0; i < chr_count; i++)
{
_desc_str[1 + i] = str[i];
}
}
// first byte is length (including header), second byte is string type
_desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
return _desc_str;
}

View File

@@ -0,0 +1,620 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jerzy Kasenbreg
* Copyright (c) 2021 Koji KITAYAMA
* Copyright (c) 2023 Espressif
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef _USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_
#include "uvc_frame_config.h"
/* Time stamp base clock. It is a deprecated parameter. */
#define UVC_CLOCK_FREQUENCY 27000000
/* video capture path */
#define UVC_ENTITY_CAP_INPUT_TERMINAL 0x01
#define UVC_ENTITY_CAP_OUTPUT_TERMINAL 0x02
enum {
#if (CFG_TUD_VIDEO)
ITF_NUM_VIDEO_CONTROL,
ITF_NUM_VIDEO_STREAMING,
#if CONFIG_UVC_SUPPORT_TWO_CAM
ITF_NUM_VIDEO_CONTROL_2,
ITF_NUM_VIDEO_STREAMING_2,
#endif
#endif
ITF_NUM_TOTAL
};
#if (CFG_TUD_VIDEO)
#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
/* Interface 1, Alternate 1 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MJPEG_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
/* Interface 1, Alternate 1 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_LEN(n) (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ (n*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
/* Interface 1, Alternate 1 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_UNCOMPR_BULK_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MJPEG_BULK_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MULTI_MJPEG_BULK_LEN(n) (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ (n*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_BULK_LEN(n) (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ (n*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_BULK_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_FRAME_BASED_LEN (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
/* Interface 1, Alternate 1 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ 7/* Endpoint */\
)
#define TUD_VIDEO_CAPTURE_DESC_MULTI_FRAME_BASED_LEN(n) (\
TUD_VIDEO_DESC_IAD_LEN\
/* control */\
+ TUD_VIDEO_DESC_STD_VC_LEN\
+ (TUD_VIDEO_DESC_CS_VC_LEN + 1/*bInCollection*/)\
+ TUD_VIDEO_DESC_CAMERA_TERM_LEN\
+ TUD_VIDEO_DESC_OUTPUT_TERM_LEN\
/* Interface 1, Alternate 0 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ (TUD_VIDEO_DESC_CS_VS_IN_LEN + 1/*bNumFormats x bControlSize*/)\
+ TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ (n*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN\
/* Interface 1, Alternate 1 */\
+ TUD_VIDEO_DESC_STD_VS_LEN\
+ 7/* Endpoint */\
)
/* Windows support YUY2 and NV12
* https://docs.microsoft.com/en-us/windows-hardware/drivers/stream/usb-video-class-driver-overview */
#define TUD_VIDEO_DESC_CS_VS_FMT_YUY2(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_YUY2, 16, _frmidx, _asrx, _asry, _interlace, _cp)
#define TUD_VIDEO_DESC_CS_VS_FMT_NV12(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_NV12, 12, _frmidx, _asrx, _asry, _interlace, _cp)
#define TUD_VIDEO_DESC_CS_VS_FMT_M420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_M420, 12, _frmidx, _asrx, _asry, _interlace, _cp)
#define TUD_VIDEO_DESC_CS_VS_FMT_I420(_fmtidx, _numfmtdesc, _frmidx, _asrx, _asry, _interlace, _cp) \
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR(_fmtidx, _numfmtdesc, TUD_VIDEO_GUID_I420, 12, _frmidx, _asrx, _asry, _interlace, _cp)
#define TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(bCamIndex ,bFrameIndex) \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(bFrameIndex, 0, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height, \
UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate, \
UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 / 8, \
(10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate))
#define TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(bCamIndex ,bFrameIndex) \
TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(bFrameIndex, 0, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height, \
UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16, UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].width * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].height * 16 * UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate, \
(10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), /*bytesPreLine*/ 0, (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate), (10000000/UVC_FRAMES_INFO[bCamIndex][bFrameIndex-1].rate))
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR(_stridx, _itf,_epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
_width * _height * 16, \
(10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* VS alt 1 */\
TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \
/* EP */ \
TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
_width * _height * 16 / 8, \
(10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* VS alt 1 */\
TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \
/* EP */ \
TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG(_stridx, _itf, _epin, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \
/*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 1), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 2), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 3), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 4), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* VS alt 1 */\
TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \
/* EP */ \
TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_UNCOMPR_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_YUY2(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_UNCOMPR_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
_width * _height * 16, \
(10000000/_fps), (10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MJPEG_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
_width * _height * 16 / 8, \
(10000000/_fps), (10000000/_fps), (10000000/_fps), (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* EP */ \
TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_MJPEG_BULK(_stridx, _itf, _epin, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG_LEN\
+ (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_MJPEG(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \
/*bmFlags*/0, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 1), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 2), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 3), \
TUD_VIDEO_DESC_CS_VS_FRM_MJPEG_CONT_TEMPLATE(_itf/2, 4), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* EP */ \
TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_H264(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
(10000000/_fps), /*bytesPreLine*/ 0, \
(10000000/_fps), (10000000/_fps)*_fps, (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* VS alt 1 */\
TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \
/* EP */ \
TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_H264_BULK(_stridx, _itf, _epin, _width, _height, _fps, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/1, \
/*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT(/*bFrameIndex */1, 0, _width, _height, \
_width * _height * 16, _width * _height * 16 * _fps, \
(10000000/_fps), /*bytesPreLine*/ 0, \
(10000000/_fps), (10000000/_fps), (10000000/_fps)), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* EP */ \
TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264(_stridx, _itf, _epin, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 0, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \
/*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 1), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 2), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 3), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 4), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* VS alt 1 */\
TUD_VIDEO_DESC_STD_VS(_itf + 1, 1, 1, _stridx), \
/* EP */ \
TUD_VIDEO_DESC_EP_ISO(_epin, _epsize, 1)
#define TUD_VIDEO_CAPTURE_DESCRIPTOR_MULTI_H264_BULK(_stridx, _itf, _epin, _epsize) \
TUD_VIDEO_DESC_IAD(_itf, /* 2 Interfaces */ 0x02, _stridx), \
/* Video control 0 */ \
TUD_VIDEO_DESC_STD_VC(_itf, 0, _stridx), \
TUD_VIDEO_DESC_CS_VC( /* UVC 1.5*/ 0x0150, \
/* wTotalLength - bLength */ \
TUD_VIDEO_DESC_CAMERA_TERM_LEN + TUD_VIDEO_DESC_OUTPUT_TERM_LEN, \
UVC_CLOCK_FREQUENCY, _itf + 1), \
TUD_VIDEO_DESC_CAMERA_TERM(UVC_ENTITY_CAP_INPUT_TERMINAL, 0, 0,\
/*wObjectiveFocalLengthMin*/0, /*wObjectiveFocalLengthMax*/0,\
/*wObjectiveFocalLength*/0, /*bmControls*/0), \
TUD_VIDEO_DESC_OUTPUT_TERM(UVC_ENTITY_CAP_OUTPUT_TERMINAL, VIDEO_TT_STREAMING, 0, 1, 0), \
/* Video stream alt. 0 */ \
TUD_VIDEO_DESC_STD_VS(_itf + 1, 0, 1, _stridx), \
/* Video stream header for without still image capture */ \
TUD_VIDEO_DESC_CS_VS_INPUT( /*bNumFormats*/1, \
/*wTotalLength - bLength */\
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED_LEN\
+ (UVC_FRAME_NUM*TUD_VIDEO_DESC_CS_VS_FRM_FRAME_BASED_CONT_LEN)\
+ TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING_LEN,\
_epin, /*bmInfo*/0, /*bTerminalLink*/UVC_ENTITY_CAP_OUTPUT_TERMINAL, \
/*bStillCaptureMethod*/0, /*bTriggerSupport*/0, /*bTriggerUsage*/0, \
/*bmaControls(1)*/0), \
/* Video stream format */ \
TUD_VIDEO_DESC_CS_VS_FMT_FRAME_BASED(/*bFormatIndex*/1, /*bNumFrameDescriptors*/UVC_FRAME_NUM, \
/*guid*/TUD_VIDEO_GUID_H264, /*bitsPerPix*/16, /*bDefaultFrameIndex*/1, 0, 0, 0, /*bCopyProtect*/0, /*variableSize*/1), \
/* Video stream frame format */ \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 1), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 2), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 3), \
TUD_VIDEO_DESC_CS_VS_FRM_H264_CONT_TEMPLATE(_itf/2, 4), \
TUD_VIDEO_DESC_CS_VS_COLOR_MATCHING(VIDEO_COLOR_PRIMARIES_BT709, VIDEO_COLOR_XFER_CH_BT709, VIDEO_COLOR_COEF_SMPTE170M), \
/* EP */ \
TUD_VIDEO_DESC_EP_BULK(_epin, _epsize, 1)
#endif //CFG_TUD_VIDEO
/**
* ETVR Custom implementation
*
* @brief get_uvc_device_name() is hacky, way for us to let users specify
* a custom device name right after flashing their boards with a way to update it
*/
const char *get_uvc_device_name();
/**
* ETVR Custom implementation
*
* @brief get_serial_number() is a way for us to specify a per-board serial number
*/
const char *get_serial_number();
#endif

View File

@@ -0,0 +1,76 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#ifdef CONFIG_FORMAT_MJPEG_CAM1
#define FORMAT_MJPEG_CAM1 1
#endif
#ifdef CONFIG_UVC_CAM1_MULTI_FRAMESIZE
//If enable, add VGA and HVGA to list
#define UVC_CAM1_FRAME_MULTI 1
#endif
#define UVC_CAM1_FRAME_WIDTH CONFIG_UVC_CAM1_FRAMESIZE_WIDTH
#define UVC_CAM1_FRAME_HEIGHT CONFIG_UVC_CAM1_FRAMESIZE_HEIGT
#define UVC_CAM1_FRAME_RATE CONFIG_UVC_CAM1_FRAMERATE
#ifdef CONFIG_UVC_MODE_BULK_CAM1
#define UVC_CAM1_BULK_MODE
#endif
#if CONFIG_UVC_SUPPORT_TWO_CAM
#ifdef CONFIG_FORMAT_MJPEG_CAM2
#define FORMAT_MJPEG_CAM2 1
#endif
#ifdef CONFIG_UVC_CAM2_MULTI_FRAMESIZE
//If enable, add VGA and HVGA to list
#define UVC_CAM2_FRAME_MULTI 1
#endif
#define UVC_CAM2_FRAME_WIDTH CONFIG_UVC_CAM2_FRAMESIZE_WIDTH
#define UVC_CAM2_FRAME_HEIGHT CONFIG_UVC_CAM2_FRAMESIZE_HEIGT
#define UVC_CAM2_FRAME_RATE CONFIG_UVC_CAM2_FRAMERATE
#ifdef CONFIG_UVC_MODE_BULK_CAM2
#define UVC_CAM2_BULK_MODE
#endif
#endif
#ifndef UVC_CAM2_FRAME_WIDTH
#define UVC_CAM2_FRAME_WIDTH UVC_CAM1_FRAME_WIDTH
#endif
#ifndef UVC_CAM2_FRAME_HEIGHT
#define UVC_CAM2_FRAME_HEIGHT UVC_CAM1_FRAME_HEIGHT
#endif
#ifndef UVC_CAM2_FRAME_RATE
#define UVC_CAM2_FRAME_RATE UVC_CAM1_FRAME_RATE
#endif
static const struct {
int width;
int height;
int rate;
} UVC_FRAMES_INFO[][4] = {{
{UVC_CAM1_FRAME_WIDTH, UVC_CAM1_FRAME_HEIGHT, UVC_CAM1_FRAME_RATE},
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
}, {
{UVC_CAM2_FRAME_WIDTH, UVC_CAM2_FRAME_HEIGHT, UVC_CAM2_FRAME_RATE},
{CONFIG_UVC_MULTI_FRAME_WIDTH_1, CONFIG_UVC_MULTI_FRAME_HEIGHT_1, CONFIG_UVC_MULTI_FRAME_FPS_1},
{CONFIG_UVC_MULTI_FRAME_WIDTH_2, CONFIG_UVC_MULTI_FRAME_HEIGHT_2, CONFIG_UVC_MULTI_FRAME_FPS_2},
{CONFIG_UVC_MULTI_FRAME_WIDTH_3, CONFIG_UVC_MULTI_FRAME_HEIGHT_3, CONFIG_UVC_MULTI_FRAME_FPS_3},
}
};
#define UVC_FRAME_NUM (sizeof(UVC_FRAMES_INFO[0]) / sizeof(UVC_FRAMES_INFO[0][0]))
_Static_assert(UVC_FRAME_NUM == 4, "UVC_FRAME_NUM must be 4");