mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-28 16:20:26 +00:00
update uvc 2ch to stream0 use yuy2, stream1 use mpeg
this help reduce sram requirement for example, also provide different format (uncompressed & mpeg)
This commit is contained in:
parent
34870d3481
commit
34737f9c60
@ -56,8 +56,8 @@ char const* string_desc_arr[] = {
|
|||||||
"TinyUSB", // 1: Manufacturer
|
"TinyUSB", // 1: Manufacturer
|
||||||
"TinyUSB Device", // 2: Product
|
"TinyUSB Device", // 2: Product
|
||||||
NULL, // 3: Serials will use unique ID if possible
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
"TinyUSB UVC Control", // 4: UVC Interface
|
"UVC Control", // 4: UVC Interface
|
||||||
"TinyUSB UVC Streaming", // 5: UVC Interface
|
"UVC Streaming", // 5: UVC Interface
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
@ -1652,18 +1652,11 @@ static const unsigned char frame_buffer[128 * (96 + 1) * 2] = {
|
|||||||
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80, 0x10, 0x80,
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
// mpeg compressed data (not CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
||||||
#define color_bar_0_jpg_len 511
|
|
||||||
#define color_bar_1_jpg_len 512
|
|
||||||
#define color_bar_2_jpg_len 511
|
|
||||||
#define color_bar_3_jpg_len 511
|
|
||||||
#define color_bar_4_jpg_len 511
|
|
||||||
#define color_bar_5_jpg_len 512
|
|
||||||
#define color_bar_6_jpg_len 511
|
|
||||||
#define color_bar_7_jpg_len 511
|
|
||||||
|
|
||||||
unsigned char color_bar_0_jpg[] = {
|
unsigned char color_bar_0_jpg[] = {
|
||||||
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
@ -1936,4 +1929,7 @@ unsigned char color_bar_7_jpg[] = {
|
|||||||
0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a,
|
0x42, 0x51, 0x59, 0x8c, 0xb1, 0x45, 0x00, 0x25, 0x15, 0x98, 0xc4, 0xa2, 0xb5, 0x32, 0x12, 0x8a,
|
||||||
0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9
|
0xcc, 0x63, 0x68, 0xad, 0x8d, 0x84, 0xa2, 0xb3, 0x18, 0x94, 0x56, 0xa6, 0x47, 0xff, 0xd9
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -116,31 +116,27 @@ static unsigned frame_num[CFG_TUD_VIDEO_STREAMING] = {1};
|
|||||||
static unsigned tx_busy = 0;
|
static unsigned tx_busy = 0;
|
||||||
static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE};
|
static unsigned interval_ms[CFG_TUD_VIDEO_STREAMING] = {1000 / FRAME_RATE};
|
||||||
|
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
|
||||||
// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data.
|
// For mcus that does not have enough SRAM for frame buffer, we use fixed frame data.
|
||||||
// To further reduce the size, we use MJPEG format instead of YUY2.
|
// To further reduce the size, we use MJPEG format instead of YUY2.
|
||||||
#include "images.h"
|
#include "images.h"
|
||||||
|
|
||||||
#if !defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
|
||||||
static struct {
|
static struct {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t const *buffer;
|
uint8_t const *buffer;
|
||||||
} const frames[] = {
|
} const framebuf_mjpeg[] = {
|
||||||
{color_bar_0_jpg_len, color_bar_0_jpg},
|
{sizeof(color_bar_0_jpg), color_bar_0_jpg},
|
||||||
{color_bar_1_jpg_len, color_bar_1_jpg},
|
{sizeof(color_bar_1_jpg), color_bar_1_jpg},
|
||||||
{color_bar_2_jpg_len, color_bar_2_jpg},
|
{sizeof(color_bar_2_jpg), color_bar_2_jpg},
|
||||||
{color_bar_3_jpg_len, color_bar_3_jpg},
|
{sizeof(color_bar_3_jpg), color_bar_3_jpg},
|
||||||
{color_bar_4_jpg_len, color_bar_4_jpg},
|
{sizeof(color_bar_4_jpg), color_bar_4_jpg},
|
||||||
{color_bar_5_jpg_len, color_bar_5_jpg},
|
{sizeof(color_bar_5_jpg), color_bar_5_jpg},
|
||||||
{color_bar_6_jpg_len, color_bar_6_jpg},
|
{sizeof(color_bar_6_jpg), color_bar_6_jpg},
|
||||||
{color_bar_7_jpg_len, color_bar_7_jpg},
|
{sizeof(color_bar_7_jpg), color_bar_7_jpg},
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// YUY2 frame buffer
|
// YUY2 frame buffer
|
||||||
static uint8_t frame_buffer[2][FRAME_WIDTH * FRAME_HEIGHT * 16 / 8];
|
#define FRAMEBUF_SIZE (FRAME_WIDTH * FRAME_HEIGHT * 16 / 8)
|
||||||
|
static uint8_t framebuf_yuy2[FRAMEBUF_SIZE];
|
||||||
|
|
||||||
static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
|
static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
|
||||||
/* EBU color bars: https://stackoverflow.com/questions/6939422 */
|
/* EBU color bars: https://stackoverflow.com/questions/6939422 */
|
||||||
@ -179,7 +175,26 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
size_t get_framebuf(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, size_t fnum, void **fb) {
|
||||||
|
uint32_t idx = ctl_idx + stm_idx;
|
||||||
|
|
||||||
|
if (idx == 0) {
|
||||||
|
// stream 0 use uncompressed YUY2 frame
|
||||||
|
fill_color_bar(framebuf_yuy2, frame_num[idx]);
|
||||||
|
*fb = framebuf_yuy2;
|
||||||
|
return FRAMEBUF_SIZE;
|
||||||
|
}else {
|
||||||
|
// stream 1 use MJPEG frame
|
||||||
|
size_t const bar_id = fnum & 0x7;
|
||||||
|
|
||||||
|
*fb = (void*)(uintptr_t) framebuf_mjpeg[bar_id].buffer;
|
||||||
|
return framebuf_mjpeg[bar_id].size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
|
void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
|
||||||
static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, };
|
static unsigned start_ms[CFG_TUD_VIDEO_STREAMING] = {0, };
|
||||||
@ -191,22 +206,16 @@ void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
|
|||||||
frame_num[idx] = 0;
|
frame_num[idx] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
void* fp;
|
||||||
|
size_t fb_size;
|
||||||
|
|
||||||
if (!(already_sent & (1u << idx))) {
|
if (!(already_sent & (1u << idx))) {
|
||||||
already_sent |= 1u << idx;
|
already_sent |= 1u << idx;
|
||||||
tx_busy |= 1u << idx;
|
tx_busy |= 1u << idx;
|
||||||
start_ms[idx] = board_millis();
|
start_ms[idx] = board_millis();
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
|
||||||
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp);
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4],
|
tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size);
|
||||||
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
|
||||||
#else
|
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
fill_color_bar(frame_buffer[idx], frame_num[idx]);
|
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cur = board_millis();
|
unsigned cur = board_millis();
|
||||||
@ -215,17 +224,8 @@ void video_send_frame(uint_fast8_t ctl_idx, uint_fast8_t stm_idx) {
|
|||||||
start_ms[idx] += interval_ms[idx];
|
start_ms[idx] += interval_ms[idx];
|
||||||
tx_busy |= 1u << idx;
|
tx_busy |= 1u << idx;
|
||||||
|
|
||||||
#ifdef CFG_EXAMPLE_VIDEO_READONLY
|
fb_size = get_framebuf(ctl_idx, stm_idx, frame_num[idx], &fp);
|
||||||
#if defined(CFG_EXAMPLE_VIDEO_DISABLE_MJPEG)
|
tud_video_n_frame_xfer(ctl_idx, stm_idx, fp, fb_size);
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)&frame_buffer[(frame_num[idx] % (FRAME_WIDTH / 2)) * 4],
|
|
||||||
FRAME_WIDTH * FRAME_HEIGHT * 16/8);
|
|
||||||
#else
|
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*)(uintptr_t)frames[frame_num[idx] % 8].buffer, frames[frame_num[idx] % 8].size);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
fill_color_bar(frame_buffer[idx], frame_num[idx]);
|
|
||||||
tud_video_n_frame_xfer(ctl_idx, stm_idx, (void*) frame_buffer[idx], FRAME_WIDTH * FRAME_HEIGHT * 16 / 8);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,13 +55,14 @@ enum {
|
|||||||
// array of pointer to string descriptors
|
// array of pointer to string descriptors
|
||||||
char const* string_desc_arr[] = {
|
char const* string_desc_arr[] = {
|
||||||
(const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409)
|
(const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409)
|
||||||
"TinyUSB", // 1: Manufacturer
|
"TinyUSB", // 1: Manufacturer
|
||||||
"TinyUSB Device", // 2: Product
|
"TinyUSB Device", // 2: Product
|
||||||
NULL, // 3: Serials will use unique ID if possible
|
NULL, // 3: Serials will use unique ID if possible
|
||||||
"TinyUSB UVC Control 1", // 4: UVC Interface 1
|
"UVC Control 1", // 4: UVC Interface 1
|
||||||
"TinyUSB UVC Streaming 1", // 5: UVC Interface 1
|
"UVC Streaming 1", // 5: UVC Interface 1
|
||||||
"TinyUSB UVC Control 2", // 6: UVC Interface 2
|
"UVC Control 2", // 6: UVC Interface 2
|
||||||
"TinyUSB UVC Streaming 2", // 7: UVC Interface 2
|
"UVC Streaming 2", // 7: UVC Interface 2
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -140,15 +141,8 @@ typedef struct TU_ATTR_PACKED {
|
|||||||
typedef struct TU_ATTR_PACKED {
|
typedef struct TU_ATTR_PACKED {
|
||||||
tusb_desc_interface_t itf;
|
tusb_desc_interface_t itf;
|
||||||
tusb_desc_video_streaming_input_header_1byte_t header;
|
tusb_desc_video_streaming_input_header_1byte_t header;
|
||||||
|
|
||||||
#if USE_MJPEG
|
|
||||||
tusb_desc_video_format_mjpeg_t format;
|
|
||||||
tusb_desc_video_frame_mjpeg_continuous_t frame;
|
|
||||||
#else
|
|
||||||
tusb_desc_video_format_uncompressed_t format;
|
tusb_desc_video_format_uncompressed_t format;
|
||||||
tusb_desc_video_frame_uncompressed_continuous_t frame;
|
tusb_desc_video_frame_uncompressed_continuous_t frame;
|
||||||
#endif
|
|
||||||
|
|
||||||
tusb_desc_video_streaming_color_matching_t color;
|
tusb_desc_video_streaming_color_matching_t color;
|
||||||
|
|
||||||
#if USE_ISO_STREAMING
|
#if USE_ISO_STREAMING
|
||||||
@ -157,15 +151,37 @@ typedef struct TU_ATTR_PACKED {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
tusb_desc_endpoint_t ep;
|
tusb_desc_endpoint_t ep;
|
||||||
} uvc_streaming_desc_t;
|
} uvc_streaming_yuy2_desc_t;
|
||||||
|
|
||||||
|
typedef struct TU_ATTR_PACKED {
|
||||||
|
tusb_desc_interface_t itf;
|
||||||
|
tusb_desc_video_streaming_input_header_1byte_t header;
|
||||||
|
tusb_desc_video_format_mjpeg_t format;
|
||||||
|
tusb_desc_video_frame_mjpeg_continuous_t frame;
|
||||||
|
tusb_desc_video_streaming_color_matching_t color;
|
||||||
|
|
||||||
|
#if USE_ISO_STREAMING
|
||||||
|
// For ISO streaming, USB spec requires to alternate interface
|
||||||
|
tusb_desc_interface_t itf_alt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tusb_desc_endpoint_t ep;
|
||||||
|
} uvc_streaming_mpeg_desc_t;
|
||||||
|
|
||||||
typedef struct TU_ATTR_PACKED {
|
typedef struct TU_ATTR_PACKED {
|
||||||
tusb_desc_configuration_t config;
|
tusb_desc_configuration_t config;
|
||||||
|
|
||||||
struct TU_ATTR_PACKED {
|
struct TU_ATTR_PACKED {
|
||||||
tusb_desc_interface_assoc_t iad;
|
tusb_desc_interface_assoc_t iad;
|
||||||
uvc_control_desc_t video_control;
|
uvc_control_desc_t video_control;
|
||||||
uvc_streaming_desc_t video_streaming;
|
uvc_streaming_yuy2_desc_t video_streaming;
|
||||||
} uvc[2];
|
} uvc_yuy2;
|
||||||
|
|
||||||
|
struct TU_ATTR_PACKED {
|
||||||
|
tusb_desc_interface_assoc_t iad;
|
||||||
|
uvc_control_desc_t video_control;
|
||||||
|
uvc_streaming_mpeg_desc_t video_streaming;
|
||||||
|
} uvc_mpeg;
|
||||||
} uvc_cfg_desc_t;
|
} uvc_cfg_desc_t;
|
||||||
|
|
||||||
const uvc_cfg_desc_t desc_fs_configuration = {
|
const uvc_cfg_desc_t desc_fs_configuration = {
|
||||||
@ -180,369 +196,336 @@ const uvc_cfg_desc_t desc_fs_configuration = {
|
|||||||
.bmAttributes = TU_BIT(7),
|
.bmAttributes = TU_BIT(7),
|
||||||
.bMaxPower = 100 / 2
|
.bMaxPower = 100 / 2
|
||||||
},
|
},
|
||||||
.uvc = {
|
//------------- Stream 0: YUY2 -------------//
|
||||||
{
|
.uvc_yuy2 = {
|
||||||
.iad = {
|
.iad = {
|
||||||
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
|
.bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
|
||||||
|
|
||||||
.bFirstInterface = ITF_NUM_VIDEO_CONTROL_1,
|
.bFirstInterface = ITF_NUM_VIDEO_CONTROL_1,
|
||||||
.bInterfaceCount = 2,
|
.bInterfaceCount = 2,
|
||||||
.bFunctionClass = TUSB_CLASS_VIDEO,
|
.bFunctionClass = TUSB_CLASS_VIDEO,
|
||||||
.bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION,
|
.bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION,
|
||||||
.bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED,
|
.bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED,
|
||||||
.iFunction = 0
|
.iFunction = 0
|
||||||
|
},
|
||||||
|
.video_control = {
|
||||||
|
.itf = {
|
||||||
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
|
|
||||||
|
.bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 0,
|
||||||
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
|
.bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL,
|
||||||
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
|
.iInterface = STRID_UVC_CONTROL_1
|
||||||
},
|
},
|
||||||
|
.header = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_header_1itf_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER,
|
||||||
|
|
||||||
.video_control = {
|
.bcdUVC = VIDEO_BCD_1_50,
|
||||||
.itf = {
|
.wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
.dwClockFrequency = UVC_CLOCK_FREQUENCY,
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
.bInCollection = 1,
|
||||||
|
.baInterfaceNr = {ITF_NUM_VIDEO_STREAMING_1}
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_1,
|
|
||||||
.bAlternateSetting = 0,
|
|
||||||
.bNumEndpoints = 0,
|
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL,
|
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
|
||||||
.iInterface = STRID_UVC_CONTROL_1
|
|
||||||
},
|
|
||||||
.header = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_control_header_1itf_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER,
|
|
||||||
|
|
||||||
.bcdUVC = VIDEO_BCD_1_50,
|
|
||||||
.wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only
|
|
||||||
.dwClockFrequency = UVC_CLOCK_FREQUENCY,
|
|
||||||
.bInCollection = 1,
|
|
||||||
.baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_1 }
|
|
||||||
},
|
|
||||||
.camera_terminal = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_control_camera_terminal_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
|
|
||||||
|
|
||||||
.bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
|
||||||
.wTerminalType = VIDEO_ITT_CAMERA,
|
|
||||||
.bAssocTerminal = 0,
|
|
||||||
.iTerminal = 0,
|
|
||||||
.wObjectiveFocalLengthMin = 0,
|
|
||||||
.wObjectiveFocalLengthMax = 0,
|
|
||||||
.wOcularFocalLength = 0,
|
|
||||||
.bControlSize = 3,
|
|
||||||
.bmControls = { 0, 0, 0 }
|
|
||||||
},
|
|
||||||
.output_terminal = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_control_output_terminal_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
|
|
||||||
|
|
||||||
.bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
|
||||||
.wTerminalType = VIDEO_TT_STREAMING,
|
|
||||||
.bAssocTerminal = 0,
|
|
||||||
.bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
|
||||||
.iTerminal = 0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
.camera_terminal = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_camera_terminal_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
|
||||||
|
|
||||||
.video_streaming = {
|
.bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
||||||
.itf = {
|
.wTerminalType = VIDEO_ITT_CAMERA,
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
.bAssocTerminal = 0,
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
.iTerminal = 0,
|
||||||
|
.wObjectiveFocalLengthMin = 0,
|
||||||
|
.wObjectiveFocalLengthMax = 0,
|
||||||
|
.wOcularFocalLength = 0,
|
||||||
|
.bControlSize = 3,
|
||||||
|
.bmControls = {0, 0, 0}
|
||||||
|
},
|
||||||
|
.output_terminal = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_output_terminal_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
|
||||||
|
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1,
|
.bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
||||||
.bAlternateSetting = 0,
|
.wTerminalType = VIDEO_TT_STREAMING,
|
||||||
.bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0
|
.bAssocTerminal = 0,
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
.bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
.iTerminal = 0
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
|
||||||
.iInterface = STRID_UVC_STREAMING_1
|
|
||||||
},
|
|
||||||
.header = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER,
|
|
||||||
|
|
||||||
.bNumFormats = 1,
|
|
||||||
.wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t)
|
|
||||||
- sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only
|
|
||||||
.bEndpointAddress = EPNUM_VIDEO_IN_1,
|
|
||||||
.bmInfo = 0,
|
|
||||||
.bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
|
||||||
.bStillCaptureMethod = 0,
|
|
||||||
.bTriggerSupport = 0,
|
|
||||||
.bTriggerUsage = 0,
|
|
||||||
.bControlSize = 1,
|
|
||||||
.bmaControls = { 0 }
|
|
||||||
},
|
|
||||||
.format = {
|
|
||||||
#if USE_MJPEG
|
|
||||||
.bLength = sizeof(tusb_desc_video_format_mjpeg_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG,
|
|
||||||
.bFormatIndex = 1, // 1-based index
|
|
||||||
.bNumFrameDescriptors = 1,
|
|
||||||
.bmFlags = 0,
|
|
||||||
#else
|
|
||||||
.bLength = sizeof(tusb_desc_video_format_uncompressed_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
|
|
||||||
.bFormatIndex = 1, // 1-based index
|
|
||||||
.bNumFrameDescriptors = 1,
|
|
||||||
.guidFormat = { TUD_VIDEO_GUID_YUY2 },
|
|
||||||
.bBitsPerPixel = 16,
|
|
||||||
#endif
|
|
||||||
.bDefaultFrameIndex = 1,
|
|
||||||
.bAspectRatioX = 0,
|
|
||||||
.bAspectRatioY = 0,
|
|
||||||
.bmInterlaceFlags = 0,
|
|
||||||
.bCopyProtect = 0
|
|
||||||
},
|
|
||||||
.frame = {
|
|
||||||
#if USE_MJPEG
|
|
||||||
.bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG,
|
|
||||||
#else
|
|
||||||
.bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
|
|
||||||
#endif
|
|
||||||
.bFrameIndex = 1, // 1-based index
|
|
||||||
.bmCapabilities = 0,
|
|
||||||
.wWidth = FRAME_WIDTH,
|
|
||||||
.wHeight = FRAME_HEIGHT,
|
|
||||||
.dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1,
|
|
||||||
.dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
|
|
||||||
.dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8,
|
|
||||||
.dwDefaultFrameInterval = 10000000 / FRAME_RATE,
|
|
||||||
.bFrameIntervalType = 0, // continuous
|
|
||||||
.dwFrameInterval = {
|
|
||||||
10000000 / FRAME_RATE, // min
|
|
||||||
10000000, // max
|
|
||||||
10000000 / FRAME_RATE // step
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.color = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_streaming_color_matching_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
|
|
||||||
|
|
||||||
.bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
|
|
||||||
.bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
|
|
||||||
.bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
|
|
||||||
},
|
|
||||||
|
|
||||||
#if USE_ISO_STREAMING
|
|
||||||
.itf_alt = {
|
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
|
||||||
|
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1,
|
|
||||||
.bAlternateSetting = 1,
|
|
||||||
.bNumEndpoints = 1,
|
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
|
||||||
.iInterface = STRID_UVC_STREAMING_1
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.ep = {
|
|
||||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_ENDPOINT,
|
|
||||||
|
|
||||||
.bEndpointAddress = EPNUM_VIDEO_IN_1,
|
|
||||||
.bmAttributes = {
|
|
||||||
.xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS,
|
|
||||||
.sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous
|
|
||||||
},
|
|
||||||
.wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE,
|
|
||||||
.bInterval = 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.iad = {
|
|
||||||
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
|
|
||||||
|
|
||||||
.bFirstInterface = ITF_NUM_VIDEO_CONTROL_2,
|
.video_streaming = {
|
||||||
.bInterfaceCount = 2,
|
.itf = {
|
||||||
.bFunctionClass = TUSB_CLASS_VIDEO,
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
.bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION,
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
.bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED,
|
|
||||||
.iFunction = 0
|
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0
|
||||||
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
|
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
||||||
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
|
.iInterface = STRID_UVC_STREAMING_1
|
||||||
},
|
},
|
||||||
|
.header = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER,
|
||||||
|
|
||||||
.video_control = {
|
.bNumFormats = 1,
|
||||||
.itf = {
|
.wTotalLength = sizeof(uvc_streaming_yuy2_desc_t) - sizeof(tusb_desc_interface_t)
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
- sizeof(tusb_desc_endpoint_t) -
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
(USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0), // CS VS descriptors only
|
||||||
|
.bEndpointAddress = EPNUM_VIDEO_IN_1,
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2,
|
.bmInfo = 0,
|
||||||
.bAlternateSetting = 0,
|
.bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
||||||
.bNumEndpoints = 0,
|
.bStillCaptureMethod = 0,
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
.bTriggerSupport = 0,
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL,
|
.bTriggerUsage = 0,
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
.bControlSize = 1,
|
||||||
.iInterface = STRID_UVC_CONTROL_2
|
.bmaControls = {0}
|
||||||
},
|
},
|
||||||
.header = {
|
.format = {
|
||||||
.bLength = sizeof(tusb_desc_video_control_header_1itf_t),
|
.bLength = sizeof(tusb_desc_video_format_uncompressed_t),
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER,
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
|
||||||
|
.bFormatIndex = 1, // 1-based index
|
||||||
.bcdUVC = VIDEO_BCD_1_50,
|
.bNumFrameDescriptors = 1,
|
||||||
.wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only
|
.guidFormat = {TUD_VIDEO_GUID_YUY2},
|
||||||
.dwClockFrequency = UVC_CLOCK_FREQUENCY,
|
.bBitsPerPixel = 16,
|
||||||
.bInCollection = 1,
|
.bDefaultFrameIndex = 1,
|
||||||
.baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 }
|
.bAspectRatioX = 0,
|
||||||
},
|
.bAspectRatioY = 0,
|
||||||
.camera_terminal = {
|
.bmInterlaceFlags = 0,
|
||||||
.bLength = sizeof(tusb_desc_video_control_camera_terminal_t),
|
.bCopyProtect = 0
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
},
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
|
.frame = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t),
|
||||||
.bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
.wTerminalType = VIDEO_ITT_CAMERA,
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
|
||||||
.bAssocTerminal = 0,
|
.bFrameIndex = 1, // 1-based index
|
||||||
.iTerminal = 0,
|
.bmCapabilities = 0,
|
||||||
.wObjectiveFocalLengthMin = 0,
|
.wWidth = FRAME_WIDTH,
|
||||||
.wObjectiveFocalLengthMax = 0,
|
.wHeight = FRAME_HEIGHT,
|
||||||
.wOcularFocalLength = 0,
|
.dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1,
|
||||||
.bControlSize = 3,
|
.dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
|
||||||
.bmControls = { 0, 0, 0 }
|
.dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8,
|
||||||
},
|
.dwDefaultFrameInterval = 10000000 / FRAME_RATE,
|
||||||
.output_terminal = {
|
.bFrameIntervalType = 0, // continuous
|
||||||
.bLength = sizeof(tusb_desc_video_control_output_terminal_t),
|
.dwFrameInterval = {
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
10000000 / FRAME_RATE, // min
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
|
10000000, // max
|
||||||
|
10000000 / FRAME_RATE // step
|
||||||
.bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
|
||||||
.wTerminalType = VIDEO_TT_STREAMING,
|
|
||||||
.bAssocTerminal = 0,
|
|
||||||
.bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
|
||||||
.iTerminal = 0
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
.color = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_streaming_color_matching_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
|
||||||
|
|
||||||
.video_streaming = {
|
.bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
|
||||||
.itf = {
|
.bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
.bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
},
|
||||||
|
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2,
|
|
||||||
.bAlternateSetting = 0,
|
|
||||||
.bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0
|
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
|
||||||
.iInterface = STRID_UVC_STREAMING_2
|
|
||||||
},
|
|
||||||
.header = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER,
|
|
||||||
|
|
||||||
.bNumFormats = 1,
|
|
||||||
.wTotalLength = sizeof(uvc_streaming_desc_t) - sizeof(tusb_desc_interface_t)
|
|
||||||
- sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only
|
|
||||||
.bEndpointAddress = EPNUM_VIDEO_IN_2,
|
|
||||||
.bmInfo = 0,
|
|
||||||
.bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
|
||||||
.bStillCaptureMethod = 0,
|
|
||||||
.bTriggerSupport = 0,
|
|
||||||
.bTriggerUsage = 0,
|
|
||||||
.bControlSize = 1,
|
|
||||||
.bmaControls = { 0 }
|
|
||||||
},
|
|
||||||
.format = {
|
|
||||||
#if USE_MJPEG
|
|
||||||
.bLength = sizeof(tusb_desc_video_format_mjpeg_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG,
|
|
||||||
.bFormatIndex = 1, // 1-based index
|
|
||||||
.bNumFrameDescriptors = 1,
|
|
||||||
.bmFlags = 0,
|
|
||||||
#else
|
|
||||||
.bLength = sizeof(tusb_desc_video_format_uncompressed_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
|
|
||||||
.bFormatIndex = 1, // 1-based index
|
|
||||||
.bNumFrameDescriptors = 1,
|
|
||||||
.guidFormat = { TUD_VIDEO_GUID_YUY2 },
|
|
||||||
.bBitsPerPixel = 16,
|
|
||||||
#endif
|
|
||||||
.bDefaultFrameIndex = 1,
|
|
||||||
.bAspectRatioX = 0,
|
|
||||||
.bAspectRatioY = 0,
|
|
||||||
.bmInterlaceFlags = 0,
|
|
||||||
.bCopyProtect = 0
|
|
||||||
},
|
|
||||||
.frame = {
|
|
||||||
#if USE_MJPEG
|
|
||||||
.bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG,
|
|
||||||
#else
|
|
||||||
.bLength = sizeof(tusb_desc_video_frame_uncompressed_continuous_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
|
|
||||||
#endif
|
|
||||||
.bFrameIndex = 1, // 1-based index
|
|
||||||
.bmCapabilities = 0,
|
|
||||||
.wWidth = FRAME_WIDTH,
|
|
||||||
.wHeight = FRAME_HEIGHT,
|
|
||||||
.dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1,
|
|
||||||
.dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
|
|
||||||
.dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8,
|
|
||||||
.dwDefaultFrameInterval = 10000000 / FRAME_RATE,
|
|
||||||
.bFrameIntervalType = 0, // continuous
|
|
||||||
.dwFrameInterval = {
|
|
||||||
10000000 / FRAME_RATE, // min
|
|
||||||
10000000, // max
|
|
||||||
10000000 / FRAME_RATE // step
|
|
||||||
}
|
|
||||||
},
|
|
||||||
.color = {
|
|
||||||
.bLength = sizeof(tusb_desc_video_streaming_color_matching_t),
|
|
||||||
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
|
||||||
.bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
|
|
||||||
|
|
||||||
.bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
|
|
||||||
.bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
|
|
||||||
.bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
|
|
||||||
},
|
|
||||||
|
|
||||||
#if USE_ISO_STREAMING
|
#if USE_ISO_STREAMING
|
||||||
.itf_alt = {
|
.itf_alt = {
|
||||||
.bLength = sizeof(tusb_desc_interface_t),
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
.bDescriptorType = TUSB_DESC_INTERFACE,
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
|
|
||||||
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2,
|
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_1,
|
||||||
.bAlternateSetting = 1,
|
.bAlternateSetting = 1,
|
||||||
.bNumEndpoints = 1,
|
.bNumEndpoints = 1,
|
||||||
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
||||||
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
.iInterface = STRID_UVC_STREAMING_2
|
.iInterface = STRID_UVC_STREAMING_1
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
|
.ep = {
|
||||||
|
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_ENDPOINT,
|
||||||
|
|
||||||
.ep = {
|
.bEndpointAddress = EPNUM_VIDEO_IN_1,
|
||||||
.bLength = sizeof(tusb_desc_endpoint_t),
|
.bmAttributes = {
|
||||||
.bDescriptorType = TUSB_DESC_ENDPOINT,
|
.xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS,
|
||||||
|
.sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous
|
||||||
|
},
|
||||||
|
.wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE,
|
||||||
|
.bInterval = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//------------- Stream 1: MPEG -------------//
|
||||||
|
.uvc_mpeg = {
|
||||||
|
.iad = {
|
||||||
|
.bLength = sizeof(tusb_desc_interface_assoc_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_INTERFACE_ASSOCIATION,
|
||||||
|
|
||||||
.bEndpointAddress = EPNUM_VIDEO_IN_2,
|
.bFirstInterface = ITF_NUM_VIDEO_CONTROL_2,
|
||||||
.bmAttributes = {
|
.bInterfaceCount = 2,
|
||||||
.xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS,
|
.bFunctionClass = TUSB_CLASS_VIDEO,
|
||||||
.sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous
|
.bFunctionSubClass = VIDEO_SUBCLASS_INTERFACE_COLLECTION,
|
||||||
},
|
.bFunctionProtocol = VIDEO_ITF_PROTOCOL_UNDEFINED,
|
||||||
.wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE,
|
.iFunction = 0
|
||||||
.bInterval = 1
|
},
|
||||||
|
|
||||||
|
.video_control = {
|
||||||
|
.itf = {
|
||||||
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
|
|
||||||
|
.bInterfaceNumber = ITF_NUM_VIDEO_CONTROL_2,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = 0,
|
||||||
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
|
.bInterfaceSubClass = VIDEO_SUBCLASS_CONTROL,
|
||||||
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
|
.iInterface = STRID_UVC_CONTROL_2
|
||||||
|
},
|
||||||
|
.header = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_header_1itf_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_HEADER,
|
||||||
|
|
||||||
|
.bcdUVC = VIDEO_BCD_1_50,
|
||||||
|
.wTotalLength = sizeof(uvc_control_desc_t) - sizeof(tusb_desc_interface_t), // CS VC descriptors only
|
||||||
|
.dwClockFrequency = UVC_CLOCK_FREQUENCY,
|
||||||
|
.bInCollection = 1,
|
||||||
|
.baInterfaceNr = { ITF_NUM_VIDEO_STREAMING_2 }
|
||||||
|
},
|
||||||
|
.camera_terminal = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_camera_terminal_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
|
||||||
|
|
||||||
|
.bTerminalID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
||||||
|
.wTerminalType = VIDEO_ITT_CAMERA,
|
||||||
|
.bAssocTerminal = 0,
|
||||||
|
.iTerminal = 0,
|
||||||
|
.wObjectiveFocalLengthMin = 0,
|
||||||
|
.wObjectiveFocalLengthMax = 0,
|
||||||
|
.wOcularFocalLength = 0,
|
||||||
|
.bControlSize = 3,
|
||||||
|
.bmControls = { 0, 0, 0 }
|
||||||
|
},
|
||||||
|
.output_terminal = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_control_output_terminal_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
|
||||||
|
|
||||||
|
.bTerminalID = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
||||||
|
.wTerminalType = VIDEO_TT_STREAMING,
|
||||||
|
.bAssocTerminal = 0,
|
||||||
|
.bSourceID = UVC_ENTITY_CAP_INPUT_TERMINAL,
|
||||||
|
.iTerminal = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.video_streaming = {
|
||||||
|
.itf = {
|
||||||
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
|
|
||||||
|
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2,
|
||||||
|
.bAlternateSetting = 0,
|
||||||
|
.bNumEndpoints = CFG_TUD_VIDEO_STREAMING_BULK, // bulk 1, iso 0
|
||||||
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
|
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
||||||
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
|
.iInterface = STRID_UVC_STREAMING_2
|
||||||
|
},
|
||||||
|
.header = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_streaming_input_header_1byte_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_INPUT_HEADER,
|
||||||
|
|
||||||
|
.bNumFormats = 1,
|
||||||
|
.wTotalLength = sizeof(uvc_streaming_mpeg_desc_t) - sizeof(tusb_desc_interface_t)
|
||||||
|
- sizeof(tusb_desc_endpoint_t) - (USE_ISO_STREAMING ? sizeof(tusb_desc_interface_t) : 0) , // CS VS descriptors only
|
||||||
|
.bEndpointAddress = EPNUM_VIDEO_IN_2,
|
||||||
|
.bmInfo = 0,
|
||||||
|
.bTerminalLink = UVC_ENTITY_CAP_OUTPUT_TERMINAL,
|
||||||
|
.bStillCaptureMethod = 0,
|
||||||
|
.bTriggerSupport = 0,
|
||||||
|
.bTriggerUsage = 0,
|
||||||
|
.bControlSize = 1,
|
||||||
|
.bmaControls = { 0 }
|
||||||
|
},
|
||||||
|
.format = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_format_mjpeg_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_MJPEG,
|
||||||
|
.bFormatIndex = 1, // 1-based index
|
||||||
|
.bNumFrameDescriptors = 1,
|
||||||
|
.bmFlags = 0,
|
||||||
|
.bDefaultFrameIndex = 1,
|
||||||
|
.bAspectRatioX = 0,
|
||||||
|
.bAspectRatioY = 0,
|
||||||
|
.bmInterlaceFlags = 0,
|
||||||
|
.bCopyProtect = 0
|
||||||
|
},
|
||||||
|
.frame = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_frame_mjpeg_continuous_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_MJPEG,
|
||||||
|
.bFrameIndex = 1, // 1-based index
|
||||||
|
.bmCapabilities = 0,
|
||||||
|
.wWidth = FRAME_WIDTH,
|
||||||
|
.wHeight = FRAME_HEIGHT,
|
||||||
|
.dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1,
|
||||||
|
.dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
|
||||||
|
.dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8,
|
||||||
|
.dwDefaultFrameInterval = 10000000 / FRAME_RATE,
|
||||||
|
.bFrameIntervalType = 0, // continuous
|
||||||
|
.dwFrameInterval = {
|
||||||
|
10000000 / FRAME_RATE, // min
|
||||||
|
10000000, // max
|
||||||
|
10000000 / FRAME_RATE // step
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
.color = {
|
||||||
|
.bLength = sizeof(tusb_desc_video_streaming_color_matching_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_CS_INTERFACE,
|
||||||
|
.bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
|
||||||
|
|
||||||
|
.bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
|
||||||
|
.bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
|
||||||
|
.bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
|
||||||
|
},
|
||||||
|
|
||||||
|
#if USE_ISO_STREAMING
|
||||||
|
.itf_alt = {
|
||||||
|
.bLength = sizeof(tusb_desc_interface_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_INTERFACE,
|
||||||
|
|
||||||
|
.bInterfaceNumber = ITF_NUM_VIDEO_STREAMING_2,
|
||||||
|
.bAlternateSetting = 1,
|
||||||
|
.bNumEndpoints = 1,
|
||||||
|
.bInterfaceClass = TUSB_CLASS_VIDEO,
|
||||||
|
.bInterfaceSubClass = VIDEO_SUBCLASS_STREAMING,
|
||||||
|
.bInterfaceProtocol = VIDEO_ITF_PROTOCOL_15,
|
||||||
|
.iInterface = STRID_UVC_STREAMING_2
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
.ep = {
|
||||||
|
.bLength = sizeof(tusb_desc_endpoint_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_ENDPOINT,
|
||||||
|
|
||||||
|
.bEndpointAddress = EPNUM_VIDEO_IN_2,
|
||||||
|
.bmAttributes = {
|
||||||
|
.xfer = CFG_TUD_VIDEO_STREAMING_BULK ? TUSB_XFER_BULK : TUSB_XFER_ISOCHRONOUS,
|
||||||
|
.sync = CFG_TUD_VIDEO_STREAMING_BULK ? 0 : 1 // asynchronous
|
||||||
|
},
|
||||||
|
.wMaxPacketSize = CFG_TUD_VIDEO_STREAMING_BULK ? 64 : CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE,
|
||||||
|
.bInterval = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,8 +541,8 @@ static uint8_t * get_hs_configuration_desc(void) {
|
|||||||
desc_hs_configuration = desc_fs_configuration;
|
desc_hs_configuration = desc_fs_configuration;
|
||||||
// change endpoint bulk size to 512 if bulk streaming
|
// change endpoint bulk size to 512 if bulk streaming
|
||||||
if (CFG_TUD_VIDEO_STREAMING_BULK) {
|
if (CFG_TUD_VIDEO_STREAMING_BULK) {
|
||||||
desc_hs_configuration.uvc[0].video_streaming.ep.wMaxPacketSize = 512;
|
desc_hs_configuration.uvc_yuy2.video_streaming.ep.wMaxPacketSize = 512;
|
||||||
desc_hs_configuration.uvc[1].video_streaming.ep.wMaxPacketSize = 512;
|
desc_hs_configuration.uvc_mpeg.video_streaming.ep.wMaxPacketSize = 512;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
init = true;
|
init = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user