2022年DirectShow开发应用 .pdf

上传人:Che****ry 文档编号:27262587 上传时间:2022-07-23 格式:PDF 页数:11 大小:171.32KB
返回 下载 相关 举报
2022年DirectShow开发应用 .pdf_第1页
第1页 / 共11页
2022年DirectShow开发应用 .pdf_第2页
第2页 / 共11页
点击查看更多>>
资源描述

《2022年DirectShow开发应用 .pdf》由会员分享,可在线阅读,更多相关《2022年DirectShow开发应用 .pdf(11页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、写这篇笔记,就当是对这个期间学习DirectShow的一个总结,假如它可以给你带来一些收获的话,那我会感到更高兴。还有我遇到的一些问题,希望和大家一起讨论。一、基本概念1DirectShow概述DirectShow的主要功能是流媒体的采集与回放。它集成了 DirectDraw,DirectSound,Direct3D的一些技术。它是一个开放的架构,你自己可以写自己的Filter 组件。DirectShow的架构:(这个图太经典了)2Filter Filter 其实就是一个COM 组件,但它有自己的特性。它由输入,处理,输出三部分组成, 输入,输出是叫PIN,输入的叫输入pin,输出的叫输出PI

2、N。PIN 也是一 .种 COM 组件,它实现了 IPin 接口。在 Filter 的实现里, PIN 其实是 Filter 的一个数据成员。(个人想法)(1)Filter 分为三类: Source Filter( 源过滤器 ),Transform Filter(转换过滤器 )Render Filter( 渲染过滤器 ) (2)Source Filter 的主要负责音、视频数据的采集,读取。比如File Source Filter(文件源过滤器 ),它是从磁盘里的音视文件读取数据的。Transform Filter 负责音、视数据的压缩,解压,编码、解码、分析。比如: Spliiter Fil

3、ter (分离器),其功能是将音频流和视频流分离开来Mux Filter( 复合器 ),将音频流和视频流全成单一数据流还有一此 Encoder,Decoder,Compressor等。(3)Render Filter负责音、视流的渲染,就是和输出,它将数据流送到输出设备,(显示器、磁盘、声卡)。Filter 有三种状态,运行,暂停,停止。关于数据流:3.Filter Graph(过滤器图 ) Filter Graph是 DirectShow一个基本的概念。我们开发一个DirectShow应用,其中最重要的步骤就是构造一个Filter Graph 。下图就是一个Filter Graph 名师资料

4、总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 11 页 - - - - - - - - - 这是一个实现本地文件(avi 文件 )回放的 Filter Graph ,File Source负责读文件理的数据,之后将数据传输给AVISplitter,AVI Spliiter 将接收的数据进行分析,分离成视频流和音频流。视频流经过AVI Ddcompressor的解码,送到 Video Renderer输出到显示器。 从 AVI Spliter出来的音频流则送到DirectSoun

5、d Device,由 DirectSound Device送到音频输出设备。4Filter Graph Manager Filter Graph Manager也是一个COM 组件,它是DirectShow的控制中心,它控制Filter的运行。它有以下几个功能:(1)协调各个Filter 的状态。 Filter 有运行,暂停,停止三种状态,在Filter Graph中,各个 Filter 的状态必须协调一到,否则会引起冲突。 Filter Graph Manager负责协调各个Filter的状态。(2) 提供一个参考时间,用以同步音频流和视频流。(3) 提供一套用于建立Filter Graph

6、的方法(4)与应用程序进行交互,它会将Filter Graph内部发生的事件,通过消息的方式通知应用程序。5Sample Filter Graph运行的时候,数据从上游的Filter 传到下游的Filter ,数据有一个单位,这个单位叫 Sample ,就是数据将分成一个一个的Sample 进行传输。6Media Type 媒体类型是DirectShow的一个基本的概念, 它描述了两个过滤器之间传输数据(Sample)的格式。两个过滤器在连接之前,必须就所采用的媒体类型进行协商。媒体类型,用AM_MEDIA_TYPE结构体来表示,它的结构可以看MSDN 文档。其中有几个域是比较重要的typed

7、ef struct _MediaType GUIDmajortype/主类型GUIDsubtype /辅助类型 (进一步描述数据格式) GUID formattype /更详细描述数据格式 ULONG cbFormat /描述 formatype数据块的大小 BYTE* pbFormat /描述 formattype数据块的内存指针名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 11 页 - - - - - - - - - /其它略 比较常用的描述媒体类型的GUID ma

8、jortype的有:MEDIATYPE_Video(数字视频 ) MEDIATYPE_Audio(数字音频 ) MEDIATYPE_AnologVideo(模拟视频 )/似乎没用过MEDIATYPE_AnologAudio(模拟音频 )/同上MEDIATYPE_Stream(字节流 )/Filter Source Filter从文件里读出来的数据MEDIATYPE_Interleaved /DV 的数据流(包括音视频数据)Subtype /MEDIASUBTYPE_Y Formattype FORMAT_None FORMAT_DvInfo (描述 DV 的数据类型格式) FORMAT_Vid

9、eoInfo (描述一般视频数据格式) FORMAT_WaveFormatE (描述一般音频数据格式) FORMAT_VideoInfo2/ 媒体类型协商:两个过滤器在传输数据之前,必须就所采用的媒体类型进行协商。7.Filter 的连接过程DirectShow提供了多方法来连接Filter ,如IFilterGraph:ConectDirect,IGraphBuilder:Connect Filter 的连接过程实际是两个过滤器就媒体类型进行协商的过程。Filter 连接的过程其实它们的 PIN 连接的过程,就是上游的输出PIN 与上游的输入PIN 连接。我们知道,每一个PIN都有它自己支持

10、的媒体类型,而当两个PIN 没有共同支持的媒体类型的时候,它们是不能连接的,所以连接之前要进行协商。在 Conect 函数的实现里,可以看到大致过程是这样的:连接是由输出PIN 发出的Connect Start IFPIN 已连接THEN EXIT IF Filter 不是停止状态THENEXIT/开始协商过程CALL AgreeMediaType 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 11 页 - - - - - - - - - Connect End Agr

11、eeMediaType Start 在输出 PIN 或输入 PIN 媒体类型枚举器mediatypeEnums 调用函数 TryMediaTypes,并把枚举器的指针传给它AgreeMediaType End TryMediaTypes Start FOREACH mediatype IN mediatypEnums AttempConnection(media) NEXT TryMediaTypes End AttemptConnection Start CheckMediaType /检查媒体类型是否被支持(输出PIN 自己)IF支持THEN 在 PIN 上保存媒体类型ELSEFAILED

12、 END IF CALLReceiveConnect/ 询问输入PIN 是否接受当前的媒体类型。IFSUCCEEDTHEN CALL CompleteConnect ELSE FAIL END IF AttemptConnect End CompleteConnect的作用是完成连接后的一些后续工作,主要是决定数据传输的时候使用哪一个内存分配器,由谁来创建内存分配器(IMemAllocator)。注: Filter 传输的数据单元叫Sample ,它是一个COM 组件,封装了一个缓冲区。Sample由内存分配器来管理。内存分配器是实现了IMenAllocator接口的 COM 组件,负责管理S

13、ample 。智能连接 :构造 Filter Graph的时候通过一些方法的调用,DirectShow会帮我们构造整个Filter Graph 。用到的方法有IGraphBuilder:RenderFile, IGraphBuilder:RenderICaptureGraphBuilder2:RenderStream名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 11 页 - - - - - - - - - 8.Filter 的数据传送(1)数据传送有两种模式:拉模式,推

14、模式。推模式: 上游 Filter 调用下游输入PIN 上的 IMemInputPin:Receive,使用这种模式的话,输入 PIN必须实现IMemInputPin接口。比较典型的使用推模式的Filter 是 Capture Source Filter 。拉模式:下游的Filter 调用上游输出PIN 的 IAsycnRender接口的方法,这是,输出PIN必须实现IAsyncReader接口。比较典型的使用拉模式的是Fillter Source. (2)传送过程中的内存管理:在传送的过程中,必须分配一定的缓冲。这个过程是通过内存分配器 (IMemAllocator)来实现, 它管理一系列的

15、Sample 。Sample 是一个 COM 对象(实现 IMediaSample接口),它封装并管理一个缓冲区。在连接的过程中,Filter 协商双方共同使用的内存管理器,并知道了内存管理器的位置。这样,当上游的Filter 要传输数据的时候,它将调用 IMemAllocator:GetBuffer来得到一个闲的 Sample 然后将数据进去,传输给下游。9关于 Filter Graph的状态转换:10质量控制:好像没什么用,没用到过11音、视同步:(1)参考时钟:主要就是为Filter Graph 设置一个参考时钟,凡实现了 IReferenceClock接口的都可以作为参考时钟, FGM

16、(Filter Graph Manager)有一套选定参考时钟的策略:一般有Live Source(Capture Source Filter)就选它作时钟,因为,这种Filter包装的硬件上一般都有一个定时器。如果没有Live Source ,那就选Audio Renderer,因为声卡上一般也有定时器。如果还没有的话,那就看其它Filter 有没有实现IReferenceClock。确实没有的话,就选系统时钟。(2)时间戳 (Time Stample) 送到 Renderer 渲染的 Sample 必须打上时间戳, 就是一个渲染的Start Time 和 End Time 好让 Rende

17、rer为它选择渲染时间。IMediaSample:SetTime 12DirectShow对硬件的支持DirectShow中 Filter 是工作在用户模式(user mode), 而硬件设备,比如:视频采集卡,是工作是内核模式(kernel mode ),那么,它们是怎样进行交互的呢?DirectShow为我们提供了包装 Filter ,包装 Filter 也是工作用户模式,不过它可以跟硬件驱动程序进行交互,再通过硬件驱动去控制硬件设备。DirectShow里面有一个叫ksProxy 的包装 Filter, 它是支持所有WDM 设备, 它提供了一个框架,然后由硬件厂商进行实现。名师资料总结

18、- - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 11 页 - - - - - - - - - 二常用的接口比较有用的接口和方法IBaseFilter 这是所有Filter 至少要实现的接口IPinPIN 至少要实现的接口IFilterGraph 提供了一些建立Filter Graph的方法IGraphBuilder(这个接口是由IFilterGraph继承来的,它提供了一些更方便的方法来建立Filter Graph ,比如: RenderFile,Render,AddSourceFil

19、ter)IMediaControl (控制 Filter Graph的状态)IVideoWindow(控制视频窗口 ) /接口方法: put_MessageDrain IMediaEventEx(事件处理有关的) IMediaSeeking(用于媒体播放定位的) 上面这些接口,都是通过Filter Graph Manager暴露出来的,我们只创建一个Filter Graph Manaer组件,就可以它们ICaptureGraphBuilder2(用来建立Capture Filter Graph,这是一个非常有用的接口) 方法:(1)SetFiltergraph/设置对应的IGraphBuild

20、er*,也就是 FilterGraph (2)RenderStream /用得最多的方法,对Capture Source Filter指定的输出PIN(Capture ,Preview,CC,VBI,)完成 Filter Graph下游其它部分的构造。它的原型如下: HRESULT RenderStream(constGUID*pCategory , const GUID *pType,IUnknown *pSource,IBaseFilter* pIntermediate ,IBaseFilter* pSink);它比较常见的用法如下:为了对视频进行预览,我们只要如下调用: RenderSt

21、ream(PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pCap,NULL,NULL); 为了对视频进行保存的:RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux); pMux 是一个 Mux Splitter对输入的音、视频数据合并并进行编码,(3) SetOutputFileName这个方法是在对视频进行保存时调用的,可以设置保存文件路径,保存类型(如avi,asf ),并会返回一个Mux Filter指针。它的原型是:HRESULT SetOutputFileName(cons

22、tGUID*pType,名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 11 页 - - - - - - - - - LPCOLESTR lpwstrFile, /文件保存位置IBaseFilter* ppf , / 返回一个 Mux Filter指针IFileSinkFilter* pSink / 这个指针用来更改文件保存路径,如果不需要可以置为 NULL);pType 可能是一个subtype ,当它是subtype 时,只能下面两种取值:MEDIASUBTYPE_A

