uvc攝像頭代碼解析之描述符

1.uvc驅動模塊入口

  1. module_init(uvc_init);  //1.模塊入口  
module_init(uvc_init); //1.模塊入口

2.初始化函數

  1. static int __init uvc_init(void)    // 2.初始化函數  
  2. {  
  3.     int result;  
  4.     result = usb_register(&uvc_driver.driver);  // 3.註冊usb設備驅動(usb攝像頭設備)  
  5.     if (result == 0)    //註冊失敗  
  6.         printk(KERN_INFO DRIVER_DESC ” (“ DRIVER_VERSION “)\n”);  
  7.     return result;  
  8. }  
static int __init uvc_init(void) // 2.初始化函數
{
    int result;
    result = usb_register(&uvc_driver.driver);  // 3.註冊usb設備驅動(usb攝像頭設備)
    if (result == 0)    //註冊失敗
        printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
    return result;
}

3.註冊usb設備驅動(usb攝像頭設備)

3.1 usb攝像頭驅動

  1. struct uvc_driver uvc_driver = {    // 3.1 usb攝像頭設備  
  2.     .driver = {  
  3.         .name       = ”uvcvideo”,  
  4.         .probe      = uvc_probe,    // 4. probe方法  
  5.         .disconnect = uvc_disconnect,  
  6.         .suspend    = uvc_suspend,  
  7.         .resume     = uvc_resume,  
  8.         .reset_resume   = uvc_reset_resume,  
  9.         .id_table   = uvc_ids,      //3.2 支持的設備id列表  
  10.         .supports_autosuspend = 1,  
  11.     },  
  12. };  
struct uvc_driver uvc_driver = {    // 3.1 usb攝像頭設備
    .driver = {
        .name       = "uvcvideo",
        .probe      = uvc_probe,    // 4. probe方法
        .disconnect = uvc_disconnect,
        .suspend    = uvc_suspend,
        .resume     = uvc_resume,
        .reset_resume   = uvc_reset_resume,
        .id_table   = uvc_ids,      //3.2 支持的設備id列表
        .supports_autosuspend = 1,
    },
};

3.2 支持的設備id列表uvc_ids

  1. static struct usb_device_id uvc_ids[] = {  
  2.     /* Genius eFace 2025 */  
  3.     { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,  
  4.       .idVendor     = 0x0458,  
  5.       .idProduct        = 0x706e,  
  6.       .bInterfaceClass  = USB_CLASS_VIDEO,  //uvc接口類 0x0e  
  7.       .bInterfaceSubClass   = 1,  
  8.       .bInterfaceProtocol   = 0,  
  9.       .driver_info      = UVC_QUIRK_PROBE_MINMAX },  
  10.     …  
  11.     …  
  12.     …  
  13.     /* SiGma Micro USB Web Camera */  
  14.     { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,  
  15.       .idVendor     = 0x1c4f,  
  16.       .idProduct        = 0x3000,  
  17.       .bInterfaceClass  = USB_CLASS_VIDEO,  
  18.       .bInterfaceSubClass   = 1,  
  19.       .bInterfaceProtocol   = 0,  
  20.       .driver_info      = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT },  
  21.     /* Generic USB Video Class */   //通用usb視頻類  
  22.     { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },  //匹配方法:uvc類  
  23.     {}  
  24. };  
static struct usb_device_id uvc_ids[] = {
    /* Genius eFace 2025 */
    { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
      .idVendor     = 0x0458,
      .idProduct        = 0x706e,
      .bInterfaceClass  = USB_CLASS_VIDEO,  //uvc接口類 0x0e
      .bInterfaceSubClass   = 1,
      .bInterfaceProtocol   = 0,
      .driver_info      = UVC_QUIRK_PROBE_MINMAX },
    ...
    ...
    ...
    /* SiGma Micro USB Web Camera */
    { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
      .idVendor     = 0x1c4f,
      .idProduct        = 0x3000,
      .bInterfaceClass  = USB_CLASS_VIDEO,
      .bInterfaceSubClass   = 1,
      .bInterfaceProtocol   = 0,
      .driver_info      = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
    /* Generic USB Video Class */   //通用usb視頻類
    { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },  //匹配方法:uvc類
    {}
};

4.probe方法

  1. static int uvc_probe(struct usb_interface *intf,const struct usb_device_id *id)  
  2. {  
  3.     struct usb_device *udev = interface_to_usbdev(intf);    //通過usb接口獲取usb設備  
  4.     struct uvc_device *dev; //聲明uvc設備  
  5.     int ret;  
  6.     if (id->idVendor && id->idProduct)    //有廠商id和商品id(知名設備)  
  7.         uvc_trace(UVC_TRACE_PROBE, ”Probing known UVC device %s (%04x:%04x)\n”, udev->devpath, id->idVendor,id->idProduct);  
  8.     else                                //通用uvc設備  
  9.         uvc_trace(UVC_TRACE_PROBE, ”Probing generic UVC device %s\n”,udev->devpath);  
  10.     /* Allocate memory for the device and initialize it. */  
  11.     if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)   //分配uvc設備內存  
  12.         return -ENOMEM;  
  13.     INIT_LIST_HEAD(&dev->entities);  //初始化entities(實體)鏈表 Terminal或Unit  
  14.     INIT_LIST_HEAD(&dev->chains);    //初始化chains(鏈)鏈表  
  15.     INIT_LIST_HEAD(&dev->streams);   //初始化streams(視頻流)鏈表  
  16.     atomic_set(&dev->nstreams, 0);  
  17.     atomic_set(&dev->users, 0);  
  18.     atomic_set(&dev->nmappings, 0);  
  19.     dev->udev = usb_get_dev(udev);   //捆綁usb設備,並增加其引用計數  
  20.     dev->intf = usb_get_intf(intf);  //捆綁usb接口,並增加其引用計數  
  21.     dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;    //獲取usb接口描述符接口數  
  22.     dev->quirks = (uvc_quirks_param == -1) ? id->driver_info : uvc_quirks_param;  
  23.     if (udev->product != NULL)   //存在產品名  
  24.         strlcpy(dev->name, udev->product, sizeof dev->name);   //設置uvc設備名字爲其產品名  
  25.     else                        //通用的uvc設備名  
  26.         snprintf(dev->name, sizeof dev->name,“UVC Camera (%04x:%04x)”,le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));  
  27.     /* Parse the Video Class control descriptor. */  
  28.     if (uvc_parse_control(dev) < 0) {    //–>5 uvc解析usb視頻類控制描述符  
  29.         uvc_trace(UVC_TRACE_PROBE, ”Unable to parse UVC descriptors.\n”);  
  30.         goto error;  
  31.     }  
  32.     uvc_printk(KERN_INFO, ”Found UVC %u.%02x device %s (%04x:%04x)\n”,dev->uvc_version >> 8, dev->uvc_version & 0xff,  
  33.         udev->product ? udev->product : ”<unnamed>”,le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));  
  34.     if (dev->quirks != id->driver_info) {  
  35.         uvc_printk(KERN_INFO, ”Forcing device quirks to 0x%x by module parameter for testing purpose.\n”, dev->quirks);  
  36.         uvc_printk(KERN_INFO, ”Please report required quirks to the linux-uvc-devel mailing list.\n”);  
  37.     }  
  38.     /* Initialize controls. */  
  39.     if (uvc_ctrl_init_device(dev) < 0)   //8.uvc初始化控制  
  40.         goto error;  
  41.     /* Scan the device for video chains. */  
  42.     if (uvc_scan_device(dev) < 0)    //10.uvc掃描視頻鏈  
  43.         goto error;  
  44.     /* Register video devices. */  
  45.     if (uvc_register_chains(dev) < 0)    //11.uvc註冊視頻設備  
  46.         goto error;  
  47.     /* Save our data pointer in the interface data. */  
  48.     usb_set_intfdata(intf, dev);    //設置uvc設備爲usb接口的數據  
  49.     /* Initialize the interrupt URB. */  
  50.     if ((ret = uvc_status_init(dev)) < 0) {  //12 uvc設備狀態初始化  
  51.         uvc_printk(KERN_INFO, ”Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n”, ret);  
  52.     }  
  53.     uvc_trace(UVC_TRACE_PROBE, ”UVC device initialized.\n”);  
  54.     usb_enable_autosuspend(udev);   //使能自動掛起  
  55.     return 0;  
  56. error:  
  57.     uvc_unregister_video(dev);  
  58.     return -ENODEV;  
  59. }  
static int uvc_probe(struct usb_interface *intf,const struct usb_device_id *id)
{
    struct usb_device *udev = interface_to_usbdev(intf);    //通過usb接口獲取usb設備
    struct uvc_device *dev; //聲明uvc設備
    int ret;
    if (id->idVendor && id->idProduct)    //有廠商id和商品id(知名設備)
        uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s (%04x:%04x)\n", udev->devpath, id->idVendor,id->idProduct);
    else                                //通用uvc設備
        uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",udev->devpath);
    /* Allocate memory for the device and initialize it. */
    if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)   //分配uvc設備內存
        return -ENOMEM;
    INIT_LIST_HEAD(&dev->entities);  //初始化entities(實體)鏈表 Terminal或Unit
    INIT_LIST_HEAD(&dev->chains);    //初始化chains(鏈)鏈表
    INIT_LIST_HEAD(&dev->streams);   //初始化streams(視頻流)鏈表
    atomic_set(&dev->nstreams, 0);
    atomic_set(&dev->users, 0);
    atomic_set(&dev->nmappings, 0);
    dev->udev = usb_get_dev(udev);   //捆綁usb設備,並增加其引用計數
    dev->intf = usb_get_intf(intf);  //捆綁usb接口,並增加其引用計數
    dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;    //獲取usb接口描述符接口數
    dev->quirks = (uvc_quirks_param == -1) ? id->driver_info : uvc_quirks_param;
    if (udev->product != NULL)   //存在產品名
        strlcpy(dev->name, udev->product, sizeof dev->name);   //設置uvc設備名字爲其產品名
    else                        //通用的uvc設備名
        snprintf(dev->name, sizeof dev->name,"UVC Camera (%04x:%04x)",le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));
    /* Parse the Video Class control descriptor. */
    if (uvc_parse_control(dev) < 0) {    //-->5 uvc解析usb視頻類控制描述符
        uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC descriptors.\n");
        goto error;
    }
    uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",dev->uvc_version >> 8, dev->uvc_version & 0xff,
        udev->product ? udev->product : "<unnamed>",le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));
    if (dev->quirks != id->driver_info) {
        uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module parameter for testing purpose.\n", dev->quirks);
        uvc_printk(KERN_INFO, "Please report required quirks to the linux-uvc-devel mailing list.\n");
    }
    /* Initialize controls. */
    if (uvc_ctrl_init_device(dev) < 0)   //8.uvc初始化控制
        goto error;
    /* Scan the device for video chains. */
    if (uvc_scan_device(dev) < 0)    //10.uvc掃描視頻鏈
        goto error;
    /* Register video devices. */
    if (uvc_register_chains(dev) < 0)    //11.uvc註冊視頻設備
        goto error;
    /* Save our data pointer in the interface data. */
    usb_set_intfdata(intf, dev);    //設置uvc設備爲usb接口的數據
    /* Initialize the interrupt URB. */
    if ((ret = uvc_status_init(dev)) < 0) {  //12 uvc設備狀態初始化
        uvc_printk(KERN_INFO, "Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n", ret);
    }
    uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
    usb_enable_autosuspend(udev);   //使能自動掛起
    return 0;
