uvc摄像头代码解析2

1.uvc驱动模块入口
module_init(uvc_init);  //1.模块入口
2.初始化函数
    static int __init uvc_init(void)    // 2.初始化函数  
    {  
        int result;  
        result = usb_register(&uvc_driver.driver);  // 3.注册usb设备驱动(usb摄像头设备)  
        if (result == 0)    //注册失败  
            printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");  
        return result;  
    }  
3.注册usb设备驱动(usb摄像头设备)

3.1 usb摄像头驱动

    struct uvc_driver uvc_driver = {    // 3.1 usb摄像头设备  
        .driver = {  
            .name       = "uvcvideo",  
            .probe      = uvc_probe,    // 4. probe方法  
            .disconnect = uvc_disconnect,  
            .suspend    = uvc_suspend,  
            .resume     = uvc_resume,  
            .reset_resume   = uvc_reset_resume,  
            .id_table   = uvc_ids,      //3.2 支持的设备id列表  
            .supports_autosuspend = 1,  
        },  
    };  
3.2 支持的设备id列表uvc_ids
    static struct usb_device_id uvc_ids[] = {  
        /* Genius eFace 2025 */  
        { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,  
          .idVendor     = 0x0458,  
          .idProduct        = 0x706e,  
          .bInterfaceClass  = USB_CLASS_VIDEO,  //uvc接口类 0x0e  
          .bInterfaceSubClass   = 1,  
          .bInterfaceProtocol   = 0,  
          .driver_info      = UVC_QUIRK_PROBE_MINMAX },  
        ...  
        ...  
        ...  
        /* SiGma Micro USB Web Camera */  
        { .match_flags      = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,  
          .idVendor     = 0x1c4f,  
          .idProduct        = 0x3000,  
          .bInterfaceClass  = USB_CLASS_VIDEO,  
          .bInterfaceSubClass   = 1,  
          .bInterfaceProtocol   = 0,  
          .driver_info      = UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT },  
        /* Generic USB Video Class */   //通用usb视频类  
        { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },  //匹配方法:uvc类  
        {}  
    };  
4.probe方法
    static int uvc_probe(struct usb_interface *intf,const struct usb_device_id *id)  
    {  
        struct usb_device *udev = interface_to_usbdev(intf);    //通过usb接口获取usb设备  
        struct uvc_device *dev; //声明uvc设备  
        int ret;  
        if (id->idVendor && id->idProduct)    //有厂商id和商品id(知名设备)  
            uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s (%04x:%04x)\n", udev->devpath, id->idVendor,id->idProduct);  
        else                                //通用uvc设备  
            uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",udev->devpath);  
        /* Allocate memory for the device and initialize it. */  
        if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)   //分配uvc设备内存  
            return -ENOMEM;  
        INIT_LIST_HEAD(&dev->entities);  //初始化entities(实体)链表 Terminal或Unit  
        INIT_LIST_HEAD(&dev->chains);    //初始化chains(链)链表  
        INIT_LIST_HEAD(&dev->streams);   //初始化streams(视频流)链表  
        atomic_set(&dev->nstreams, 0);  
        atomic_set(&dev->users, 0);  
        atomic_set(&dev->nmappings, 0);  
        dev->udev = usb_get_dev(udev);   //捆绑usb设备,并增加其引用计数  
        dev->intf = usb_get_intf(intf);  //捆绑usb接口,并增加其引用计数  
        dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;    //获取usb接口描述符接口数  
        dev->quirks = (uvc_quirks_param == -1) ? id->driver_info : uvc_quirks_param;  
        if (udev->product != NULL)   //存在产品名  
            strlcpy(dev->name, udev->product, sizeof dev->name);   //设置uvc设备名字为其产品名  
        else                        //通用的uvc设备名  
            snprintf(dev->name, sizeof dev->name,"UVC Camera (%04x:%04x)",le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));  
        /* Parse the Video Class control descriptor. */  
        if (uvc_parse_control(dev) < 0) {    //-->5 uvc解析usb视频类控制描述符  
            uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC descriptors.\n");  
            goto error;  
        }  
        uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",dev->uvc_version >> 8, dev->uvc_version & 0xff,  
            udev->product ? udev->product : "<unnamed>",le16_to_cpu(udev->descriptor.idVendor),le16_to_cpu(udev->descriptor.idProduct));  
        if (dev->quirks != id->driver_info) {  
            uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module parameter for testing purpose.\n", dev->quirks);  
            uvc_printk(KERN_INFO, "Please report required quirks to the linux-uvc-devel mailing list.\n");  
        }  
        /* Initialize controls. */  
        if (uvc_ctrl_init_device(dev) < 0)   //8.uvc初始化控制  
            goto error;  
        /* Scan the device for video chains. */  
        if (uvc_scan_device(dev) < 0)    //10.uvc扫描视频链  
            goto error;  
        /* Register video devices. */  
        if (uvc_register_chains(dev) < 0)    //11.uvc注册视频设备  
            goto error;  
        /* Save our data pointer in the interface data. */  
        usb_set_intfdata(intf, dev);    //设置uvc设备为usb接口的数据  
        /* Initialize the interrupt URB. */  
        if ((ret = uvc_status_init(dev)) < 0) {  //12 uvc设备状态初始化  
            uvc_printk(KERN_INFO, "Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n", ret);  
        }  
        uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");  
        usb_enable_autosuspend(udev);   //使能自动挂起  
        return 0;  
    error:  
        uvc_unregister_video(dev);  
        return -ENODEV;  
    }  