23、vi(保存为Avi 格式),MEDIASUBTYPE_Asf(保存为 Asf), 因为这两种格式是windows 可以识别的,所以它自动返回一个Mux Filter指针如果要保存为其它格式,那么要将pType 这个参数指定为一个Mux Filter或一个 File Writer的 GUID 。模拟电视卡可能用到的接口:ICrossbar /输入端子选择IAMTuner IAMTVTuner /电视卡上TV Tuner 的包装类,控制电视频道的接收与选择常用方法: put_Channel /设置接收频道三、无题1 DirectShow开发环境的配置(VC 6.0) 一般包含的头文件是dshow.

24、h 或 streams.h 有时还会用到其它头文件,比如:qedit.h 用到的静态连接库文件:strmiids.lib strmbasd.lib(strmbase.lib Release版本 )quartz.lib winmm.lib uuid.lib 路径配置: VC toolsoption 有配置的时候, 最后把所有的库文件都包含上去,这样连接的时候就不会出现莫名其妙的错误了。2 DirectShow应用开发的一般步骤(1)创建一个 Filter Graph Manager组件(2)构造一个完整的Filter Graph (3)从Filter Graph Manager组件得到各种接口,

25、比如:IMediaControl ,对程序进行控制名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 11 页 - - - - - - - - - 具体如下:(1) 创建 Filter Graph Manager组件的代码如下:hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_FilterGraph, (void*)&pGraph) 相关接口的查询:IMediaControl *pControl=N

