root/sys/dev/usb/uvideoreg.h
/*      $NetBSD: uvideoreg.h,v 1.8 2023/04/10 15:26:56 mlelstv Exp $    */

/*
 * Copyright (c) 2008 Patrick Mahoney
 * All rights reserved.
 *
 * This code was written by Patrick Mahoney (pat@polycrystal.org) as
 * part of Google Summer of Code 2008.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *        This product includes software developed by the NetBSD
 *        Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#define UVIDEO_VERSION          0x001

/* This is the standard GUID / UUID.  In USB, it comes in the usual
 * little-endian packed format. */

typedef struct {
        uDWord          data1;
        uWord           data2;
        uWord           data3;
        uByte           data4[8];
} UPACKED usb_guid_t;

typedef struct {
        uint32_t        data1;
        uint16_t        data2;
        uint16_t        data3;
        uint8_t         data4[8];
} guid_t;
#define GUID_LEN 16

/*
 * Video Control descriptors
 */

#define UDESC_VC_HEADER         0x01
#define UDESC_INPUT_TERMINAL    0x02
#define UDESC_OUTPUT_TERMINAL   0x03
#define UDESC_SELECTOR_UNIT     0x04
#define UDESC_PROCESSING_UNIT   0x05
#define UDESC_EXTENSION_UNIT    0x06

#define UDESC_VC_INTERRUPT_ENDPOINT     0x03

/* Terminal Types */
#define UVDIEO_TT_VENDOR_SPECIFIC       0x0100
#define UVIDEO_TT_STREAMING             0x0101

/* Input Terminal Types */
#define UVIDEO_ITT_VENDOR_SPECIFIC      0x0200
#define UVIDEO_ITT_CAMERA               0x0201
#define UVIDEO_ITT_MEDIA_TRANSPORT_INPUT 0x0202

/* Output Terminal Types */
#define UVIDEO_OTT_VENDOR_SPECIFIC      0x0300
#define UVIDEO_OTT_DISPLAY              0x0301
#define UVIDEO_OTT_MEDIA_TRANSPORT_OUTPUT 0x0302

/* generic descriptor with Subtype */
typedef struct {
        uByte   bLength;
        uByte   bDescriptorType;
        uByte   bDescriptorSubtype;
} uvideo_descriptor_t;

/* Class-specific Video Control Interface Header Descriptor */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uWord           bcdUVC;
        uWord           wTotalLength;
        uDWord          dwClockFrequency;
        uByte           bInCollection;
        /* followed by n bytes where n is equal to value of bInCollection */
        uByte           baInterfaceNr[];
} UPACKED uvideo_vc_header_descriptor_t;

/* Input Terminal Descriptor */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bTerminalID;
        uWord           wTerminalType;
        uByte           bAssocTerminal;
        uByte           iTerminal;
        /* possibly more, depending on Terminal type */
} UPACKED uvideo_input_terminal_descriptor_t;

/* Output Terminal Descriptor */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bTerminalID;
        uWord           wTerminalType;
        uByte           bAssocTerminal;
        uByte           bSourceID;
        uByte           iTerminal;
} UPACKED uvideo_output_terminal_descriptor_t;

/* Camera Terminal Descriptor */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;     /* UDESC_VC_INPUT_TERMINAL */
        uByte           bTerminalID;
        uWord           wTerminalType;          /* UVIDEO_ITT_CAMERA */
        uByte           bAssocTerminal;
        uByte           iTerminal;
        uWord           wObjectiveFocalLengthMin;
        uWord           wObjectiveFocalLengthMax;
        uWord           wOcularFocalLength;
        uByte           bControlSize;
        uByte           bmControls[];
} UPACKED uvideo_camera_terminal_descriptor_t;