4.1 uvc设备结构体
    struct uvc_device {  
        struct usb_device *udev;    //usb设备指针  
        struct usb_interface *intf; //usb接口指针  
        unsigned long warnings;  
        __u32 quirks;  
        int intfnum;    //接口数  
        char name[32];  //设备名  
        enum uvc_device_state state;    //uvc设备状态  
        atomic_t users;  
        atomic_t nmappings;  
        /* Video control interface */  
        __u16 uvc_version;  //UVC协议版本  
        __u32 clock_frequency;  //时钟频率  
        struct list_head entities;  //uvc实体链表头(挂着uvc设备的Terminal和Unit)  
        struct list_head chains;    //uvc视频链链表头  
        /* Video Streaming interfaces */  
        struct list_head streams;   //uvc视频流链表头  
        atomic_t nstreams;//uvc视频流个数  
        /* Status Interrupt Endpoint */  
        struct usb_host_endpoint *int_ep;   //usb_host_endpoint对象  
        struct urb *int_urb;    //中断urb  
        __u8 *status;   //uvc设备状态标志  
        struct input_dev *input;    //输入设备  
        char input_phys[64];    //输入设备设备节点路径  
    };  

4.2 uvc协议标准上的描述符布局

     参考USB_Video_Class_1.1.pdf中 Figure 3-1 Video Camera Descriptor Layout Example

    -->(Interface Association Descript)IDA接口描述符  
    -->标准VC接口描述符 --------------------------------VC(video control)  
        -->uvc类视频接口描述符(header)-->输入Terminal接口描述符-->处理Unit接口描述符-->编码Unit接口描述符-->输出Terminal接口描述符  
    -->标准中断端点描述符  
        -->uvc类中断端点描述符  
    -->标准VS接口描述符 --------------------------------VS(video streaming) Alt.Setting 0  
        -->uvc类视频接口描述符(header)-->format负荷格式描述符-->若干frame-->静态图像帧格式描述符  
        -->uvc类视频接口描述符(header)-->format负荷格式描述符-->若干frame-->静态图像帧格式描述符->颜色匹配描述符  
        ...(1...n)  
        -->Bulk-in 静态图像数据端点描述符  
    -->标准VS接口描述符 --------------------------------VS(video streaming) Alt.Setting 1  
        -->标准同步输入视频端点描述符  
        -->Bulk-in 静态图像数据端点描述符  
    ...(1...n)  
    -->标准VS接口描述符 --------------------------------VS(video streaming) Alt.Setting n  
        -->标准同步输入视频端点描述符  
        -->Bulk-in 静态图像数据端点描述符  

这些布局是可变的 但大体布局是这样,下面两张图也是典型的布局


具体分析的时候可以利用lsubs工具打印所有描述符来分析

usb描述符的框架图

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