error:
    uvc_unregister_video(dev);
    return -ENODEV;
}

4.1 uvc設備結構體

  1. struct uvc_device {  
  2.     struct usb_device *udev;    //usb設備指針  
  3.     struct usb_interface *intf; //usb接口指針  
  4.     unsigned long warnings;  
  5.     __u32 quirks;  
  6.     int intfnum;    //接口數  
  7.     char name[32];  //設備名  
  8.     enum uvc_device_state state;    //uvc設備狀態  
  9.     atomic_t users;  
  10.     atomic_t nmappings;  
  11.     /* Video control interface */  
  12.     __u16 uvc_version;  //UVC協議版本  
  13.     __u32 clock_frequency;  //時鐘頻率  
  14.     struct list_head entities;  //uvc實體鏈表頭(掛着uvc設備的Terminal和Unit)  
  15.     struct list_head chains;    //uvc視頻鏈鏈表頭  
  16.     /* Video Streaming interfaces */  
  17.     struct list_head streams;   //uvc視頻流鏈表頭  
  18.     atomic_t nstreams;//uvc視頻流個數  
  19.     /* Status Interrupt Endpoint */  
  20.     struct usb_host_endpoint *int_ep;   //usb_host_endpoint對象  
  21.     struct urb *int_urb;    //中斷urb  
  22.     __u8 *status;   //uvc設備狀態標誌  
  23.     struct input_dev *input;    //輸入設備  
  24.     char input_phys[64];    //輸入設備設備節點路徑  
  25. };  
struct uvc_device {
    struct usb_device *udev;    //usb設備指針
    struct usb_interface *intf; //usb接口指針
    unsigned long warnings;
    __u32 quirks;
    int intfnum;    //接口數
    char name[32];  //設備名
    enum uvc_device_state state;    //uvc設備狀態
    atomic_t users;
    atomic_t nmappings;
    /* Video control interface */
    __u16 uvc_version;  //UVC協議版本
    __u32 clock_frequency;  //時鐘頻率
    struct list_head entities;  //uvc實體鏈表頭(掛着uvc設備的Terminal和Unit)
    struct list_head chains;    //uvc視頻鏈鏈表頭
    /* Video Streaming interfaces */
    struct list_head streams;   //uvc視頻流鏈表頭
    atomic_t nstreams;//uvc視頻流個數
    /* Status Interrupt Endpoint */
    struct usb_host_endpoint *int_ep;   //usb_host_endpoint對象
    struct urb *int_urb;    //中斷urb
    __u8 *status;   //uvc設備狀態標誌
    struct input_dev *input;    //輸入設備
    char input_phys[64];    //輸入設備設備節點路徑
};

4.2 uvc協議標準上的描述符佈局

  1. –>(Interface Association Descript)IDA接口描述符  
  2. –>標準VC接口描述符 ——————————–VC(video control)  
  3.     –>uvc類視頻接口描述符(header)–>輸入Terminal接口描述符–>處理Unit接口描述符–>編碼Unit接口描述符–>輸出Terminal接口描述符  
  4. –>標準中斷端點描述符  
  5.     –>uvc類中斷端點描述符  
  6. –>標準VS接口描述符 ——————————–VS(video streaming) Alt.Setting 0  
  7.     –>uvc類視頻接口描述符(header)–>format負荷格式描述符–>若干frame–>靜態圖像幀格式描述符  
  8.     –>uvc類視頻接口描述符(header)–>format負荷格式描述符–>若干frame–>靜態圖像幀格式描述符->顏色匹配描述符  
  9.     …(1…n)  
  10.     –>Bulk-in 靜態圖像數據端點描述符  
  11. –>標準VS接口描述符 ——————————–VS(video streaming) Alt.Setting 1  
  12.     –>標準同步輸入視頻端點描述符  
  13.     –>Bulk-in 靜態圖像數據端點描述符  
  14. …(1…n)  
  15. –>標準VS接口描述符 ——————————–VS(video streaming) Alt.Setting n  
  16.     –>標準同步輸入視頻端點描述符  
  17.     –>Bulk-in 靜態圖像數據端點描述符  
-->(Interface Association Descript)IDA接口描述符
-->標準VC接口描述符 --------------------------------VC(video control)
    -->uvc類視頻接口描述符(header)-->輸入Terminal接口描述符-->處理Unit接口描述符-->編碼Unit接口描述符-->輸出Terminal接口描述符
-->標準中斷端點描述符
    -->uvc類中斷端點描述符
-->標準VS接口描述符 --------------------------------VS(video streaming) Alt.Setting 0
    -->uvc類視頻接口描述符(header)-->format負荷格式描述符-->若干frame-->靜態圖像幀格式描述符
    -->uvc類視頻接口描述符(header)-->format負荷格式描述符-->若干frame-->靜態圖像幀格式描述符->顏色匹配描述符
    ...(1...n)
    -->Bulk-in 靜態圖像數據端點描述符
-->標準VS接口描述符 --------------------------------VS(video streaming) Alt.Setting 1
    -->標準同步輸入視頻端點描述符
    -->Bulk-in 靜態圖像數據端點描述符
...(1...n)
-->標準VS接口描述符 --------------------------------VS(video streaming) Alt.Setting n
    -->標準同步輸入視頻端點描述符
    -->Bulk-in 靜態圖像數據端點描述符

這些佈局是可變的 但大體佈局是這樣,下面兩張圖也是典型的佈局


具體分析的時候可以利用lsubs工具打印所有描述符來分析

usb描述符的框架圖