/* bmControls fields of uvideo_camera_terminal_descriptor_t */
#define UVIDEO_CAMERA_CONTROL_SCANNING_MODE             (1<<0)
#define UVIDEO_CAMERA_CONTROL_AUTO_EXPOSURE_MODE        (1<<1)
#define UVIDEO_CAMERA_CONTROL_AUTO_EXPOSURE_PRIO        (1<<2)
#define UVIDEO_CAMERA_CONTROL_EXPOSURE_TIME_ABSOLUTE    (1<<3)
#define UVIDEO_CAMERA_CONTROL_EXPOSURE_TIME_RELATIVE    (1<<4)
#define UVIDEO_CAMERA_CONTROL_FOCUS_ABSOLUTE            (1<<5)
#define UVIDEO_CAMERA_CONTROL_FOCUS_RELATIVE            (1<<6)
#define UVIDEO_CAMERA_CONTROL_IRIS_ABSOLUTE             (1<<7)
#define UVIDEO_CAMERA_CONTROL_IRIS_RELATIVE             (1<<8)
#define UVIDEO_CAMERA_CONTROL_ZOOM_ABSOLUTE             (1<<9)
#define UVIDEO_CAMERA_CONTROL_ZOOM_RELATIVE             (1<<10)
#define UVIDEO_CAMERA_CONTROL_PANTILT_ABSOLUTE          (1<<11)
#define UVIDEO_CAMERA_CONTROL_PANTILT_RELATIVE          (1<<12)
#define UVIDEO_CAMERA_CONTROL_ROLL_ABSOLUTE             (1<<13)
#define UVIDEO_CAMERA_CONTROL_ROLL_RELATIVE             (1<<14)
/* 15,16 reserved */
#define UVIDEO_CAMERA_CONTROL_FOCUS_AUTO                (1<<17)
#define UVIDEO_CAMERA_CONTROL_PRIVACY                   (1<<18)

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bUnitID;
        uByte           bNrInPins;
        uByte           baSourceID[];
        /* The position of the next field is baSourceID[0] + bNrInPins
         * and should be accessed via a function. */
/*      uByte           iSelector */
} UPACKED uvideo_selector_unit_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bUnitID;
        uByte           bSourceID;
        uWord           wMaxMultiplier;
        uByte           bControlSize;
        uByte           bmControls[];
/*      uByte           iProcessing */
/*      uByte           bmVideoStandards */
#define PU_GET_VIDEO_STANDARDS(desc)    \
        (*((desc)->bmControls + (desc)->bControlSize))
#define UVIDEO_STANDARD_NONE            (1<<0)
#define UVIDEO_STANDARD_NTSC_525_60     (1<<1)
#define UVIDEO_STANDARD_PAL_625_50      (1<<2)
#define UVIDEO_STANDARD_SECAM_625_50    (1<<3)
#define UVIDEO_STANDARD_NTSC_625_50     (1<<4)
#define UVIDEO_STANDARD_PAL_525_60      (1<<5)
} UPACKED uvideo_processing_unit_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bUnitID;
        usb_guid_t      guidExtensionCode;
        uByte           bNumControls;
        uByte           bNrInPins;
        uByte           baSourceID[];
/*      uByte           bControlSize */
/*      uByte           bmControls */
#define XU_GET_CONTROL_SIZE(desc)                       \
        (*((desc)->baSourceID + (desc)->bNrInPins))
#define XU_GET_CONTROLS(desc)                           \
        ((desc)->baSourceID + (desc)->bNrInPins + 1)
/*      uByte           iExtension */
} UPACKED uvideo_extension_unit_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType; /* UDESC_ENDPOINT */
        uByte           bDescriptorSubtype;
        uWord           wMaxTransferSize;
} UPACKED uvideo_vc_interrupt_endpoint_descriptor_t;



/*
 * Video Streaming descriptors
 */