Bus 001 Device 002: ID 0c45:62f1 Microdia   //总线 设备ID  
Device Descriptor:                          //设备描述符  
  bLength                18  
  bDescriptorType         1  
  bcdUSB               2.00  
  bDeviceClass          239 Miscellaneous Device  
  bDeviceSubClass         2 ?  
  bDeviceProtocol         1 Interface Association  
  bMaxPacketSize0        64  
  idVendor           0x0c45 Microdia  
  idProduct          0x62f1   
  bcdDevice            1.00  
  iManufacturer           2 Sonix Technology Co., Ltd.  
  iProduct                1 USB 2.0 Camera  
  iSerial                 0   
  bNumConfigurations      1  
  Configuration Descriptor:                 //配置描述符  
    bLength                 9  
    bDescriptorType         2  
    wTotalLength          697  
    bNumInterfaces          4  
    bConfigurationValue     1  
    iConfiguration          0   
    bmAttributes         0x80  
      (Bus Powered)  
    MaxPower              500mA  
    Interface Association:                  //3.6 Interface Association Descriptor   
      bLength                 8  
      bDescriptorType        11  
      bFirstInterface         0  
      bInterfaceCount         2  
      bFunctionClass         14 Video  
      bFunctionSubClass       3 Video Interface Collection  
      bFunctionProtocol       0   
      iFunction               5 USB Camera  
    Interface Descriptor:                   //Table 3-2 Standard VC Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        0  
      bAlternateSetting       0  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      1 Video Control  
      bInterfaceProtocol      0   
      iInterface              5 USB Camera  
      VideoControl Interface Descriptor:    //Table 3-3 Class-specific VC Interface Header Descriptor  
        bLength                13  
        bDescriptorType        36  
        bDescriptorSubtype      1 (HEADER)    
        bcdUVC               1.00  
        wTotalLength          103  
        dwClockFrequency       15.000000MHz  
        bInCollection           1  
        baInterfaceNr( 0)       1  
      VideoControl Interface Descriptor:    //Table 3-5 Output Terminal Descriptor  
        bLength                 9  
        bDescriptorType        36  
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)  
        bTerminalID             2  
        wTerminalType      0x0101 USB Streaming  
        bAssocTerminal          0  
        bSourceID               5  
        iTerminal               0   
      VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor  
        bLength                26  
        bDescriptorType        36  
        bDescriptorSubtype      6 (EXTENSION_UNIT)  
        bUnitID                 4  
        guidExtensionCode         {7033f028-1163-2e4a-ba2c-6890eb334016}  
        bNumControl             8  
        bNrPins                 1  
        baSourceID( 0)          3  
        bControlSize            1  
        bmControls( 0)       0x0f  
        iExtension              0   
      VideoControl Interface Descriptor:    //Table 3-10 Extension Unit Descriptor  
        bLength                26  
        bDescriptorType        36  
        bDescriptorSubtype      6 (EXTENSION_UNIT)  
        bUnitID                 5  
        guidExtensionCode         {3fae1228-d7bc-114e-a357-6f1edef7d61d}  
        bNumControl             8  
        bNrPins                 1  
        baSourceID( 0)          4  
        bControlSize            1  
        bmControls( 0)       0xff  
        iExtension              0   
      VideoControl Interface Descriptor:    //Table 3-6 Camera Terminal Descriptor  
        bLength                18  
        bDescriptorType        36  
        bDescriptorSubtype      2 (INPUT_TERMINAL)  
        bTerminalID             1  
        wTerminalType      0x0201 Camera Sensor  
        bAssocTerminal          0  
        iTerminal               0   
        wObjectiveFocalLengthMin      0  
        wObjectiveFocalLengthMax      0  
        wOcularFocalLength            0  
        bControlSize                  3  
        bmControls           0x00000000  
      VideoControl Interface Descriptor:    //Table 3-8 Processing Unit Descriptor  
        bLength                11  
        bDescriptorType        36  
        bDescriptorSubtype      5 (PROCESSING_UNIT)  
      Warning: Descriptor too short  
        bUnitID                 3  
        bSourceID               1  
        wMaxMultiplier          0  
        bControlSize            2  
        bmControls     0x0000053f  
          Brightness  
          Contrast  
          Hue  
          Saturation  
          Sharpness  
          Gamma  
          Backlight Compensation  
          Power Line Frequency  
        iProcessing             0   
        bmVideoStandards     0x 0  
      Endpoint Descriptor:                  //Table 3-11 Standard VC Interrupt Endpoint Descriptor  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x83  EP 3 IN  
        bmAttributes            3  
          Transfer Type            Interrupt  
          Synch Type               None  
          Usage Type               Data  
        wMaxPacketSize     0x0010  1x 16 bytes  
        bInterval               6  
    Interface Descriptor:                   //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       0  
      bNumEndpoints           0  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      VideoStreaming Interface Descriptor:      //Table 3-14 Class-specific VS Interface Input Header Descriptor  
        bLength                            14  
        bDescriptorType                    36  
        bDescriptorSubtype                  1 (INPUT_HEADER)  
        bNumFormats                         1  
        wTotalLength                      323  
        bEndPointAddress                  129  
        bmInfo                              0  
        bTerminalLink                       2  
        bStillCaptureMethod                 2  
        bTriggerSupport                     1  
        bTriggerUsage                       1  
        bControlSize                        1  
        bmaControls( 0)                    27  
      VideoStreaming Interface Descriptor:      //Table 3-1 Uncompressed Video Format Descriptor  
        bLength                            27  
        bDescriptorType                    36  
        bDescriptorSubtype                  4 (FORMAT_UNCOMPRESSED)  
        bFormatIndex                        1  
        bNumFrameDescriptors                5  
        guidFormat                            {59555932-0000-1000-8000-00aa00389b71}  
        bBitsPerPixel                      16  
        bDefaultFrameIndex                  1  
        bAspectRatioX                       0  
        bAspectRatioY                       0  
        bmInterlaceFlags                 0x00  
          Interlaced stream or variable: No  
          Fields per frame: 1 fields  
          Field 1 first: No  
          Field pattern: Field 1 only  
          bCopyProtect                      0  
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
        bLength                            50  
        bDescriptorType                    36  
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
        bFrameIndex                         1  
        bmCapabilities                   0x00  
          Still image unsupported  
        wWidth                            640  
        wHeight                           480  
        dwMinBitRate                 24576000  
        dwMaxBitRate                147456000  
        dwMaxVideoFrameBufferSize      614400  
        dwDefaultFrameInterval         333333  
        bFrameIntervalType                  6  
        dwFrameInterval( 0)            333333  
        dwFrameInterval( 1)            400000  
        dwFrameInterval( 2)            500000  
        dwFrameInterval( 3)            666666  
        dwFrameInterval( 4)           1000000  
        dwFrameInterval( 5)           2000000  
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
        bLength                            50  
        bDescriptorType                    36  
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
        bFrameIndex                         2  
        bmCapabilities                   0x00  
          Still image unsupported  
        wWidth                            352  
        wHeight                           288  
        dwMinBitRate                  8110080  
        dwMaxBitRate                 48660480  
        dwMaxVideoFrameBufferSize      202752  
        dwDefaultFrameInterval         333333  
        bFrameIntervalType                  6  
        dwFrameInterval( 0)            333333  
        dwFrameInterval( 1)            400000  
        dwFrameInterval( 2)            500000  
        dwFrameInterval( 3)            666666  
        dwFrameInterval( 4)           1000000  
        dwFrameInterval( 5)           2000000  
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
        bLength                            50  
        bDescriptorType                    36  
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
        bFrameIndex                         3  
        bmCapabilities                   0x00  
          Still image unsupported  
        wWidth                            320  
        wHeight                           240  
        dwMinBitRate                  6144000  
        dwMaxBitRate                 36864000  
        dwMaxVideoFrameBufferSize      153600  
        dwDefaultFrameInterval         333333  
        bFrameIntervalType                  6  
        dwFrameInterval( 0)            333333  
        dwFrameInterval( 1)            400000  
        dwFrameInterval( 2)            500000  
        dwFrameInterval( 3)            666666  
        dwFrameInterval( 4)           1000000  
        dwFrameInterval( 5)           2000000  
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
        bLength                            50  
        bDescriptorType                    36  
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
        bFrameIndex                         4  
        bmCapabilities                   0x00  
          Still image unsupported  
        wWidth                            176  
        wHeight                           144  
        dwMinBitRate                  2027520  
        dwMaxBitRate                 12165120  
        dwMaxVideoFrameBufferSize       50688  
        dwDefaultFrameInterval         333333  
        bFrameIntervalType                  6  
        dwFrameInterval( 0)            333333  
        dwFrameInterval( 1)            400000  
        dwFrameInterval( 2)            500000  
        dwFrameInterval( 3)            666666  
        dwFrameInterval( 4)           1000000  
        dwFrameInterval( 5)           2000000  
      VideoStreaming Interface Descriptor:      //Table 3-2 Uncompressed Video Frame Descriptors  
        bLength                            50  
        bDescriptorType                    36  
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)  
        bFrameIndex                         5  
        bmCapabilities                   0x00  
          Still image unsupported  
        wWidth                            160  
        wHeight                           120  
        dwMinBitRate                  1536000  
        dwMaxBitRate                  9216000  
        dwMaxVideoFrameBufferSize       38400  
        dwDefaultFrameInterval         333333  
        bFrameIntervalType                  6  
        dwFrameInterval( 0)            333333  
        dwFrameInterval( 1)            400000  
        dwFrameInterval( 2)            500000  
        dwFrameInterval( 3)            666666  
        dwFrameInterval( 4)           1000000  
        dwFrameInterval( 5)           2000000  
      VideoStreaming Interface Descriptor:      //Table 3-18 Still Image Frame Descriptor  
        bLength                            26  
        bDescriptorType                    36  
        bDescriptorSubtype                  3 (STILL_IMAGE_FRAME)  
        bEndpointAddress                    0  
        bNumImageSizePatterns               5  
        wWidth( 0)                        640  
        wHeight( 0)                       480  
        wWidth( 1)                        352  
        wHeight( 1)                       288  
        wWidth( 2)                        320  
        wHeight( 2)                       240  
        wWidth( 3)                        176  
        wHeight( 3)                       144  
        wWidth( 4)                        160  
        wHeight( 4)                       120  
        bNumCompressionPatterns             5  
      VideoStreaming Interface Descriptor:      //Table 3-19 Color Matching Descriptor  
        bLength                             6  
        bDescriptorType                    36  
        bDescriptorSubtype                 13 (COLORFORMAT)  
        bColorPrimaries                     1 (BT.709,sRGB)  
        bTransferCharacteristics            1 (BT.709)  
        bMatrixCoefficients                 4 (SMPTE 170M (BT.601))  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       1  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x0080  1x 128 bytes  
        bInterval               1  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       2  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x0100  1x 256 bytes  
        bInterval               1  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       3  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x0320  1x 800 bytes  
        bInterval               1  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       4  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x0b20  2x 800 bytes  
        bInterval               1  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       5  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x1320  3x 800 bytes  
        bInterval               1  
    Interface Descriptor:                       //Table 3-13 Standard VS Interface Descriptor  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        1  
      bAlternateSetting       6  
      bNumEndpoints           1  
      bInterfaceClass        14 Video  
      bInterfaceSubClass      2 Video Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      Endpoint Descriptor:                      //Table 3-20 Standard VS Isochronous Video Data Endpoint Descriptor  
        bLength                 7  
        bDescriptorType         5  
        bEndpointAddress     0x81  EP 1 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x1400  3x 1024 bytes  
        bInterval               1  
