1. 程式人生 > >uvc攝像頭程式碼解析之描述符

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協議標準上的描述符佈局

-->(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

	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;

	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)

		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;

	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;

	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;

	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;

	case UVC_VC_EXTENSION_UNIT:	//UVC擴充套件Unit
		p = buflen >= 22 ? buffer[21] : 0;	//Unit輸入引腳數
		n = buflen >= 24 + p ? buffer[22+p] : 0;	//bControlSize控制位域長度
		if (buflen < 24 + p + n) {	//判斷buflen長度是否符合
			uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol interface %d EXTENSION_UNIT error\n",udev->devnum, alts->desc.bInterfaceNumber);
			return -EINVAL;
		}
		unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);	//分配uvc實體 buffer[3]是實體ID
		if (unit == NULL)
			return -ENOMEM;
		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);	//guidExtensionCode 廠商特殊<span class="wp_keywordlink" style="margin: 0px; padding: 0px; border: 0px; background: transparent;"><a target=_blank href="http://www.xuebuyuan.com/" title="程式碼" target="_blank" style="text-decoration: none; color: rgb(1, 150, 227);">程式碼</a></span>id
		unit->extension.bNumControls = buffer[20];	//Unit的控制元件數
		memcpy(unit->baSourceID, &buffer[22], p);	//複製Unit ID到baSourceID
		unit->extension.bControlSize = buffer[22+p];	//bControlSize 控制位域大小
		unit->extension.bmControls = (__u8 *)unit + sizeof *unit;	//bmControls控制點陣圖指標
		memcpy(unit->extension.bmControls, &buffer[23+p], n);	//初始化控制點陣圖
		if (buffer[23+p+n] != 0)	//設定擴充套件Unit實體名
			usb_string(udev, buffer[23+p+n], unit->name,sizeof unit->name);
		else
			sprintf(unit->name, "Extension %u", buffer[3]);
		list_add_tail(&unit->list, &dev->entities);	//新增uvc實體到uvc實體連結串列中
		break;
	default:
		uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE descriptor (%u)\n", buffer[2]);
		break;
	}
	return 0;
}

5.2.1 新增uvc實體到uvc裝置的實體連結串列下

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


5.2.2 分配uvc實體

staticstruct 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)分配記憶體空間