輸入命令lsusb -d 0c45:62f1 -v

  1. Bus 001 Device 002: ID 0c45:62f1 Microdia   //總線 設備ID  
  2. Device Descriptor:                          //設備描述符  
  3.   bLength                18  
  4.   bDescriptorType         1  
  5.   bcdUSB               2.00  
  6.   bDeviceClass          239 Miscellaneous Device  
  7.   bDeviceSubClass         2 ?  
  8.   bDeviceProtocol         1 Interface Association  
  9.   bMaxPacketSize0        64  
  10.   idVendor           0x0c45 Microdia  
  11.   idProduct          0x62f1   
  12.   bcdDevice            1.00  
  13.   iManufacturer           2 Sonix Technology Co., Ltd.  
  14.   iProduct                1 USB 2.0 Camera  
  15.   iSerial                 0   
  16.   bNumConfigurations      1  
  17.   Configuration Descriptor:                 //配置描述符  
  18.     bLength                 9  
  19.     bDescriptorType         2  
  20.     wTotalLength          697  
  21.     bNumInterfaces          4  
  22.     bConfigurationValue     1  
  23.     iConfiguration          0   
  24.     bmAttributes         0x80  
  25.       (Bus Powered)  
  26.     MaxPower              500mA  
  27.     Interface Association:                  //3.6 Interface Association Descriptor   
  28.       bLength                 8  
  29.       bDescriptorType        11  
  30.       bFirstInterface         0  
  31.       bInterfaceCount         2  
  32.       bFunctionClass         14 Video  
  33.       bFunctionSubClass       3 Video Interface Collection  
  34.       bFunctionProtocol       0   
  35.       iFunction               5 USB Camera  
  36.     Interface Descriptor:                   //Table 3-2 Standard VC Interface Descriptor  
  37.       bLength                 9  
  38.       bDescriptorType         4  
  39.       bInterfaceNumber        0  
  40.       bAlternateSetting       0  
  41.       bNumEndpoints           1  
  42.       bInterfaceClass        14 Video  
  43.       bInterfaceSubClass      1 Video Control  
  44.       bInterfaceProtocol      0   
  45.       iInterface              5 USB Camera  
  46.       VideoControl Interface Descriptor:    //Table 3-3 Class-specific VC Interface Header Descriptor  
  47.         bLength                13  
  48.         bDescriptorType        36  
  49.         bDescriptorSubtype      1 (HEADER)    
  50.         bcdUVC               1.00  
  51.         wTotalLength          103  
  52.         dwClockFrequency       15.000000MHz  
  53.         bInCollection           1  
  54.         baInterfaceNr( 0)       1  
  55.       VideoControl Interface Descriptor:    //Table 3-5 Output Terminal Descriptor  
  56.         bLength                 9  
  57.         bDescriptorType        36  
  58.         bDescriptorSubtype      3 (OUTPUT_TERMINAL)  
  59.         bTerminalID             2  
  60.         wTerminalType      0x0101 USB Streaming  
  61.         bAssocTerminal          0  
  62.         bSourceID               5  
  63.         iTerminal               0   
  64.       VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor  
  65.         bLength                26  
  66.         bDescriptorType        36  
  67.         bDescriptorSubtype      6 (EXTENSION_UNIT)  
  68.         bUnitID                 4  
  69.         guidExtensionCode         {7033f028-1163-2e4a-ba2c-6890eb334016}  
  70.         bNumControl             8  
  71.         bNrPins                 1  
  72.         baSourceID( 0)          3  
  73.         bControlSize            1  
  74.         bmControls( 0)       0x0f  
  75.         iExtension              0   
  76.       VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor  
  77.         bLength                26  
  78.         bDescriptorType        36  
  79.         bDescriptorSubtype      6 (EXTENSION_UNIT)  
  80.         bUnitID                 5  
  81.         guidExtensionCode         {3fae1228-d7bc-114e-a357-6f1edef7d61d}  
  82.         bNumControl             8  
  83.         bNrPins                 1  
  84.         baSourceID( 0)          4  
  85.         bControlSize            1  
  86.         bmControls( 0)       0xff  
  87.         iExtension              0   
  88.       VideoControl Interface Descriptor:    //Table 3-6 Camera Terminal Descriptor  
  89.         bLength                18  
  90.         bDescriptorType        36  
  91.         bDescriptorSubtype      2 (INPUT_TERMINAL)  
  92.         bTerminalID             1  
  93.         wTerminalType      0x0201 Camera Sensor  
  94.         bAssocTerminal          0  
  95.         iTerminal               0   
  96.         wObjectiveFocalLengthMin      0  
  97.         wObjectiveFocalLengthMax      0  
  98.         wOcularFocalLength            0  
  99.         bControlSize                  3  
  100.         bmControls           0x00000000  
  101.       VideoControl Interface Descriptor:    //Table 3-8 Processing Unit Descriptor  
  102.         bLength                11  
  103.         bDescriptorType        36  
  104.         bDescriptorSubtype      5 (PROCESSING_UNIT)  
  105.       Warning: Descriptor too short  
  106.         bUnitID                 3  
  107.         bSourceID               1  
  108.         wMaxMultiplier          0  
  109.         bControlSize            2  
  110.         bmControls     0x0000053f  
  111.           Brightness  
  112.           Contrast  
  113.           Hue  
  114.           Saturation  
  115.           Sharpness  
  116.           Gamma  
  117.           Backlight Compensation  
  118.           Power Line Frequency  
  119.         iProcessing             0   
  120.         bmVideoStandards     0x 0  
  121.       Endpoint Descriptor:                  //Table 3-11 Standard VC Interrupt Endpoint Descriptor  
  122.         bLength                 7  
  123.         bDescriptorType         5  
  124.         bEndpointAddress     0x83  EP 3 IN  
  125.         bmAttributes            3  
  126.           Transfer Type            Interrupt  
  127.           Synch Type               None  
  128.           Usage Type               Data  
  129.         wMaxPacketSize     0x0010  1x 16 bytes  
  130.         bInterval               6  
  131.     Interface Descriptor:                   //Table 3-13 Standard VS Interface Descriptor  
  132.       bLength                 9  
  133.       bDescriptorType         4  
  134.       bInterfaceNumber        1  
  135.       bAlternateSetting       0  
  136.       bNumEndpoints           0  
  137.       bInterfaceClass        14 Video  
  138.       bInterfaceSubClass      2 Video Streaming  
  139.       bInterfaceProtocol      0   
  140.       iInterface              0   
  141.       VideoStreaming Interface Descriptor:      //Table 3-14 Class-specific VS Interface Input Header Descriptor  
  142.         bLength                            14  
  143.         bDescriptorType                    36  
  144.         bDescriptorSubtype                  1 (INPUT_HEADER)  
  145.         bNumFormats                         1  
  146.         wTotalLength                      323  
  147.         bEndPointAddress                  129  
  148.         bmInfo                              0  
  149.         bTerminalLink                       2  
  150.         bStillCaptureMethod                 2  
  151.         bTriggerSupport                     1  
  152.         bTriggerUsage                       1  
  153.         bControlSize                        1  
  154.         bmaControls( 0)                    27  
  155.       VideoStreaming Interface Descriptor:      //Table 3-1 Uncompressed Video Format Descriptor  
  156.         bLength                            27  
  157.         bDescriptorType                    36  
  158.         bDescriptorSubtype                  4 (FORMAT_UNCOMPRESSED)  
  159.         bFormatIndex                        1  
  160.         bNumFrameDescriptors                5  
  161.         guidFormat                            {59555932-0000-1000-8000-00aa00389b71}  
  162.         bBitsPerPixel                      16  
  163.         bDefaultFrameIndex                  1  
  164.         bAspectRatioX                       0  
  165.         bAspectRatioY                       0  
  166.         bmInterlaceFlags                 0x00  
  167.           Interlaced stream or variable: No  
  168.           Fields per frame: 1 fields  
  169.           Field 1 first: No  
  170.           Field pattern: Field 1 only  
  171.           bCopyProtect                      0  
  172.       VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
  173.         bLength                            50  
  174.         bDescriptorType                    36  
  175.         bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
  176.         bFrameIndex                         1  
  177.         bmCapabilities                   0x00  
  178.           Still image unsupported  
  179.         wWidth                            640  
  180.         wHeight                           480  
  181.         dwMinBitRate                 24576000  
  182.         dwMaxBitRate                147456000  
  183.         dwMaxVideoFrameBufferSize      614400  
  184.         dwDefaultFrameInterval         333333  
  185.         bFrameIntervalType                  6  
  186.         dwFrameInterval( 0)            333333  
  187.         dwFrameInterval( 1)            400000  
  188.         dwFrameInterval( 2)            500000  
  189.         dwFrameInterval( 3)            666666  
  190.         dwFrameInterval( 4)           1000000  
  191.         dwFrameInterval( 5)           2000000  
  192.       VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
  193.         bLength                            50  
  194.         bDescriptorType                    36  
  195.         bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
  196.         bFrameIndex                         2  
  197.         bmCapabilities                   0x00  
  198.           Still image unsupported  
  199.         wWidth                            352  
  200.         wHeight                           288  
  201.         dwMinBitRate                  8110080  
  202.         dwMaxBitRate                 48660480  
  203.         dwMaxVideoFrameBufferSize      202752  
  204.         dwDefaultFrameInterval         333333  
  205.         bFrameIntervalType                  6  
  206.         dwFrameInterval( 0)            333333  
  207.         dwFrameInterval( 1)            400000  
  208.         dwFrameInterval( 2)            500000  
  209.         dwFrameInterval( 3)            666666  
  210.         dwFrameInterval( 4)           1000000  
  211.         dwFrameInterval( 5)           2000000  
  212.       VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
  213.         bLength                            50  
  214.         bDescriptorType                    36  
  215.         bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
  216.         bFrameIndex                         3  
  217.         bmCapabilities                   0x00  
  218.           Still image unsupported  
  219.         wWidth                            320  
  220.         wHeight                           240  
  221.         dwMinBitRate                  6144000  
  222.         dwMaxBitRate                 36864000  
  223.         dwMaxVideoFrameBufferSize      153600  
  224.         dwDefaultFrameInterval         333333  
  225.         bFrameIntervalType                  6  
  226.         dwFrameInterval( 0)            333333  
  227.         dwFrameInterval( 1)            400000  
  228.         dwFrameInterval( 2)            500000  
  229.         dwFrameInterval( 3)            666666  
  230.         dwFrameInterval( 4)           1000000  
  231.         dwFrameInterval( 5)           2000000  
  232.       VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
  233.         bLength                            50  
  234.         bDescriptorType                    36  
  235.         bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
  236.         bFrameIndex                         4  
  237.         bmCapabilities                   0x00  
  238.           Still image unsupported  
  239.         wWidth                            176  
  240.         wHeight                           144  
  241.         dwMinBitRate                  2027520  
  242.         dwMaxBitRate                 12165120  
  243.         dwMaxVideoFrameBufferSize       50688  
  244.         dwDefaultFrameInterval         333333  
  245.         bFrameIntervalType                  6  
  246.         dwFrameInterval( 0)            333333  
  247.         dwFrameInterval( 1)            400000  
  248.         dwFrameInterval( 2)            500000  
  249.         dwFrameInterval( 3)            666666  
  250.         dwFrameInterval( 4)           1000000  
  251.         dwFrameInterval( 5)           2000000  
  252.       VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
  253.         bLength                            50  
  254.         bDescriptorType                    36  
  255.         bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
  256.         bFrameIndex                         5  
  257.         bmCapabilities                   0x00  
  258.           Still image unsupported  
  259.         wWidth                            160  
  260.         wHeight                           120  
  261.         dwMinBitRate                  1536000  
  262.         dwMaxBitRate                  9216000  
  263.         dwMaxVideoFrameBufferSize       38400  
  264.         dwDefaultFrameInterval         333333  
  265.         bFrameIntervalType                  6  
  266.         dwFrameInterval( 0)            333333  
  267.         dwFrameInterval( 1)            400000  
  268.         dwFrameInterval( 2)            500000  
  269.         dwFrameInterval( 3)            666666  
  270.         dwFrameInterval( 4)           1000000  
  271.         dwFrameInterval( 5)           2000000  
  272.       VideoStreaming Interface Descriptor:      //Table 3-18 Still Image Frame Descriptor  
  273.         bLength                            26  
  274.         bDescriptorType                    36  
  275.         bDescriptorSubtype                  3 (STILL_IMAGE_FRAME)  
  276.         bEndpointAddress                    0  
  277.         bNumImageSizePatterns               5  
  278.         wWidth( 0)                        640  
  279.         wHeight( 0)                       480  
  280.         wWidth( 1)                        352  
  281.         wHeight( 1)                       288  
  282.         wWidth( 2)                        320  
  283.         wHeight( 2)                       240  
  284.         wWidth( 3)                        176  
  285.         wHeight( 3)                       144  
  286.         wWidth( 4)                        160  
  287.         wHeight( 4)                       120  
  288.         bNumCompressionPatterns             5  
  289.       VideoStreaming Interface Descriptor:      //Table 3-19 Color Matching Descriptor  
  290.         bLength                             6  
  291.         bDescriptorType                    36  
  292.         bDescriptorSubtype                 13 (COLORFORMAT)  
  293.         bColorPrimaries                     1 (BT.709,sRGB)  
  294.         bTransferCharacteristics            1 (BT.709)  
  295.         bMatrixCoefficients                 4 (SMPTE 170M (BT.601))  
  296.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  297.       bLength                 9  
  298.       bDescriptorType         4  
  299.       bInterfaceNumber        1  
  300.       bAlternateSetting       1  
  301.       bNumEndpoints           1  
  302.       bInterfaceClass        14 Video  
  303.       bInterfaceSubClass      2 Video Streaming  
  304.       bInterfaceProtocol      0   
  305.       iInterface              0   
  306.       Endpoint Descriptor:  
  307.         bLength                 7  
  308.         bDescriptorType         5  
  309.         bEndpointAddress     0x81  EP 1 IN  
  310.         bmAttributes            5  
  311.           Transfer Type            Isochronous  
  312.           Synch Type               Asynchronous  
  313.           Usage Type               Data  
  314.         wMaxPacketSize     0x0080  1x 128 bytes  
  315.         bInterval               1  
  316.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  317.       bLength                 9  
  318.       bDescriptorType         4  
  319.       bInterfaceNumber        1  
  320.       bAlternateSetting       2  
  321.       bNumEndpoints           1  
  322.       bInterfaceClass        14 Video  
  323.       bInterfaceSubClass      2 Video Streaming  
  324.       bInterfaceProtocol      0   
  325.       iInterface              0   
  326.       Endpoint Descriptor:  
  327.         bLength                 7  
  328.         bDescriptorType         5  
  329.         bEndpointAddress     0x81  EP 1 IN  
  330.         bmAttributes            5  
  331.           Transfer Type            Isochronous  
  332.           Synch Type               Asynchronous  
  333.           Usage Type               Data  
  334.         wMaxPacketSize     0x0100  1x 256 bytes  
  335.         bInterval               1  
  336.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  337.       bLength                 9  
  338.       bDescriptorType         4  
  339.       bInterfaceNumber        1  
  340.       bAlternateSetting       3  
  341.       bNumEndpoints           1  
  342.       bInterfaceClass        14 Video  
  343.       bInterfaceSubClass      2 Video Streaming  
  344.       bInterfaceProtocol      0   
  345.       iInterface              0   
  346.       Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
  347.         bLength                 7  
  348.         bDescriptorType         5  
  349.         bEndpointAddress     0x81  EP 1 IN  
  350.         bmAttributes            5  
  351.           Transfer Type            Isochronous  
  352.           Synch Type               Asynchronous  
  353.           Usage Type               Data  
  354.         wMaxPacketSize     0x0320  1x 800 bytes  
  355.         bInterval               1  
  356.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  357.       bLength                 9  
  358.       bDescriptorType         4  
  359.       bInterfaceNumber        1  
  360.       bAlternateSetting       4  
  361.       bNumEndpoints           1  
  362.       bInterfaceClass        14 Video  
  363.       bInterfaceSubClass      2 Video Streaming  
  364.       bInterfaceProtocol      0   
  365.       iInterface              0   
  366.       Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
  367.         bLength                 7  
  368.         bDescriptorType         5  
  369.         bEndpointAddress     0x81  EP 1 IN  
  370.         bmAttributes            5  
  371.           Transfer Type            Isochronous  
  372.           Synch Type               Asynchronous  
  373.           Usage Type               Data  
  374.         wMaxPacketSize     0x0b20  2x 800 bytes  
  375.         bInterval               1  
  376.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  377.       bLength                 9  
  378.       bDescriptorType         4  
  379.       bInterfaceNumber        1  
  380.       bAlternateSetting       5  
  381.       bNumEndpoints           1  
  382.       bInterfaceClass        14 Video  
  383.       bInterfaceSubClass      2 Video Streaming  
  384.       bInterfaceProtocol      0   
  385.       iInterface              0   
  386.       Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
  387.         bLength                 7  
  388.         bDescriptorType         5  
  389.         bEndpointAddress     0x81  EP 1 IN  
  390.         bmAttributes            5  
  391.           Transfer Type            Isochronous  
  392.           Synch Type               Asynchronous  
  393.           Usage Type               Data  
  394.         wMaxPacketSize     0x1320  3x 800 bytes  
  395.         bInterval               1  
  396.     Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
  397.       bLength                 9  
  398.       bDescriptorType         4  
  399.       bInterfaceNumber        1  
  400.       bAlternateSetting       6  
  401.       bNumEndpoints           1  
  402.       bInterfaceClass        14 Video  
  403.       bInterfaceSubClass      2 Video Streaming  
  404.       bInterfaceProtocol      0   
  405.       iInterface              0   
  406.       Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
  407.         bLength                 7  
  408.         bDescriptorType         5  
  409.         bEndpointAddress     0x81  EP 1 IN  
  410.         bmAttributes            5  
  411.           Transfer Type            Isochronous  
  412.           Synch Type               Asynchronous  
  413.           Usage Type               Data  
  414.         wMaxPacketSize     0x1400  3x 1024 bytes  
  415.         bInterval               1  
  416. ////////////////////////////////////////////////////////////////////////////音頻部分  
  417.     Interface Association:                        
  418.       bLength                 8  
  419.       bDescriptorType        11  
  420.       bFirstInterface         2  
  421.       bInterfaceCount         2  
  422.       bFunctionClass          1 Audio  
  423.       bFunctionSubClass       0   
  424.       bFunctionProtocol       0   
  425.       iFunction               4 USB Microphone  
  426.     Interface Descriptor:  
  427.       bLength                 9  
  428.       bDescriptorType         4  
  429.       bInterfaceNumber        2  
  430.       bAlternateSetting       0  
  431.       bNumEndpoints           0  
  432.       bInterfaceClass         1 Audio  
  433.       bInterfaceSubClass      1 Control Device  
  434.       bInterfaceProtocol      0   
  435.       iInterface              4 USB Microphone  
  436.       AudioControl Interface Descriptor:  
  437.         bLength                 9  
  438.         bDescriptorType        36  
  439.         bDescriptorSubtype      1 (HEADER)  
  440.         bcdADC               1.00  
  441.         wTotalLength           41  
  442.         bInCollection           1  
  443.         baInterfaceNr( 0)       3  
  444.       AudioControl Interface Descriptor:  
  445.         bLength                12  
  446.         bDescriptorType        36  
  447.         bDescriptorSubtype      2 (INPUT_TERMINAL)  
  448.         bTerminalID             1  
  449.         wTerminalType      0x0201 Microphone  
  450.         bAssocTerminal          0  
  451.         bNrChannels             1  
  452.         wChannelConfig     0x0000  
  453.         iChannelNames           0   
  454.         iTerminal               0   
  455.       AudioControl Interface Descriptor:  
  456.         bLength                11  
  457.         bDescriptorType        36  
  458.         bDescriptorSubtype      6 (FEATURE_UNIT)  
  459.         bUnitID                 2  
  460.         bSourceID               1  
  461.         bControlSize            2  
  462.         bmaControls( 0)      0x01  
  463.         bmaControls( 0)      0x00  
  464.           Mute  
  465.         bmaControls( 1)      0x02  
  466.         bmaControls( 1)      0x00  
  467.           Volume  
  468.         iFeature                0   
  469.       AudioControl Interface Descriptor:  
  470.         bLength                 9  
  471.         bDescriptorType        36  
  472.         bDescriptorSubtype      3 (OUTPUT_TERMINAL)  
  473.         bTerminalID             3  
  474.         wTerminalType      0x0101 USB Streaming  
  475.         bAssocTerminal          0  
  476.         bSourceID               2  
  477.         iTerminal               0   
  478.     Interface Descriptor:  
  479.       bLength                 9  
  480.       bDescriptorType         4  
  481.       bInterfaceNumber        3  
  482.       bAlternateSetting       0  
  483.       bNumEndpoints           0  
  484.       bInterfaceClass         1 Audio  
  485.       bInterfaceSubClass      2 Streaming  
  486.       bInterfaceProtocol      0   
  487.       iInterface              0   
  488.     Interface Descriptor:  
  489.       bLength                 9  
  490.       bDescriptorType         4  
  491.       bInterfaceNumber        3  
  492.       bAlternateSetting       1  
  493.       bNumEndpoints           1  
  494.       bInterfaceClass         1 Audio  
  495.       bInterfaceSubClass      2 Streaming  
  496.       bInterfaceProtocol      0   
  497.       iInterface              0   
  498.       AudioStreaming Interface Descriptor:  
  499.         bLength                 7  
  500.         bDescriptorType        36  
  501.         bDescriptorSubtype      1 (AS_GENERAL)  
  502.         bTerminalLink           3  
  503.         bDelay                  1 frames  
  504.         wFormatTag              1 PCM  
  505.       AudioStreaming Interface Descriptor:  
  506.         bLength                29  
  507.         bDescriptorType        36  
  508.         bDescriptorSubtype      2 (FORMAT_TYPE)  
  509.         bFormatType             1 (FORMAT_TYPE_I)  
  510.         bNrChannels             1  
  511.         bSubframeSize           2  
  512.         bBitResolution         16  
  513.         bSamFreqType            7 Discrete  
  514.         tSamFreq[ 0]         8000  
  515.         tSamFreq[ 1]        11025  
  516.         tSamFreq[ 2]        16000  
  517.         tSamFreq[ 3]        22050  
  518.         tSamFreq[ 4]        24000  
  519.         tSamFreq[ 5]        44100  
  520.         tSamFreq[ 6]        48000  
  521.       Endpoint Descriptor:  
  522.         bLength                 9  
  523.         bDescriptorType         5  
  524.         bEndpointAddress     0x84  EP 4 IN  
  525.         bmAttributes            5  
  526.           Transfer Type            Isochronous  
  527.           Synch Type               Asynchronous  
  528.           Usage Type               Data  
  529.         wMaxPacketSize     0x0190  1x 400 bytes  
  530.         bInterval               4  
  531.         bRefresh                0  
  532.         bSynchAddress           0  
  533.         AudioControl Endpoint Descriptor:  
  534.           bLength                 7  
  535.           bDescriptorType        37  
  536.           bDescriptorSubtype      1 (EP_GENERAL)  
  537.           bmAttributes         0x01  
  538.             Sampling Frequency  
  539.           bLockDelayUnits         0 Undefined  
  540.           wLockDelay              0 Undefined  
  541. /////////////////////////////////////////////////////////////////  
  542. Device Qualifier (for other device speed):  //設備限定符  
  543.   bLength                10  
  544.   bDescriptorType         6  
  545.   bcdUSB               2.00  
  546.   bDeviceClass          239 Miscellaneous Device  
  547.   bDeviceSubClass         2 ?  
  548.   bDeviceProtocol         1 Interface Association  
  549.   bMaxPacketSize0        64  
  550.   bNumConfigurations      1  
  551. Device Status:     0x0002  
  552.   (Bus Powered)  
  553.   Remote Wakeup Enabled  