音频部分  
    Interface Association:                        
      bLength                 8  
      bDescriptorType        11  
      bFirstInterface         2  
      bInterfaceCount         2  
      bFunctionClass          1 Audio  
      bFunctionSubClass       0   
      bFunctionProtocol       0   
      iFunction               4 USB Microphone  
    Interface Descriptor:  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        2  
      bAlternateSetting       0  
      bNumEndpoints           0  
      bInterfaceClass         1 Audio  
      bInterfaceSubClass      1 Control Device  
      bInterfaceProtocol      0   
      iInterface              4 USB Microphone  
      AudioControl Interface Descriptor:  
        bLength                 9  
        bDescriptorType        36  
        bDescriptorSubtype      1 (HEADER)  
        bcdADC               1.00  
        wTotalLength           41  
        bInCollection           1  
        baInterfaceNr( 0)       3  
      AudioControl Interface Descriptor:  
        bLength                12  
        bDescriptorType        36  
        bDescriptorSubtype      2 (INPUT_TERMINAL)  
        bTerminalID             1  
        wTerminalType      0x0201 Microphone  
        bAssocTerminal          0  
        bNrChannels             1  
        wChannelConfig     0x0000  
        iChannelNames           0   
        iTerminal               0   
      AudioControl Interface Descriptor:  
        bLength                11  
        bDescriptorType        36  
        bDescriptorSubtype      6 (FEATURE_UNIT)  
        bUnitID                 2  
        bSourceID               1  
        bControlSize            2  
        bmaControls( 0)      0x01  
        bmaControls( 0)      0x00  
          Mute  
        bmaControls( 1)      0x02  
        bmaControls( 1)      0x00  
          Volume  
        iFeature                0   
      AudioControl Interface Descriptor:  
        bLength                 9  
        bDescriptorType        36  
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)  
        bTerminalID             3  
        wTerminalType      0x0101 USB Streaming  
        bAssocTerminal          0  
        bSourceID               2  
        iTerminal               0   
    Interface Descriptor:  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        3  
      bAlternateSetting       0  
      bNumEndpoints           0  
      bInterfaceClass         1 Audio  
      bInterfaceSubClass      2 Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
    Interface Descriptor:  
      bLength                 9  
      bDescriptorType         4  
      bInterfaceNumber        3  
      bAlternateSetting       1  
      bNumEndpoints           1  
      bInterfaceClass         1 Audio  
      bInterfaceSubClass      2 Streaming  
      bInterfaceProtocol      0   
      iInterface              0   
      AudioStreaming Interface Descriptor:  
        bLength                 7  
        bDescriptorType        36  
        bDescriptorSubtype      1 (AS_GENERAL)  
        bTerminalLink           3  
        bDelay                  1 frames  
        wFormatTag              1 PCM  
      AudioStreaming Interface Descriptor:  
        bLength                29  
        bDescriptorType        36  
        bDescriptorSubtype      2 (FORMAT_TYPE)  
        bFormatType             1 (FORMAT_TYPE_I)  
        bNrChannels             1  
        bSubframeSize           2  
        bBitResolution         16  
        bSamFreqType            7 Discrete  
        tSamFreq[ 0]         8000  
        tSamFreq[ 1]        11025  
        tSamFreq[ 2]        16000  
        tSamFreq[ 3]        22050  
        tSamFreq[ 4]        24000  
        tSamFreq[ 5]        44100  
        tSamFreq[ 6]        48000  
      Endpoint Descriptor:  
        bLength                 9  
        bDescriptorType         5  
        bEndpointAddress     0x84  EP 4 IN  
        bmAttributes            5  
          Transfer Type            Isochronous  
          Synch Type               Asynchronous  
          Usage Type               Data  
        wMaxPacketSize     0x0190  1x 400 bytes  
        bInterval               4  
        bRefresh                0  
        bSynchAddress           0  
        AudioControl Endpoint Descriptor:  
          bLength                 7  
          bDescriptorType        37  
          bDescriptorSubtype      1 (EP_GENERAL)  
          bmAttributes         0x01  
            Sampling Frequency  
          bLockDelayUnits         0 Undefined  
          wLockDelay              0 Undefined  
