ImageVerifierCode 换一换
格式:DOCX , 页数:30 ,大小:67.47KB ,
资源ID:10226926      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10226926.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(DirectShow.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

DirectShow.docx

1、DirectShow本篇文档主要描述关于用Directshow进行视频开发的一些技术主要包括下面内容: 1关于视频捕捉(About Video Capture in Dshow) 2选择一个视频捕捉设备(Select capture device) 3预览视频(Previewing Video) 4如何捕捉视频流并保存到文件(Capture video to File) 5将设备从系统中移走时的事件通知(Device remove Notify) 6如何控制Capture Graph(Controlling Capture Graph) 7如何配置一个视频捕捉设备 8从静止图像pin中捕捉图片

2、 1 关于视频捕捉(About Video Capture in Dshow)1 视频捕捉Graph的构建一个能够捕捉音频或者视频的graph图都称之为捕捉graph图。捕捉graph图比一般的文件回放graph图要复杂许多,dshow提供了一个Capture Graph Builder COM组件使得捕捉graph图的生成更加简单。Capture Graph Builder提供了一个ICaptureGraphBuilder2接口,这个接口提供了一些方法用来构建和控制捕捉graph。首先创建一个Capture Graph Builder对象和一个graph manger对象,然后用filter

3、 graph manager 作参数,调用ICaptureGraphBuilder2:SetFiltergraph来初始化Capture Graph Builder。看下面的代码把HRESULT InitCaptureGraphBuilder( IGraphBuilder *ppGraph, / Receives the pointer. ICaptureGraphBuilder2 *ppBuild / Receives the pointer. ) if (!ppGraph | !ppBuild) return E_POINTER; IGraphBuilder *pGraph = NULL;

4、 ICaptureGraphBuilder2 *pBuild = NULL; / Create the Capture Graph Builder. HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void*)&pGraph); if (SUCCEEDED(hr) / Create the Filter Graph Manager. hr = CoCreateInstance(CLSID_FilterGraph, 0

5、, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void*)&pGraph); if (SUCCEEDED(hr) / Initialize the Capture Graph Builder. pBuild-SetFiltergraph(pGraph); / Return both interface pointers to the caller. *ppBuild = pBuild; *ppGraph = pGraph; / The caller must release both interfaces. return S_OK; else pBui

6、ld-Release(); return hr; / Failed2视频捕捉的设备现在许多新的视频捕捉设备都采用的是WDM驱动方法,在WDM机制中,微软提供了一个独立于硬件设备的驱动,称为类驱动程序。驱动程序的供应商提供的驱动程序称为minidrivers。Minidrivers提供了直接和硬件打交道的函数,在这些函数中调用了类驱动。在directshow的filter图表中,任何一个WDM捕捉设备都是做为一个WDM Video Capture过滤器(Filter)出现。WDM Video Capture过滤器根据驱动程序的特征构建自己的filter 下面是陆其明的一篇有关于dshow和硬件的

7、文章,可以拿来参考一下/陆文章开始 大家知道,为了提高系统的稳定性,Windows操作系统对硬件操作进行了隔离;应用程序一般不能直接访问硬件。DirectShow Filter工作在用户模式(User mode,操作系统特权级别为Ring 3),而硬件工作在内核模式(Kernel mode,操作系统特权级别为Ring 0),那么它们之间怎么协同工作呢?DirectShow解决的方法是,为这些硬件设计包装Filter;这种Filter能够工作在用户模式下,外观、控制方法跟普通Filter一样,而包装Filter内部完成与硬件驱动程序的交互。这样的设计,使得编写DirectShow应用程序的开发人

8、员,从为支持硬件而需做出的特殊处理中解脱出来。DirectShow已经集成的包装Filter,包括Audio Capture Filter(qcap.dll)、VfW Capture Filter(qcap.dll,Filter的Class Id为CLSID_VfwCapture)、TV Tuner Filter(KSTVTune.ax,Filter的Class Id为CLSID_CTVTunerFilter)、Analog Video Crossbar Filter(ksxbar.ax)、TV Audio Filter(Filter的Class Id为CLSID_TVAudioFilter)

9、等;另外,DirectShow为采用WDM驱动程序的硬件设计了KsProxy Filter(Ksproxy.ax,)。我们来看一下结构图:图1从上图中,我们可以看出,Ksproxy.ax、Kstune.ax、Ksxbar.ax这些包装Filter跟其它普通的DirectShow Filter处于同一个级别,可以协同工作;用户模式下的Filter通过Stream Class控制硬件的驱动程序minidriver(由硬件厂商提供的实现对硬件控制功能的DLL);Stream Class和minidriver一起向上层提供系统底层级别的服务。值得注意的是,这里的Stream Class是一种驱动模型,

10、它负责调用硬件的minidriver;另外,Stream Class的功能还在于协调minidriver之间的工作,使得一些数据可以直接在Kernel mode下从一个硬件传输到另一个硬件(或同一个硬件上的不同功能模块),提高了系统的工作效率。(更多的关于底层驱动程序的细节,请读者参阅Windows DDK。)下面,我们分别来看一下几种常见的硬件。VfW视频采集卡。这类硬件在市场上已经处于一种淘汰的趋势;新生产的视频采集卡一般采用WDM驱动模型。但是,DirectShow为了保持向后兼容,还是专门提供了一个包装Filter支持这种硬件。和其他硬件的包装Filter一样,这种包装Filter的创

11、建不是像普通Filter一样使用CoCreateInstance,而要通过系统枚举,然后BindToObject。音频采集卡(声卡)。声卡的采集功能也是通过包装Filter来实现的;而且现在的声卡大部分都有混音的功能。这个Filter一般有几个Input pin,每个pin都代表一个输入,如Line In、Microphone、CD、MIDI等。值得注意的是,这些pin代表的是声卡上的物理输入端子,在Filter Graph中是永远不会连接到其他Filter上的。声卡的输出功能,可以有两个Filter供选择:DirectSound Renderer Filter和Audio Renderer

12、(WaveOut) Filter。注意,这两个Filter不是上述意义上的包装Filter,它们能够同硬件交互,是因为它们使用了API函数:前者使用了DirectSound API,后者使用了waveOut API。这两个Filter的区别,还在于后者输出音频的同时不支持混音。(顺便说明一下,Video Renderer Filter能够访问显卡,也是因为使用了GDI、DirectDraw或Direct3D API。)如果你的机器上有声卡的话,你可以通过GraphEdit,在Audio Capture Sources目录下看到这个声卡的包装Filter。WDM驱动的硬件(包括视频捕捉卡、硬件解

13、压卡等)。这类硬件都使用Ksproxy.ax这个包装Filter。Ksproxy.ax实现了很多功能,所以有“瑞士军刀”的美誉;它还被称作为“变色龙Filter”,因为该Filter上定义了统一的接口,而接口的实现因具体的硬件驱动程序而异。在Filter Graph中,Ksproxy Filter显示的名字为硬件的Friendly name(一般在驱动程序的.inf文件中定义)。我们可以通过GraphEdit,在WDM Streaming开头的目录中找到本机系统中安装的WDM硬件。因为KsProxy.ax能够代表各种WDM的音视频设备,所以这个包装Filter的工作流程有点复杂。这个Filte

14、r不会预先知道要代表哪种类型的设备,它必须首先访问驱动程序的属性集,然后动态配置Filter上应该实现的接口。当Ksproxy Filter上的接口方法被应用程序或其他Filter调用时,它会将调用方法以及参数传递给驱动程序,由驱动程序最终完成指定功能。除此以外,WDM硬件还支持内核流(Kernel Streaming),即内核模式下的数据传输,而无需经过到用户模式的转换。因为内核模式与用户模式之间的相互转换,需要花费很大的计算量。如果使用内核流,不仅可以避免大量的计算,还避免了内核数据与主机内存之间的拷贝过程。在这种情况下,用户模式的Filter Graph中,即使pin之间是连接的,也不会

15、有实际的数据流动。典型的情况,如带有Video Port Pin的视频捕捉卡,Preview时显示的图像就是在内核模式下直接传送到显卡的显存的。所以,你也休想在VP Pin后面截获数据流。讲到这里,我想大家应该对DirectShow对硬件的支持问题有了一个总体的认识。对于应用程序开发人员来说,这方面的内容不用研究得太透,而只需作为背景知识了解一下就好了。其实,大量繁琐的工作DirectShow已经帮我们做好了。/陆其明文章结束 Direcshow中视频捕捉的FilterPin的种类捕捉Filter一般都有两个或多个输出pin,他们输出的媒体类型都一样,比如预览pin和捕捉pin,因此根据媒体类

16、型就不能很好的区别这些pin。此时就要根据pin的功能来区别每个pin了,每个pin都有一个GUID,称为pin的种类。如果想仔细的了解pin的种类,请看后面的相关内容Working with Pin Categories。对于大多数的应用来说,ICaptureGraphBuilder2提供了一些函数可以自动确定pin的种类。预览pin和捕捉pin视频捕捉Filter都提供了预览和捕捉的输出pin,预览pin用来将视频流在屏幕上显示,捕捉pin用来将视频流写入文件。预览pin和输出pin有下面的区别:1 为了保证捕捉pin对视频桢流量,预览pin必要的时候可以停止。2 经过捕捉pin的视频桢都

17、有时间戳,但是预览pin的视频流没有时间戳。预览pin的视频流之所以没有时间戳的原因在于filter图表管理器在视频流里加一个很小的latency,如果捕捉时间被认为就是render时间的话,视频renderFilter就认为视频流有一个小小的延迟,如果此时render filter试图连续播放的时候,就会丢桢。去掉时间戳就保证了视频桢来了就可以播放,不用等待,也不丢桢。预览pin的种类GUID为PIN_CATEGORY_PREVIEW捕捉pin的种类GUID为PIN_CATEGORY_CAPTUREVideo Port pinVideo Port是一个介于视频设备(TV)和视频卡之间的硬件设

18、备。同过Video Port,视频数据可以直接发送到图像卡上,通过硬件的覆盖,视频可以直接在屏幕显示出来。Video Port就是连接两个设备的。使用Video Port的最大好处是,不用CPU的任何工作,视频流直接写入内存中。当然它也有下面的缺点drawbacks:略如果捕捉设备使用了Video Port,捕捉Filter就用一个video port pin代替预览pin。video port pin的种类GUID为PIN_CATEGORY_VIDEOPORT一个捕捉filter至少有一个Capture pin,另外,它可能有一个预览pin 和一个video port pin,或者两者都没有

19、,也许filter有很多的capture pin,和预览pin,每一个pin都代表一种媒体类型,因此一个filter可以有一个视频capture pin,视频预览pin,音频捕捉pin,音频预览pin。Upstream WDM Filters在捕捉Filter之上,WDM设备可能需要额外的filters,下面就是这些filterTV Tuner FilterTV Audio Filter.Analog Video Crossbar Filter尽管这些都是一些独立的filter,但是他们可能代表的是同一个硬件设备,每个filter都控制设备的不同函数,这些filter通过pin连接起来,但是在

20、pin中没有数据流动。因此,这些pin 的连接和媒体类型无关。他们使用一个GUID值来定义一个给定设备的minidriver,例如:TV tuner Filter 和video capture filter都支持同一种medium。在实际应用中,如果你使用ICaptureGraphBuilder2来创建你的capture graphs,这些filters就会自动被添加到你的graph中。更多的详细资料,可以参考WDM Class Driver Filters2选择一个视频捕捉设备(Select capture device)如何选择一个视频捕捉设备,可以采用系统设备枚举,详细资料参见Using

21、 the System Device Enumerator 。enumerator可以根据filter的种类返回一个设备的monikers。Moniker是一个com对象,可以参见IMoniker的SDK。对于捕捉设备,下面两种类是相关的。CLSID_AudioInputDeviceCategory 音频设备CLSID_VideoInputDeviceCategory 视频设备下面的代码演示了如何枚举一个视频捕捉设备ICreateDevEnum *pDevEnum = NULL;IEnumMoniker *pEnum = NULL;/ Create the System Device Enum

22、erator.HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast(&pDevEnum);if (SUCCEEDED(hr) /创建一?个?枚?举器,?枚?举视频设备? hr = pDevEnum-CreateClassEnumerator( CLSID_VideoInputDeviceCategory, &pEnum, 0);IEnumMoniker接口pEnum返回一个IMoniker接口的列表,代表一系列的

23、moniker,你可以显示所有的设备,然后让用户选择一个。采用IMoniker:BindToStorage方法,返回一个IPropertyBag接口指针。然后调用IPropertyBag:Read读取moniker的属性。下面看看都包含什么属性1 FriendlyName 是设备的名字2 Description 属性仅仅适用于DV和D-VHS/MPEG摄象机,如果这个属性可用,这个属性更详细的描述了设备的资料3DevicePath 这个属性是不可读的,但是每个设备都有一个独一无二的。你可以用这个属性来区别同一个设备的不同实例下面的代码演示了如何显示遍历设备的名称 ,接上面的代码HWND hLi

24、st; / Handle to the list box.IMoniker *pMoniker = NULL;while (pEnum-Next(1, &pMoniker, NULL) = S_OK) IPropertyBag *pPropBag; hr = pMoniker-BindToStorage(0, 0, IID_IPropertyBag, (void*)(&pPropBag); if (FAILED(hr) pMoniker-Release(); continue; / Skip this one, maybe the next one will work. / Find the

25、description or friendly name. VARIANT varName; VariantInit(&varName); hr = pPropBag-Read(LDescription, &varName, 0); if (FAILED(hr) hr = pPropBag-Read(LFriendlyName, &varName, 0); if (SUCCEEDED(hr) / Add it to the applications list box. USES_CONVERSION; (long)SendMessage(hList, LB_ADDSTRING, 0, (LPA

26、RAM)OLE2T(varName.bstrVal); VariantClear(&varName); pPropBag-Release(); pMoniker-Release();如果用户选中了一个设备调用IMoniker:BindToObject为设备生成filter,然后将filter加入到graph中。IBaseFilter *pCap = NULL;hr = pMoniker-BindToObject(0, 0, IID_IBaseFilter, (void*)&pCap);if (SUCCEEDED(hr) hr = m_pGraph-AddFilter(pCap, LCaptur

27、e Filter);3预览视频(Previewing Video)为了创建可以预览视频的graph,可以调用下面的代码ICaptureGraphBuilder2 *pBuild; / Capture Graph Builder/ Initialize pBuild (not shown).IBaseFilter *pCap; / Video capture filter./* Initialize pCap and add it to the filter graph (not shown). */hr = pBuild-RenderStream(&PIN_CATEGORY_PREVIEW,

28、&MEDIATYPE_Video, pCap, NULL, NULL);4如何捕捉视频流并保存到文件(Capture video to File)1 将视频流保存到AVI文件下面的图表显示了graph图图2AVI Mux filter接收从capture pin过来的视频流,然后将其打包成AVI流。音频流也可以连接到AVI Mux Filter上,这样mux filter就将视频流和视频流合成AVI流。File writer将AVI流写入到文件中。可以像下面这样构建graph图IBaseFilter *pMux;hr = pBuild-SetOutputFileName( &MEDIASUBT

29、YPE_Avi, / Specifies AVI for the target file. LC:Example.avi, / File name. &pMux, / Receives a pointer to the mux. NULL); / (Optional) Receives a pointer to the file sink.第一个参数表明文件的类型,这里表明是AVI,第二个参数是制定文件的名称。对于AVI文件,SetOutputFileName函数会创建一个AVI mux Filter 和一个 File writer Filter ,并且将两个filter添加到graph图中,

30、在这个函数中,通过File Writer Filter 请求IFileSinkFilter接口,然后调用IFileSinkFilter:SetFileName方法,设置文件的名称。然后将两个filter连接起来。第三个参数返回一个指向 AVI Mux的指针,同时,它也通过第四个参数返回一个IFileSinkFilter参数,如果你不需要这个参数,你可以将这个参数设置成NULL。然后,你应该调用下面的函数将capture filter 和AVI Mux连接起来。hr = pBuild-RenderStream( &PIN_CATEGORY_CAPTURE, / Pin category. &ME

31、DIATYPE_Video, / Media type. pCap, / Capture filter. NULL, / Intermediate filter (optional). pMux); / Mux or file sink filter./ Release the mux filter.pMux-Release();第5个参数就是使用的上面函数返回的pMux指针。当捕捉音频的时候,媒体类型要设置为MEDIATYPE_Audio,如果你从两个不同的设备捕捉视频和音频,你最好将音频设置成主流,这样可以防止两个数据流间drift,因为avi mux filter为同步音频,会调整视频的播放速度的。为了设置master 流,调用IConfigAviMux:SetMasterStream方法,可以采用如下的代码:IConfigAviMux *pConfigMux = NULL;hr = p

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1