#ifndef USBVideo1_h
#define USBVideo1_h

#define USB_VIDEO                           0xe

#define USB_VIDEO_UNDEFINED_SUBCLASS        0
#define USB_VIDEO_CONTROL_SUBCLASS          1
#define USB_VIDEO_STREAMING_SUBCLASS        2
#define USB_VIDEO_INTERFACE_COLLECTION      3

#define USB_VIDEO_PROTOCOL                  0

#define USB_VIDEO_CS_CONTROL                ((USB_VIDEO << 16) | (USB_VIDEO_CONTROL_SUBCLASS << 8) )
#define USB_VIDEO_CS_STREAMING              ((USB_VIDEO << 16) | (USB_VIDEO_STREAMING_SUBCLASS << 8) )

typedef __packed struct
{
    USB_DescriptorSubBase;
            #define     USB_VIDEO_SI_INPUT_HEADER           1
    uint8_t         bNumFormats;
    uint16_t        wTotalLength;
    uint8_t         bEndpointAddress;
    uint8_t         bmInfo;
    uint8_t         bTerminalLink;
    uint8_t         bStillCaptureMethod;
    uint8_t         bTriggerSupport;
    uint8_t         bTriggerUsage;
    uint8_t         bControlSize;
    uint8_t         bmaControls[];
} USBVideo_SI_InputHeader;

#define USBVideo_SI_IH_bmaControlCount(inputheader) ((((inputheader)->bLength) -  \
                   (&(inputheader)->bmaControls[0] - ((uint8_t*)(inputheader)))) /  (inputheader)->bControlSize)
                   
typedef __packed struct
{
    USB_DescriptorSubBase;
            #define     USB_VIDEO_SI_OUTPUT_HEADER          2
    uint8_t         bNumFormats;
    uint16_t        wTotalLength;
    uint8_t         bEndpointAddress;
    uint8_t         bmInfo;
    uint8_t         bTerminalLink;
    uint8_t         bControlSize;
    uint8_t*        bmaControls[];
} USBVideo_SI_OutputHeader;



typedef __packed struct
{
    USB_DescriptorSubBase;
            #define     USB_VIDEO_SI_STILL_IMAGE_FRAME      3
    uint8_t         bEndpointAddress;
    uint8_t         bNumImageSizePatterns;
    __packed struct 
    {
        uint16_t    wWidth;
        uint16_t    wHeight;
    } dim[];   
} USBVideo_SI_StillImageFrame;

typedef __packed struct
{
    uint8_t         bNumCompressionPattern;
    uint8_t         bCompression[];
} USBVideo_SI_StillImageFrame1;

#define USBVideo_SI_StillImageFrame1Ptr(framePtr) ((USBVideo_SI_StillImageFrame1*) \
                    (((char*)&framePtr->dim[0]) + \
                    framePtr->bNumImageSizePatterns * sizeof (framePtr->dim[0]))

typedef __packed struct
{
    USB_DescriptorSubBase;
            #define     USB_VIDEO_SI_FORMAT_UNCOMPRESSED    4
    uint8_t         bFormatIndex;
    uint8_t         bNumFrameDescriptors;
    uint8_t         guidFormat[16];
    uint8_t         bBitsPerPixel;
    uint8_t         bDefaultFrameIndex;
    uint8_t         bAspectRatioX;
    uint8_t         bAspectRatioY;
    uint8_t         bmInterfaceFlags;
    uint8_t         bCopyProtect;
} USBVideo_SI_FormatUncompressed;

typedef __packed struct
{
    USB_DescriptorSubBase;
            #define     USB_VIDEO_SI_FRAME_UNCOMPRESSED     5
    uint8_t         bFrameIndex;
    uint8_t         bmCapabilities;
    uint16_t        wWidth;
    uint16_t        wHeight;
    uint32_t        dwMinBitRate;
    uint32_t        dwMaxBitRate;
    uint32_t        dwMaxVideoFrameBufferSize;
    uint32_t        dwDefaultFrameInterval;
    uint8_t         bFrameIntervalType; /* if 0 this is followed by
                                           USBVideo_SI_FrameUncompressedContiguous */
    uint32_t        dwFrameInterval[];
} USBVideo_SI_FrameUncompressed;

typedef __packed struct
{
    uint32_t        dwMinFrameInterval;
    uint32_t        dwMaxFrameInterval;
    uint32_t        dwFrameIntervalStep;
} USBVideo_SI_FrameUncompressedContiguous;


#endif