/  
Device Qualifier (for other device speed):  //设备限定符  
  bLength                10  
  bDescriptorType         6  
  bcdUSB               2.00  
  bDeviceClass          239 Miscellaneous Device  
  bDeviceSubClass         2 ?  
  bDeviceProtocol         1 Interface Association  
  bMaxPacketSize0        64  
  bNumConfigurations      1  
Device Status:     0x0002  
  (Bus Powered)  
  Remote Wakeup Enabled
可以通过描述符布局,分析出摄像头框架

第一步找出Terminal和Unit的(bTerminalID/bUnitID)
IT(1)
OT(2)
XU(4)
XU(5)
PU(3)
第二步从OT输出Terminal开始分析
OT(2)的bSourceID=5
所以XU(5)->OT(2)
XU(5)的bNrPins=1所以只有一个输入baSourceID( 0)=4
所以XU(4)->XU(5)->OT(2)
XU(4)的bNrPins=1所以只有一个输入baSourceID( 0)=3
所以PU(3)->XU(4)->XU(5)->OT(2)
PU(3)的bSourceID=1
所以IT(1)->PU(3)->XU(4)->XU(5)->OT(2)

 4.3 probe方法初始化uvc设备结构体对象

 

 5 uvc解析usb视频类控制描述符

    static int uvc_parse_control(struct uvc_device *dev)  
    {  
        struct usb_host_interface *alts = dev->intf->cur_altsetting;  //获取当前usb_host_interface  
        unsigned char *buffer = alts->extra; //额外描述符  
        int buflen = alts->extralen; //额外描述符长度  
        int ret;  
        /* 解析默认的交替设置,正如UVC标准协议定义的单个交替设置,默认是交替设置0(Alt.Setting 0)*/  
        while (buflen > 2) {  
            if (uvc_parse_vendor_control(dev, buffer, buflen) || buffer[1] != USB_DT_CS_INTERFACE)  //5.1解析厂商特殊控制  
                goto next_descriptor;   //特殊厂商处理则直接跳过标准处理  
            if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0) //5.2.解析uvc标准控制  
                return ret;  
    next_descriptor:    //buffer[0]是bLength描述符长度  
            buflen -= buffer[0];    //调整buflen长度  
            buffer += buffer[0];    //调整buffer指针  
        }  