Bus 001 Device 002: ID 0c45:62f1 Microdia     //總線 設備ID
Device Descriptor:                          //設備描述符
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0c45 Microdia
  idProduct          0x62f1 
  bcdDevice            1.00
  iManufacturer           2 Sonix Technology Co., Ltd.
  iProduct                1 USB 2.0 Camera
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:                 //配置描述符
    bLength                 9
    bDescriptorType         2
    wTotalLength          697
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:                  //3.6 Interface Association Descriptor 
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass         14 Video
      bFunctionSubClass       3 Video Interface Collection
      bFunctionProtocol       0 
      iFunction               5 USB Camera
    Interface Descriptor:                   //Table 3-2 Standard VC Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      1 Video Control
      bInterfaceProtocol      0 
      iInterface              5 USB Camera
      VideoControl Interface Descriptor:    //Table 3-3 Class-specific VC Interface Header Descriptor
        bLength                13
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)  
        bcdUVC               1.00
        wTotalLength          103
        dwClockFrequency       15.000000MHz
        bInCollection           1
        baInterfaceNr( 0)       1
      VideoControl Interface Descriptor:    //Table 3-5 Output Terminal Descriptor
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             2
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               5
        iTerminal               0 
      VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor
        bLength                26
        bDescriptorType        36
        bDescriptorSubtype      6 (EXTENSION_UNIT)
        bUnitID                 4
        guidExtensionCode         {7033f028-1163-2e4a-ba2c-6890eb334016}
        bNumControl             8
        bNrPins                 1
        baSourceID( 0)          3
        bControlSize            1
        bmControls( 0)       0x0f
        iExtension              0 
      VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor
        bLength                26
        bDescriptorType        36
        bDescriptorSubtype      6 (EXTENSION_UNIT)
        bUnitID                 5
        guidExtensionCode         {3fae1228-d7bc-114e-a357-6f1edef7d61d}
        bNumControl             8
        bNrPins                 1
        baSourceID( 0)          4
        bControlSize            1
        bmControls( 0)       0xff
        iExtension              0 
      VideoControl Interface Descriptor:    //Table 3-6 Camera Terminal Descriptor
        bLength                18
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             1
        wTerminalType      0x0201 Camera Sensor
        bAssocTerminal          0
        iTerminal               0 
        wObjectiveFocalLengthMin      0
        wObjectiveFocalLengthMax      0
        wOcularFocalLength            0
        bControlSize                  3
        bmControls           0x00000000
      VideoControl Interface Descriptor:    //Table 3-8 Processing Unit Descriptor
        bLength                11
        bDescriptorType        36
        bDescriptorSubtype      5 (PROCESSING_UNIT)
      Warning: Descriptor too short
        bUnitID                 3
        bSourceID               1
        wMaxMultiplier          0
        bControlSize            2
        bmControls     0x0000053f
          Brightness
          Contrast
          Hue
          Saturation
          Sharpness
          Gamma
          Backlight Compensation
          Power Line Frequency
        iProcessing             0 
        bmVideoStandards     0x 0
      Endpoint Descriptor:                  //Table 3-11 Standard VC Interrupt Endpoint Descriptor
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               6
    Interface Descriptor:                   //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      VideoStreaming Interface Descriptor:      //Table 3-14 Class-specific VS Interface Input Header Descriptor
        bLength                            14
        bDescriptorType                    36
        bDescriptorSubtype                  1 (INPUT_HEADER)
        bNumFormats                         1
        wTotalLength                      323
        bEndPointAddress                  129
        bmInfo                              0
        bTerminalLink                       2
        bStillCaptureMethod                 2
        bTriggerSupport                     1
        bTriggerUsage                       1
        bControlSize                        1
        bmaControls( 0)                    27
      VideoStreaming Interface Descriptor:      //Table 3-1 Uncompressed Video Format Descriptor
        bLength                            27
        bDescriptorType                    36
        bDescriptorSubtype                  4 (FORMAT_UNCOMPRESSED)
        bFormatIndex                        1
        bNumFrameDescriptors                5
        guidFormat                            {59555932-0000-1000-8000-00aa00389b71}
        bBitsPerPixel                      16
        bDefaultFrameIndex                  1
        bAspectRatioX                       0
        bAspectRatioY                       0
        bmInterlaceFlags                 0x00
          Interlaced stream or variable: No
          Fields per frame: 1 fields
          Field 1 first: No
          Field pattern: Field 1 only
          bCopyProtect                      0
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         1
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            640
        wHeight                           480
        dwMinBitRate                 24576000
        dwMaxBitRate                147456000
        dwMaxVideoFrameBufferSize      614400
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         2
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            352
        wHeight                           288
        dwMinBitRate                  8110080
        dwMaxBitRate                 48660480
        dwMaxVideoFrameBufferSize      202752
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         3
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            320
        wHeight                           240
        dwMinBitRate                  6144000
        dwMaxBitRate                 36864000
        dwMaxVideoFrameBufferSize      153600
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         4
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            176
        wHeight                           144
        dwMinBitRate                  2027520
        dwMaxBitRate                 12165120
        dwMaxVideoFrameBufferSize       50688
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors
        bLength                            50
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         5
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            160
        wHeight                           120
        dwMinBitRate                  1536000
        dwMaxBitRate                  9216000
        dwMaxVideoFrameBufferSize       38400
        dwDefaultFrameInterval         333333
        bFrameIntervalType                  6
        dwFrameInterval( 0)            333333
        dwFrameInterval( 1)            400000
        dwFrameInterval( 2)            500000
        dwFrameInterval( 3)            666666
        dwFrameInterval( 4)           1000000
        dwFrameInterval( 5)           2000000
      VideoStreaming Interface Descriptor:      //Table 3-18 Still Image Frame Descriptor
        bLength                            26
        bDescriptorType                    36
        bDescriptorSubtype                  3 (STILL_IMAGE_FRAME)
        bEndpointAddress                    0
        bNumImageSizePatterns               5
        wWidth( 0)                        640
        wHeight( 0)                       480
        wWidth( 1)                        352
        wHeight( 1)                       288
        wWidth( 2)                        320
        wHeight( 2)                       240
        wWidth( 3)                        176
        wHeight( 3)                       144
        wWidth( 4)                        160
        wHeight( 4)                       120
        bNumCompressionPatterns             5
      VideoStreaming Interface Descriptor:      //Table 3-19 Color Matching Descriptor
        bLength                             6
        bDescriptorType                    36
        bDescriptorSubtype                 13 (COLORFORMAT)
        bColorPrimaries                     1 (BT.709,sRGB)
        bTransferCharacteristics            1 (BT.709)
        bMatrixCoefficients                 4 (SMPTE 170M (BT.601))
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0080  1x 128 bytes
        bInterval               1
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0100  1x 256 bytes
        bInterval               1
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       3
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0320  1x 800 bytes
        bInterval               1
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       4
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0b20  2x 800 bytes
        bInterval               1
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       5
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x1320  3x 800 bytes
        bInterval               1
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       6
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x1400  3x 1024 bytes
        bInterval               1
