10
10
*********************************************************************/
11
11
12
12
#include " Adafruit_TinyUSB.h"
13
- #include " usb_descriptors.h"
14
13
15
14
// --------------------------------------------------------------------+
16
- //
15
+ // Video descriptors
17
16
// --------------------------------------------------------------------+
17
+
18
+ /* Time stamp base clock. It is a deprecated parameter. */
18
19
#define FRAME_WIDTH 128
19
20
#define FRAME_HEIGHT 96
20
21
#define FRAME_RATE 30
21
22
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
24
56
};
25
57
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;
27
107
28
108
// YUY2 frame buffer
29
109
static 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);
41
121
42
122
void setup () {
43
123
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
+
44
131
usb_video.begin ();
45
132
}
46
133
@@ -53,6 +140,7 @@ void loop() {
53
140
54
141
if (!already_sent) {
55
142
already_sent = 1 ;
143
+ tx_busy = 1 ;
56
144
start_ms = millis ();
57
145
fill_color_bar (frame_buffer, frame_num);
58
146
tud_video_n_frame_xfer (0 , 0 , (void *) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
@@ -62,6 +150,7 @@ void loop() {
62
150
if (cur - start_ms < interval_ms) return ; // not enough time
63
151
if (tx_busy) return ;
64
152
start_ms += interval_ms;
153
+ tx_busy = 1 ;
65
154
66
155
fill_color_bar (frame_buffer, frame_num);
67
156
tud_video_n_frame_xfer (0 , 0 , (void *) frame_buffer, FRAME_WIDTH * FRAME_HEIGHT * 16 / 8 );
0 commit comments