//判断描述符是否有1个端点  
if (alts->desc.bNumEndpoints == 1 && !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {  
    struct usb_host_endpoint *ep = &alts->endpoint[0];   //获取usb_host_endpoint  
    struct usb_endpoint_descriptor *desc = &ep->desc;    //获取端点描述符  
    //判断是否中断输入端点  
    if (usb_endpoint_is_int_in(desc) && le16_to_cpu(desc->wMaxPacketSize) >= 8 && desc->bInterval != 0) {  
        uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint (addr %02x).\n", desc->bEndpointAddress);  
        dev->int_ep = ep;  
    }  
}  
return 0; 
5.1 解析厂商特殊控制 (特殊厂商处理返回1,不是返回0)
    static int uvc_parse_vendor_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)  
    {  
        struct usb_device *udev = dev->udev;  
        struct usb_host_interface *alts = dev->intf->cur_altsetting;  //获取usb_host_interface  
        struct uvc_entity *unit;  
        unsigned int n, p;  
        int handled = 0;    //返回值 默认为0  
        switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {  
        case 0x046d:        /* Logitech 罗技*/  
            ...  
            handled = 1;    //特殊厂商处理则返回1  
            break;  
        }  
        return handled;  
    }  
5.1.1 uvc实体结构体
    struct uvc_entity { //uvc实体  
        struct list_head list;  //实体链表头  
        struct list_head chain; //视频链链表头  
        __u8 id;    //实体id  
        __u16 type; //实体类型  
        char name[64];  //实体名  
        union {  
            struct {  
                __u16 wObjectiveFocalLengthMin;  
                __u16 wObjectiveFocalLengthMax;  
                __u16 wOcularFocalLength;  
                __u8  bControlSize; //控制位域大小  
                __u8  *bmControls;  //控制位图指针  
            } camera;       //输入Terminal UVC_ITT_CAMERA  
            struct {  
                __u8  bControlSize; //控制位域大小  
                __u8  *bmControls;  //控制位图指针  
                __u8  bTransportModeSize;  
                __u8  *bmTransportModes;  
            } media;        //输入Terminal UVC_ITT_MEDIA_TRANSPORT_INPUT  
            struct {  
            } output;       //输出Terminal  
            //处理Unit  
            struct {  
                __u16 wMaxMultiplier;  
                __u8  bControlSize; //控制位域大小  
                __u8  *bmControls;  //控制位图指针  
                __u8  bmVideoStandards;  
            } processing;   //处理Unit  
            //选择器Unit  
            struct {  
            } selector;     //选择器Unit  
            //扩展Unit  
            struct {  
                __u8  guidExtensionCode[16];  
                __u8  bNumControls;  
                __u8  bControlSize; //控制位域大小  
                __u8  *bmControls;  //控制位图指针  
                __u8  *bmControlsType;  
            } extension;    //扩展Unit  
        };  
        __u8 bNrInPins; //输入引脚数  
        __u8 *baSourceID;   //第一个输入引脚ID(Terminal/Unit ID)  
        unsigned int ncontrols; //uvc控制个数  
        struct uvc_control *controls;   //ucv控制数组指针  
    };  

