1010*********************************************************************/
1111
1212#include " Adafruit_TinyUSB.h"
13- #include " usb_descriptors.h"
1413
1514// --------------------------------------------------------------------+
16- //
15+ // Video descriptors
1716// --------------------------------------------------------------------+
17+
18+ /* Time stamp base clock. It is a deprecated parameter. */
1819#define FRAME_WIDTH 128
1920#define FRAME_HEIGHT 96
2021#define FRAME_RATE 30
2122
22- uint8_t const desc_video[] = {
23- TUD_VIDEO_CAPTURE_DESCRIPTOR_UNCOMPR_BULK (0 , 0x80 , FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, 64 )
23+ /* video capture path
24+ *
25+ * | Camera Terminal (0x01) | ----> | Output Terminal (0x02 Streaming) |
26+ * */
27+ #define TERMID_CAMERA 0x01
28+ #define TERMID_OUTPUT 0x02
29+
30+ tusb_desc_video_control_camera_terminal_t const desc_camera_terminal = {
31+ .bLength = sizeof (tusb_desc_video_control_camera_terminal_t ),
32+ .bDescriptorType = TUSB_DESC_CS_INTERFACE,
33+ .bDescriptorSubType = VIDEO_CS_ITF_VC_INPUT_TERMINAL,
34+
35+ .bTerminalID = TERMID_CAMERA,
36+ .wTerminalType = VIDEO_ITT_CAMERA,
37+ .bAssocTerminal = 0 ,
38+ .iTerminal = 0 ,
39+ .wObjectiveFocalLengthMin = 0 ,
40+ .wObjectiveFocalLengthMax = 0 ,
41+ .wOcularFocalLength = 0 ,
42+ .bControlSize = 3 ,
43+ .bmControls = { 0 , 0 , 0 }
44+ };
45+
46+ tusb_desc_video_control_output_terminal_t const desc_output_terminal = {
47+ .bLength = sizeof (tusb_desc_video_control_output_terminal_t ),
48+ .bDescriptorType = TUSB_DESC_CS_INTERFACE,
49+ .bDescriptorSubType = VIDEO_CS_ITF_VC_OUTPUT_TERMINAL,
50+
51+ .bTerminalID = TERMID_OUTPUT,
52+ .wTerminalType = VIDEO_TT_STREAMING,
53+ .bAssocTerminal = 0 ,
54+ .bSourceID = TERMID_CAMERA,
55+ .iTerminal = 0
2456};
2557
26- Adafruit_USBD_Video usb_video (desc_video, sizeof (desc_video));
58+ tusb_desc_video_format_uncompressed_t const desc_format = {
59+ .bLength = sizeof (tusb_desc_video_format_uncompressed_t ),
60+ .bDescriptorType = TUSB_DESC_CS_INTERFACE,
61+ .bDescriptorSubType = VIDEO_CS_ITF_VS_FORMAT_UNCOMPRESSED,
62+ .bFormatIndex = 1 , // 1-based index
63+ .bNumFrameDescriptors = 1 ,
64+ .guidFormat = { TUD_VIDEO_GUID_YUY2 },
65+ .bBitsPerPixel = 16 ,
66+ .bDefaultFrameIndex = 1 ,
67+ .bAspectRatioX = 0 ,
68+ .bAspectRatioY = 0 ,
69+ .bmInterlaceFlags = 0 ,
70+ .bCopyProtect = 0
71+ };
72+
73+ tusb_desc_video_frame_uncompressed_continuous_t desc_frame = {
74+ .bLength = sizeof (tusb_desc_video_frame_uncompressed_continuous_t ),
75+ .bDescriptorType = TUSB_DESC_CS_INTERFACE,
76+ .bDescriptorSubType = VIDEO_CS_ITF_VS_FRAME_UNCOMPRESSED,
77+ .bFrameIndex = 1 , // 1-based index
78+ .bmCapabilities = 0 ,
79+ .wWidth = FRAME_WIDTH,
80+ .wHeight = FRAME_HEIGHT,
81+ .dwMinBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * 1 ,
82+ .dwMaxBitRate = FRAME_WIDTH * FRAME_HEIGHT * 16 * FRAME_RATE,
83+ .dwMaxVideoFrameBufferSize = FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 ,
84+ .dwDefaultFrameInterval = 10000000 / FRAME_RATE,
85+ .bFrameIntervalType = 0 , // continuous
86+ .dwFrameInterval = {
87+ 10000000 / FRAME_RATE, // min
88+ 10000000 , // max
89+ 10000000 / FRAME_RATE // step
90+ }
91+ };
92+
93+ tusb_desc_video_streaming_color_matching_t desc_color = {
94+ .bLength = sizeof (tusb_desc_video_streaming_color_matching_t ),
95+ .bDescriptorType = TUSB_DESC_CS_INTERFACE,
96+ .bDescriptorSubType = VIDEO_CS_ITF_VS_COLORFORMAT,
97+
98+ .bColorPrimaries = VIDEO_COLOR_PRIMARIES_BT709,
99+ .bTransferCharacteristics = VIDEO_COLOR_XFER_CH_BT709,
100+ .bMatrixCoefficients = VIDEO_COLOR_COEF_SMPTE170M
101+ };
102+
103+ // --------------------------------------------------------------------+
104+ // Video and frame buffer
105+ // --------------------------------------------------------------------+
106+ Adafruit_USBD_Video usb_video;
27107
28108// YUY2 frame buffer
29109static uint8_t frame_buffer[FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 ];
@@ -41,6 +121,13 @@ static void fill_color_bar(uint8_t* buffer, unsigned start_position);
41121
42122void setup () {
43123 Serial.begin (115200 );
124+
125+ usb_video.addTerminal (&desc_camera_terminal);
126+ usb_video.addTerminal (&desc_output_terminal);
127+ usb_video.addFormat (&desc_format);
128+ usb_video.addFrame (&desc_frame);
129+ usb_video.addColorMatching (&desc_color);
130+
44131 usb_video.begin ();
45132}
46133
@@ -53,6 +140,7 @@ void loop() {
53140
54141 if (!already_sent) {
55142 already_sent = 1 ;
143+ tx_busy = 1 ;
56144 start_ms = millis ();
57145 fill_color_bar (frame_buffer, frame_num);
58146 tud_video_n_frame_xfer (0 , 0 , (void *) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
@@ -62,6 +150,7 @@ void loop() {
62150 if (cur - start_ms < interval_ms) return ; // not enough time
63151 if (tx_busy) return ;
64152 start_ms += interval_ms;
153+ tx_busy = 1 ;
65154
66155 fill_color_bar (frame_buffer, frame_num);
67156 tud_video_n_frame_xfer (0 , 0 , (void *) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
0 commit comments