26、ULL; Hr=pGraph-QueryInterface(IID_IMediaControl,(void*)&pControl): IVideoWindow* pVW=NULL; Hr=pGraph-QueryInterface(IID_IVideoWindow,(void*)&pVW); (2) 之后,创建Filter Graph 这是整个程序最关键的部分创建 Filter Graph有下面一些方法IFilterGraph:AddFilter IFilterGraph:ConnectDirect IGraphBuilder:AddSourceFilter IGraphBuilder:Con

27、nect IGraphBuilder:RenderFile IGraphBuilder:Render ICaptureGraphBuilder2:RenderStream 一般采用智能连接比较方便,当智能连接不行的时候再自己手动连接(3) 视频窗口的设置:如果要对视频进行预览的话,那就要设置视频窗口。视频窗口是由Renderer Filter自动创建出来,我们编程的时候,只需要对它时进行设置就行了IVideoWindow接口用来专门控制视频窗口,用以下常见的方法:/put_Owner 为视频窗口指定父窗口,通过这个方法,我们可以将视频窗口嵌到我们自己的窗口,比如一个静态文本控件,SetWind

28、owPosition 设置视频窗口的位置,/put_MessageDrain 这个是比较有用的。对视频窗口而言, 我们是不能改写它的窗口处理过程,因为它是由DirectShow自动创建的。我们可以通过这个方法将视频窗口收到的消息挂接到一个我们自己的窗口,这样就实现了对视频窗口的消息处理了。/put_Visible将视频窗口显示出来/SetNotifyWindow当 Filter Graph中发生一些事件时,会向应用程序发送一些消息,这个方法是指定处理这此消息的的窗口/put_WindowStyle 设置 Video Window的样式,比如:long style=0; get_WindowSt