5.2 解析uvc标准控制
    static int uvc_parse_standard_control(struct uvc_device *dev,const unsigned char *buffer, int buflen)  
    {  
        struct usb_device *udev = dev->udev; //获取usb设备  
        struct uvc_entity *unit, *term; //uvc实体Unit或Terminal  
        struct usb_interface *intf; //usb接口  
        struct usb_host_interface *alts = dev->intf->cur_altsetting;  //获取当前usb接口配置描述符  
        unsigned int i, n, p, len;  
        __u16 type;  
          
        switch (buffer[2]) {    //buffer[2]存放bDescriptorSubType  
Table 3-3 Class-specific VC Interface Header Descriptor
    case UVC_VC_HEADER: //vc 接口头部描述符  
        n = buflen >= 12 ? buffer[11] : 0;   //bInCollection 视频流接口数  
        if (buflen < 12 || buflen < 12 + n) {  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d HEADER error\n", udev->devnum,alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        dev->uvc_version = get_unaligned_le16(&buffer[3]);   //bcdUVC  
        dev->clock_frequency = get_unaligned_le32(&buffer[7]);   //获取时钟频率  
        /* Parse all USB Video Streaming interfaces. 解析所有USB视频接口*/  
        for (i = 0; i < n; ++i) {    //遍历视频流接口  
            intf = usb_ifnum_to_if(udev, buffer[12+i]); //baInterfaceNr(n) 获取视频流对应的usb接口  
            if (intf == NULL) {  
                uvc_trace(UVC_TRACE_DESCR, "device %d interface %d doesn't exists\n",udev->devnum, i);  
                continue;  
            }  
            uvc_parse_streaming(dev, intf); //6.uvc解析uvc视频流  
        }  
        break;  
Table 3-4 Input Terminal Descriptor
    case UVC_VC_INPUT_TERMINAL: //UVC输入Terminal  
        if (buflen < 8) {    //检验buflen长度  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/  
        type = get_unaligned_le16(&buffer[4]);  //获取Terminal类型(ITT_ VENDOR_SPECIFIC/ITT_CAMERA/ITT_MEDIA_TRANSPORT_INPUT)  
        if ((type & 0xff00) == 0) { //错误类型  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\n", udev->devnum,alts->desc.bInterfaceNumber,buffer[3], type);  
            return 0;  
        }  
        n = 0;  
        p = 0;  
        len = 8;    //标准长度(0~7)  
Table 3-6 Camera Terminal Descriptor
    if (type == UVC_ITT_CAMERA) {   //摄像头传感器    (speciafication.pdf P67)  
        n = buflen >= 15 ? buffer[14] : 0;   //bControlSize 控制位域大小     
        len = 15;  
    }   
    else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {   //连续的媒体 (USB_Video_Transport_1.5.pdf P11)  
        n = buflen >= 9 ? buffer[8] : 0; //bControlSize 控制位域大小  
        p = buflen >= 10 + n ? buffer[9+n] : 0;  //bmTransportModesSize 传输模式位域大小  
        len = 10;  
    }  
    if (buflen < len + n + p) {  //检验buflen长度是否合适  
        uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d INPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);  
        return -EINVAL;  
    }  
    term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //分配uvc实体 buffer[3]是实体ID  
    if (term == NULL)  
        return -ENOMEM;  
    if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {  //摄像头传感器      
        term->camera.bControlSize = n;   //bControlSize 控制位域大小  
        term->camera.bmControls = (__u8 *)term + sizeof *term;   //bmControls 控制位图指针  
        term->camera.wObjectiveFocalLengthMin = get_unaligned_le16(&buffer[8]);  // wObjectiveFocalLengthMin 焦点长度最小值  
        term->camera.wObjectiveFocalLengthMax = get_unaligned_le16(&buffer[10]); //wObjectiveFocalLengthMax 焦点长度最大值  
        term->camera.wOcularFocalLength = get_unaligned_le16(&buffer[12]);   //wOcularFocalLength  Ocular焦距  
        memcpy(term->camera.bmControls, &buffer[15], n); //初始化控制位图  
    }   

    else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) {  //连续的媒体  
        term->media.bControlSize = n;    //bControlSize 控制位域大小  
        term->media.bmControls = (__u8 *)term + sizeof *term;    //bmControls控制位图指针  
        term->media.bTransportModeSize = p;  //bTransportModeSize 传输模式位域大小  
        term->media.bmTransportModes = (__u8 *)term + sizeof *term + n;  //bmTransportModes传输模式位图指针  
        memcpy(term->media.bmControls, &buffer[9], n);   //初始化控制位图  
        memcpy(term->media.bmTransportModes, &buffer[10+n], p);  //初始化传输模式位图  
    }  
    if (buffer[7] != 0) //设置实体名  
        usb_string(udev, buffer[7], term->name,sizeof term->name);  
    else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)   //设置Camera Terminal实体名  
        sprintf(term->name, "Camera %u", buffer[3]);  
    else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)    //设置Media Terminal实体名  
        sprintf(term->name, "Media %u", buffer[3]);  
    else      
        sprintf(term->name, "Input %u", buffer[3]);  
    list_add_tail(&term->list, &dev->entities);   //添加uvc实体到uvc实体链表中  
    break;  
Table 3-5 Output Terminal Descriptor
    case UVC_VC_OUTPUT_TERMINAL:    //UVC输出Terminal  
        if (buflen < 9) {    //检验buflen长度  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d OUTPUT_TERMINAL error\n",udev->devnum, alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        /* Make sure the terminal type MSB is not null, otherwise it could be confused with a unit.*/  
        type = get_unaligned_le16(&buffer[4]);  //wTerminalType 输出Terminal类型  
        if ((type & 0xff00) == 0) {  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d OUTPUT_TERMINAL %d has invalid type 0x%04x, skipping\n", udev->devnum,  
                alts->desc.bInterfaceNumber, buffer[3], type);  
            return 0;  
        }  
        term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //分配uvc实体 buffer[3]是实体ID  
        if (term == NULL)  
            return -ENOMEM;  
        memcpy(term->baSourceID, &buffer[7], 1); //复制Terminal ID到baSourceID  
        if (buffer[8] != 0) //设置Terminal实体名  
            usb_string(udev, buffer[8], term->name,sizeof term->name);  
        else    //设置output Terminal实体名  
            sprintf(term->name, "Output %u", buffer[3]);  
        list_add_tail(&term->list, &dev->entities);   //添加uvc实体到uvc实体链表中  
        break;  
