USB_Video.h: add more definitions from the spec.

fixes #5940

Change-Id: Idb9ae8dfdaa9f0fab43be3767bf97e1c87245940
Reviewed-on: https://review.haiku-os.org/c/haiku/+/1022
Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
brjhaiku 2019-02-10 03:08:31 +05:30 committed by Adrien Destugues
parent 09b40d1634
commit f57d609e9b

View File

@ -11,16 +11,21 @@
// Based on specification for UVC version 1.5.
#include <BeBuild.h> // for _PACKED definition
#include <lendian_bitfield.h>
#include <SupportDefs.h>
#define USB_VIDEO_DEVICE_CLASS 0x0E
enum { // Video Interface Class Code
USB_VIDEO_INTERFACE_VIDEO_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,
USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS = 0x02,
USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS = 0x03,
};
@ -63,7 +68,7 @@ enum { // Video Class-Specific VideoStreaming Interface descriptor subtypes
USB_VIDEO_VS_FRAME_MJPEG = 0x07,
USB_VIDEO_VS_FORMAT_MPEG2TS = 0x0a,
USB_VIDEO_VS_FORMAT_DV = 0x0c,
USB_VIDEO_VS_COLORFORMAT = 0x0d,
USB_VIDDE_VS_COLORFORMAT = 0x0d,
USB_VIDEO_VS_FORMAT_FRAME_BASED = 0x10,
USB_VIDEO_VS_FRAME_FRAME_BASED = 0x11,
USB_VIDEO_VS_FORMAT_STREAM_BASED = 0x12,
@ -76,6 +81,20 @@ enum { // Video Class-Specific VideoStreaming Interface descriptor subtypes
};
enum { // Video Streaming Interface Control Selectors
USB_VIDEO_VS_CONTROL_UNDEFINED = 0x00,
USB_VIDEO_VS_PROBE_CONTROL = 0x01,
USB_VIDEO_VS_COMMIT_CONTROL = 0x02,
USB_VIDEO_VS_STILL_PROBE_CONTROL = 0x03,
USB_VIDEO_VS_STILL_COMMIT_CONTROL = 0x04,
USB_VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL = 0x05,
USB_VIDEO_VS_STREAM_ERROR_CODE_CONTROL = 0x06,
USB_VIDEO_VS_GENERATE_KEY_FRAME_CONTROL = 0x07,
USB_VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL = 0x08,
USB_VIDEO_VS_SYNCH_DELAY_CONTROL = 0x09
};
enum {
// USB Terminal Types
USB_VIDEO_VENDOR_USB_IO = 0x100,
@ -96,7 +115,7 @@ enum {
};
enum {
enum { // Video Class-Specific Endpoint Descriptor Subtypes
EP_SUBTYPE_UNDEFINED = 0x00,
EP_SUBTYPE_GENERAL = 0x01,
EP_SUBTYPE_ENDPOINT = 0x02,
@ -104,8 +123,189 @@ enum {
};
// Class Specific Video Control Interface Header
// 1.5: Table 3-3 p.48
enum { // Terminal Control Selectors
USB_VIDEO_TE_CONTROL_UNDEFINED = 0x00
};
enum { // Selector Unit Control Selectors
USB_VIDEO_SU_CONTROL_UNDEFINED = 0x00,
USB_VIDEO_SU_INPUT_SELECT_CONTROL = 0x01
};
enum { // Video Class-Specific Request Codes
USB_VIDEO_RC_UNDEFINED = 0x00,
USB_VIDEO_RC_SET_CUR = 0x01,
USB_VIDEO_RC_GET_CUR = 0x81,
USB_VIDEO_RC_GET_MIN = 0x82,
USB_VIDEO_RC_GET_MAX = 0x83,
USB_VIDEO_RC_GET_RES = 0x84,
USB_VIDEO_RC_GET_LEN = 0x85,
USB_VIDEO_RC_GET_INFO = 0x86,
USB_VIDEO_RC_GET_DEF = 0x87
};
enum { // Camera Terminal Control Selectors
USB_VIDEO_CT_CONTROL_UNDEFINED = 0x00,
USB_VIDEO_CT_SCANNING_MODE_CONTROL = 0x01,
USB_VIDEO_CT_AE_MODE_CONTROL = 0x02,
USB_VIDEO_CT_AE_PRIORITY_CONTROL = 0x03,
USB_VIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL = 0x04,
USB_VIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL = 0x05,
USB_VIDEO_CT_FOCUS_ABSOLUTE_CONTROL = 0x06,
USB_VIDEO_CT_FOCUS_RELATIVE_CONTROL = 0x07,
USB_VIDEO_CT_FOCUS_AUTO_CONTROL = 0x08,
USB_VIDEO_CT_IRIS_ABSOLUTE_CONTROL = 0x09,
USB_VIDEO_CT_IRIS_RELATIVE_CONTROL = 0x0A,
USB_VIDEO_CT_ZOOM_ABSOLUTE_CONTROL = 0x0B,
USB_VIDEO_CT_ZOOM_RELATIVE_CONTROL = 0x0C,
USB_VIDEO_CT_PANTILT_ABSOLUTE_CONTROL = 0x0D,
USB_VIDEO_CT_PANTILT_RELATIVE_CONTROL = 0x0E,
USB_VIDEO_CT_ROLL_ABSOLUTE_CONTROL = 0x0F,
USB_VIDEO_CT_ROLL_RELATIVE_CONTROL = 0x10,
USB_VIDEO_CT_PRIVACY_CONTROL = 0x11
};
enum { // Processing Unit Control Selectors
USB_VIDEO_PU_CONTROL_UNDEFINED = 0x00,
USB_VIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL = 0x01,
USB_VIDEO_PU_BRIGHTNESS_CONTROL = 0x02,
USB_VIDEO_PU_CONTRAST_CONTROL = 0x03,
USB_VIDEO_PU_GAIN_CONTROL = 0x04,
USB_VIDEO_PU_POWER_LINE_FREQUENCY_CONTROL = 0x05,
USB_VIDEO_PU_HUE_CONTROL = 0x06,
USB_VIDEO_PU_SATURATION_CONTROL = 0x07,
USB_VIDEO_PU_SHARPNESS_CONTROL = 0x08,
USB_VIDEO_PU_GAMMA_CONTROL = 0x09,
USB_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL = 0x0A,
USB_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL = 0x0B,
USB_VIDEO_PU_WHITE_BALANCE_TEMPERATURE_COMPONENT_CONTROL = 0x0C,
USB_VIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL = 0x0D,
USB_VIDEO_PU_DIGITAL_MULTIPLEXER_CONTROL = 0x0E,
USB_VIDEO_PU_DIGITAL_MULTIPLEXER_LIMIT_CONTROL = 0x0F,
USB_VIDEO_PU_HUE_AUTO_CONTROL = 0x10,
USB_VIDEO_PU_ANALOG_VIDEO_STANDARD_CONTROL = 0x11,
USB_VIDEO_PU_ANALOG_LOCK_STATUS_CONTROL = 0x12
};
enum { // Extension Unit Control Selectors
USB_VIDEO_XU_CONTROL_UNDEFINED = 0x00
};
typedef struct {
/* The orignator bitfield of the status_type struct can have the
following values: 0 = reserved, 1 = VideoControl interface,
2 = VideoStreaming interface. */
struct status_type {
LBITFIELD8_2 (
originator: 4,
reserved: 4
);
} status_type;
/* The second common status_packet_format field orignator includes ID of
* the Terminal, Unit or Interface that reports the interrupt. */
uint8 originator;
union {
struct videocontrol_interface_as_orignator {
/* If the orginator bitfield value is 1 (VideoControl interface)
* then third field of the status_packet_format is event field that
* includes value 0x00 for control change. Other values
* (0x01 - 0xFF) are reserved. */
uint8 event;
/* The fourth field selector reports the Control Selector of the
* control that have issued the interrupt. */
uint8 selector;
/* The fifth field attribute specifies the type of control change:
* 0x00 is Control value change, 0x01 is Control info change,
* 0x02 is Control failure change
* and values 0x03 - 0xFF are reserved. */
uint8 attribute;
/* After that can be several value fields that can include values
* 0x00, 0x01 and 0x02. */
uint8 value[0];
} videocontrol_interface_as_orignator;
struct videostreaming_interface_as_originator {
/* If the originator bitfield value is 2 (VideoStreaming interface)
* then third field of the status_packet_format is event field that
* can have value 0x00 (Button Press)
* or values 0x01 - 0xFF (Stream errors). */
uint8 event;
/* If event value is 0x00 (Button Press) there is only one value
* field. It can include values 0x00 (Button released)
* or 0x01 (Button pressed). If event value was some Stream error
* value, then there can be several value fields. */
uint8* value;
} videostreaming_interface_as_originator;
} originators;
} _PACKED usb_video_status_packet_format;
typedef struct {
uint8 length; // 9 bytes
uint8 descriptor_type;
uint8 interface_number;
uint8 alternate_setting;
uint8 num_endpoints;
uint8 interface_class;
uint8 interface_sub_class;
uint8 interface_protocol;
// Not used. Must be set to USB_VIDEO_PC_PROTOCOL_UNDEFINED
uint8 interface;
} _PACKED usb_video_standard_vc_interface_descriptor;
typedef struct {
uint8 length; // 8 bytes
uint8 descriptor_type;
uint8 first_interface;
uint8 interface_count;
uint8 function_class;
uint8 function_sub_class;
uint8 function_protocol;
// Not used. Must be set to USB_VIDEO_PC_PROTOCOL_UNDEFINED
uint8 function;
} _PACKED usb_video_standard_video_interface_collection_iad;
typedef struct {
uint8 length; // 6 bytes + nr_in_pins
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 unit_id;
uint8 nr_in_pins;
uint8* source_id;
uint8 selector;
} _PACKED usb_video_selector_unit_descriptor;
typedef struct {
uint8 header_length;
struct header_info {
LBITFIELD8_8 (
frame_id: 1,
end_of_frame: 1,
presentation_time: 1,
source_clock_reference: 1,
reserved: 1,
still_image: 1,
error: 1,
end_of_header: 1
);
} _header_info;
} _PACKED usb_video_payload_header_format;
typedef struct {
uint32 presentation_time;
uint8 source_clock[6];
} _PACKED usb_video_payload_header_format_extended_fields;
typedef struct {
uint8 length;
uint8 descriptor_type; // USB_AUDIO_CS_INTERFACE
@ -118,6 +318,80 @@ typedef struct {
} _PACKED usb_videocontrol_header_descriptor;
typedef struct {
uint8 length; // 24 bytes + nr_in_pins + control_size
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 unit_id;
uint8 guid_extension_code[16];
uint8 num_controls;
uint8 nr_in_pins;
uint8 source_id[0];
#if 0
// Remaining part of the structure can't be encoded because source_id has
// a variable size
uint8 control_size;
struct controls {
LBITFIELD8_8 (
vendor_specific0 : 1,
vendor_specific1 : 1,
vendor_specific2 : 1,
vendor_specific3 : 1,
vendor_specific4 : 1,
vendor_specific5 : 1,
vendor_specific6 : 1,
vendor_specific7 : 1
);
} * _controls;
uint8 extension;
#endif
} _PACKED usb_video_extension_unit_descriptor;
typedef struct {
uint8 length; // 7 bytes
uint8 descriptor_type;
struct end_point_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3, // Reserved. Set to zero.
direction: 1 // 0 = OUT, 1 = IN
);
} _end_point_address;
struct attributes {
LBITFIELD8_3 (
transfer_type: 2, // Must be set to 11 (Interrupt)
synchronization_type: 2, // Must be set to 00 (None)
reserved: 4 // Reserved. Must be set to zero
);
} _attributes;
uint16 max_packet_size;
uint8 interval;
} _PACKED usb_video_vc_interrupt_endpoint_descriptor;
typedef struct {
uint8 length; // 9 bytes
uint8 descriptor_type;
uint8 interface_number;
uint8 alternate_setting;
uint8 num_endpoints;
uint8 interface_class;
uint8 interface_sub_class;
uint8 interface_protocol;
// Not used. Must be set to USB_VIDEO_PC_PROTOCOL_UNDEFINED
uint8 interface;
} _PACKED usb_video_standard_vs_interface_descriptor;
typedef struct {
uint8 length; // 5 bytes
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint16 max_transfer_size;
} _PACKED usb_video_class_specific_vc_interrupt_endpoint_descriptor;
// Input Terminal Descriptor
// 1.5: Table 3-4, page 50
typedef struct {
@ -141,6 +415,51 @@ typedef struct {
} _PACKED usb_video_input_terminal_descriptor;
typedef struct {
uint8 length; // 13 bytes + (num_formats*control_size)
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 num_formats;
uint16 total_length;
struct endpoint_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3, // Set to zero.
direction: 1 // 0 = OUT, 1 = IN
);
} _endpoint_address;
struct info {
LBITFIELD8_2 (
dynamic_format_change_support: 1,
reserved: 7 // Set to zero.
);
} _info;
uint8 terminal_link;
uint8 still_capture_method;
uint8 trigger_support;
uint8 trigger_usage;
uint8 control_size;
struct ma_controls {
// For four first bits, a bit set to 1 indicates that the named field
// is supported by the Video Probe and Commit Control when
// its format_index is 1:
LBITFIELD8_7 (
key_frame_rate: 1,
p_frame_rate: 1,
comp_quality: 1,
comp_window_size: 1,
// For the next two bits, a bit set to 1 indicates that the named
// control is supported by the device when
// format_index is 1:
generate_key_frame: 1,
update_frame_segment: 1,
reserved: 2 // (control_size*8-1): Set to zero.
);
} * _ma_controls;
} _PACKED usb_video_class_specific_vs_interface_input_header_descriptor;
// Output terminal descriptor
// 1.5: Table 3-5, page 51
typedef struct {
@ -155,6 +474,36 @@ typedef struct {
} _PACKED usb_video_output_terminal_descriptor;
typedef struct {
uint8 length; // 9 + (num_formats*control_size)
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 num_formats;
uint16 total_length;
struct endpoint_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3, // Set to zero.
direction: 1 // 0 = OUT
);
} _endpoint_address;
uint8 terminal_link;
uint8 control_size;
struct ma_controls {
// For four first bits, a bit set to 1 indicates that the named field
// is supported by the Video Probe and Commit Control when its
// format_index is 1:
LBITFIELD8_5 (
key_frame_rate: 1,
p_frame_rate: 1,
comp_quality: 1,
comp_window_size: 1,
reserved: 4 // (control_size*8-1) Set to zero.
);
} * _ma_controls;
} _PACKED usb_video_class_specific_vs_interface_output_header_descriptor;
// Processing unit descriptor
// 1.5: Table 3-8, page 54
typedef struct {
@ -165,13 +514,164 @@ typedef struct {
uint8 source_id;
uint16 max_multiplier;
uint8 control_size;
uint8 controls[3];
uint8 processing;
uint8 video_standards;
#if B_HOST_IS_LENDIAN
struct controls {
struct control_a {
LBITFIELD16 (
brightness: 1,
contrast: 1,
hue: 1,
saturation: 1,
sharpness: 1,
gamma: 1,
white_balance_temperature: 1,
white_balance_component: 1,
backlight_compensation: 1,
gain: 1,
power_line_frequency: 1,
hue_auto: 1,
white_balance_temperature_auto: 1,
white_balance_component_auto: 1,
digital_multiplier: 1,
digital_multiplier_limit: 1
);
} _control_a;
struct control_b {
LBITFIELD3 (
analog_video_standard: 1,
analog_video_lock_status: 1,
reserved: 14 // Reserved. Se to zero.
);
} _control_b;
} _controls;
#else
struct controls {
struct control_b {
LBITFIELD3 (
analog_video_standard: 1,
analog_video_lock_status: 1,
reserved: 14 // Reserved. Se to zero.
);
} _control_b;
struct control_a {
LBITFIELD16 (
brightness: 1,
contrast: 1,
hue: 1,
saturation: 1,
sharpness: 1,
gamma: 1,
white_balance_temperature: 1,
white_balance_component: 1,
backlight_compensation: 1,
gain: 1,
power_line_frequency: 1,
hue_auto: 1,
white_balance_temperature_auto: 1,
white_balance_component_auto: 1,
digital_multiplier: 1,
digital_multiplier_limit: 1
);
} _control_a;
} _controls;
#endif
uint8 processing;
struct video_standards {
LBITFIELD8_8 (
none: 1,
ntsc_525_60: 1,
pal_625_50: 1,
secam_625_50: 1,
ntsc_625_50: 1,
pal_525_60: 1,
reserved6: 1, // Reserved. Set to zero.
reserved7: 1 // Reserved. Set to zero.
);
} _video_standards;
} _PACKED usb_video_processing_unit_descriptor;
struct usb_video_frame_descriptor {
typedef struct {
uint8 length; // 15 + control_size bytes
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 terminal_id;
uint16 terminal_type;
uint8 assoc_terminal;
uint8 terminal;
uint16 objective_focal_length_min;
uint16 objective_focal_length_max;
uint16 ocular_focal_length;
uint8 control_size;
#if B_HOST_IS_LENDIAN
struct controls {
struct control_a {
LBITFIELD16 (
scanning_mode: 1,
auto_exposure_mode: 1,
auto_exposure_priority: 1,
exposure_time_absolute: 1,
exposure_time_relative: 1,
focus_absolute: 1,
focus_relative: 1,
iris_absolute: 1,
iris_relative: 1,
zoom_absolute: 1,
zoom_relative: 1,
pan_tilt_absolute: 1,
pan_tilt_relative: 1,
roll_absolute: 1,
roll_relative: 1,
reserved15: 1
);
} _control_a;
struct control_b {
LBITFIELD4 (
reserved16: 1,
focus_auto: 1,
privacy: 1,
// D19...(control_size*8-1): Reserved, set to zero.
reserved: 13
);
} _contorl_b;
} _controls;
#else
struct controls {
struct control_b {
LBITFIELD4 (
reserved16: 1,
focus_auto: 1,
privacy: 1,
// D19...(control_size*8-1): Reserved, set to zero.
reserved: 13
);
} _contorl_b;
struct control_a {
LBITFIELD16 (
scanning_mode: 1,
auto_exposure_mode: 1,
auto_exposure_priority: 1,
exposure_time_absolute: 1,
exposure_time_relative: 1,
focus_absolute: 1,
focus_relative: 1,
iris_absolute: 1,
iris_relative: 1,
zoom_absolute: 1,
zoom_relative: 1,
pan_tilt_absolute: 1,
pan_tilt_relative: 1,
roll_absolute: 1,
roll_relative: 1,
reserved15: 1
);
} _control_a;
} _controls;
#endif
} _PACKED usb_video_camera_terminal_descriptor;
typedef struct {
uint8 length;
uint8 descriptor_type;
uint8 descriptor_subtype;
@ -195,4 +695,137 @@ struct usb_video_frame_descriptor {
} _PACKED;
typedef struct {
uint8 length; // 34 bytes
struct hint {
LBITFIELD5 (
frame_interval: 1,
key_frame_rate: 1,
p_frame_rate: 1,
comp_quality: 1,
reserved: 12
);
} _hint;
uint8 format_index;
uint8 frame_index;
uint32 frame_interval;
uint16 key_frame_rate;
uint16 p_frame_rate;
uint16 comp_quality;
uint16 comp_window_size;
uint16 delay;
uint32 max_video_frame_size;
uint32 max_payload_transfer_size;
uint32 clock_frequency;
struct framing_info {
LBITFIELD8_3 (
is_frame_id_required: 1,
is_end_of_frame_present: 1,
reserved: 6
);
} _framing_info;
uint8 prefered_version;
uint8 min_version;
uint8 max_version;
} _PACKED usb_video_video_probe_and_commit_controls;
typedef struct {
uint8 length; // 11 bytes
uint8 frame_index;
uint8 compression_index;
uint32 max_video_frame_size;
uint32 max_payload_transfer_size;
} _PACKED usb_video_video_still_probe_control_and_still_commit_control;
typedef struct {
// 10 bytes + (4 * num_image_size_patterns) - 4 + num_compression_pattern
uint8 length;
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 endpoint_address;
uint8 num_image_size_patterns;
struct pattern_size {
uint16 width;
uint16 height;
} * _pattern_size;
uint8 num_compression_pattern;
uint8* compression;
} _PACKED usb_video_still_image_frame_descriptor;
typedef struct {
uint8 length; // 7 bytes
struct endpoint_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3,
direction: 1 // Set to 1 = IN endpoint)
);
} _endpoint_address;
struct attributes {
LBITFIELD8_2 (
transfer_type: 2, // Set to 10 = Bulk
reserved: 6
);
} _attributes;
uint16 max_packet_size;
uint8 interval;
} _PACKED usb_video_standard_vs_bulk_still_image_data_endpoint_descriptor;
typedef struct {
uint8 length; // 6 bytes
uint8 descriptor_type;
uint8 descriptor_sub_type;
uint8 color_primaries;
uint8 transfer_characteristics;
uint8 matrix_coefficients;
} _PACKED usb_video_color_matching_descriptor;
typedef struct {
uint8 length; // 7 bytes
uint8 descriptor_type;
struct endpoint_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3, // Reset to zero.
direction: 1 // 0 = OUT endpoint, 1 = IN endpoint
);
} _endpoint_address;
struct attributes {
LBITFIELD8_3 (
transfer_type: 2, // 01 = isochronous
synchronization_type: 2, // 01 = asynchronous
reserved: 4
);
} _attributes;
uint16 max_packet_size;
uint8 interval;
} _PACKED usb_video_std_vs_isochronous_video_data_endpoint_descriptor;
typedef struct {
uint8 length; // 7 bytes
uint8 descriptor_type;
struct endpoint_address {
LBITFIELD8_3 (
endpoint_number: 4, // Determined by the designer
reserved: 3, // Reset to zero.
direction: 1 // 0 = OUT endpoint
);
} _endpoint_address;
struct attributes {
LBITFIELD8_2 (
transfer_type: 2, // Set to 10 = Bulk
reserved: 6
);
} _attributes;
uint16 max_packet_size;
uint8 interval;
} _PACKED usb_video_standard_vs_bulk_video_data_endpoint_descriptor;
#endif /* !USB_VIDEO_H */