////////////////////////////////////////////////////////////////////////////音頻部分
    Interface Association:                      
      bLength                 8
      bDescriptorType        11
      bFirstInterface         2
      bInterfaceCount         2
      bFunctionClass          1 Audio
      bFunctionSubClass       0 
      bFunctionProtocol       0 
      iFunction               4 USB Microphone
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      1 Control Device
      bInterfaceProtocol      0 
      iInterface              4 USB Microphone
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdADC               1.00
        wTotalLength           41
        bInCollection           1
        baInterfaceNr( 0)       3
      AudioControl Interface Descriptor:
        bLength                12
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             1
        wTerminalType      0x0201 Microphone
        bAssocTerminal          0
        bNrChannels             1
        wChannelConfig     0x0000
        iChannelNames           0 
        iTerminal               0 
      AudioControl Interface Descriptor:
        bLength                11
        bDescriptorType        36
        bDescriptorSubtype      6 (FEATURE_UNIT)
        bUnitID                 2
        bSourceID               1
        bControlSize            2
        bmaControls( 0)      0x01
        bmaControls( 0)      0x00
          Mute
        bmaControls( 1)      0x02
        bmaControls( 1)      0x00
          Volume
        iFeature                0 
      AudioControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             3
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               2
        iTerminal               0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol      0 
      iInterface              0 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass         1 Audio
      bInterfaceSubClass      2 Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      AudioStreaming Interface Descriptor:
        bLength                 7
        bDescriptorType        36
        bDescriptorSubtype      1 (AS_GENERAL)
        bTerminalLink           3
        bDelay                  1 frames
        wFormatTag              1 PCM
      AudioStreaming Interface Descriptor:
        bLength                29
        bDescriptorType        36
        bDescriptorSubtype      2 (FORMAT_TYPE)
        bFormatType             1 (FORMAT_TYPE_I)
        bNrChannels             1
        bSubframeSize           2
        bBitResolution         16
        bSamFreqType            7 Discrete
        tSamFreq[ 0]         8000
        tSamFreq[ 1]        11025
        tSamFreq[ 2]        16000
        tSamFreq[ 3]        22050
        tSamFreq[ 4]        24000
        tSamFreq[ 5]        44100
        tSamFreq[ 6]        48000
      Endpoint Descriptor:
        bLength                 9
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0190  1x 400 bytes
        bInterval               4
        bRefresh                0
        bSynchAddress           0
        AudioControl Endpoint Descriptor:
          bLength                 7
          bDescriptorType        37
          bDescriptorSubtype      1 (EP_GENERAL)
          bmAttributes         0x01
            Sampling Frequency
          bLockDelayUnits         0 Undefined
          wLockDelay              0 Undefined
/////////////////////////////////////////////////////////////////
Device Qualifier (for other device speed):  //設備限定符
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0002
  (Bus Powered)
  Remote Wakeup Enabled

可以通過描述符佈局,分析出攝像頭框架
第一步找出Terminal和Unit的(bTerminalID/bUnitID)
IT(1)
OT(2)
XU(4)
XU(5)
PU(3)
第二步從OT輸出Terminal開始分析
OT(2)的bSourceID=5
所以XU(5)->OT(2)
XU(5)的bNrPins=1所以只有一個輸入baSourceID( 0)=4
所以XU(4)->XU(5)->OT(2)
XU(4)的bNrPins=1所以只有一個輸入baSourceID( 0)=3
所以PU(3)->XU(4)->XU(5)->OT(2)
PU(3)的bSourceID=1
所以IT(1)->PU(3)->XU(4)->XU(5)->OT(2)

 4.3 probe方法初始化uvc設備結構體對象

 

 5 uvc解析usb視頻類控制描述符

  1. static int uvc_parse_control(struct uvc_device *dev)  
  2. {  
  3.     struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取當前usb_host_interface  
  4.     unsigned char *buffer = alts->extra; //額外描述符  
  5.     int buflen = alts->extralen; //額外描述符長度  
  6.     int ret;  
  7.     /* 解析默認的交替設置,正如UVC標準協議定義的單個交替設置,默認是交替設置0(Alt.Setting 0)*/  
  8.     while (buflen > 2) {  
  9.         if (uvc_parse_vendor_control(dev, buffer, buflen) || buffer[1] != USB_DT_CS_INTERFACE)  //5.1解析廠商特殊控制  
  10.             goto next_descriptor;   //特殊廠商處理則直接跳過標準處理  
static int uvc_parse_control(struct uvc_device *dev)
{
    struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取當前usb_host_interface
    unsigned char *buffer = alts->extra; //額外描述符
    int buflen = alts->extralen; //額外描述符長度
    int ret;
    /* 解析默認的交替設置,正如UVC標準協議定義的單個交替設置,默認是交替設置0(Alt.Setting 0)*/
    while (buflen > 2) {
        if (uvc_parse_vendor_control(dev, buffer, buflen) || buffer[1] != USB_DT_CS_INTERFACE)  //5.1解析廠商特殊控制
            goto next_descriptor;   //特殊廠商處理則直接跳過標準處理

   }

  1.         if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0) //5.2.解析uvc標準控制  
  2.             return ret;  
  3. next_descriptor:    //buffer[0]是bLength描述符長度  
  4.         buflen -= buffer[0];    //調整buflen長度  
  5.         buffer += buffer[0];    //調整buffer指針  
  6.     }  
       if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0) //5.2.解析uvc標準控制
            return ret;