Table 3-7 Selector Unit Descriptor
    case UVC_VC_SELECTOR_UNIT:  //UVC选择器Unit  
        p = buflen >= 5 ? buffer[4] : 0; //Unit输入引脚数  
        if (buflen < 5 || buflen < 6 + p) {   //检验buflen是否符合  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d SELECTOR_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);    //分配uvc实体 buffer[3]是实体ID  
        if (unit == NULL)  
            return -ENOMEM;  
        memcpy(unit->baSourceID, &buffer[5], p); //复制Unit ID到bSourceID  
        if (buffer[5+p] != 0)   //设置selector Unit名  
            usb_string(udev, buffer[5+p], unit->name,sizeof unit->name);  
        else  
            sprintf(unit->name, "Selector %u", buffer[3]);  
        list_add_tail(&unit->list, &dev->entities);   //添加uvc实体到uvc实体链表中  
        break;  
Table 3-8 Processing Unit Descriptor
    case UVC_VC_PROCESSING_UNIT:    //UVC处理Unit  
        n = buflen >= 8 ? buffer[7] : 0; //bControlSize控制位域大小  
        p = dev->uvc_version >= 0x0110 ? 10 : 9;  //uvc类协议版本  
        if (buflen < p + n) {        //检验buflen长度是否符合  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d PROCESSING_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);    //分配uvc实体 buffer[3]是实体ID  
        if (unit == NULL)  
            return -ENOMEM;  
        memcpy(unit->baSourceID, &buffer[4], 1); //复制Unit ID到bSourceID  
        unit->processing.wMaxMultiplier = get_unaligned_le16(&buffer[5]);    //最大数字放大率  
        unit->processing.bControlSize = buffer[7];   //bControlSize 控制位域大小  
        unit->processing.bmControls = (__u8 *)unit + sizeof *unit;   //bmControls控制位图指针  
        memcpy(unit->processing.bmControls, &buffer[8], n);  //初始化控制位图  
        if (dev->uvc_version >= 0x0110)   //版本大于1.1  
            unit->processing.bmVideoStandards = buffer[9+n]; //设置视频标准支持位图  
        if (buffer[8+n] != 0)   //设置处理Unit名  
            usb_string(udev, buffer[8+n], unit->name,sizeof unit->name);  
        else  
            sprintf(unit->name, "Processing %u", buffer[3]);  
        list_add_tail(&unit->list, &dev->entities);   //添加uvc实体到uvc实体链表中  
        break;  
Table 3-9 Extension Unit Descriptor
    case UVC_VC_EXTENSION_UNIT: //UVC扩展Unit  
        p = buflen >= 22 ? buffer[21] : 0;   //Unit输入引脚数  
        n = buflen >= 24 + p ? buffer[22+p] : 0; //bControlSize控制位域长度  
        if (buflen < 24 + p + n) {   //判断buflen长度是否符合  
            uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d EXTENSION_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);  
            return -EINVAL;  
        }  
        unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);    //分配uvc实体 buffer[3]是实体ID  
        if (unit == NULL)  
            return -ENOMEM;  
        memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);   //guidExtensionCode 厂商特殊代码id  
        unit->extension.bNumControls = buffer[20];   //Unit的控件数  
        memcpy(unit->baSourceID, &buffer[22], p);    //复制Unit ID到baSourceID  
        unit->extension.bControlSize = buffer[22+p]; //bControlSize 控制位域大小  
        unit->extension.bmControls = (__u8 *)unit + sizeof *unit;    //bmControls控制位图指针  
        memcpy(unit->extension.bmControls, &buffer[23+p], n);    //初始化控制位图  
        if (buffer[23+p+n] != 0)    //设置扩展Unit实体名  
            usb_string(udev, buffer[23+p+n], unit->name,sizeof unit->name);  
        else  
            sprintf(unit->name, "Extension %u", buffer[3]);  
        list_add_tail(&unit->list, &dev->entities);   //添加uvc实体到uvc实体链表中  
        break;  
    default:  
        uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE descriptor (%u)\n", buffer[2]);  
        break;  
    }  
    return 0;  

5.2.1 添加uvc实体到uvc设备的实体链表下

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


5.2.2 分配uvc实体

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

    case VC_INPUT_TERMINAL(n=bControlSize控制位域长度,p=bmTransportModesSize 传输模式位域大小)  
    term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],1, n + p); //输入Terminal只有一个pad  
    case VC_OUTPUT_TERMINAL  
    term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],1, 0);    //输出Terminal只有一个pad  
    case VC_SELECTOR_UNIT:(p=Unit输入引脚数)  
    unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);            //选择Unit有p个输入pad,1个输出pad  
    case VC_PROCESSING_UNIT(n=bControlSize控制位域长度)  
    unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);                //处理Unit只有1个输入pad,1个输出pad  
    case VC_EXTENSION_UNIT(n=bControlSize控制位域长度,p=Unit输入引脚数)  
    unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);            //扩展Unit有p个输入pad,1个输出pad  
这里的pad可以理解为规范书上说的pin,画了个圈圈那个叫做"pad"
    static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,unsigned int num_pads, unsigned int extra_size)  
    {  
        struct uvc_entity *entity;  
        unsigned int num_inputs;  
        unsigned int size;  
        num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;    //输入Terminal个数=pad个数-1个输出Terminal  
        size = sizeof(*entity) + extra_size + num_inputs;   //uvc实体大小+额外尺寸+输入Ternimal个数  
        entity = kzalloc(size, GFP_KERNEL); //分配uvc实体内存  
        if (entity == NULL)  
            return NULL;  
        entity->id = id; //设置uvc实体id  
        entity->type = type; //设置uvc实体类型  
        entity->bNrInPins = num_inputs;  //设置uvc实体输入Terminal个数  
        entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;    //Ternimal ID指针  
        return entity;  
    }  
这里extra_size是给uvc实体的联合体中的*指针变量(*bmControls、*bmTransportModes;)分配内存空间,而num_inputs是给*baSourceID(指向输入Terminal ID)分配内存空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值