1 Video Class 根底概念
Usb协议中,除了通用的软硬件电气接口规范等,还包含了各式各样的Class协议,用来为不同的功用界说各自的规范接口和详细的总线上的数据交互格局和内容。这些Class协议的数量十分多,最常见的比方支撑U盘功用的Mass Storage Class,以及通用的数据交换协议:CDC class。此外还包含Audio Class, Print Class等等。
理论上说,即便没有这些Class,经过专用驱动也能够完结各式各样的运用功用。可是,正如Mass Storage Class的运用,使得各个厂商出产的U盘都能经过操作体系自带的一致的驱动程序来运用,对U盘的遍及运用起了极大的推进作用,拟定其它这些Class也是为了相同的意图。
Video Class 协议的意图是给USB接口的视频设备供给一个一致的数据交换规范。开端版别是在2003年9月才增加到USB Class规范中的,1.1的版别更是在2005年才发布。相比之下,Mass Storage Class 早在1998年就发布了。支撑Video Class协议的多媒体芯片也是在2005年才连续发布。所以USB 视频设备现在的现状是,在设备一端,大都仍旧还选用原先的各种包含通用USB功用的多媒体处理芯片,主机端需求装置专用的驱动程序,底子上各个产品之间不具备兼容性。乃至关于操作体系而言,也只要在XP的SP2今后,才包含了对通用的Video class协议的支撑。所以即便是某些多媒体设备(比方Logitech最新的几款摄像头)包含了对Video Class的支撑,在Win2000等操作体系上仍然需求装置驱动程序。不过,应该说运用Video Class无疑会是一个趋势,在相应的多媒体芯片连续投入市场后,支撑Video Class的多媒体设备应该会在一两年内会敏捷遍及开来。
除了在硬件上经过相应的多媒体芯片支撑Video Class的设备以外,关于包含了操作体系的智能手机,当然也能够在手机端经过驱动程序来完结对Video Class的支撑,就好像原先支撑任何一种专用的USB驱动相同。只不过数据交换的格局不是自己随意制定的,而是依照Video Class的规范来完结的。
由于现在支撑Video Class的设备还很少,所以在Linux上还没有开源的Video Class的主机端驱动,设备端的Video Class驱动就更没有见到开源的代码了。本文在介绍USB Video Class架构的根底上,首要是评论Linux操作体系下设备端Video Class驱动的完结。不过在其它渠道下的完结思路应该也是相似的。
2 USB Video Class 协议结构
2.1 设备拓扑结构
在拓扑结构上Video Class 将视频设备笼统为几个首要的硬件功用模块:
输入端点 Input Terminal
输出端点 Output Terminal
camera端点 Camera Terminal
挑选单元 Selector Unit
处理单元 Processing Unit
拓宽单元 Extension Unit
下图是一幅摘自USB_Video_Example 1.1.pdf (www.usb.org)的拓扑结构示例图:
图1 USB Video Camera Topology Example
从sensor和另一个复合视频设备得到的数据流由IT 和 CT输入,经SU挑选送PU处理,再由OT绑定到指定的USB端点。最后由USB端点与主机交互将数据发送到host端。在实践设备中,或许没有其间的某些功用模块,也或许其间的几个模块都是由同一硬件来完结的。
2.2 协议层次结构
上图中,左半部的结构组成了Video Class中的操控接口界面,右半部的结构组成了视频流传输接口界面。这两部分构成了Video Class的首要协议结构。
2.2.1 Descriptor Layout
与Class相关的信息,当然是主机端经过向设备端获取描绘符(Descriptor)来得到的, 下图摘自USB_Video_Class_1.1.pdf , 给出了一个Video Class协议描绘符运用示例的Layout。
图2 Video Camera Descriptor Layout Example
能够看到,在Descriptor Layout中,在规范描绘符里,除了Device Descriptor, Configuration Descriptor, Interface Descriptor, Endpoint Descriptor,String Descriptor以外,还有一个USB2.0 协议中后期才新加的IAD 即 Interface AssociaTIon Descriptor,用来描绘多个相关Interface之间的联系,在Video Class中,IAD用来描绘VideoControl Interface和VideoStreaming Interface之间的联系。
图中深色的部分便是Video Class 协议相关的专用描绘符(Class Specific Descriptor)了。首要便是对硬件图画收集和处理模块的物理拓扑结构和功用的描绘,以及对视频传输格局(包含编码格局,码率等等视频图画相关参数)的描绘。
经过从设备处取得这些描绘符,主机能够得知视频设备端的结构及其所支撑的功用。而操控这些功用模块,对数据源和数据流进行装备,则需求经过Request来完结。
2.3 Request
Request是由主机向设备端建议的功用恳求,包含一切USB设备都需求支撑的Standard Device Requests 和与Class相关的Class Specific Requests :
2.3.1 Standard Device Requests
下图列出了USB Spec中规则的规范Request
图3 Standard Device Requests
这其间,有一部分Request是由USB操控芯片在硬件一级就直接完结的应对作业,比方SET_ADDRESS,有些则需求由软件来做进一步的处理,比方Set_ConfiguraTIon。软硬件的这种使命的区分还与详细的硬件芯片相关。由于这部分是规范协议相关,本文就不胪陈。
2.3.2 Class Specific Requests
Class Specific Requests的数据结构Layout与规范Request是相同的,只是内容不同罢了。VideoClass的Class Specific Requests首要依据Interface分为两类,其下又依据详细功用模块做进一步的区分:
Ø VideoControl Requests
- Camera Terminal Control Requests
- Selector Unit Control Requests
- Processing Unit Control Requests
- Extension Unit Control Requests
Ø VideoStreaming Requests
- Interface Control Requests
这其间,Interface Control Requests由于是用来在主机和设备之间洽谈数据交互格局和分辨率,流量等信息的,所以一般来说是有必要完结的。
而Camera Terminal Control Requests 和 Processing Unit Control Requests中的内容,则是现在常用的即时通讯软件如MSN / QQ 等在其视频操控界面上集成的操控参数。
其间,Camera Terminal Control Requests包含了对曝光时刻,曝光形式,对焦,变焦,平移等sensor获取数据阶段时的参数操控。
而Processing Unit Control Requests中则包含了亮度,增益,色彩,对比度,白平衡等等sensor在获取到图画数据后,图画处理阶段的相关参数。
不过实践上,以上两者的区分在硬件层次并不是必定的。许多参数的操控在sensor硬件级别上是同一层次的。不过,将这些功用笼统成这两类,正如在硬件的拓扑结构大将功用模块笼统出来相同,有利于通用化的程序设计
3.1 驱动架构
3.1.1 渠道及软件根底
本文评论的是USB Video Class在Linux操作体系上的设备端完结。详细是在Omap渠道上,根据USB Gadget的驱动架构来完结的。
USB Gadget驱动分为两层,底层是处理与USB操控芯片硬件相关的内容,对上层屏蔽了大部分硬件相关的设置,并处理了一部分规范Request和EP0相关的规范操作流程。上层则是Class相关的部分,官方的Gadget驱动中,现已包含了File Storage(U盘功用),RNDIS(USB网卡功用)等的支撑。考虑到Video Class的数据交换进程与File Storage有许多相似的当地,所以本文在Video Class的完结中,在大的结构上仿照了File Storage驱动的架构。
3.1.2 底子结构和数据流程
在本文完结的Video Class驱动中,全体的结构底子上分为两大部分。
一部分是担任处理模块的初始化进程,并担任处理Usb总线上的Descriptor和Requests的交互进程。包含USB总线上的操控和查询包的接纳,解说,分配和应对。
另一部分,是在初始化进程中发动的一个独立的内核线程。担任详细的操控指令的履行和图画数据的获取及传输作业。这其间的许多操作都有或许引起睡觉,或许需求对文件进行操作,因而有必要有一个线程做为依托。
模块的流程底子上是这样的:
在init函数中向Gadget底层驱动注册VideoClass数据结构。一切的描绘符都界说为大局结构变量,在模块初始化进程中,进一步完结对描绘符的填充进程,发动独立的内核线程,并注册EP0的complete回调函数。
在发动的内核线程中翻开并初始化camera设备。将camera设置为默许的参数装备。读取图画数据并将数据填充到BUF里然后提交Request到VideoStream Interface里的BULK IN端点中。然后睡觉等候由于数据传送结束被唤醒或有(反常)ExcepTIon产生被唤醒。
假如是数据传送结束,则持续读取,填充并发送图画数据,假如有反常产生,则转而处理反常。
另一方面,哪些状况会引发反常呢?首要是驱动程序与BUS总线交互信息的这部分模块中,假如产生主机端从头设置ConfiguraTIon,改动USB设备装备,或许产生总线插拔等引起总线状况改动的时分,会产生一个相应的反常,等候内核线程被唤醒并处理这些反常。
此外,在处理Requests的时分,有时分需求与camera驱动模块交互操控信息,相同需求操作文件句柄,现在的做法是在ep0 request的回调函数(context)中发动一个bottom half task,在Bottom half中完结相应的操控。
从整体结构上说,这样做很丑陋,抱负的话应该在上述独立的内核线程中一致处理与Camera模块相关的操作,可是现在的架构,要唤醒该线程,只要两个途径,一是数据传输结束或被撤销,二是有总线状况改动相关的反常产生。假如硬加一个反常用来处理Requests好像也很丑陋,并且对架构需求有较大的调整。所以现在只好简化的选用了前面所说的计划。
然后关于什么时分翻开设备,开端往USB总线上放置数据,现在的处理方法也不是十分抱负。现在是在模块初始化后当即获取榜首帧图画然后等候主机端读取,实践上,主机端或许并不马上组织图画数据的传输。可是假如在主机端需求的时分才去读取数据的话,由于sensor获取数据需求一段曝光时刻再加上紧缩数据所需的时刻,不或许马上呼应,所以在时刻上必定不能满意开端一段的数据传输恳求。也需求持续仔细剖析在何时发动camera模块最为适宜。
3.2 与Camera驱动和V4L2子体系的合作
在linux内核中,2002年12月起发布了V4L2 (Video For Linux Two ) 0.1版别的规范,V4l2试图为一切和视频相关的设备都供给一致的接口,这其间当然也就包含了Camera设备。
而USB Video Class这一部分内容恰恰与视频设备也是密切相关的,所以在某些渠道产品的完结中,乃至是在VideoClass中直接包含了Camera的驱动程序。这样做关于单一产品来说,能够大大简化驱动的层次结构,应该说是处理Camera的最直接简练的方法。
可是,在本文的完结中,考虑到Linux内核中合理的模块区分的准则,也是为了契合Gadget驱动的其他Class完结的一向风格,所以仍是尽量运用V4L2的接口来操控Camera模块。这样做也有利于代码的移植。减小不同功用模块之间的耦合性。
抱负的方法天然是一切的与Camera相关的操作都经过V4L2接口来完结,不过现在的完结中仍是有些破例,引发破例的首要因素是功率问题。
由于在USB总线上传输图画,遭到总线速度的约束,特别是在非USB2.0接口的芯片中,所以必然要选用JPEG或MPEG编码对数据进行紧缩。V4L2子体系的结构中,包含了对编码器的支撑,可是,也许是笔者对V4L2子体系的学习还不行深化,其对编码器的支撑应该是对硬件编码芯片的支撑,即便如此,也没有见到相关的代码,并且,在完结中运用的手机主板上也没有硬件的编解码芯片,所以在完结中Camera驱动经过V4L2子体系对运用层供给的是原始的未经编码的数据流,由运用程序调用IJG ( Independent JPEG Group )JPEG库函数来完结jpeg的编解码作业。
所以假如经过V4L2的read接口来获取数据,必然只能得到原始的图画数据,并且在V4L2的完结中,经过Read方法获取的数据,需求经过屡次内存复制才干抵达调用者处。所以也会很大程度的影响图画处理的速度。
要对图画进行紧缩,要不在用户空间调用IJG库,要不在内核中再完结一个JPEG紧缩算法。按前者来完结的话,触及到Video Class怎么去发动一个用户程序来读取Camera数据并在紧缩后再传送给内核,也不是彻底无法完结,可是无疑是一个十分糟糕的完结方法。
后者的话,触及到这个JPEG紧缩算法应该在什么当地完结,以及由谁来调用的问题(Video Class 仍是 V4L2)。考虑到在存在硬件编码芯片的状况下,该芯片的办理和运用应该会归入V4L2子体系中,所以考虑到兼容性,现在完结的方法是将JPEG紧缩算法作为一个独立的模块刺进内核,由V4L2子体系调用相关函数对图画数据进行紧缩,然后再在Camera驱动中Export一个额定的函数接口,USB Video Class经过该函数接口发动Camera图画的读取和紧缩进程,以差异规范的V4L2子体系的数据处理流程。紧缩后的图画数据直接写入经过指针参数传递进来的内存地址空间中,尽或许的削减内存复制的次数,加快图画的传递。
这样做带来的问题便是需求在V4L2架构中增加额定的接口,增加了USB Video Class和V4L2子体系之间的耦合性,不能彻底将这两个模块阻隔开来。应该还有更好的处理计划。
3.3 JPEG编码相关
Jpeg的编解码,在Linux操作体系中,底子上选用的都是IJG(www.ijg.org)的JPEG库函数Libjpeg,这是一个适当牢靠安稳和高效的开源项目,支撑JPEG规范(不包含JPEG2000)的绝大大都编码方法。如非无法,的确没有必要别的再写一个编码程序。可是由于需求在内核中运用,所以只好自己再编一个了。
JPEG编码相关的代码除了IJG的源代码以外,在网上还能够查找到若干,可是无疑IJG的代码是最完善的。其它我能搜到的代码,多多少少都有一些BUG,并且也只是完结了JPEG规范的最底子的功用(当然,关于Video Class的运用来说现已是足够了)。最重要的是,大都是用浮点数运算来完结的,放下速度不说,在本文的完结中OMAP渠道的CPU也不支撑浮点数运算。。。所以,本文完结中,终究是参阅了网上搜到的某个算法的流程(首要是IJG的架构太杂乱,一来没有时刻精力和才能进行完好的剖析,二来也不适合在内核中运用如此杂乱的架构),在快速离散余弦改动的整数算法上仿照了IJG库的算法两者归纳起来完结的。终究的代码还有许多需求改善的当地,不过,关于VideoClass来说,应该牵强够用了。这其间的详细问题,打算在别的独自的文档中再阐明。
3.4 操作体系相关
说操作体系相关,或许说大了一些,这儿首要触及的内容是在本文的完结中,在WIN2000和WINXP渠道的MSN测验中,遇到的一些问题。
由于VideoClass的协议只是规则了数据传输的格局和内容,对详细完结中的一些细节并没有作硬性的规则,所以导致有些细节或许存在不兼容的完结方法。(当然,我想首要仍是本文的完结,由于才能有限,没有充沛考虑到各种状况下的容错性,假如驱动做得好应该能够防止出现问题)。所以在WIN2000和WINXP的MSN测验中,遇到了一些渠道相关的问题,有些功用在2000下能正常作业在XP下存在Bug,有些却相反。有些现已处理,有些只是猜想了或许的原因,罗列如下:
3.4.1 视频窗口封闭再翻开后,没有图画
开端是在XP的MSN上发现有这样的问题,2000下没有,剖析BUS数据能够看到,XP在封闭视频窗口的时分,会履行一个Abort Pipe的操作,这个操作应该会中止BULK传输,可是在设备端,Gadget底层驱动接纳不到这个事情(也有或许是Gadget底层驱动的BUG),所以在VideoClass中无从得知这个传输现已被撤销了,这样睡觉在等候数据传送结束或失利上的线程也就无法被唤醒,天然也就不会持续发送数据。形成主机端再度翻开视频窗口时接纳不到图画数据。而在2000下的MSN中,封闭视频窗口的动作体系不会发送这个Abort Pipe事情,所以也就没有问题。
考虑到每次翻开视频窗口的时分,主机端都会设置Streaming Interface的图画分辨率,码率等参数。而这之后主机端才会读取图画数据,所今后来处理的方法是在主机端设置Streaming Interface的时分,将之前现已放入BULK IN传输节点的数据 Dequeue出来,这样会形成这个传输的失利,然后唤醒睡觉的线程。可是假如只是这样做,XP能够正常作业了,2000又显现不了图画了。剖析以为由于部分数据丢掉,所以形成榜首帧图画的数据是不完好的,无法正常解紧缩显现,可是XP下的MSN有较好的容错性,能够丢掉这一帧图画,持续读取之后的数据,而2000下的MSN容错才能较差,无法再正常解读后边的图画数据。所以终究的处理方法是在发现传输失利后,将当时这一帧的图画数据从头开端从头发送,这样在XP和2000下就都能正常作业了。
不知道这种处理计划是否只是是一种治标的计划,有待今后持续研讨。
3.4.2 某些分辨率下图画无法正常显现
在Win2000中假如供给160*120分辨率的图画,图画十分简单就中止改写了,而BUS上实践数据仍是在发送的。而在160*112(两者都是16的整倍数)的分辨率的状况下,就简直不会产生这种状况。假如说这有或许仍是JPEG的紧缩算法有点问题,那别的一种状况就必定是XP 和 2000的差异了:假如设备这端经过描绘符和Streaming Interface声明只能支撑160*120 或许 160*112 的分辨率,2000能够承受这种分辨率,而XP底子就不能承受,总线上的操控传输就中止了,在界面上则显现检测不到Camera或Camera正在被其它设备翻开占用,只要在进一步供给更高的320*240的分辨率的状况下,XP才会供认Camera的存在!其它问题倒不大,便是在本文的完结渠道上,受软件编码JPEG速度的约束,320*240的分辨率下,视频的帧频会低一些,影响图画的流畅性。
3.5 其它
3.5.1 特殊作用的操控
应该说,VideoClass的Control Request底子上包括了V4L2规范界面供给的大部分操控参数,可是,仍是有一部分没有包括,至于特定驱动专有的操控就更无法表现了,尤其是在MSN等运用程序的界面上,更不或许供给这些参数的操控了。可是,咱们仍是能够想方法trick过这个问题。
比方手机上常见的图画作用的设定,尽管不是特别有意义,可是既然是很常见的,为什么不能把它也做到Web Cam中呢?所以,假如必定要做,咱们能够使用MSN操控界面上的原有的操控界面,借用其间一两个操控参数来完结图画作用的设定。
本文的完结中挑选选用色彩来操控图画作用,由于实践上这个参数是很不常用的,乃至只能在XP的高档设定中找到,关于99.9%的用户我信任都不会去改动这个参数。而它的字面意义与咱们完结的功用也不算一点联系都没有,究竟有许多作用实践上便是改动一下图画的色彩(当然还有一部分破例了)。
相似的能够用一些咱们以为常用的设置替换既有的参数。这样做的缺陷便是操控参数的字面意义与实践功用不太符合,长处当然便是能够供给给用户更多更常用的图画设置。比方设置一个是非,素描之类的图画的作用,玩玩笼统派视频谈天。