next_descriptor:    //buffer[0]是bLength描述符長度
        buflen -= buffer[0];    //調整buflen長度
        buffer += buffer[0];    //調整buffer指針
    }

  1. //判斷描述符是否有1個端點  
  2. if (alts->desc.bNumEndpoints == 1 && !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {  
  3.     struct usb_host_endpoint *ep = &alts->endpoint[0];   //獲取usb_host_endpoint  
  4.     struct usb_endpoint_descriptor *desc = &ep->desc;    //獲取端點描述符  
  5.     //判斷是否中斷輸入端點  
  6.     if (usb_endpoint_is_int_in(desc) && le16_to_cpu(desc->wMaxPacketSize) >= 8 && desc->bInterval != 0) {  
  7.         uvc_trace(UVC_TRACE_DESCR, ”Found a Status endpoint (addr %02x).\n”, desc->bEndpointAddress);  
  8.         dev->int_ep = ep;  
  9.     }  
  10. }  
  11. return 0;  
  //判斷描述符是否有1個端點
    if (alts->desc.bNumEndpoints == 1 && !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {
        struct usb_host_endpoint *ep = &alts->endpoint[0];   //獲取usb_host_endpoint
        struct usb_endpoint_descriptor *desc = &ep->desc;    //獲取端點描述符
        //判斷是否中斷輸入端點
        if (usb_endpoint_is_int_in(desc) && le16_to_cpu(desc->wMaxPacketSize) >= 8 && desc->bInterval != 0) {
            uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint (addr %02x).\n", desc->bEndpointAddress);
            dev->int_ep = ep;
        }
    }
    return 0;
}

5.1 解析廠商特殊控制 (特殊廠商處理返回1,不是返回0)

  1. static int uvc_parse_vendor_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)  
  2. {  
  3.     struct usb_device *udev = dev->udev;  
  4.     struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取usb_host_interface  
  5.     struct uvc_entity *unit;  
  6.     unsigned int n, p;  
  7.     int handled = 0;    //返回值 默認爲0  
  8.     switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {  
  9.     case 0x046d:        /* Logitech 羅技*/  
  10.         …  
  11.         handled = 1;    //特殊廠商處理則返回1  
  12.         break;  
  13.     }  
  14.     return handled;  
  15. }  
static int uvc_parse_vendor_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)
{
    struct usb_device *udev = dev->udev;
    struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取usb_host_interface
    struct uvc_entity *unit;
    unsigned int n, p;
    int handled = 0;    //返回值 默認爲0
    switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
    case 0x046d:        /* Logitech 羅技*/
        ...
        handled = 1;    //特殊廠商處理則返回1
        break;
    }
    return handled;
}

5.1.1 uvc實體結構體

  1. struct uvc_entity { //uvc實體  
  2.     struct list_head list;  //實體鏈表頭  
  3.     struct list_head chain; //視頻鏈鏈表頭  
  4.     __u8 id;    //實體id  
  5.     __u16 type; //實體類型  
  6.     char name[64];  //實體名  
  7.     union {  
  8.         struct {  
  9.             __u16 wObjectiveFocalLengthMin;  
  10.             __u16 wObjectiveFocalLengthMax;  
  11.             __u16 wOcularFocalLength;  
  12.             __u8  bControlSize; //控制位域大小  
  13.             __u8  *bmControls;  //控制位圖指針  
  14.         } camera;       //輸入Terminal UVC_ITT_CAMERA  
  15.         struct {  
  16.             __u8  bControlSize; //控制位域大小  
  17.             __u8  *bmControls;  //控制位圖指針  
  18.             __u8  bTransportModeSize;  
  19.             __u8  *bmTransportModes;  
  20.         } media;        //輸入Terminal UVC_ITT_MEDIA_TRANSPORT_INPUT  
  21.         struct {  
  22.         } output;       //輸出Terminal  
  23.         //處理Unit  
  24.         struct {  
  25.             __u16 wMaxMultiplier;  
  26.             __u8  bControlSize; //控制位域大小  
  27.             __u8  *bmControls;  //控制位圖指針  
  28.             __u8  bmVideoStandards;  
  29.         } processing;   //處理Unit  
  30.         //選擇器Unit  
  31.         struct {  
  32.         } selector;     //選擇器Unit  
  33.         //擴展Unit  
  34.         struct {  
  35.             __u8  guidExtensionCode[16];  
  36.             __u8  bNumControls;  
  37.             __u8  bControlSize; //控制位域大小  
  38.             __u8  *bmControls;  //控制位圖指針  
  39.             __u8  *bmControlsType;  
  40.         } extension;    //擴展Unit  
  41.     };  
  42.     __u8 bNrInPins; //輸入引腳數  
  43.     __u8 *baSourceID;   //第一個輸入引腳ID(Terminal/Unit ID)  
  44.     unsigned int ncontrols; //uvc控制個數  
  45.     struct uvc_control *controls;   //ucv控制數組指針  
  46. };  
struct uvc_entity {   //uvc實體
    struct list_head list;  //實體鏈表頭
    struct list_head chain; //視頻鏈鏈表頭
    __u8 id;    //實體id
    __u16 type; //實體類型
    char name[64];  //實體名
    union {
        struct {
            __u16 wObjectiveFocalLengthMin;
            __u16 wObjectiveFocalLengthMax;
            __u16 wOcularFocalLength;
            __u8  bControlSize; //控制位域大小
            __u8  *bmControls;  //控制位圖指針
        } camera;       //輸入Terminal UVC_ITT_CAMERA
        struct {
            __u8  bControlSize; //控制位域大小
            __u8  *bmControls;  //控制位圖指針
            __u8  bTransportModeSize;
            __u8  *bmTransportModes;
        } media;        //輸入Terminal UVC_ITT_MEDIA_TRANSPORT_INPUT
        struct {
        } output;       //輸出Terminal
        //處理Unit
        struct {
            __u16 wMaxMultiplier;
            __u8  bControlSize; //控制位域大小
            __u8  *bmControls;  //控制位圖指針
            __u8  bmVideoStandards;
        } processing;   //處理Unit
        //選擇器Unit
        struct {
        } selector;     //選擇器Unit
        //擴展Unit
        struct {
            __u8  guidExtensionCode[16];
            __u8  bNumControls;
            __u8  bControlSize; //控制位域大小
            __u8  *bmControls;  //控制位圖指針
            __u8  *bmControlsType;
        } extension;    //擴展Unit
    };
    __u8 bNrInPins; //輸入引腳數
    __u8 *baSourceID;   //第一個輸入引腳ID(Terminal/Unit ID)
    unsigned int ncontrols; //uvc控制個數
    struct uvc_control *controls;   //ucv控制數組指針
};