#define UDESC_VS_INPUT_HEADER           0x01
#define UDESC_VS_OUTPUT_HEADER          0x02
#define UDESC_VS_STILL_IMAGE_FRAME      0x03
#define UDESC_VS_FORMAT_UNCOMPRESSED    0x04
#define UDESC_VS_FRAME_UNCOMPRESSED     0x05
#define UDESC_VS_FORMAT_MJPEG           0x06
#define UDESC_VS_FRAME_MJPEG            0x07
/* reserved in spec v1.1                0x08 */
/* reserved in spec v1.1                0x09 */
#define UDESC_VS_FORMAT_MPEG2TS         0x0A
/* reserved in spec v 1.1               0x0B */
#define UDESC_VS_FORMAT_DV              0x0C
#define UDESC_VS_COLORFORMAT            0x0D
/* reserved in spec v1.1                0x0E */
/* reserved in spec v1.1                0x0F */
#define UDESC_VS_FORMAT_FRAME_BASED     0x10
#define UDESC_VS_FRAME_FRAME_BASED      0x11
#define UDESC_VS_FORMAT_STREAM_BASED    0x12

/* Copy protection state */
#define UVIDEO_NO_RESTRICTIONS          0
#define UVIDEO_RESTRICT_DUP             1

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bNumFormats;
        uWord           wTotalLength;
        uByte           bEndpointAddress;
        uByte           bmInfo;
        uByte           bTerminalLink;
        uByte           bStillCaptureMethod;
        uByte           bTriggerSupport;
        uByte           bTriggerUsage;
        uByte           bControlSize;
        uByte           bmaControls[];
#define UVIDEO_VS_KEYFRAME_RATE (1<<0)
#define UVIDEO_VS_PFRAME_RATE   (1<<1)
#define UVIDEO_VS_COMP_QUALITY  (1<<2)
#define UVIDEO_VS_COMP_WINDOW_SIZE      (1<<3)
#define UVIDEO_VS_GENERATE_KEYFRAME     (1<<4)
#define UVIDEO_VS_UPDATE_FRAME_SEGMENT  (1<<5)
} UPACKED uvideo_vs_input_header_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bNumFormats;
        uWord           wTotalLength;
        uByte           bEndpointAddress;
        uByte           bTerminalLink;
        uByte           bControlSize;
        uByte           bmaControls[];
} UPACKED uvideo_vs_output_header_descriptor_t;


typedef struct {
        uWord           wWidth;
        uWord           wHeight;
} UPACKED uvideo_still_image_frame_dimensions_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bEndpointAddress;
        uByte           bNumImageSizePatterns;
        uvideo_still_image_frame_dimensions_t wwaDimensions[];
        /* position dependent on size of previous item */
        /* uByte        bNumCompressionPattern */
        /* uByte        bCompression[] */
} UPACKED uvideo_still_image_frame_descriptor_t;


/* Color matching information */

/* bColroPrimaries */
#define UVIDEO_COLOR_PRIMARIES_UNSPECIFIED      0
#define UVIDEO_COLOR_PRIMARIES_sRGB             1 /* same as BT709 */
#define UVIDEO_COLOR_PRIMARIES_BT709            1 /* default */
#define UVIDEO_COLOR_PRIMARIES_BT470_2_M        2
#define UVIDEO_COLOR_PRIMARIES_BT470_2_BG       3
#define UVIDEO_COLOR_PRIMARIES_SMPTE_170M       4
#define UVIDEO_COLOR_PRIMARIES_SMPTE_240M       5

/* bTransferCharacteristics */
#define UVIDEO_GAMMA_FUNCTION_UNSPECIFIED       0
#define UVIDEO_GAMMA_FUNCTION_BT709             1 /* default */
#define UVIDEO_GAMMA_FUNCTION_BT470_2_M         2
#define UVIDEO_GAMMA_FUNCTION_BT470_2_BG        3
#define UVIDEO_GAMMA_FUNCTION_SMPTE_170M        4
#define UVIDEO_GAMMA_FUNCTION_SMPTE_240M        5
#define UVIDEO_GAMMA_FUNCTION_LINEAR            6       
#define UVIDEO_GAMMA_FUNCTION_sRGB              7 /* similar to BT709 */

