1
1
/*
2
- * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
2
+ * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
10
10
#include <inttypes.h>
11
11
12
12
#include "esp_log.h"
13
+ #include "include/libuvc_def.h"
13
14
#include "usb/usb_host.h"
14
15
#include "usb/usb_types_ch9.h"
15
16
#include "usb_stream_descriptor.h"
16
17
17
- // esp32/tools/esp32-arduino-libs/idf-release_v5.1-6b1f40b9bf/esp32s3/include/usb/include/usb/
18
18
void print_device_descriptor (const uint8_t * buff )
19
19
{
20
20
if (buff == NULL ) {
@@ -91,12 +91,106 @@ void print_uvc_header_desc(const uint8_t *buff, uint8_t sub_class)
91
91
#endif
92
92
}
93
93
94
- void parse_vs_format_mjpeg_desc (const uint8_t * buff , uint8_t * format_idx , uint8_t * frame_num )
94
+ struct format_table_entry {
95
+ enum uvc_frame_format format ;
96
+ uint8_t abstract_fmt ;
97
+ uint8_t guid [16 ];
98
+ int children_count ;
99
+ enum uvc_frame_format * children ;
100
+ };
101
+
102
+ struct format_table_entry * _get_format_entry (enum uvc_frame_format format )
103
+ {
104
+ #define ABS_FMT (_fmt , _num , ...) \
105
+ case _fmt: { \
106
+ static enum uvc_frame_format _fmt##_children[] = __VA_ARGS__; \
107
+ static struct format_table_entry _fmt##_entry = { \
108
+ _fmt, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, _num, _fmt##_children }; \
109
+ return &_fmt##_entry; }
110
+
111
+ #define FMT (_fmt , ...) \
112
+ case _fmt: { \
113
+ static struct format_table_entry _fmt##_entry = { \
114
+ _fmt, 0, __VA_ARGS__, 0, NULL }; \
115
+ return &_fmt##_entry; }
116
+
117
+ switch (format ) {
118
+ /* Define new formats here */
119
+ ABS_FMT (UVC_FRAME_FORMAT_ANY , 2 ,
120
+ {UVC_FRAME_FORMAT_UNCOMPRESSED , UVC_FRAME_FORMAT_COMPRESSED })
121
+
122
+ ABS_FMT (UVC_FRAME_FORMAT_UNCOMPRESSED , 8 , {
123
+ UVC_FRAME_FORMAT_YUYV , UVC_FRAME_FORMAT_UYVY , UVC_FRAME_FORMAT_GRAY8 ,
124
+ UVC_FRAME_FORMAT_GRAY16 , UVC_FRAME_FORMAT_NV12 , UVC_FRAME_FORMAT_P010 ,
125
+ UVC_FRAME_FORMAT_BGR , UVC_FRAME_FORMAT_RGB
126
+ })
127
+ FMT (UVC_FRAME_FORMAT_YUYV ,
128
+ {'Y' , 'U' , 'Y' , '2' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
129
+ FMT (UVC_FRAME_FORMAT_UYVY ,
130
+ {'U' , 'Y' , 'V' , 'Y' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
131
+ FMT (UVC_FRAME_FORMAT_GRAY8 ,
132
+ {'Y' , '8' , '0' , '0' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
133
+ FMT (UVC_FRAME_FORMAT_GRAY16 ,
134
+ {'Y' , '1' , '6' , ' ' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
135
+ FMT (UVC_FRAME_FORMAT_NV12 ,
136
+ {'N' , 'V' , '1' , '2' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
137
+ FMT (UVC_FRAME_FORMAT_P010 ,
138
+ {'P' , '0' , '1' , '0' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
139
+ FMT (UVC_FRAME_FORMAT_BGR ,
140
+ {0x7d , 0xeb , 0x36 , 0xe4 , 0x4f , 0x52 , 0xce , 0x11 , 0x9f , 0x53 , 0x00 , 0x20 , 0xaf , 0x0b , 0xa7 , 0x70 })
141
+ FMT (UVC_FRAME_FORMAT_RGB ,
142
+ {0x7e , 0xeb , 0x36 , 0xe4 , 0x4f , 0x52 , 0xce , 0x11 , 0x9f , 0x53 , 0x00 , 0x20 , 0xaf , 0x0b , 0xa7 , 0x70 })
143
+ FMT (UVC_FRAME_FORMAT_BY8 ,
144
+ {'B' , 'Y' , '8' , ' ' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
145
+ FMT (UVC_FRAME_FORMAT_BA81 ,
146
+ {'B' , 'A' , '8' , '1' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
147
+ FMT (UVC_FRAME_FORMAT_SGRBG8 ,
148
+ {'G' , 'R' , 'B' , 'G' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
149
+ FMT (UVC_FRAME_FORMAT_SGBRG8 ,
150
+ {'G' , 'B' , 'R' , 'G' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
151
+ FMT (UVC_FRAME_FORMAT_SRGGB8 ,
152
+ {'R' , 'G' , 'G' , 'B' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
153
+ FMT (UVC_FRAME_FORMAT_SBGGR8 ,
154
+ {'B' , 'G' , 'G' , 'R' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
155
+ ABS_FMT (UVC_FRAME_FORMAT_COMPRESSED , 2 ,
156
+ {UVC_FRAME_FORMAT_MJPEG , UVC_FRAME_FORMAT_H264 })
157
+ FMT (UVC_FRAME_FORMAT_MJPEG ,
158
+ {'M' , 'J' , 'P' , 'G' })
159
+ FMT (UVC_FRAME_FORMAT_H264 ,
160
+ {'H' , '2' , '6' , '4' , 0x00 , 0x00 , 0x10 , 0x00 , 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 })
161
+
162
+ default :
163
+ return NULL ;
164
+ }
165
+
166
+ #undef ABS_FMT
167
+ #undef FMT
168
+ }
169
+
170
+ static enum uvc_frame_format uvc_frame_format_for_guid (const uint8_t guid [16 ])
171
+ {
172
+ struct format_table_entry * format ;
173
+ enum uvc_frame_format fmt ;
174
+
175
+ for (fmt = 0 ; fmt < UVC_FRAME_FORMAT_COUNT ; ++ fmt ) {
176
+ format = _get_format_entry (fmt );
177
+ if (!format || format -> abstract_fmt ) {
178
+ continue ;
179
+ }
180
+ if (!memcmp (format -> guid , guid , 16 )) {
181
+ return format -> format ;
182
+ }
183
+ }
184
+
185
+ return UVC_FRAME_FORMAT_UNKNOWN ;
186
+ }
187
+
188
+ void parse_vs_format_mjpeg_desc (const uint8_t * buff , uint8_t * format_idx , uint8_t * frame_num , enum uvc_frame_format * fmt )
95
189
{
96
190
if (buff == NULL ) {
97
191
return ;
98
192
}
99
- const vs_format_desc_t * desc = (const vs_format_desc_t * ) buff ;
193
+ const vs_format_mjpeg_desc_t * desc = (const vs_format_mjpeg_desc_t * ) buff ;
100
194
#ifdef CONFIG_UVC_PRINT_DESC
101
195
printf ("\t*** VS Format MJPEG Descriptor ***\n" );
102
196
#ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
@@ -123,14 +217,17 @@ void parse_vs_format_mjpeg_desc(const uint8_t *buff, uint8_t *format_idx, uint8_
123
217
if (frame_num ) {
124
218
* frame_num = desc -> bNumFrameDescriptors ;
125
219
}
220
+ if (fmt ) {
221
+ * fmt = UVC_FRAME_FORMAT_MJPEG ;
222
+ }
126
223
}
127
224
128
- void parse_vs_frame_mjpeg_desc (const uint8_t * buff , uint8_t * frame_idx , uint16_t * width , uint16_t * heigh , uint8_t * interval_type , const uint32_t * * pp_interval , uint32_t * dflt_interval )
225
+ void parse_vs_frame_mjpeg_desc (const uint8_t * buff , uint8_t * frame_idx , uint16_t * width , uint16_t * height , uint8_t * interval_type , const uint32_t * * pp_interval , uint32_t * dflt_interval )
129
226
{
130
227
if (buff == NULL ) {
131
228
return ;
132
229
}
133
- const vs_frame_desc_t * desc = (const vs_frame_desc_t * ) buff ;
230
+ const vs_frame_mjpeg_desc_t * desc = (const vs_frame_mjpeg_desc_t * ) buff ;
134
231
#ifdef CONFIG_UVC_PRINT_DESC
135
232
printf ("\t*** VS MJPEG Frame Descriptor ***\n" );
136
233
#ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
@@ -160,6 +257,104 @@ void parse_vs_frame_mjpeg_desc(const uint8_t *buff, uint8_t *frame_idx, uint16_t
160
257
} else {
161
258
// Discrete Frame Intervals
162
259
size_t num_of_intervals = (desc -> bLength - 26 ) / 4 ;
260
+ assert (num_of_intervals == desc -> bFrameIntervalType ); // num_of_intervals should same as bFrameIntervalType
261
+ uint32_t * interval = (uint32_t * )& desc -> dwFrameInterval ;
262
+ for (int i = 0 ; i < num_of_intervals ; ++ i ) {
263
+ printf ("\tFrameInterval[%d] %" PRIu32 "\n" , i , interval [i ]);
264
+ }
265
+ }
266
+ #endif
267
+ if (width ) {
268
+ * width = desc -> wWidth ;
269
+ }
270
+ if (height ) {
271
+ * height = desc -> wHeigh ;
272
+ }
273
+ if (frame_idx ) {
274
+ * frame_idx = desc -> bFrameIndex ;
275
+ }
276
+ if (interval_type ) {
277
+ * interval_type = desc -> bFrameIntervalType ;
278
+ }
279
+ if (pp_interval ) {
280
+ * pp_interval = & (desc -> dwFrameInterval );
281
+ }
282
+ if (dflt_interval ) {
283
+ * dflt_interval = desc -> dwDefaultFrameInterval ;
284
+ }
285
+ }
286
+
287
+ void parse_vs_format_frame_based_desc (const uint8_t * buff , uint8_t * format_idx , uint8_t * frame_num , enum uvc_frame_format * fmt )
288
+ {
289
+ if (buff == NULL ) {
290
+ return ;
291
+ }
292
+ const vs_format_frame_based_desc_t * desc = (const vs_format_frame_based_desc_t * ) buff ;
293
+ #ifdef CONFIG_UVC_PRINT_DESC
294
+ printf ("\t*** VS Format Frame-Based Descriptor ***\n" );
295
+ #ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
296
+ printf ("\tbLength 0x%x\n" , desc -> bLength );
297
+ printf ("\tbDescriptorType 0x%x\n" , desc -> bDescriptorType );
298
+ printf ("\tbDescriptorSubType 0x%x\n" , desc -> bDescriptorSubType );
299
+ #endif
300
+ printf ("\tbFormatIndex 0x%x\n" , desc -> bFormatIndex );
301
+ printf ("\tbNumFrameDescriptors %u\n" , desc -> bNumFrameDescriptors );
302
+ printf ("\tguidFormat %.*s\n" , 16 , desc -> guidFormat );
303
+ printf ("\tbDefaultFrameIndex %u\n" , desc -> bDefaultFrameIndex );
304
+ #ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
305
+ printf ("\tbAspectRatioX %u\n" , desc -> bAspectRatioX );
306
+ printf ("\tbAspectRatioY %u\n" , desc -> bAspectRatioY );
307
+ printf ("\tbmInterlaceFlags 0x%x\n" , desc -> bmInterlaceFlags );
308
+ printf ("\tbCopyProtect %u\n" , desc -> bCopyProtect );
309
+ #endif
310
+ #endif
311
+ if (format_idx ) {
312
+ * format_idx = desc -> bFormatIndex ;
313
+ }
314
+ if (frame_num ) {
315
+ * frame_num = desc -> bNumFrameDescriptors ;
316
+ }
317
+ if (fmt ) {
318
+ * fmt = uvc_frame_format_for_guid (desc -> guidFormat );
319
+ }
320
+ }
321
+
322
+ void parse_vs_frame_frame_based_desc (const uint8_t * buff , uint8_t * frame_idx , uint16_t * width , uint16_t * height , uint8_t * interval_type , const uint32_t * * pp_interval , uint32_t * dflt_interval )
323
+ {
324
+ if (buff == NULL ) {
325
+ return ;
326
+ }
327
+ const vs_frame_frame_based_desc_t * desc = (const vs_frame_frame_based_desc_t * ) buff ;
328
+ #ifdef CONFIG_UVC_PRINT_DESC
329
+ printf ("\t*** VS Frame-Based Frame Descriptor ***\n" );
330
+ #ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
331
+ printf ("\tbLength 0x%x\n" , desc -> bLength );
332
+ printf ("\tbDescriptorType 0x%x\n" , desc -> bDescriptorType );
333
+ printf ("\tbDescriptorSubType 0x%x\n" , desc -> bDescriptorSubType );
334
+ #endif
335
+ printf ("\tbFrameIndex 0x%x\n" , desc -> bFrameIndex );
336
+ #ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
337
+ printf ("\tbmCapabilities 0x%x\n" , desc -> bmCapabilities );
338
+ #endif
339
+ printf ("\twWidth %u\n" , desc -> wWidth );
340
+ printf ("\twHeigh %u\n" , desc -> wHeigh );
341
+ #ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
342
+ printf ("\tdwMinBitRate %" PRIu32 "\n" , desc -> dwMinBitRate );
343
+ printf ("\tdwMaxBitRate %" PRIu32 "\n" , desc -> dwMaxBitRate );
344
+ printf ("\tdwDefaultFrameInterval %" PRIu32 "\n" , desc -> dwDefaultFrameInterval );
345
+ printf ("\tbFrameIntervalType %u\n" , desc -> bFrameIntervalType );
346
+ printf ("\tdwBytesPerLine %" PRIu32 "\n" , desc -> dwBytesPerLine );
347
+ #endif
348
+
349
+ if (desc -> bFrameIntervalType == 0 ) {
350
+ // Continuous Frame Intervals
351
+ printf ("\tdwMinFrameInterval %" PRIu32 "\n" , desc -> dwMinFrameInterval );
352
+ printf ("\tdwMaxFrameInterval %" PRIu32 "\n" , desc -> dwMaxFrameInterval );
353
+ printf ("\tdwFrameIntervalStep %" PRIu32 "\n" , desc -> dwFrameIntervalStep );
354
+ } else {
355
+ // Discrete Frame Intervals
356
+ size_t num_of_intervals = (desc -> bLength - 26 ) / 4 ;
357
+ assert (num_of_intervals == desc -> bFrameIntervalType ); // num_of_intervals should same as bFrameIntervalType
163
358
uint32_t * interval = (uint32_t * )& desc -> dwFrameInterval ;
164
359
for (int i = 0 ; i < num_of_intervals ; ++ i ) {
165
360
printf ("\tFrameInterval[%d] %" PRIu32 "\n" , i , interval [i ]);
@@ -169,8 +364,8 @@ void parse_vs_frame_mjpeg_desc(const uint8_t *buff, uint8_t *frame_idx, uint16_t
169
364
if (width ) {
170
365
* width = desc -> wWidth ;
171
366
}
172
- if (heigh ) {
173
- * heigh = desc -> wHeigh ;
367
+ if (height ) {
368
+ * height = desc -> wHeigh ;
174
369
}
175
370
if (frame_idx ) {
176
371
* frame_idx = desc -> bFrameIndex ;
@@ -260,8 +455,8 @@ void print_intf_desc(const uint8_t *buff)
260
455
printf ("\tbAlternateSetting %d\n" , intf_desc -> bAlternateSetting );
261
456
printf ("\tbNumEndpoints %d\n" , intf_desc -> bNumEndpoints );
262
457
printf ("\tbInterfaceClass 0x%x (%s)\n" , intf_desc -> bInterfaceClass ,
263
- intf_desc -> bInterfaceClass == USB_CLASS_VIDEO ? "Video" :
264
- (intf_desc -> bInterfaceClass == USB_CLASS_AUDIO ? "Audio" : "Unknown" ));
458
+ intf_desc -> bInterfaceClass == USB_CLASS_VIDEO ? "Video" :
459
+ (intf_desc -> bInterfaceClass == USB_CLASS_AUDIO ? "Audio" : "Unknown" ));
265
460
printf ("\tbInterfaceSubClass 0x%x\n" , intf_desc -> bInterfaceSubClass );
266
461
#ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
267
462
printf ("\tbInterfaceProtocol 0x%x\n" , intf_desc -> bInterfaceProtocol );
@@ -429,7 +624,7 @@ void parse_ac_feature_desc(const uint8_t *buff, uint8_t *source_idx, uint8_t *fe
429
624
printf ("\tbUnitID %d\n" , desc -> bUnitID );
430
625
printf ("\tbSourceID %d\n" , desc -> bSourceID );
431
626
printf ("\tbControlSize %d\n" , desc -> bControlSize );
432
- for (size_t i = 0 ; i < (desc -> bLength - 7 )/ desc -> bControlSize ; i += desc -> bControlSize ) {
627
+ for (size_t i = 0 ; i < (desc -> bLength - 7 ) / desc -> bControlSize ; i += desc -> bControlSize ) {
433
628
printf ("\tbmaControls[ch%d] 0x%x\n" , i , desc -> bmaControls [i ]);
434
629
}
435
630
#ifdef CONFIG_UVC_PRINT_DESC_VERBOSE
@@ -443,7 +638,7 @@ void parse_ac_feature_desc(const uint8_t *buff, uint8_t *source_idx, uint8_t *fe
443
638
* source_idx = desc -> bSourceID ;
444
639
}
445
640
uint8_t ch_num = 0 ;
446
- for (size_t i = 0 ; i < (desc -> bLength - 7 )/ desc -> bControlSize ; i += desc -> bControlSize ) {
641
+ for (size_t i = 0 ; i < (desc -> bLength - 7 ) / desc -> bControlSize ; i += desc -> bControlSize ) {
447
642
if ((desc -> bmaControls [i ] & AUDIO_FEATURE_CONTROL_VOLUME ) && volume_ch ) {
448
643
* volume_ch = * volume_ch | (1 << ch_num );
449
644
}
0 commit comments