2 * Copyright 2016, Adrien Destugues, pulkomandy@pulkomandy.tk
3 * Distributed under terms of the MIT license.
8 #include <usb/USB_video.h>
14 DumpVideoCSInterfaceDescriptorHeader(
15 const usb_videocontrol_header_descriptor
* descriptor
)
17 printf(" Type .............. 0x%02x\n",
18 descriptor
->descriptor_type
);
19 printf(" Subtype ........... 0x%02x (Header)\n",
20 descriptor
->descriptor_subtype
);
21 printf(" UVC Release ....... %d.%d\n",
22 descriptor
->bcd_release_no
>> 8, descriptor
->bcd_release_no
& 0xFF);
23 printf(" Total Length ...... %u\n",
24 descriptor
->total_length
);
25 printf(" Clock Frequency ... %" B_PRIu32
"\n",
26 descriptor
->clock_frequency
);
27 printf(" Interfaces ........ ");
29 for (uint8 i
= 0; i
< descriptor
->in_collection
; i
++)
30 printf("%u, ", descriptor
->interface_numbers
[i
]);
36 TerminalTypeName(uint16 terminalType
)
38 switch (terminalType
) {
39 case USB_VIDEO_VENDOR_USB_IO
:
40 return "Vendor specific";
41 case USB_VIDEO_STREAMING_USB_IO
:
44 case USB_VIDEO_VENDOR_IN
:
45 return "Vendor specific input";
46 case USB_VIDEO_CAMERA_IN
:
48 case USB_VIDEO_MEDIA_TRANSPORT_IN
:
49 return "Media transport input";
51 case USB_VIDEO_VENDOR_OUT
:
52 return "Vendor specific output";
53 case USB_VIDEO_DISPLAY_OUT
:
55 case USB_VIDEO_MEDIA_TRANSPORT_OUT
:
56 return "Media transport output";
58 case USB_VIDEO_VENDOR_EXT
:
59 return "Vendor specific format";
60 case USB_VIDEO_COMPOSITE_EXT
:
62 case USB_VIDEO_SVIDEO_EXT
:
64 case USB_VIDEO_COMPONENT_EXT
:
74 DumpVideoCSInterfaceDescriptorOutputTerminal(
75 const usb_video_output_terminal_descriptor
* descriptor
)
77 printf(" Type .............. 0x%02x\n",
78 descriptor
->descriptor_type
);
79 printf(" Subtype ........... 0x%02x (Output Terminal)\n",
80 descriptor
->descriptor_subtype
);
81 printf(" Terminal ID ....... %u\n",
82 descriptor
->terminal_id
);
83 printf(" Terminal Type ..... 0x%04x (%s)\n",
84 descriptor
->terminal_type
,
85 TerminalTypeName(descriptor
->terminal_type
));
86 printf(" Associated Terminal %u\n",
87 descriptor
->assoc_terminal
);
88 printf(" Source ID ......... %u\n",
89 descriptor
->source_id
);
90 printf(" Terminal .......... %u\n",
91 descriptor
->terminal
);
96 DumpVideoCSInterfaceDescriptorInputTerminal(
97 const usb_video_input_terminal_descriptor
* descriptor
)
99 printf(" Type .............. 0x%02x\n",
100 descriptor
->descriptor_type
);
101 printf(" Subtype ........... 0x%02x (Input Terminal)\n",
102 descriptor
->descriptor_subtype
);
103 printf(" Terminal ID ....... %u\n",
104 descriptor
->terminal_id
);
105 printf(" Terminal Type ..... 0x%04x (%s)\n",
106 descriptor
->terminal_type
,
107 TerminalTypeName(descriptor
->terminal_type
));
108 printf(" Terminal .......... %u\n",
109 descriptor
->terminal
);
111 if (descriptor
->terminal_type
== USB_VIDEO_CAMERA_IN
)
113 printf(" Min. Focal length . %u\n",
114 descriptor
->camera
.focal_length_min
);
115 printf(" Max. Focal length . %u\n",
116 descriptor
->camera
.focal_length_min
);
117 printf(" Focal length ...... %u\n",
118 descriptor
->camera
.focal_length
);
119 printf(" Controls .......... %02x%02x%02x\n",
120 descriptor
->camera
.controls
[0],
121 descriptor
->camera
.controls
[1],
122 descriptor
->camera
.controls
[2]);
128 ProcessingControlString(int index
)
133 return "Brightness, ";
139 return "Saturation, ";
141 return "Sharpness, ";
145 return "White balance temp., ";
147 return "White balance component, ";
149 return "Backlight compensation, ";
153 return "Power line frequency, ";
155 return "Automatic hue, ";
157 return "Automatic white balance temp., ";
159 return "Automatic white balance component, ";
161 return "Digital multiplier, ";
163 return "Digital multiplier limit, ";
165 return "Analog video standard, ";
167 return "Analog video lock status, ";
169 return "Automatic contrast, ";
177 DumpVideoCSInterfaceDescriptorProcessingUnit(
178 const usb_video_processing_unit_descriptor
* descriptor
)
180 printf(" Type .............. 0x%02x\n",
181 descriptor
->descriptor_type
);
182 printf(" Subtype ........... 0x%02x (Processing unit)\n",
183 descriptor
->descriptor_subtype
);
184 printf(" Unit ID ........... %u\n",
185 descriptor
->unit_id
);
186 printf(" Source ID ......... %u\n",
187 descriptor
->source_id
);
188 printf(" Max Multiplier .... %f\n",
189 descriptor
->max_multiplier
/ 100.f
);
190 printf(" Controls .......... ");
191 uint32_t controls
= (descriptor
->controls
[0] << 16)
192 | (descriptor
->controls
[1] << 8)
193 | descriptor
->controls
[2];
194 for (int i
= 0; i
< 19; i
++)
196 if (controls
& (1 << (23 - i
))) {
197 printf(ProcessingControlString(i
));
201 printf(" Processing ........ %u\n",
202 descriptor
->processing
);
203 printf(" Video Standards ... 0x%02x\n",
204 descriptor
->video_standards
);
209 DumpVideoCSInterfaceDescriptorExtensionUnit(
210 const usb_generic_descriptor
* descriptor
)
214 printf(" Type .............. 0x%02x\n",
215 descriptor
->descriptor_type
);
216 printf(" Subtype ........... 0x%02x (Extension unit)\n",
217 (uint8
)descriptor
->data
[i
++]);
218 printf(" Unit ID ........... %u\n",
219 (uint8
)descriptor
->data
[i
++]);
221 printf(" GUID .............. ");
222 for (i
= 2; i
< 16 + 2; i
++)
223 printf("%02x ", descriptor
->data
[i
]);
226 printf(" Control count ..... %u\n",
227 (uint8
)descriptor
->data
[i
++]);
229 printf(" Input pins ........ ");
230 i
= 20; // Skip the input pin count
231 for (; i
- 20 < descriptor
->data
[19]; i
++)
232 printf("%u, ", descriptor
->data
[i
]);
235 printf(" Controls .......... ");
236 uint8_t end
= descriptor
->data
[i
++];
238 for (; i
- start
< end
; i
++)
239 printf("%02x", (uint8
)descriptor
->data
[i
]);
242 printf(" Extension ......... %u\n",
243 (uint8
)descriptor
->data
[i
++]);
248 DumpVideoControlCSInterfaceDescriptor(const usb_generic_descriptor
* descriptor
)
250 uint8 descriptorSubtype
= descriptor
->data
[0];
251 switch (descriptorSubtype
) {
252 case USB_VIDEO_VC_HEADER
:
253 DumpVideoCSInterfaceDescriptorHeader(
254 (usb_videocontrol_header_descriptor
*)descriptor
);
256 case USB_VIDEO_VC_INPUT_TERMINAL
:
257 DumpVideoCSInterfaceDescriptorInputTerminal(
258 (usb_video_input_terminal_descriptor
*)descriptor
);
260 case USB_VIDEO_VC_OUTPUT_TERMINAL
:
261 DumpVideoCSInterfaceDescriptorOutputTerminal(
262 (usb_video_output_terminal_descriptor
*)descriptor
);
264 case USB_VIDEO_VC_PROCESSING_UNIT
:
265 DumpVideoCSInterfaceDescriptorProcessingUnit(
266 (usb_video_processing_unit_descriptor
*)descriptor
);
268 case USB_VIDEO_VC_EXTENSION_UNIT
:
269 DumpVideoCSInterfaceDescriptorExtensionUnit(descriptor
);
272 DumpDescriptorData(descriptor
);
278 DumpVideoControlCSInterruptEndpointDescriptor(const usb_generic_descriptor
* descriptor
)
280 printf(" Type .............. 0x%02x (Endpoint)\n",
281 descriptor
->descriptor_type
);
282 printf(" Subtype ........... 0x%02x (Interrupt)\n",
283 (uint8
)descriptor
->data
[0]);
284 printf(" Max Transfer Size . %u\n",
285 (uint16
)((descriptor
->data
[1] << 8) | descriptor
->data
[2]));
290 DumpVideoControlCSEndpointDescriptor(const usb_generic_descriptor
* descriptor
)
292 uint8 descriptorSubtype
= descriptor
->data
[0];
293 switch (descriptorSubtype
) {
294 case EP_SUBTYPE_INTERRUPT
:
295 DumpVideoControlCSInterruptEndpointDescriptor(descriptor
);
298 DumpDescriptorData(descriptor
);
304 DumpVideoStreamInputHeaderDescriptor(const usb_generic_descriptor
* descriptor
)
306 printf(" Type .............. 0x%02x (VideoStream Interface)\n",
307 descriptor
->descriptor_type
);
308 printf(" Subtype ........... 0x%02x (Input header)\n",
309 (uint8
)descriptor
->data
[0]);
310 printf(" Format count ...... %u\n",
311 (uint8
)descriptor
->data
[1]);
312 printf(" Total length ...... %u\n",
313 (uint16
)((descriptor
->data
[2] << 8) | descriptor
->data
[3]));
314 printf(" Endpoint .......... 0x%02x\n",
315 (uint8
)descriptor
->data
[4]);
316 printf(" Info .............. 0x%02x\n",
317 (uint8
)descriptor
->data
[5]);
318 printf(" Terminal Link ..... 0x%02x\n",
319 (uint8
)descriptor
->data
[6]);
320 printf(" Still capture ..... 0x%02x\n",
321 (uint8
)descriptor
->data
[7]);
322 printf(" Trigger support ... %u\n",
323 (uint8
)descriptor
->data
[8]);
324 printf(" Trigger usage ..... %u\n",
325 (uint8
)descriptor
->data
[9]);
327 uint8 nformat
= descriptor
->data
[1];
328 uint8 formatsize
= descriptor
->data
[10];
331 for (i
= 0; i
< nformat
; i
++)
333 printf(" Format %2d ......... 0x", i
);
334 for (j
= 0; j
< formatsize
; j
++)
335 printf("%02x", (uint8
)descriptor
->data
[11 + i
* formatsize
+ j
]);
342 DumpVideoStillImageDescriptor(const usb_generic_descriptor
* descriptor
)
344 printf(" Type .............. 0x%02x (VideoStream Interface)\n",
345 descriptor
->descriptor_type
);
346 printf(" Subtype ........... 0x%02x (Still Image)\n",
347 (uint8
)descriptor
->data
[0]);
348 printf(" Endpoint .......... %u\n",
349 (uint8
)descriptor
->data
[1]);
351 uint8 npatterns
= descriptor
->data
[2];
353 printf(" Resolutions ....... ");
354 for (i
= 0; i
< npatterns
; i
++)
356 // FIXME these are reverse-endian compared to everything else.
357 // Is my webcam wrong, or is it some quirk in the spec?
359 (uint16
)((descriptor
->data
[i
* 4 + 4] << 8) | (descriptor
->data
[i
* 4 + 3])),
360 (uint16
)((descriptor
->data
[i
* 4 + 6] << 8) | (descriptor
->data
[i
* 4 + 5])));
366 npatterns
= descriptor
->data
[i
];
367 while (npatterns
> 0)
369 printf(" Compression ....... %u\n",
370 (uint8
)descriptor
->data
[i
]);
377 VSInterfaceString(int subtype
)
380 case USB_VIDEO_VS_UNDEFINED
:
382 case USB_VIDEO_VS_INPUT_HEADER
:
383 return "Input header";
384 case USB_VIDEO_VS_OUTPUT_HEADER
:
385 return "Output header";
386 case USB_VIDEO_VS_STILL_IMAGE_FRAME
:
387 return "Still image";
388 case USB_VIDEO_VS_FORMAT_UNCOMPRESSED
:
389 return "Uncompressed format";
390 case USB_VIDEO_VS_FRAME_UNCOMPRESSED
:
391 return "Uncompressed frame";
392 case USB_VIDEO_VS_FORMAT_MJPEG
:
393 return "MJPEG format";
394 case USB_VIDEO_VS_FRAME_MJPEG
:
395 return "MJPEG frame";
396 case USB_VIDEO_VS_FORMAT_MPEG2TS
:
397 return "MPEG2TS format";
398 case USB_VIDEO_VS_FORMAT_DV
:
400 case USB_VIDEO_VS_COLORFORMAT
:
401 return "Color format";
402 case USB_VIDEO_VS_FORMAT_FRAME_BASED
:
403 return "Frame based format";
404 case USB_VIDEO_VS_FRAME_FRAME_BASED
:
405 return "Frame based frame";
406 case USB_VIDEO_VS_FORMAT_STREAM_BASED
:
407 return "Stream based format";
408 case USB_VIDEO_VS_FORMAT_H264
:
409 return "H264 format";
410 case USB_VIDEO_VS_FRAME_H264
:
412 case USB_VIDEO_VS_FORMAT_H264_SIMULCAST
:
413 return "H264 simulcast";
414 case USB_VIDEO_VS_FORMAT_VP8
:
416 case USB_VIDEO_VS_FRAME_VP8
:
418 case USB_VIDEO_VS_FORMAT_VP8_SIMULCAST
:
419 return "VP8 simulcast";
427 DumpVideoFormatDescriptor(const usb_generic_descriptor
* descriptor
)
429 printf(" Type .............. 0x%02x (VideoStream Interface)\n",
430 descriptor
->descriptor_type
);
431 printf(" Subtype ........... 0x%02x (%s)\n",
432 (uint8
)descriptor
->data
[0], VSInterfaceString(descriptor
->data
[0]));
433 printf(" Index ............. 0x%02x\n",
434 (uint8
)descriptor
->data
[1]);
435 printf(" Frame number ...... 0x%02x\n",
436 (uint8
)descriptor
->data
[2]);
438 printf(" GUID .............. ");
439 for (uint8 i
= 3; i
< 16 + 3; i
++)
440 printf("%02x ", descriptor
->data
[i
]);
443 printf(" Bits per pixel .... %u\n",
444 (uint8
)descriptor
->data
[19]);
445 printf(" Default frame idx . 0x%02x\n",
446 (uint8
)descriptor
->data
[20]);
447 printf(" Aspect ratio ...... %u:%u\n",
448 (uint8
)descriptor
->data
[21], (uint8
)descriptor
->data
[22]);
449 printf(" Interlace flags ... 0x%02x\n",
450 (uint8
)descriptor
->data
[23]);
451 printf(" Copy protect ...... %u\n",
452 (uint8
)descriptor
->data
[24]);
457 DumpVideoFrameDescriptor(const usb_video_frame_descriptor
* descriptor
)
459 printf(" Type .............. 0x%02x (VideoStream Interface)\n",
460 descriptor
->descriptor_type
);
461 printf(" Subtype ........... 0x%02x (%s)\n",
462 descriptor
->descriptor_subtype
,
463 VSInterfaceString(descriptor
->descriptor_subtype
));
464 printf(" Index ............. 0x%02x\n",
465 descriptor
->frame_index
);
466 printf(" Capabilities ...... 0x%02x\n",
467 descriptor
->capabilities
);
468 printf(" Resolution ........ %u x %u\n",
469 descriptor
->width
, descriptor
->height
);
470 printf(" Bit rates ......... %" B_PRIu32
" - %" B_PRIu32
"\n",
471 descriptor
->min_bit_rate
, descriptor
->max_bit_rate
);
472 printf(" Frame buffer size . %" B_PRIu32
"\n",
473 descriptor
->max_video_frame_buffer_size
);
474 printf(" Frame interval .... %.4fms\n",
475 descriptor
->default_frame_interval
/ 10000.f
);
476 for (uint8 i
= 0; i
< descriptor
->frame_interval_type
; i
++)
478 printf(" Frame interval %2d . %.4fms\n",
479 i
, descriptor
->discrete_frame_intervals
[i
] / 10000.f
);
481 // TODO if frame__interval_type is 0, dump continuous frame intervals
486 DumpVideoStreamCSInterfaceDescriptor(const usb_generic_descriptor
* descriptor
)
488 uint8 subtype
= descriptor
->data
[0];
490 case USB_VIDEO_VS_INPUT_HEADER
:
491 DumpVideoStreamInputHeaderDescriptor(descriptor
);
493 case USB_VIDEO_VS_STILL_IMAGE_FRAME
:
494 DumpVideoStillImageDescriptor(descriptor
);
496 case USB_VIDEO_VS_FORMAT_UNCOMPRESSED
:
497 case USB_VIDEO_VS_FORMAT_MJPEG
:
498 DumpVideoFormatDescriptor(descriptor
);
500 case USB_VIDEO_VS_FRAME_UNCOMPRESSED
:
501 case USB_VIDEO_VS_FRAME_MJPEG
:
502 DumpVideoFrameDescriptor((usb_video_frame_descriptor
*)descriptor
);
505 DumpDescriptorData(descriptor
);
513 DumpVideoDescriptor(const usb_generic_descriptor
* descriptor
, int subclass
)
516 case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS
:
517 switch (descriptor
->descriptor_type
) {
518 case USB_VIDEO_CS_INTERFACE
:
519 DumpVideoControlCSInterfaceDescriptor(descriptor
);
521 case USB_VIDEO_CS_ENDPOINT
:
522 DumpVideoControlCSEndpointDescriptor(descriptor
);
525 DumpDescriptorData(descriptor
);
529 case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS
:
530 switch (descriptor
->descriptor_type
) {
531 case USB_VIDEO_CS_INTERFACE
:
532 DumpVideoStreamCSInterfaceDescriptor(descriptor
);
535 DumpDescriptorData(descriptor
);
539 case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS
:
540 switch (descriptor
->descriptor_type
) {
541 case USB_VIDEO_CS_INTERFACE
:
543 DumpDescriptorData(descriptor
);
546 DumpDescriptorData(descriptor
);
551 DumpDescriptorData(descriptor
);