/* bMatrixCoefficients */
#define UVIDEO_LUMA_CHROMA_MATRIX_UNSPECIFIED   0
#define UVIDEO_LUMA_CHROMA_MATRIX_BT709         1
#define UVIDEO_LUMA_CHROMA_MATRIX_FCC           2
#define UVIDEO_LUMA_CHROMA_MATRIX_BT470_2_BG    3
#define UVIDEO_LUMA_CHROMA_MATRIX_SMPTE_170M    4 /* default */
#define UVIDEO_LUMA_CHROMA_MATRIX_SMPTE_240M    5

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bColorPrimaries;
        uByte           bTransferCharacteristics;
        uByte           bMatrixCoefficients;
} UPACKED uvideo_color_matching_descriptor_t;

/*
 * Format and Frame descriptors
 */

#define UVIDEO_FRAME_CAP_STILL_IMAGE    1<<0
#define UVIDEO_FRAME_CAP_FIXED_RATE     1<<1

#define UVIDEO_FRAME_INTERVAL_CONTINUOUS 0

/* TODO: interlace flags */


typedef struct {
        uDWord          dwMinFrameInterval;
        uDWord          dwMaxFrameInterval;
        uDWord          dwFrameIntervalStep;
} UPACKED uvideo_frame_interval_continuous_t;

typedef struct {
        uDWord  dwFrameInterval[1]; /* length depends on bFrameIntervalType */
} UPACKED uvideo_frame_interval_discrete_t;

typedef union {
        uvideo_frame_interval_continuous_t      continuous;
        uvideo_frame_interval_discrete_t        discrete;
} uvideo_frame_interval_t;

/* generic format descriptor header */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFormatIndex;
} UPACKED uvideo_vs_format_descriptor_t;

/* generic frame descriptor header */
typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFrameIndex;
} UPACKED uvideo_vs_frame_descriptor_t;


/*  uncompressed format and frame descriptors */
static const guid_t uvideo_guid_format_yuy2 = {
        0x32595559,
        0x0000,
        0x0010,
        {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}
};

static const guid_t uvideo_guid_format_nv12 = {
        0x3231564E,
        0x0000,
        0x0010,
        {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}
};

static const guid_t uvideo_guid_format_uyvy = {
        0x59565955,
        0x0000,
        0x0010,
        {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}
};

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFormatIndex;
        uByte           bNumFrameDescriptors;
        usb_guid_t      guidFormat;
        uByte           bBitsPerPixel;
        uByte           bDefaultFrameIndex;
        uByte           bAspectRatioX;
        uByte           bAspectRatioY;
        uByte           bmInterlaceFlags;
        uByte           bCopyProtect;
} UPACKED uvideo_vs_format_uncompressed_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFrameIndex;
        uByte           bmCapabilities;
        uWord           wWidth;
        uWord           wHeight;
        uDWord          dwMinBitRate;
        uDWord          dwMaxBitRate;
        uDWord          dwMaxVideoFrameBufferSize;
        uDWord          dwDefaultFrameInterval;
        uByte           bFrameIntervalType;
        uvideo_frame_interval_t uFrameInterval;
} UPACKED uvideo_vs_frame_uncompressed_descriptor_t;


/* Frame based Format and Frame descriptors.  This is for generic
 * frame based payloads not covered by other types (e.g, uncompressed
 * or MJPEG). */

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFormatIndex;
        uByte           bNumFrameDescriptors;
        usb_guid_t      guidFormat;
        uByte           bBitsPerPixel;
        uByte           bDefaultFrameIndex;
        uByte           bAspectRatioX;
        uByte           bAspectRatioY;
        uByte           bmInterlaceFlags;
        uByte           bCopyProtect;
} UPACKED uvideo_format_frame_based_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFrameIndex;
        uByte           bmCapabilities;
        uWord           wWidth;
        uWord           wHeight;
        uDWord          dwMinBitRate;
        uDWord          dwMaxBitRate;
        uDWord          dwDefaultFrameInterval;
        uByte           bFrameIntervalType;
        uDWord          dwBytesPerLine;
        uvideo_frame_interval_t uFrameInterval;
} UPACKED uvideo_frame_frame_based_descriptor_t;


