uvc攝像頭代碼解析2


轉載於: http://blog.csdn.net/orz415678659/article/details/10022993

 

1.uvc驅動模塊入口

[cpp] view plain copy
 
  1. module_init(uvc_init);  //1.模塊入口  

2.初始化函數

[cpp] view plain copy
 
  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. }  

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

3.1 usb攝像頭驅動

[cpp] view plain copy
 
  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. };  

3.2 支持的設備id列表uvc_ids

[cpp] view plain copy
 
  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. };  

4.probe方法

[cpp] view plain copy
 
  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. }  

4.1 uvc設備結構體

[cpp] view plain copy
 
  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. };  

4.2 uvc協議標准上的描述符布局



[cpp] view plain copy
 
  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 靜態圖像數據端點描述符  

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




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

usb描述符的框架圖

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

 

[cpp] view plain copy
 
  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  

可以通過描述符布局,分析出攝像頭框架
第一步找出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視頻類控制描述符

[cpp] view plain copy
 
  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;   //特殊廠商處理則直接跳過標准處理  

   }

[cpp] view plain copy
 
  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.     }  

[cpp] view plain copy
 
  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;  

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

[cpp] view plain copy
 
  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. }  

5.1.1 uvc實體結構體

[cpp] view plain copy
 
  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. };  

5.2 解析uvc標准控制

[cpp] view plain copy
 
  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  

[cpp] view plain copy
 
  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;  

[cpp] view plain copy
 
  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)  

[cpp] view plain copy
 
  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. }   

[cpp] view plain copy
 
  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;  


[cpp] view plain copy
 
  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;  

[cpp] view plain copy
 
  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;  

[cpp] view plain copy
 
  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;  

[cpp] view plain copy
 
  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 廠商特殊代碼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;  

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) 

[cpp] view plain copy
 
  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  

這里的pad可以理解為規范書上說的pin,畫了個圈圈那個叫做"pad"

[cpp] view plain copy
 
  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. }  

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

 
4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM