利用 DirectShow 开发自己的 Filter
2006-07-23 11:33:58 来源:WEB开发网下面笔者就从本人的实际经验出发,对Filter基类的选择提出几点建议供大家参考。首先,你必须明确这个Filter要完成什么样的功能,即要对Filter项目进行需求分析。请尽量保持Filter实现的功能的单一性。如果必要的话,你可以将需求分解,由两个(或者更多的)功能单一的Filter去实现总的功能需求。
其次,你应该明确这个Filter大致在整个Filter Graph的位置,这个Filter的输入是什么数据,输出是什么数据,有几个输入Pin、几个输出Pin等等。你可以画出这个Filter的草图。弄清这一点十分重要,这将直接决定你使用哪种“模型”的Filter。比如,如果Filter仅有一个输入Pin和一个输出Pin,而且一进一处的媒体类型相同,则一般采用CTransInPlaceFilter作为Filter的基类;如果媒体类型不一样,则一般选择CTransformFilter作为基类。
再者,考虑一些数据传输、处理的特殊性要求。比如Filter的输入和输出的Sample并不是一一对应的,这就一般要在输入Pin上进行数据的缓存,而在输出Pin上使用专门的线程进行数据处理。这种情况下,Filter的基类选择CSource为宜(虽然这个Filter并不是源Filter)。当Filter的基类选定了之后,Pin的基类也就相应选定了。接下去,就是Filter和Pin上的代码实现了。有一点需要注意的是,从软件设计的角度上来说,应该将你的逻辑类代码同Filter的代码分开。下面,我们一起来看一下输入Pin的实现。你需要实现基类所有的纯虚函数,比如CheckMediaType等。在CheckMediaType内,你可以对媒体类型进行检验,看是否是你期望的那种。因为大部分Filter采用的是推模式传输数据,所以在输入Pin上一般都实现了Receive方法。有的基类里面已经实现了Receive,而在Filter类上留一个纯虚函数供用户重载进行数据处理。这种情况下一般是无需重载Receive方法的,除非基类的实现不符合你的实际要求。而如果你重载了Receive方法,一般会同时重载以下三个函数EndOfStream、BeginFlush和EndFlush。我们再来看一下输出Pin的实现。一般情况下,你要实现基类所有的纯虚函数,除了CheckMediaType进行媒体类型检查外,一般还有DecideBufferSize以决定Sample使用内存的大小,GetMediaType提供支持的媒体类型。
Tags:利用 DirectShow 开发
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接