/* MJPEG format and frame descriptors */

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFormatIndex;
        uByte           bNumFrameDescriptors;
        uByte           bmFlags;
#define UVIDEO_NO_FIXED_SIZE_SAMPLES 0
#define UVIDEO_FIXED_SIZE_SAMPLES 1
        uByte           bDefaultFrameIndex;
        uByte           bAspectRatioX;
        uByte           bAspectRatioY;
        uByte           bmInterlaceFlags;
        uByte           bCopyProtect;
} UPACKED uvideo_vs_format_mjpeg_descriptor_t;

typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFrameIndex;
        uByte           bmCapabilities;
        uWord           wWidth;
        uWord           wHeight;
        uDWord          dwMinBitRate;
        uDWord          dwMaxBitRate;
        uDWord          dwMaxVideoFrameBufferSize;
        uDWord          dwDefaultFrameInterval;
        uByte           bFrameIntervalType;
        uvideo_frame_interval_t uFrameInterval;
} UPACKED uvideo_vs_frame_mjpeg_descriptor_t;


typedef struct {
        uByte           bLength;
        uByte           bDescriptorType;
        uByte           bDescriptorSubtype;
        uByte           bFormatIndex;
        uDWord          dwMaxVideoFrameBufferSize;
        uByte           bFormatType;
#define UVIDEO_GET_DV_FREQ(ubyte) (((ubyte)>>7) & 1)
#define UVIDEO_DV_FORMAT_FREQ_50HZ 0
#define UVIDEO_DV_FORMAT_FREQ_60HZ 1
#define UVIDEO_GET_DV_FORMAT(ubyte) ((ubyte) & 0x3f)
#define UVIDEO_DV_FORMAT_SD_DV  0
#define UVIDEO_DV_FORMAT_SDL_DV 1
#define UVIDEO_DV_FORMAT_HD_DV  2
} UPACKED uvideo_vs_format_dv_descriptor_t;



/*
 * Video Control requests
 */

/* Pseudo bitmasks that only work when bitwise OR onto a zeroed value */
#define UVIDEO_REQUEST_TYPE_INTERFACE           (0x0001)
#define UVIDEO_REQUEST_TYPE_ENDPOINT            (0x0010)
#define UVIDEO_REQUEST_TYPE_CLASS_SPECIFIC      (0x01 << 5)
#define UVIDEO_REQUEST_TYPE_SET                 (0x0 << 7)
#define UVIDEO_REQUEST_TYPE_GET                 (0x1 << 7)

typedef enum {
        UVIDEO_REQUEST_DESC_INTERFACE,
        UVIDEO_REQUEST_DESC_ENDPOINT
} uvideo_request_descriptor;

typedef enum {
        UR_RC_UNDEFINED = 0x00,
        UR_SET_CUR      = 0x01,
        UR_GET_CUR      = 0x81,
        UR_GET_MIN      = 0x82,
        UR_GET_MAX      = 0x83,
        UR_GET_RES      = 0x84,
        UR_GET_LEN      = 0x85,
        UR_GET_INFO     = 0x86,
        UR_GET_DEF      = 0x87,
} uvideo_request;

