创建一个filter实例(transform filter)

本文档介绍了如何创建一个基于CTransformFilter的filter实例,用于视频处理。选择CTransformFilter是因为它允许对上游filter传递的样本进行复制和修改。首先,创建一个Win32 DLL项目,接着定义类CSplitFilter并继承自CTransformFilter。然后,使用Guidgen生成CLSID,并在代码中定义。最后,处理媒体类型,主要涉及CTransformFilter的媒体协商和内存分配器设置。
摘要由CSDN通过智能技术生成
1、选择所要创建的filter的用途,据此来选择基类。基类可以从CTransformFilter、CTransInPlaceFilter、CVideoTransformFilter和CBaseFilter中来选取。
(1) CTransInPlaceFilter提供了本地处理Sample的机制(Sample可以认为是存储一个视频帧的结构),当一个trans-in-place filter收到一个sample时,你可以通过重载它的Transform()函数来修改其中的数据,trans-in-place filter会在Transform()函数执行完后直接把这个sample传递给下一个filter。
(2) CTransformFilter完成的功能与CTransInPlaceFilter一样,它们的区别就是CTransformFilter总是把上游filter传递过来的sample复制一份,并把复制后的sample传递给下一个filter。当然,你可以通过重载Transform()函数来控制这个过程,包括修改其中的数据(这也是自己写filter的原因)。
(3)CVideoTransformFilter与CTransformFilter一样,只是多加了质量控制功能。
(4)以上三个filter都继承于CBaseFilter,所以如果想对filter进行更多的控制,就要直接从CBaseFilter来继承,但是所要做的工作也最多。
在这个例子中,我选择CTransformFilter,因为CTransInPlaceFilter太简单了,dx9sdk中的例子NullNull就是一个完整的CTransInPlaceFilter的框架,并且只是一个框架,什么工作也没有做,如果要用的话直接修改就可以用了。
2、在vc中选择win32 dll,创建一个dll,名字随便取,这里我取SplitFilter,选择空dll。
3、然后,创建一个类CSplitFilter,继承自CTransformFilter,当然要选择public方式。
4、为filter生成一个CLSID,可以使用Guidgen,它的用法是在命令行中打Guidgen,然后回车,Guidgen就执行了,单击New GUID就会生成一个新的GUID;单击Copy就可以把新生成的GUID复制到剪贴板上。然后在SplitFilter.h文件上粘贴进来,最后是这个样子:
 //
// GUID
//
// {3DCD790F-B7A0-429a-B9E1-3CE3255D8D1C}
DEFINE_GUID(<<name>>, 
0x3dcd790f, 0xb7a0, 0x429a, 0xb9, 0xe1, 0x3c, 0xe3, 0x25, 0x5d, 0x8d, 0x1c);
然后把其中的<<name>>换成自己设置的名字,如下:
// {3DCD790F-B7A0-429a-B9E1-3CE3255D8D1C}
DEFINE_GUID(CLSID_SplitFilter, 
0x3dcd790f, 0xb7a0, 0x429a, 0xb9, 0xe1, 0x3c, 0xe3, 0x25, 0x5d, 0x8d, 0x1c);
然后在SplitFilter.cpp中加入#include <initguid.h>
再来修改构造函数,形式如下:
CSplitFilter::CSplitFilter() : CTransformFilter(NAME("SplitFilter"), 0, CLSID_SplitFilter)
{
 
}
5、处理媒体类型
     首先要明白一点,两个filter连接,也就是两个filter的输出pin和输入pin在进行连接,这个工作是由输出pin发起的,由输入pin来检查媒体类型是否匹配,并决定是否接受这个连接。在CTransformFilter中协商媒体类型的工作是由CTransformFilter来完成的,这个工作本来是应该由pin来完成的,但是CTransformFilter中的pin只是简单的调用CTransformFilter中相应的函数而已,所以我们所有的工作只是重载CTransformFilter中的三个虚函数而已:
(1)实现CheckInputType(const CMediaType *mtIn)(不要问我如何添加这个函数,如果这个都不会的话趁早别看dshow了,赶紧去看vc的书去)。这个函数是由输入pin来调用,当上游输出pin要来进行连接的时候,我们的filter的输入pin就会调用这个函数来检查是否支持上游输出pin的媒体类型。其中的CMediaType类是对AM_MEDIA_TYPE结构的封装,AM_MEDIA_TYPE包含了有关的媒体类型,具体可查阅dxsdk文档。因为我这里只是写一个框架来为大家演示,功能只是传递sample,并不对数据有任何的修改,所以任何的格式都可以,所以不管什么格式我们都应该返回ok,实际函数如下:
HRESULT CSplitFilter::CheckInputType(const CMediaType *mtIn)
{
  
 // Everything is good.
    return S_OK;
}</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值