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

posted on 2017-05-22 11:52  Red_Point  阅读(3524)  评论(0编辑  收藏  举报

导航