/* camera terminal control selectors */
#define UVIDEO_CT_CONTROL_UNDEFINED             0x00
#define UVIDEO_CT_SCANNING_MODE_CONTROL         0x01
#define UVIDEO_CT_AE_MODE_CONTROL               0x02
#define UVIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04
#define UVIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05
#define UVIDEO_CT_FOCUS_ABSOLUTE_CONTROL        0x06
#define UVIDEO_CT_FOCUS_RELATIVE_CONTROL        0x07
#define UVIDEO_CT_IRIS_ABSOLUTE_CONTROL         0x09
#define UVIDEO_CT_IRIS_RELATIVE_CONTROL         0x0A
#define UVIDEO_CT_ZOOM_ABSOLUTE_CONTROL         0x0B
#define UVIDEO_CT_ZOOM_RELATIVE_CONTROL         0x0C
#define UVIDEO_CT_PANTILT_ABSOLUTE_CONTROL      0x0D
#define UVIDEO_CT_PANTILT_RELATIVE_CONTROL      0x0E
#define UVIDEO_CT_ROLL_ABSOLUTE_CONTROL         0x0F
#define UVIDEO_CT_ROLL_RELATIVE_CONTROL         0x10
#define UVIDEO_CT_PRIVACY_CONTROL               0x11

/* processing unit control selectors */
#define UVIDEO_PU_CONTROL_UNDEFINED                     0x00
#define UVIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL        0x01
#define UVIDEO_PU_BRIGHTNESS_CONTROL                    0x02
#define UVIDEO_PU_CONTRAST_CONTROL                      0x03
#define UVIDEO_PU_GAIN_CONTROL                          0x04
#define UVIDEO_PU_POWER_LINE_FREQUENCY_CONTROL          0x05
#define UVIDEO_PU_HUE_CONTROL                           0x06
#define UVIDEO_PU_SATURATION_CONTROL                    0x07
#define UVIDEO_PU_SHARPNESS_CONTROL                     0x08
#define UVIDEO_PU_GAMMA_CONTROL                         0x09
#define UVIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL     0x0A
#define UVIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0B
#define UVIDEO_PU_WHITE_BALANCE_COMPONENT_CONTROL       0x0C
#define UVIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL  0x0D
#define UVIDEO_PU_DIGITAL_MULTIPLIER_CONTROL            0x0E
#define UVIDEO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL      0x0F
#define UVIDEO_PU_HUE_AUTO_CONTROL                      0x10
#define UVIDEO_PU_ANALOG_VIDEO_STANDARD_CONTROL         0x11
#define UVIDEO_PU_ANALOG_LOCK_STATUS_CONTROL            0x12

/* extension unit control selectors */
#define UVIDEO_XU_CONTROL_UNDEFINED     0x00

/* VideoStreaming Interface control selectors */
#define UVIDEO_VS_CONTROL_UNDEFINED             0x00
#define UVIDEO_VS_PROBE_CONTROL                 0x01
#define UVIDEO_VS_COMMIT_CONTROL                0x02
#define UVIDEO_VS_STILL_PROBE_CONTROL           0x03
#define UVIDEO_VS_STILL_COMMIT_CONTROL          0x04
#define UVIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL   0x05
#define UVIDEO_VS_STREAM_ERROR_CODE_CONTROL     0x06
#define UVIDEO_VS_GENERATE_KEY_FRAME_CONTROL    0x07
#define UVIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL  0x08
#define UVIDEO_VS_SYNCH_DELAY_CONTROL           0x09

/* bitmask result of GET_INFO on a control */
#define UVIDEO_CONTROL_INFO_SUPPORTS_GET        (1<<0)
#define UVIDEO_CONTROL_INFO_SUPPORTS_SET        (1<<1)
#define UVIDEO_CONTROL_INFO_DISABLED            (1<<2)
#define UVIDEO_CONTROL_INFO_AUTOUPDATE          (1<<3)
#define UVIDEO_CONTROL_INFO_ASYNC               (1<<4)