5.2 解析uvc標準控制

  1. static int uvc_parse_standard_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)  
  2. {  
  3.     struct usb_device *udev = dev->udev; //獲取usb設備  
  4.     struct uvc_entity *unit, *term; //uvc實體Unit或Terminal  
  5.     struct usb_interface *intf; //usb接口  
  6.     struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取當前usb接口配置描述符  
  7.     unsigned int i, n, p, len;  
  8.     __u16 type;  
  9.       
  10.     switch (buffer[2]) {    //buffer[2]存放bDescriptorSubType  
static int uvc_parse_standard_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)
{
    struct usb_device *udev = dev->udev; //獲取usb設備
    struct uvc_entity *unit, *term; //uvc實體Unit或Terminal
    struct usb_interface *intf; //usb接口
    struct usb_host_interface *alts = dev->intf->cur_altsetting;  //獲取當前usb接口配置描述符
    unsigned int i, n, p, len;
    __u16 type;

    switch (buffer[2]) {    //buffer[2]存放bDescriptorSubType

  1. case UVC_VC_HEADER: //vc 接口頭部描述符  
  2.     n = buflen >= 12 ? buffer[11] : 0;   //bInCollection 視頻流接口數  
  3.     if (buflen < 12 || buflen < 12 + n) {  
  4.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d HEADER error\n”, udev->devnum,alts->desc.bInterfaceNumber);  
  5.         return -EINVAL;  
  6.     }  
  7.     dev->uvc_version = get_unaligned_le16(&buffer[3]);   //bcdUVC  
  8.     dev->clock_frequency = get_unaligned_le32(&buffer[7]);   //獲取時鐘頻率  
  9.     /* Parse all USB Video Streaming interfaces. 解析所有USB視頻接口*/  
  10.     for (i = 0; i < n; ++i) {    //遍歷視頻流接口  
  11.         intf = usb_ifnum_to_if(udev, buffer[12+i]); //baInterfaceNr(n) 獲取視頻流對應的usb接口  
  12.         if (intf == NULL) {  
  13.             uvc_trace(UVC_TRACE_DESCR, ”device %d interface %d doesn’t exists\n”,udev->devnum, i);  
  14.             continue;  
  15.         }  
  16.         uvc_parse_streaming(dev, intf); //6.uvc解析uvc視頻流  
  17.     }  
  18.     break;  
    case UVC_VC_HEADER: //vc 接口頭部描述符
        n = buflen >= 12 ? buffer[11] : 0;   //bInCollection 視頻流接口數
        if (buflen < 12 || buflen < 12 + n) {
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d HEADER error\n", udev->devnum,alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        dev->uvc_version = get_unaligned_le16(&buffer[3]);   //bcdUVC
        dev->clock_frequency = get_unaligned_le32(&buffer[7]);   //獲取時鐘頻率
        /* Parse all USB Video Streaming interfaces. 解析所有USB視頻接口*/
        for (i = 0; i < n; ++i) {    //遍歷視頻流接口
            intf = usb_ifnum_to_if(udev, buffer[12+i]); //baInterfaceNr(n) 獲取視頻流對應的usb接口
            if (intf == NULL) {
                uvc_trace(UVC_TRACE_DESCR, "device %d interface %d doesn't exists\n",udev->devnum, i);
                continue;
            }
            uvc_parse_streaming(dev, intf); //6.uvc解析uvc視頻流
        }
        break;

  1. case UVC_VC_INPUT_TERMINAL: //UVC輸入Terminal  
  2.     if (buflen < 8) {    //檢驗buflen長度  
  3.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d INPUT_TERMINAL error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  4.         return -EINVAL;  
  5.     }  
  6.     /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/  
  7.     type = get_unaligned_le16(&buffer[4]);  //獲取Terminal類型(ITT_ VENDOR_SPECIFIC/ITT_CAMERA/ITT_MEDIA_TRANSPORT_INPUT)  
  8.     if ((type & 0xff00) == 0) { //錯誤類型  
  9.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\n”, udev->devnum,alts->desc.bInterfaceNumber,buffer[3], type);  
  10.         return 0;  
  11.     }  
  12.     n = 0;  
  13.     p = 0;  
  14.     len = 8;    //標準長度(0~7)  
 case UVC_VC_INPUT_TERMINAL: //UVC輸入Terminal
        if (buflen < 8) {    //檢驗buflen長度
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/
        type = get_unaligned_le16(&buffer[4]);  //獲取Terminal類型(ITT_ VENDOR_SPECIFIC/ITT_CAMERA/ITT_MEDIA_TRANSPORT_INPUT)
        if ((type & 0xff00) == 0) { //錯誤類型
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\n", udev->devnum,alts->desc.bInterfaceNumber,buffer[3], type);
            return 0;
        }
        n = 0;
        p = 0;
        len = 8;    //標準長度(0~7)

  1. if (type == UVC_ITT_CAMERA) {   //攝像頭傳感器    (speciafication.pdf P67)  
  2.     n = buflen >= 15 ? buffer[14] : 0;   //bControlSize 控制位域大小     
  3.     len = 15;  
  4. }   
  5. else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {   //連續的媒體 (USB_Video_Transport_1.5.pdf P11)  
  6.     n = buflen >= 9 ? buffer[8] : 0; //bControlSize 控制位域大小  
  7.     p = buflen >= 10 + n ? buffer[9+n] : 0;  //bmTransportModesSize 傳輸模式位域大小  
  8.     len = 10;  
  9. }  
  10. if (buflen < len + n + p) {  //檢驗buflen長度是否合適  
  11.     uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d INPUT_TERMINAL error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  12.     return -EINVAL;  
  13. }  
  14. term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //分配uvc實體 buffer[3]是實體ID  
  15. if (term == NULL)  
  16.     return -ENOMEM;  
  17. if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {  //攝像頭傳感器      
  18.     term->camera.bControlSize = n;   //bControlSize 控制位域大小  
  19.     term->camera.bmControls = (__u8 *)term + sizeof *term;   //bmControls 控制位圖指針  
  20.     term->camera.wObjectiveFocalLengthMin = get_unaligned_le16(&buffer[8]);  // wObjectiveFocalLengthMin 焦點長度最小值  
  21.     term->camera.wObjectiveFocalLengthMax = get_unaligned_le16(&buffer[10]); //wObjectiveFocalLengthMax 焦點長度最大值  
  22.     term->camera.wOcularFocalLength = get_unaligned_le16(&buffer[12]);   //wOcularFocalLength  Ocular焦距  
  23.     memcpy(term->camera.bmControls, &buffer[15], n); //初始化控制位圖  
  24. }   
      if (type == UVC_ITT_CAMERA) {   //攝像頭傳感器    (speciafication.pdf P67)
            n = buflen >= 15 ? buffer[14] : 0;   //bControlSize 控制位域大小   
            len = 15;
        } 
        else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {   //連續的媒體 (USB_Video_Transport_1.5.pdf P11)
            n = buflen >= 9 ? buffer[8] : 0; //bControlSize 控制位域大小
            p = buflen >= 10 + n ? buffer[9+n] : 0;  //bmTransportModesSize 傳輸模式位域大小
            len = 10;
        }
        if (buflen < len + n + p) {  //檢驗buflen長度是否合適
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //分配uvc實體 buffer[3]是實體ID
        if (term == NULL)
            return -ENOMEM;
        if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {  //攝像頭傳感器    
            term->camera.bControlSize = n;   //bControlSize 控制位域大小
            term->camera.bmControls = (__u8 *)term + sizeof *term;   //bmControls 控制位圖指針
            term->camera.wObjectiveFocalLengthMin = get_unaligned_le16(&buffer[8]);  // wObjectiveFocalLengthMin 焦點長度最小值
            term->camera.wObjectiveFocalLengthMax = get_unaligned_le16(&buffer[10]); //wObjectiveFocalLengthMax 焦點長度最大值
            term->camera.wOcularFocalLength = get_unaligned_le16(&buffer[12]);   //wOcularFocalLength  Ocular焦距
            memcpy(term->camera.bmControls, &buffer[15], n); //初始化控制位圖
        } 

  1. else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) {  //連續的媒體  
  2.     term->media.bControlSize = n;    //bControlSize 控制位域大小  
  3.     term->media.bmControls = (__u8 *)term + sizeof *term;    //bmControls控制位圖指針  
  4.     term->media.bTransportModeSize = p;  //bTransportModeSize 傳輸模式位域大小  
  5.     term->media.bmTransportModes = (__u8 *)term + sizeof *term + n;  //bmTransportModes傳輸模式位圖指針  
  6.     memcpy(term->media.bmControls, &buffer[9], n);   //初始化控制位圖  
  7.     memcpy(term->media.bmTransportModes, &buffer[10+n], p);  //初始化傳輸模式位圖  
  8. }  
  9. if (buffer[7] != 0) //設置實體名  
  10.     usb_string(udev, buffer[7], term->name,sizeof term->name);  
  11. else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)   //設置Camera Terminal實體名  
  12.     sprintf(term->name, ”Camera %u”, buffer[3]);  
  13. else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)    //設置Media Terminal實體名  
  14.     sprintf(term->name, ”Media %u”, buffer[3]);  
  15. else      
  16.     sprintf(term->name, ”Input %u”, buffer[3]);  
  17. list_add_tail(&term->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中  
  18. break;  
      else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) {  //連續的媒體
            term->media.bControlSize = n;    //bControlSize 控制位域大小
            term->media.bmControls = (__u8 *)term + sizeof *term;    //bmControls控制位圖指針
            term->media.bTransportModeSize = p;  //bTransportModeSize 傳輸模式位域大小
            term->media.bmTransportModes = (__u8 *)term + sizeof *term + n;  //bmTransportModes傳輸模式位圖指針
            memcpy(term->media.bmControls, &buffer[9], n);   //初始化控制位圖
            memcpy(term->media.bmTransportModes, &buffer[10+n], p);  //初始化傳輸模式位圖
        }
        if (buffer[7] != 0) //設置實體名
            usb_string(udev, buffer[7], term->name,sizeof term->name);
        else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)   //設置Camera Terminal實體名
            sprintf(term->name, "Camera %u", buffer[3]);
        else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)    //設置Media Terminal實體名
            sprintf(term->name, "Media %u", buffer[3]);
        else    
            sprintf(term->name, "Input %u", buffer[3]);
        list_add_tail(&term->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中
        break;

  1. case UVC_VC_OUTPUT_TERMINAL:    //UVC輸出Terminal  
  2.     if (buflen < 9) {    //檢驗buflen長度  
  3.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d OUTPUT_TERMINAL error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  4.         return -EINVAL;  
  5.     }  
  6.     /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/  
  7.     type = get_unaligned_le16(&buffer[4]);  //wTerminalType 輸出Terminal類型  
  8.     if ((type & 0xff00) == 0) {  
  9.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d OUTPUT_TERMINAL %d has invalid type 0x%04x, skipping\n”, udev->devnum,  
  10.             alts->desc.bInterfaceNumber, buffer[3], type);  
  11.         return 0;  
  12.     }  
  13.     term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //分配uvc實體 buffer[3]是實體ID  
  14.     if (term == NULL)  
  15.         return -ENOMEM;  
  16.     memcpy(term->baSourceID, &buffer[7], 1); //複製Terminal ID到baSourceID  
  17.     if (buffer[8] != 0) //設置Terminal實體名  
  18.         usb_string(udev, buffer[8], term->name,sizeof term->name);  
  19.     else    //設置output Terminal實體名  
  20.         sprintf(term->name, ”Output %u”, buffer[3]);  
  21.     list_add_tail(&term->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中  
  22.     break;  
  case UVC_VC_OUTPUT_TERMINAL:    //UVC輸出Terminal
        if (buflen < 9) {    //檢驗buflen長度
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d OUTPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/
        type = get_unaligned_le16(&buffer[4]);  //wTerminalType 輸出Terminal類型
        if ((type & 0xff00) == 0) {
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d OUTPUT_TERMINAL %d has invalid type 0x%04x, skipping\n", udev->devnum,
                alts->desc.bInterfaceNumber, buffer[3], type);
            return 0;
        }
        term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //分配uvc實體 buffer[3]是實體ID
        if (term == NULL)
            return -ENOMEM;
        memcpy(term->baSourceID, &buffer[7], 1); //複製Terminal ID到baSourceID
        if (buffer[8] != 0) //設置Terminal實體名
            usb_string(udev, buffer[8], term->name,sizeof term->name);
        else    //設置output Terminal實體名
            sprintf(term->name, "Output %u", buffer[3]);
        list_add_tail(&term->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中
        break;

  1. case UVC_VC_SELECTOR_UNIT:  //UVC選擇器Unit  
  2.     p = buflen >= 5 ? buffer[4] : 0; //Unit輸入引腳數  
  3.     if (buflen < 5 || buflen < 6 + p) {   //檢驗buflen是否符合  
  4.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d SELECTOR_UNIT error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  5.         return -EINVAL;  
  6.     }  
  7.     unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);    //分配uvc實體 buffer[3]是實體ID  
  8.     if (unit == NULL)  
  9.         return -ENOMEM;  
  10.     memcpy(unit->baSourceID, &buffer[5], p); //複製Unit ID到bSourceID  
  11.     if (buffer[5+p] != 0)   //設置selector Unit名  
  12.         usb_string(udev, buffer[5+p], unit->name,sizeof unit->name);  
  13.     else  
  14.         sprintf(unit->name, ”Selector %u”, buffer[3]);  
  15.     list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中  
  16.     break;  
   case UVC_VC_SELECTOR_UNIT:  //UVC選擇器Unit
        p = buflen >= 5 ? buffer[4] : 0; //Unit輸入引腳數
        if (buflen < 5 || buflen < 6 + p) {   //檢驗buflen是否符合
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d SELECTOR_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);    //分配uvc實體 buffer[3]是實體ID
        if (unit == NULL)
            return -ENOMEM;
        memcpy(unit->baSourceID, &buffer[5], p); //複製Unit ID到bSourceID
        if (buffer[5+p] != 0)   //設置selector Unit名
            usb_string(udev, buffer[5+p], unit->name,sizeof unit->name);
        else
            sprintf(unit->name, "Selector %u", buffer[3]);
        list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中
        break;

  1. case UVC_VC_PROCESSING_UNIT:    //UVC處理Unit  
  2.     n = buflen >= 8 ? buffer[7] : 0; //bControlSize控制位域大小  
  3.     p = dev->uvc_version >= 0x0110 ? 10 : 9;  //uvc類協議版本  
  4.     if (buflen < p + n) {        //檢驗buflen長度是否符合  
  5.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d PROCESSING_UNIT error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  6.         return -EINVAL;  
  7.     }  
  8.     unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);    //分配uvc實體 buffer[3]是實體ID  
  9.     if (unit == NULL)  
  10.         return -ENOMEM;  
  11.     memcpy(unit->baSourceID, &buffer[4], 1); //複製Unit ID到bSourceID  
  12.     unit->processing.wMaxMultiplier = get_unaligned_le16(&buffer[5]);    //最大數字放大率  
  13.     unit->processing.bControlSize = buffer[7];   //bControlSize 控制位域大小  
  14.     unit->processing.bmControls = (__u8 *)unit + sizeof *unit;   //bmControls控制位圖指針  
  15.     memcpy(unit->processing.bmControls, &buffer[8], n);  //初始化控制位圖  
  16.     if (dev->uvc_version >= 0x0110)   //版本大於1.1  
  17.         unit->processing.bmVideoStandards = buffer[9+n]; //設置視頻標準支持位圖  
  18.     if (buffer[8+n] != 0)   //設置處理Unit名  
  19.         usb_string(udev, buffer[8+n], unit->name,sizeof unit->name);  
  20.     else  
  21.         sprintf(unit->name, ”Processing %u”, buffer[3]);  
  22.     list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中  
  23.     break;  
 case UVC_VC_PROCESSING_UNIT:    //UVC處理Unit
        n = buflen >= 8 ? buffer[7] : 0; //bControlSize控制位域大小
        p = dev->uvc_version >= 0x0110 ? 10 : 9;  //uvc類協議版本
        if (buflen < p + n) {        //檢驗buflen長度是否符合
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d PROCESSING_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);    //分配uvc實體 buffer[3]是實體ID
        if (unit == NULL)
            return -ENOMEM;
        memcpy(unit->baSourceID, &buffer[4], 1); //複製Unit ID到bSourceID
        unit->processing.wMaxMultiplier = get_unaligned_le16(&buffer[5]);    //最大數字放大率
        unit->processing.bControlSize = buffer[7];   //bControlSize 控制位域大小
        unit->processing.bmControls = (__u8 *)unit + sizeof *unit;   //bmControls控制位圖指針
        memcpy(unit->processing.bmControls, &buffer[8], n);  //初始化控制位圖
        if (dev->uvc_version >= 0x0110)   //版本大於1.1
            unit->processing.bmVideoStandards = buffer[9+n]; //設置視頻標準支持位圖
        if (buffer[8+n] != 0)   //設置處理Unit名
            usb_string(udev, buffer[8+n], unit->name,sizeof unit->name);
        else
            sprintf(unit->name, "Processing %u", buffer[3]);
        list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中
        break;

  1. case UVC_VC_EXTENSION_UNIT: //UVC擴展Unit  
  2.     p = buflen >= 22 ? buffer[21] : 0;   //Unit輸入引腳數  
  3.     n = buflen >= 24 + p ? buffer[22+p] : 0; //bControlSize控制位域長度  
  4.     if (buflen < 24 + p + n) {   //判斷buflen長度是否符合  
  5.         uvc_trace(UVC_TRACE_DESCR, ”device %d videocontrol interface %d EXTENSION_UNIT error\n”,udev->devnum, alts->desc.bInterfaceNumber);  
  6.         return -EINVAL;  
  7.     }  
  8.     unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);    //分配uvc實體 buffer[3]是實體ID  
  9.     if (unit == NULL)  
  10.         return -ENOMEM;  
  11.     memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);   //guidExtensionCode 廠商特殊<span class=”wp_keywordlink” style=”margin: 0px; padding: 0px; border: 0px; background: transparent;”><a target=_blank href=”http://www.xuebuyuan.com/” title=”代碼” target=”_blank” style=”text-decoration: none; color: rgb(1, 150, 227);”>代碼</a></span>id  
  12.     unit->extension.bNumControls = buffer[20];   //Unit的控件數  
  13.     memcpy(unit->baSourceID, &buffer[22], p);    //複製Unit ID到baSourceID  
  14.     unit->extension.bControlSize = buffer[22+p]; //bControlSize 控制位域大小  
  15.     unit->extension.bmControls = (__u8 *)unit + sizeof *unit;    //bmControls控制位圖指針  
  16.     memcpy(unit->extension.bmControls, &buffer[23+p], n);    //初始化控制位圖  
  17.     if (buffer[23+p+n] != 0)    //設置擴展Unit實體名  
  18.         usb_string(udev, buffer[23+p+n], unit->name,sizeof unit->name);  
  19.     else  
  20.         sprintf(unit->name, ”Extension %u”, buffer[3]);  
  21.     list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中  
  22.     break;  
  23. default:  
  24.     uvc_trace(UVC_TRACE_DESCR, ”Found an unknown CS_INTERFACE descriptor (%u)\n”, buffer[2]);  
  25.     break;  
  26. }  
  27. return 0;  
 case UVC_VC_EXTENSION_UNIT: //UVC擴展Unit
        p = buflen >= 22 ? buffer[21] : 0;   //Unit輸入引腳數
        n = buflen >= 24 + p ? buffer[22+p] : 0; //bControlSize控制位域長度
        if (buflen < 24 + p + n) {   //判斷buflen長度是否符合
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d EXTENSION_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);
            return -EINVAL;
        }
        unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);    //分配uvc實體 buffer[3]是實體ID
        if (unit == NULL)
            return -ENOMEM;
        memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);   //guidExtensionCode 廠商特殊<span class="wp_keywordlink" style="margin: 0px; padding: 0px; border: 0px; background: transparent;"><a target=_blank href="http://www.xuebuyuan.com/" title="代碼" target="_blank" style="text-decoration: none; color: rgb(1, 150, 227);">代碼</a></span>id
        unit->extension.bNumControls = buffer[20];   //Unit的控件數
        memcpy(unit->baSourceID, &buffer[22], p);    //複製Unit ID到baSourceID
        unit->extension.bControlSize = buffer[22+p]; //bControlSize 控制位域大小
        unit->extension.bmControls = (__u8 *)unit + sizeof *unit;    //bmControls控制位圖指針
        memcpy(unit->extension.bmControls, &buffer[23+p], n);    //初始化控制位圖
        if (buffer[23+p+n] != 0)    //設置擴展Unit實體名
            usb_string(udev, buffer[23+p+n], unit->name,sizeof unit->name);
        else
            sprintf(unit->name, "Extension %u", buffer[3]);
        list_add_tail(&unit->list, &dev->entities);   //添加uvc實體到uvc實體鏈表中
        break;
    default:
        uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE descriptor (%u)\n", buffer[2]);
        break;
    }
    return 0;
}

5.2.1 添加uvc實體到uvc設備的實體鏈表下

list_add_tail(&term->list, &dev->entities);


5.2.2 分配uvc實體

static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,unsigned int num_pads, unsigned int extra_size) 

  1. case VC_INPUT_TERMINAL(n=bControlSize控制位域長度,p=bmTransportModesSize 傳輸模式位域大小)  
  2. term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //輸入Terminal只有一個pad  
  3. case VC_OUTPUT_TERMINAL  
  4. term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //輸出Terminal只有一個pad  
  5. case VC_SELECTOR_UNIT:(p=Unit輸入引腳數)  
  6. unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);            //選擇Unit有p個輸入pad,1個輸出pad  
  7. case VC_PROCESSING_UNIT(n=bControlSize控制位域長度)  
  8. unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);                //處理Unit只有1個輸入pad,1個輸出pad  
  9. case VC_EXTENSION_UNIT(n=bControlSize控制位域長度,p=Unit輸入引腳數)  
  10. unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);            //擴展Unit有p個輸入pad,1個輸出pad  
case VC_INPUT_TERMINAL(n=bControlSize控制位域長度,p=bmTransportModesSize 傳輸模式位域大小)
term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //輸入Terminal只有一個pad
case VC_OUTPUT_TERMINAL
term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //輸出Terminal只有一個pad
case VC_SELECTOR_UNIT:(p=Unit輸入引腳數)
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);            //選擇Unit有p個輸入pad,1個輸出pad
case VC_PROCESSING_UNIT(n=bControlSize控制位域長度)
unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);                //處理Unit只有1個輸入pad,1個輸出pad
case VC_EXTENSION_UNIT(n=bControlSize控制位域長度,p=Unit輸入引腳數)
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);            //擴展Unit有p個輸入pad,1個輸出pad

這裏的pad可以理解爲規範書上說的pin,畫了個圈圈那個叫做”pad”

  1. static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,unsigned int num_pads, unsigned int extra_size)  
  2. {  
  3.     struct uvc_entity *entity;  
  4.     unsigned int num_inputs;  
  5.     unsigned int size;  
  6.     num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;    //輸入Terminal個數=pad個數-1個輸出Terminal  
  7.     size = sizeof(*entity) + extra_size + num_inputs;   //uvc實體大小+額外尺寸+輸入Ternimal個數  
  8.     entity = kzalloc(size, GFP_KERNEL); //分配uvc實體內存  
  9.     if (entity == NULL)  
  10.         return NULL;  
  11.     entity->id = id; //設置uvc實體id  
  12.     entity->type = type; //設置uvc實體類型  
  13.     entity->bNrInPins = num_inputs;  //設置uvc實體輸入Terminal個數  
  14.     entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;    //Ternimal ID指針  
  15.     return entity;  
  16. }  
static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,unsigned int num_pads, unsigned int extra_size)
{
    struct uvc_entity *entity;
    unsigned int num_inputs;
    unsigned int size;
    num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;    //輸入Terminal個數=pad個數-1個輸出Terminal
    size = sizeof(*entity) + extra_size + num_inputs;   //uvc實體大小+額外尺寸+輸入Ternimal個數
    entity = kzalloc(size, GFP_KERNEL); //分配uvc實體內存
    if (entity == NULL)
        return NULL;
    entity->id = id; //設置uvc實體id
    entity->type = type; //設置uvc實體類型
    entity->bNrInPins = num_inputs;  //設置uvc實體輸入Terminal個數
    entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;    //Ternimal ID指針
    return entity;
}

這裏extra_size是給uvc實體的聯合體中的*指針變量(*bmControls、*bmTransportModes;)分配內存空間,而num_inputs是給*baSourceID(指向輸入Terminal ID)分配內存空間




發佈了14 篇原創文章 · 獲贊 9 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章