listusb: parse UVC devices
- Various cleanups to the USB-audio side, which is similar - Add in the UVC (USB Video) specific info with parsing of some of the descriptors (most of the "control" part).
This commit is contained in:
parent
56f749a63f
commit
e64640878a
@ -14,18 +14,18 @@ enum {
|
||||
USB_AUDIO_INTERFACE_AUDIO_CLASS = 0x01
|
||||
};
|
||||
|
||||
enum { // Audio Interface Subclasses
|
||||
USB_AUDIO_INTERFACE_UNDEFINED_SUBCLASS = 0x00,
|
||||
enum { // Audio Interface Subclasses
|
||||
USB_AUDIO_INTERFACE_UNDEFINED_SUBCLASS = 0x00,
|
||||
USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS = 0x01,
|
||||
USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS, //
|
||||
USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS //
|
||||
USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS,
|
||||
USB_AUDIO_INTERFACE_MIDISTREAMING_SUBCLASS
|
||||
};
|
||||
|
||||
enum { // Audio Interface Protocol Codes
|
||||
USB_AUDIO_PROTOCOL_UNDEFINED = 0x00
|
||||
USB_AUDIO_PROTOCOL_UNDEFINED = 0x00
|
||||
};
|
||||
|
||||
enum { // Audio Interface Protocol Codes
|
||||
enum { // Audio Interface Class-Specific Descriptor Types
|
||||
USB_AUDIO_CS_UNDEFINED = 0x20,
|
||||
USB_AUDIO_CS_DEVICE = 0x21,
|
||||
USB_AUDIO_CS_CONFIGURATION = 0x22,
|
||||
@ -66,7 +66,7 @@ typedef struct {
|
||||
struct {
|
||||
uint16 total_length;
|
||||
uint8 in_collection;
|
||||
uint8 interface_numbers[1];
|
||||
uint8 interface_numbers[0];
|
||||
} _PACKED r1;
|
||||
|
||||
struct {
|
||||
|
142
headers/os/drivers/usb/USB_video.h
Normal file
142
headers/os/drivers/usb/USB_video.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2016, Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||
* Distributed under terms of the MIT license.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef USB_VIDEO_H
|
||||
#define USB_VIDEO_H
|
||||
|
||||
|
||||
// Based on specification for UVC version 1.5.
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
#define USB_VIDEO_DEVICE_CLASS 0x0E
|
||||
|
||||
enum { // Video Interface Subclasses
|
||||
USB_VIDEO_INTERFACE_UNDEFINED_SUBCLASS = 0x00,
|
||||
USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS = 0x01,
|
||||
USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS,
|
||||
USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS,
|
||||
};
|
||||
|
||||
|
||||
enum { // Video Interface Protocol Codes
|
||||
USB_VIDEO_PROTOCOL_UNDEFINED = 0x00,
|
||||
USB_VIDEO_PROTOCOL_15 = 0x01,
|
||||
};
|
||||
|
||||
|
||||
enum { // Video Interface Class-Specific Descriptor Types
|
||||
USB_VIDEO_CS_UNDEFINED = 0x20,
|
||||
USB_VIDEO_CS_DEVICE = 0x21,
|
||||
USB_VIDEO_CS_CONFIGURATION = 0x22,
|
||||
USB_VIDEO_CS_STRING = 0x23,
|
||||
USB_VIDEO_CS_INTERFACE = 0x24,
|
||||
USB_VIDEO_CS_ENDPOINT = 0x25,
|
||||
};
|
||||
|
||||
|
||||
enum { // Video Class-Specific VideoControl Interface descriptor subtypes
|
||||
USB_VIDEO_VC_DESCRIPTOR_UNDEFINED = 0x00,
|
||||
USB_VIDEO_VC_HEADER = 0x01,
|
||||
USB_VIDEO_VC_INPUT_TERMINAL = 0x02,
|
||||
USB_VIDEO_VC_OUTPUT_TERMINAL = 0x03,
|
||||
USB_VIDEO_VC_SELECTOR_UNIT = 0x04,
|
||||
USB_VIDEO_VC_PROCESSING_UNIT = 0x05,
|
||||
USB_VIDEO_VC_EXTENSION_UNIT = 0x06,
|
||||
USB_VIDEO_VC_ENCODING_UNIT = 0x07,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
// USB Terminal Types
|
||||
USB_VIDEO_VENDOR_USB_IO = 0x100,
|
||||
USB_VIDEO_STREAMING_USB_IO = 0x101,
|
||||
// Input terminal types
|
||||
USB_VIDEO_VENDOR_IN = 0x200,
|
||||
USB_VIDEO_CAMERA_IN = 0x201,
|
||||
USB_VIDEO_MEDIA_TRANSPORT_IN = 0x202,
|
||||
// Output terminal types
|
||||
USB_VIDEO_VENDOR_OUT = 0x300,
|
||||
USB_VIDEO_DISPLAY_OUT = 0x301,
|
||||
USB_VIDEO_MEDIA_TRANSPORT_OUT = 0x302,
|
||||
// External terminal types
|
||||
USB_VIDEO_VENDOR_EXT = 0x400,
|
||||
USB_VIDEO_COMPOSITE_EXT = 0x401,
|
||||
USB_VIDEO_SVIDEO_EXT = 0x402,
|
||||
USB_VIDEO_COMPONENT_EXT = 0x403,
|
||||
};
|
||||
|
||||
|
||||
// Class Specific Video Control Interface Header
|
||||
// 1.5: Table 3-3 p.48
|
||||
typedef struct {
|
||||
uint8 length;
|
||||
uint8 descriptor_type; // USB_AUDIO_CS_INTERFACE
|
||||
uint8 descriptor_subtype; // USB_AUDIO_AC_HEADER
|
||||
uint16 bcd_release_no;
|
||||
uint16 total_length;
|
||||
uint32 clock_frequency;
|
||||
uint8 in_collection;
|
||||
uint8 interface_numbers[0];
|
||||
} _PACKED usb_videocontrol_header_descriptor;
|
||||
|
||||
|
||||
// Input Terminal Descriptor
|
||||
// 1.5: Table 3-4, page 50
|
||||
typedef struct {
|
||||
uint8 length;
|
||||
uint8 descriptor_type; // USB_VIDEO_CS_INTERFACE
|
||||
uint8 descriptor_subtype; // USB_VIDEO_VC_INPUT_TERMINAL
|
||||
uint8 terminal_id;
|
||||
uint16 terminal_type;
|
||||
uint8 assoc_terminal;
|
||||
uint8 terminal;
|
||||
|
||||
union {
|
||||
struct {
|
||||
uint16 focal_length_min;
|
||||
uint16 focal_length_max;
|
||||
uint16 focal_length;
|
||||
uint8 control_size;
|
||||
uint8 controls[3];
|
||||
} _PACKED camera;
|
||||
};
|
||||
} _PACKED usb_video_input_terminal_descriptor;
|
||||
|
||||
|
||||
// Output terminal descriptor
|
||||
// 1.5: Table 3-5, page 51
|
||||
typedef struct {
|
||||
uint8 length;
|
||||
uint8 descriptor_type; // USB_VIDEO_CS_INTERFACE
|
||||
uint8 descriptor_subtype; // USB_VIDEO_VC_OUTPUT_TERMINAL
|
||||
uint8 terminal_id;
|
||||
uint16 terminal_type;
|
||||
uint8 assoc_terminal;
|
||||
uint8 source_id;
|
||||
uint8 terminal;
|
||||
} _PACKED usb_video_output_terminal_descriptor;
|
||||
|
||||
|
||||
// Processing unit descriptor
|
||||
// 1.5: Table 3-8, page 54
|
||||
typedef struct {
|
||||
uint8 length;
|
||||
uint8 descriptor_type;
|
||||
uint8 descriptor_subtype;
|
||||
uint8 unit_id;
|
||||
uint8 source_id;
|
||||
uint16 max_multiplier;
|
||||
uint8 control_size;
|
||||
uint8 controls[3];
|
||||
uint8 processing;
|
||||
uint8 video_standards;
|
||||
} _PACKED usb_video_processing_unit_descriptor;
|
||||
|
||||
|
||||
#endif /* !USB_VIDEO_H */
|
@ -6,6 +6,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel bus_managers usb ] ;
|
||||
BinCommand listusb :
|
||||
listusb.cpp
|
||||
usb_audio.cpp
|
||||
usb_video.cpp
|
||||
: be libdevice.so ;
|
||||
|
||||
# Manually reference generated headers
|
||||
|
@ -10,20 +10,22 @@
|
||||
#include <Entry.h>
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
#include <USBKit.h>
|
||||
#include <stdio.h>
|
||||
#include <usb/USB_audio.h>
|
||||
#include <usb/USB_video.h>
|
||||
|
||||
#include "usbspec_private.h"
|
||||
#include "usb-utils.h"
|
||||
|
||||
#include "listusb.h"
|
||||
|
||||
|
||||
const char*
|
||||
ClassName(int classNumber) {
|
||||
switch (classNumber) {
|
||||
case 0:
|
||||
return "Per-interface classes";
|
||||
case 1:
|
||||
case USB_AUDIO_DEVICE_CLASS:
|
||||
return "Audio";
|
||||
case 2:
|
||||
return "Communication";
|
||||
@ -45,7 +47,7 @@ ClassName(int classNumber) {
|
||||
return "Smart card";
|
||||
case 13:
|
||||
return "Content security";
|
||||
case 14:
|
||||
case USB_VIDEO_DEVICE_CLASS:
|
||||
return "Video";
|
||||
case 15:
|
||||
return "Personal Healthcare";
|
||||
@ -65,7 +67,58 @@ ClassName(int classNumber) {
|
||||
}
|
||||
|
||||
|
||||
void DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass);
|
||||
const char*
|
||||
SubclassName(int classNumber, int subclass)
|
||||
{
|
||||
if (classNumber == 0xEF) {
|
||||
if (subclass == 0x02)
|
||||
return " (Common)";
|
||||
}
|
||||
|
||||
if (classNumber == USB_VIDEO_DEVICE_CLASS) {
|
||||
switch (subclass) {
|
||||
case USB_VIDEO_INTERFACE_UNDEFINED_SUBCLASS:
|
||||
return " (Undefined)";
|
||||
case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS:
|
||||
return " (Control)";
|
||||
case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS:
|
||||
return " (Streaming)";
|
||||
case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS:
|
||||
return " (Collection)";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
ProtocolName(int classNumber, int subclass, int protocol)
|
||||
{
|
||||
switch (classNumber) {
|
||||
case 0x09:
|
||||
if (subclass == 0x00)
|
||||
{
|
||||
switch (protocol) {
|
||||
case 0x00:
|
||||
return " (Full speed)";
|
||||
case 0x01:
|
||||
return " (Hi-speed, single TT)";
|
||||
case 0x02:
|
||||
return " (Hi-speed, multiple TT)";
|
||||
case 0x03:
|
||||
return " (Super speed)";
|
||||
}
|
||||
}
|
||||
case 0xE0:
|
||||
if (subclass == 0x01 && protocol == 0x01)
|
||||
return " (Bluetooth)";
|
||||
case 0xEF:
|
||||
if (subclass == 0x02 && protocol == 0x01)
|
||||
return " (Interface Association)";
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@ -90,6 +143,9 @@ DumpDescriptor(const usb_generic_descriptor* descriptor,
|
||||
case USB_AUDIO_DEVICE_CLASS:
|
||||
DumpAudioDescriptor(descriptor, subclass);
|
||||
break;
|
||||
case USB_VIDEO_DEVICE_CLASS:
|
||||
DumpVideoDescriptor(descriptor, subclass);
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
@ -105,10 +161,12 @@ DumpInterface(const BUSBInterface* interface)
|
||||
|
||||
printf(" Class .............. 0x%02x (%s)\n",
|
||||
interface->Class(), ClassName(interface->Class()));
|
||||
printf(" Subclass ........... 0x%02x\n",
|
||||
interface->Subclass());
|
||||
printf(" Protocol ........... 0x%02x\n",
|
||||
interface->Protocol());
|
||||
printf(" Subclass ........... 0x%02x%s\n",
|
||||
interface->Subclass(),
|
||||
SubclassName(interface->Class(), interface->Subclass()));
|
||||
printf(" Protocol ........... 0x%02x%s\n",
|
||||
interface->Protocol(), ProtocolName(interface->Class(),
|
||||
interface->Subclass(), interface->Protocol()));
|
||||
printf(" Interface String ... \"%s\"\n",
|
||||
interface->InterfaceString());
|
||||
|
||||
@ -190,10 +248,13 @@ DumpInfo(BUSBDevice& device, bool verbose)
|
||||
printf("[Device /dev/bus/usb%s]\n", device.Location());
|
||||
printf(" Class .................. 0x%02x (%s)\n", device.Class(),
|
||||
ClassName(device.Class()));
|
||||
printf(" Subclass ............... 0x%02x\n", device.Subclass());
|
||||
printf(" Protocol ............... 0x%02x\n", device.Protocol());
|
||||
printf(" Subclass ............... 0x%02x%s\n", device.Subclass(),
|
||||
SubclassName(device.Class(), device.Subclass()));
|
||||
printf(" Protocol ............... 0x%02x%s\n", device.Protocol(),
|
||||
ProtocolName(device.Class(), device.Subclass(), device.Protocol()));
|
||||
printf(" Max Endpoint 0 Packet .. %d\n", device.MaxEndpoint0PacketSize());
|
||||
printf(" USB Version ............ 0x%04x\n", device.USBVersion());
|
||||
uint32_t version = device.USBVersion();
|
||||
printf(" USB Version ............ %d.%d\n", version >> 8, version & 0xFF);
|
||||
printf(" Vendor ID .............. 0x%04x", device.VendorID());
|
||||
if (vendorName != NULL)
|
||||
printf(" (%s)", vendorName);
|
||||
|
@ -11,8 +11,13 @@
|
||||
#define LISTUSB_H
|
||||
|
||||
|
||||
#include <USBKit.h>
|
||||
|
||||
|
||||
void DumpDescriptorData(const usb_generic_descriptor* descriptor);
|
||||
|
||||
void DumpAudioDescriptor(const usb_generic_descriptor* descriptor, int subclass);
|
||||
void DumpVideoDescriptor(const usb_generic_descriptor* descriptor, int subclass);
|
||||
|
||||
|
||||
#endif /* !LISTUSB_H */
|
||||
|
@ -19,10 +19,12 @@ void
|
||||
DumpAudioCSInterfaceDescriptorHeader(
|
||||
const usb_audiocontrol_header_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Header)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" bcdADC Release date 0x%04x\n",
|
||||
descriptor->bcd_release_no);
|
||||
printf(" ADC Release ....... %d.%d\n",
|
||||
descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF);
|
||||
printf(" Total Length ...... %u\n",
|
||||
descriptor->r1.total_length);
|
||||
printf(" Interfaces ........ ");
|
||||
@ -81,7 +83,7 @@ DumpChannelConfig(uint32 wChannelConfig)
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
static const char*
|
||||
TerminalTypeName(uint16 terminalType)
|
||||
{
|
||||
switch (terminalType) {
|
||||
@ -138,6 +140,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorInputTerminal(
|
||||
const usb_audio_input_terminal_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Input Terminal)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Terminal ID ....... %u\n",
|
||||
@ -164,6 +168,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorOutputTerminal(
|
||||
const usb_audio_output_terminal_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Output Terminal)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Terminal ID ....... %u\n",
|
||||
@ -184,6 +190,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorMixerUnit(
|
||||
const usb_audio_mixer_unit_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Mixer Unit)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Unit ID ........... %u\n",
|
||||
@ -222,6 +230,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorSelectorUnit(
|
||||
const usb_audio_selector_unit_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Selector Unit)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Unit ID ........... %u\n",
|
||||
@ -275,6 +285,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorFeatureUnit(
|
||||
const usb_audio_feature_unit_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Feature Unit)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Unit ID ........... %u\n",
|
||||
@ -316,6 +328,8 @@ void
|
||||
DumpAudioCSInterfaceDescriptorAssociated(
|
||||
const usb_generic_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Associate Interface)\n",
|
||||
(uint8)descriptor->data[0]);
|
||||
printf(" Interface ......... %u\n",
|
||||
@ -324,6 +338,7 @@ DumpAudioCSInterfaceDescriptorAssociated(
|
||||
printf(" Data .............. ");
|
||||
for (uint8 i = 0; i < descriptor->length - 2; i++)
|
||||
printf("%02x ", descriptor->data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
320
src/bin/listusb/usb_video.cpp
Normal file
320
src/bin/listusb/usb_video.cpp
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright 2016, Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||
* Distributed under terms of the MIT license.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <usb/USB_video.h>
|
||||
|
||||
#include "listusb.h"
|
||||
|
||||
|
||||
void
|
||||
DumpVideoCSInterfaceDescriptorHeader(
|
||||
const usb_videocontrol_header_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Header)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" UVC Release ....... %d.%d\n",
|
||||
descriptor->bcd_release_no >> 8, descriptor->bcd_release_no & 0xFF);
|
||||
printf(" Total Length ...... %u\n",
|
||||
descriptor->total_length);
|
||||
printf(" Clock Frequency ... %" B_PRIu32 "\n",
|
||||
descriptor->clock_frequency);
|
||||
printf(" Interfaces ........ ");
|
||||
|
||||
for (uint8 i = 0; i < descriptor->in_collection; i++)
|
||||
printf("%u, ", descriptor->interface_numbers[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
TerminalTypeName(uint16 terminalType)
|
||||
{
|
||||
switch (terminalType) {
|
||||
case USB_VIDEO_VENDOR_USB_IO:
|
||||
return "Vendor specific";
|
||||
case USB_VIDEO_STREAMING_USB_IO:
|
||||
return "Streaming";
|
||||
|
||||
case USB_VIDEO_VENDOR_IN:
|
||||
return "Vendor specific input";
|
||||
case USB_VIDEO_CAMERA_IN:
|
||||
return "Camera";
|
||||
case USB_VIDEO_MEDIA_TRANSPORT_IN:
|
||||
return "Media transport input";
|
||||
|
||||
case USB_VIDEO_VENDOR_OUT:
|
||||
return "Vendor specific output";
|
||||
case USB_VIDEO_DISPLAY_OUT:
|
||||
return "Display";
|
||||
case USB_VIDEO_MEDIA_TRANSPORT_OUT:
|
||||
return "Media transport output";
|
||||
|
||||
case USB_VIDEO_VENDOR_EXT:
|
||||
return "Vendor specific format";
|
||||
case USB_VIDEO_COMPOSITE_EXT:
|
||||
return "Composite";
|
||||
case USB_VIDEO_SVIDEO_EXT:
|
||||
return "S-Video";
|
||||
case USB_VIDEO_COMPONENT_EXT:
|
||||
return "Component";
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpVideoCSInterfaceDescriptorOutputTerminal(
|
||||
const usb_video_output_terminal_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Output Terminal)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Terminal ID ....... %u\n",
|
||||
descriptor->terminal_id);
|
||||
printf(" Terminal Type ..... 0x%04x (%s)\n",
|
||||
descriptor->terminal_type,
|
||||
TerminalTypeName(descriptor->terminal_type));
|
||||
printf(" Associated Terminal %u\n",
|
||||
descriptor->assoc_terminal);
|
||||
printf(" Source ID ......... %u\n",
|
||||
descriptor->source_id);
|
||||
printf(" Terminal .......... %u\n",
|
||||
descriptor->terminal);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpVideoCSInterfaceDescriptorInputTerminal(
|
||||
const usb_video_input_terminal_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Input Terminal)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Terminal ID ....... %u\n",
|
||||
descriptor->terminal_id);
|
||||
printf(" Terminal Type ..... 0x%04x (%s)\n",
|
||||
descriptor->terminal_type,
|
||||
TerminalTypeName(descriptor->terminal_type));
|
||||
printf(" Terminal .......... %u\n",
|
||||
descriptor->terminal);
|
||||
|
||||
if (descriptor->terminal_type == USB_VIDEO_CAMERA_IN)
|
||||
{
|
||||
printf(" Min. Focal length . %u\n",
|
||||
descriptor->camera.focal_length_min);
|
||||
printf(" Max. Focal length . %u\n",
|
||||
descriptor->camera.focal_length_min);
|
||||
printf(" Focal length ...... %u\n",
|
||||
descriptor->camera.focal_length);
|
||||
printf(" Controls .......... %02x%02x%02x\n",
|
||||
descriptor->camera.controls[0],
|
||||
descriptor->camera.controls[1],
|
||||
descriptor->camera.controls[2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char*
|
||||
ProcessingControlString(int index)
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
return "Brightness, ";
|
||||
case 1:
|
||||
return "Contrast, ";
|
||||
case 2:
|
||||
return "Hue, ";
|
||||
case 3:
|
||||
return "Saturation, ";
|
||||
case 4:
|
||||
return "Sharpness, ";
|
||||
case 5:
|
||||
return "Gamma, ";
|
||||
case 6:
|
||||
return "White balance temp., ";
|
||||
case 7:
|
||||
return "White balance component, ";
|
||||
case 8:
|
||||
return "Backlight compensation, ";
|
||||
case 9:
|
||||
return "Gain, ";
|
||||
case 10:
|
||||
return "Power line frequency, ";
|
||||
case 11:
|
||||
return "Automatic hue, ";
|
||||
case 12:
|
||||
return "Automatic white balance temp., ";
|
||||
case 13:
|
||||
return "Automatic white balance component, ";
|
||||
case 14:
|
||||
return "Digital multiplier, ";
|
||||
case 15:
|
||||
return "Digital multiplier limit, ";
|
||||
case 16:
|
||||
return "Analog video standard, ";
|
||||
case 17:
|
||||
return "Analog video lock status, ";
|
||||
case 18:
|
||||
return "Automatic contrast, ";
|
||||
default:
|
||||
return "Unknown, ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpVideoCSInterfaceDescriptorProcessingUnit(
|
||||
const usb_video_processing_unit_descriptor* descriptor)
|
||||
{
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Processing unit)\n",
|
||||
descriptor->descriptor_subtype);
|
||||
printf(" Unit ID ........... %u\n",
|
||||
descriptor->unit_id);
|
||||
printf(" Source ID ......... %u\n",
|
||||
descriptor->source_id);
|
||||
printf(" Max Multiplier .... %f\n",
|
||||
descriptor->max_multiplier / 100.f);
|
||||
printf(" Controls .......... ");
|
||||
uint32_t controls = (descriptor->controls[0] << 16)
|
||||
| (descriptor->controls[1] << 8)
|
||||
| descriptor->controls[2];
|
||||
for (int i = 0; i < 19; i++)
|
||||
{
|
||||
if (controls & (1 << (23 - i))) {
|
||||
printf(ProcessingControlString(i));
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
printf(" Processing ........ %u\n",
|
||||
descriptor->processing);
|
||||
printf(" Video Standards ... 0x%02x\n",
|
||||
descriptor->video_standards);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpVideoCSInterfaceDescriptorExtensionUnit(
|
||||
const usb_generic_descriptor* descriptor)
|
||||
{
|
||||
uint8 i = 0;
|
||||
|
||||
printf(" Type .............. 0x%02x\n",
|
||||
descriptor->descriptor_type);
|
||||
printf(" Subtype ........... 0x%02x (Extension unit)\n",
|
||||
(uint8)descriptor->data[i++]);
|
||||
printf(" Unit ID ........... %u\n",
|
||||
(uint8)descriptor->data[i++]);
|
||||
|
||||
printf(" GUID .............. ");
|
||||
for (i = 2; i < 16 + 2; i++)
|
||||
printf("%02x ", descriptor->data[i]);
|
||||
printf("\n");
|
||||
|
||||
printf(" Control count ..... %u\n",
|
||||
(uint8)descriptor->data[i++]);
|
||||
|
||||
printf(" Input pins ........ ");
|
||||
i = 20; // Skip the input pin count
|
||||
for (; i - 20 < descriptor->data[19]; i++)
|
||||
printf("%u, ", descriptor->data[i]);
|
||||
printf("\n");
|
||||
|
||||
printf(" Controls .......... ");
|
||||
uint8_t end = descriptor->data[i++];
|
||||
uint8_t start = i;
|
||||
for (; i - start < end; i++)
|
||||
printf("%02x", (uint8)descriptor->data[i]);
|
||||
printf("\n");
|
||||
|
||||
printf(" Extension ......... %u\n",
|
||||
(uint8)descriptor->data[i++]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpVideoControlCSInterfaceDescriptor(const usb_generic_descriptor* descriptor)
|
||||
{
|
||||
uint8 descriptorSubtype = descriptor->data[0];
|
||||
switch (descriptorSubtype) {
|
||||
case USB_VIDEO_VC_HEADER:
|
||||
DumpVideoCSInterfaceDescriptorHeader(
|
||||
(usb_videocontrol_header_descriptor*)descriptor);
|
||||
break;
|
||||
case USB_VIDEO_VC_INPUT_TERMINAL:
|
||||
DumpVideoCSInterfaceDescriptorInputTerminal(
|
||||
(usb_video_input_terminal_descriptor*)descriptor);
|
||||
break;
|
||||
case USB_VIDEO_VC_OUTPUT_TERMINAL:
|
||||
DumpVideoCSInterfaceDescriptorOutputTerminal(
|
||||
(usb_video_output_terminal_descriptor*)descriptor);
|
||||
break;
|
||||
case USB_VIDEO_VC_PROCESSING_UNIT:
|
||||
DumpVideoCSInterfaceDescriptorProcessingUnit(
|
||||
(usb_video_processing_unit_descriptor*)descriptor);
|
||||
break;
|
||||
case USB_VIDEO_VC_EXTENSION_UNIT:
|
||||
DumpVideoCSInterfaceDescriptorExtensionUnit(descriptor);
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DumpAudioStreamCSInterfaceDescriptor(const usb_generic_descriptor* descriptor);
|
||||
|
||||
void
|
||||
DumpVideoDescriptor(const usb_generic_descriptor* descriptor, int subclass)
|
||||
{
|
||||
switch (subclass) {
|
||||
case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS:
|
||||
switch (descriptor->descriptor_type) {
|
||||
case USB_VIDEO_CS_INTERFACE:
|
||||
DumpVideoControlCSInterfaceDescriptor(descriptor);
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS:
|
||||
switch (descriptor->descriptor_type) {
|
||||
case USB_VIDEO_CS_INTERFACE:
|
||||
DumpAudioStreamCSInterfaceDescriptor(descriptor);
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS:
|
||||
switch (descriptor->descriptor_type) {
|
||||
case USB_VIDEO_CS_INTERFACE:
|
||||
// TODO
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DumpDescriptorData(descriptor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user