/* Video Probe and Commit Controls request data */
typedef struct {
        uWord           bmHint;
#define UVIDEO_HINT_FRAME_INTERVAL      (1<<0)
#define UVIDEO_HINT_KEYFRAME_RATE       (1<<1)
#define UVIDEO_HINT_PFRAME_RATE         (1<<2)
#define UVIDEO_HINT_COMP_QUALITY        (1<<3)
#define UVIDEO_HINT_COMP_WINDOW_SIZE    (1<<4)
        uByte           bFormatIndex;
        uByte           bFrameIndex;
        uDWord          dwFrameInterval;
#define UVIDEO_100NS_PER_MS 10000
#define UVIDEO_FRAME_INTERVAL_UNITS_PER_USB_FRAME UVIDEO_100NS_PER_MS
        uWord           wKeyFrameRate;
        uWord           wPFrameRate;
        uWord           wCompQuality;
        uWord           wCompWindowSize;
        uWord           wDelay;
        uDWord          dwMaxVideoFrameSize;
        uDWord          dwMaxPayloadTransferSize;
        /* Following fields are not in v1.0 of UVC.  Will have to do
         * UR_GET_LEN to discover the length of this descriptor. */
        uDWord          dwClockFrequency;
        uByte           bmFramingInfo;
#define UVIDEO_FRAMING_INFO_FID (1<<0)
#define UVIDEO_FRAMING_INFO_EOF (1<<1)
        uByte           bPreferedVersion;
        uByte           bMinVersion;
        uByte           bMaxVersion;
} UPACKED uvideo_probe_and_commit_data_t;

/* Video Still Probe and Still Commit Controls request data */
typedef struct {
        uByte           bFormatIndex;
        uByte           bFrameIndex;
        uByte           bCompressionIndex;
        uDWord          dwMaxVideoFrameSize;
        uDWord          dwMaxPayloadTransferSize;
} UPACKED uvideo_still_probe_and_still_commit_data_t;
#define UVIDEO_STILL_PROBE_AND_STILL_COMMIT_DATA_SIZE 11;



/* common header for Video Control and Video Stream status */
typedef struct {
        uByte           bStatusType;
#define UV_STATUS_TYPE_CONTROL  0x02
#define UV_STATUS_TYPE_STREAM   0x04
        uByte           bOriginator;
} UPACKED uvideo_status_t;

typedef struct {
        uByte           bStatusType;
        uByte           bOriginator;
        uByte           bEvent;
#define UV_CONTROL_CHANGE       0x00 /* any other value is Reserved */
        uByte           bSelector;
        uByte           bAttribute;
#define UV_CONTROL_VALUE_CHANGE         0x00
#define UV_CONTROL_INFO_CHANGE          0x01
#define UV_CONTROL_FAILURE_CHANGE       0x02
        uByte           bValue;
} UPACKED uvideo_control_status_t;

typedef struct {
        uByte           bStatusType;
        uByte           bOriginator;
        uByte           bEvent;
#define UV_BUTTON_PRESS 0x00 /* any other value is Stream Error */
        uByte           bValue;
#define UV_BUTTON_RELEASED      0x00
#define UV_BUTTON_PRESSED       0x01
} UPACKED uvideo_streaming_status_t;

typedef struct {
        uByte           bHeaderLength;
        uByte           bmHeaderInfo;
#define UV_FRAME_ID     1<<0
#define UV_END_OF_FRAME 1<<1
#define UV_PRES_TIME    1<<2
#define UV_SRC_CLOCK    1<<3
/* D4: Reserved */
#define UV_STILL_IMAGE  1<<5
#define UV_ERROR        1<<6
#define UV_END_OF_HDR   1<<7
/* other fields depend on which bits are set above and have no fixed offset */
/*      uDWord          dwPresentationTime; */
#define UVIDEO_PTS_SIZE 4
/*      uByte           scrSourceClock[UVIDEO_SOURCE_CLOCK_SIZE]; */
#define UVIDEO_SOURCE_CLOCK_SIZE 6
#define UV_GET_SOURCE_TIME_CLOCK(sc) (UGETDW(sc))
/* bits 42..32 */
#define UV_GET_SOF_COUNTER(sc) (((sc)[4] | ((sc)[5] << 8)) &0x7ff)
} UPACKED uvideo_payload_header_t;

/* Note: this might be larger depending on presence of source clock,
   SOF counter, or other things... bHeaderLength is actual length. */
#define UVIDEO_PAYLOAD_HEADER_SIZE 12