29、yle(&style); style&=WS_CAPTION; put_WindowStyle(style) 这样就可以去掉Video Window的标题栏了名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 11 页 - - - - - - - - - /put_FullScreenMode设置全屏模式(4)启动 Filter Graph pGraph-Run(); 3 常用的 Filter Graph 的构造构造 Filter Graph ,可以 GraphEdit这个工

30、具来测试(1) 本地文件播放最方便的方法:IGraphBuilder:RenderFile(filename); 只要选择播放的文件,IGraphBuilder就智能地帮你构造出整个Filter Graph (2) 视频输入设备采集视频的预览ICaptureGraphBuilder2 * pGB=NULL; Hr=CoCreateInstance (CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void*)&pGB); /对于 DV 面言,它可能有两种视频输出PIN, 一种是 Interleav

31、ed Pin, 一种是 Video Pin /前面一种包含音视频流,后面一种只有视频流,所以我们预览的时候,可以先试一下Interleaved Pin,如果失败的话,再试一下Video Pin Hr=pGB-RenderStream(PIN_CATEGORY_PREVIEW,MEDIATYPE_Interleaved, /pCap,NULL,NULL); if(FAILED(hr) hr=pGB-RenderStream(PIN_GATEGORY_PREVIEW,MEDIATYPE_Video,pCap,NULL,NULL); if(FAILED(hr) return hr; (3) 采集视频

32、的录制(输出为本地文件)pGB-SetOutputFileName(&MEDIASUBTYPE_Asf, filename, &pMux,&pSink); MEDIASUBTYPE_Asf指定为保存为Asf 格式,MEDIASUBTYPE_Avi 保存为 AVI 格式如是要保存为其它格式,要有相应格式的Mux Spliiter 或 Filter Writer , 然后传入它的GUID filename是保存路径名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 11 页 -

33、- - - - - - - - hr=pGB-RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pCap,NULL,pMux); if(FAILED(hr) hr=pGB-RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux); (4) 模拟电视卡VBI 信息的渲染电视卡的 VBI 信息,用以下三种: CC(Closed Caption),WST(World Standard Teletext),忘记了CC( Closed Caption) 电视卡的

34、 VBI 信号可能是从VBIPIN 输出的,也可能是从CCPIN 输出的,所以我们要进行判断。Hr=pGB-RenderStream(&PIN_CATEGORY_VBI,&MEDIATYPE_Video,pCap,NULL,NULL); If(FAILED(hr) pGB-RenderStream(&PIN_CATEGORY_CC,&MEDIATYPE_Video,pCap,NULL,NULL); if(FAILED(hr) return hr; RenderStream会帮我们创建整个Filter Graph RenderStream不支持 WST 信号的渲染,我们必须手动创建Filter

35、Graph 四杂记(1)电视卡 Crossbar, TV Tuner Crossbar是用于输入端子的选择。使用的时候,我们只要用ICrossbar:Route导通相应的端子就可以了。有的电视卡有两个Crossbar 。TV Tuner控制电视卡接收与频道选择,可以通过接口IAMTVTuner进行操作(2)Stream Buffer Engine 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 11 页 - - - - - - - - - 这个可以实现实时流媒体的缓冲。

36、它有两个Filters ,Stream Buffer Source,Stream Buffer Sink Stream Buffer Source负责流媒体的采集,并写入磁盘,以供给Stream Buffer Sink读取。对于流媒体, Stream Buffer Source只支持 DV 和 MPEG-2 两种格式, 所以,在输入 Source时,有时候要进行格式转换。Stream Buffer Source 优先采用的格式是MPEG-2 。Stream Buffer Sink负责读取Source写入的数据,然后进行回放。读取的时候,它会先找到Stream Buffer Source写入的一

37、个Stub 文件,里面包含了指向其它文件的指针。使用 Stream Buffer Engine时,我们要构造两个Filter Graph 。(3) WM Asf Writer 将视频保存为Asf 文件的时候,要用到WM Asf Writer,它有一个音频输入端,一个视频输入端,它要求只两个端都要接上,否则构造出来的Filter Graph无法启动。这个要求感觉有点勉强,不知有没有解决方法。(4)ISampleGrabber 在创建 CLSID_SampleGrabber组件的时候,我们不能直接就得到里面的ISampleGrabber ,而是要先得到IBaseFilter接口,然后再用QueryInterface得到 ISampleGrabber.感觉很奇怪。根据 IUnknown原则,无论我们先得到那个接口都是可以的啊。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 11 页 - - - - - - - - -

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