利用DirectShow开发自己的filter

合集下载

深入浅出DirectShow-Filter

深入浅出DirectShow-Filter

深入浅出DirectShow-Filter1. Filter概述Filter是一个COM组件,由一个或多个Pin组成。

Pin也是一个COM组件。

Filter文件的扩展名为.ax,但也可以是.dll。

Filter根据其包含Input pin或Output pin的情况(或在Filter Graph的位置),大致可分为三类:Source Filter(仅有Output pin)、Transform Filter(同时具有Input pin和Output pin)和Renderer Filter(仅有Input pin)。

一般情况下,创建Filter使用一个普通的Win32 DLL项目。

而且,一般Filter项目不使用MFC。

这时,应用程序通过CoCreateInstance 函数Filter实例;Filter与应用程序在二进制级别的协作。

另外一种方法,也可以在MFC的应用程序项目中创建Filter。

这种情况下,Filter 不需注册为COM组件,Filter与应用程序之间的协作是源代码级别的;创建Filter实例,不再使用CoCreateInstance函数,而是直接new 出一个Filter对象,如下:m_pFilterObject = new CFilterClass();// make the initial refcount 1 to match COM creationm_pFilterObject ->AddRef();因为Filter的基类实现了对象的引用计数,所以即使在第二种情况下,对创建后的Filter对象的操作也完全可以遵循COM标准。

Filter是一个独立功能模块,最好不要将Filter依赖于其他第三方的DLL。

因为Filter具有COM的位置透餍蕴氐悖現ilter文件可以放在硬盘的任何位置,只要位置移动后重新注册。

但此时,如果Filter依赖其他DLL,则Filter对该DLL的定位就会出现问题。

基于COM的DirectshowFilter实现

基于COM的DirectshowFilter实现

收稿日期:2003-09-23作者简介:黄振宇(1973—),男,湖北武汉人,硕士研究生,研究方向为机器人视觉、图像处理和模式识别。

基于COM 的Directshow Filter 实现黄振宇,王 敏,吴 涛(华中科技大学,湖北武汉430074)摘 要:视频处理程序设计的过程中,以往开发人员要在处理硬件设备和数据格式差异上花费大量的精力,且程序不具有可复用性,而利用微软提供的Directshow 视频处理通用平台,封装了硬件差异,且实现了处理过程的模块化。

文中在介绍Directshow 视频处理中的运用的基础上,重点结合COM 技术介绍了Directshow Filter 模块化设计方法和步骤,对其中所蕴涵的组件对象概念做了详细的剖析。

并以变换过滤器为例,演示了实现过程,给出了关键代码的示例,指出Directshow 是一项有前景的视频处理技术。

关键词:过滤器;组件对象模型;Directshow中图分类号:TP311 文献标识码:A 文章编号:1005-3751(2004)05-0113-04R ealizing Directshow Filter B ased on COMHUAN G Zhen 2yu ,WAN G Min ,WU Tao(Huazhong University of Science and Technology ,Wuhan 430074,China )Abstract :In the program design of video process ,anciently the programmer should deal with the differences of hardware and format of da 2ta ,and the program can not be reused.But using the Microsoft ’s Directshow ,common video process platform ,encapsulated the differ 2ences and realized the process blocking.In this article ,on the basis of the introduction of the using Directshow in the video process ,dis 2cusses the design method and approach of Directshow Filter module based on COM ,analyses the concept of module object contained in it.And using the Transform Filter as example ,shows the process of realization ,gives the pivotal codes.Point out that Directshow is a useful technology of video process.K ey w ords :filter ;COM ;Directshow0 引 言 在基于Windows 的视频处理程序设计的过程中,以往开发人员要用大量的时间处理不同的硬件设备驱动差异和数据格式带来的麻烦,以及时间戳、数据同步、内存分配等普遍性问题,无法将精力集中在视频算法的开发上来。

directshow filter 写法

directshow filter 写法

文章标题:深度剖析:直播软件中的 DirectShow Filter 写法在当前直播软件的发展中,DirectShow Filter 写法是一个十分重要的环节。

通过对该主题的全面评估,我们可以更深入地了解直播软件的技术实现,为我们的开发工作提供有价值的参考和指导。

在本文中,我们将从简到繁地探讨 DirectShow Filter 的写法,共享我对这一主题的个人观点和理解。

1. 什么是 DirectShow Filter?DirectShow Filter 是一种在 Windows 评台上使用的多媒体框架,它可以在多种媒体应用程序中使用,如音频、视频的播放、录制和处理等。

在直播软件中,DirectShow Filter 可以用来实现视频的捕获、编码、解码和输出等功能,是直播软件中不可或缺的一部分。

2. DirectShow Filter 的写法在 DirectShow Filter 的写法中,我们首先需要了解 Filter 的基本概念和作用。

Filter 可以理解为一个数据处理单元,它可以对输入的数据进行处理,并输出处理后的数据。

在实际写作中,我们需要按照DirectShow 的规范和要求,实现各种不同类型的 Filter,如视频捕获Filter、音频解码 Filter 等。

3. DirectShow Filter 的实现在实现具体的 DirectShow Filter 时,我们需要考虑到各种不同的输入和输出格式,以及处理过程中可能出现的异常情况。

在写作过程中,我们需要保证 Filter 的稳定性和兼容性,确保它可以在各种不同的场景下正常工作。

4. 个人观点和理解对于 DirectShow Filter 的写法,我的个人观点是,我们需要充分了解DirectShow 框架的规范和要求,同时也需要考虑到实际应用中可能出现的各种不同情况。

在写作过程中,我们需要注重代码的可读性和可维护性,以便在后续的开发工作中能够快速定位和解决问题。

Directshow开发的基本技巧

Directshow开发的基本技巧
EC_ERRORABORT表明出现了一个错误。
应用程序可以通知filter graph manager,在某个指定的事件发生时,向指定的窗口发生一个指定的消息。这样应用程序就可以在消息循环中对发生的事件产生反应。
首先定义消息,
#define WM_GRAPHNOTIFY WM_APP + 1
然后向filter graph manager请求IMediaEventEx接口,然后调用IM来设置消息通知窗口
if (SUCCEEDED(hr))
{
hr = pConfig->SetRenderingMode(VMRMode_Windowless);
pConfig->Release();
}
if (SUCCEEDED(hr))
{
// Set the window.
hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&pWc);
2如何处理事件通知(Event Notification)
当一个Directshow的应用程序运行的时候,在filter Graph内部就会发生各种各样的事件,例如,一个filter也许发生数据流错误。Filter通过给graph mangaer发送事件通知来和graph通信,这个事件通知包括一个事件码和两个事件参数。事件码表示发生事件的类型,两个参数用来传递信息。
IVideoWindow *pVidWin = NULL;
pGraph->QueryInterface(IID_IVideoWindow, (void **)&g_pVidWin);
pVidWin->put_Owner((OAHWND)hwnd);

设计自定义的Filter

设计自定义的Filter

如何设计自定义的transform filter(转)对于DIrectShow的初学者而言,最大的困难莫过于尝试设计自定义的filter。

设计自定义的transform filter是困难的因为首先filter是一种dll (后缀名为.ax)而编写dll工程需要一定的VC基础所以建议先补充一点dll的知识其次dll的注册,GUID的生成和工程的配置都很麻烦。

再次网上缺乏现成的transform filter的例子。

DirectShow给的源码比如NULLINPLACE 和CONTRAST都太复杂,都带有对话框和属性页,不适合初学者,而且这些例子没有一个涉及到图像格式的转换,而transform filter最大的公用就是媒体类型的转换,因此这些例子不适用作为一个初学者,我深深受到这些问题的困扰,经过刻苦钻研终于走出了这个泥潭,豁然开朗。

于是把它记录下来,希望可以对其他人有帮助,也作为对08年的一个小结。

我的例子是设计一个transform filter 把YUY2 16bit 的媒体转化为RGB24 24bit的类型。

原因是我的摄像头只支持YUY2 16bit这种格式,我想得到位图。

顺便学习一下Filter的设计以下为具体步骤:一配置开发环境1. VC中在Tools->Options->Directories 设置好DirectX SDK的头文件和库文件路径2. 编译了基类源码,生成strmbasd.lib (debug版), strmbase.lib(release版)3. VC向导新建一个win32 DLL(empty)工程4. Setting->Link->Output file name: YUV2RGBfilter.ax5. Setting->Link加入strmbasd.lib winmm.lib quartz.lib vfw32.lib (注意路径)6. 定义一个同名.def文件,加入到工程,内容如下:LIBRARY YUV2RGBfilter.axEXPORTSDllMain PRIVATEDllGetClassObject PRIVATEDllCanUnloadNow PRIVATEDllRegisterServer PRIVATEDllUnregisterServer PRIVATE7.建立一个类YUV2RGBfilter 建立他的cpp文件和h文件8. 在YUV2RGBfilter.cpp中定义DLL的入口函数及注册放在cpp文件的最后//// DllEntryPoint//extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); BOOL APIENTRY DllMain(HANDLE hModule,DWORD dwReason,LPVOID lpReserved){return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);}//////////////////////////////////////////////////////////////////////////// Exported entry points for registration and unregistration// (in this case they only call through to default implementations).////////////////////////////////////////////////////////////////////////// STDAPI DllRegisterServer(){return AMovieDllRegisterServer2( TRUE );}STDAPI DllUnregisterServer(){return AMovieDllRegisterServer2( FALSE );}9. cpp文件中要包含的头文件#include <streams.h>#include <windows.h>#include <initguid.h>#include <olectl.h>#if (1100 > _MSC_VER)#include <olectlid.h>#endif#include "Y2Ruids.h" // our own public guids#include "YUV2RGBfilter.h"二开发Filter1. 生成GUID( 命令行模式下运行guidgen工具) 为他建立一个文件Y2Ruids.h 单独引用#include <initguid.h>// YUV2toRGB24 Filter Object// {F91FC8FD-B1A6-49b0-A308-D6EDEAF405DA}DEFINE_GUID(CLSID_YUV2toRGB24,0xf91fc8fd, 0xb1a6, 0x49b0, 0xa3, 0x8, 0xd6, 0xed, 0xea, 0xf4, 0x5, 0xda);2. 构造CYUV2RGBfilter类继承自CTransformFilter 写在TransformFilter.h中// ----------------------------------------------------------------------------// Class definitions of CYUV2RGBfilter// ----------------------------------------------------------------------------////class CYUV2RGBfilter : public CTransformFilter{public:static CUnknown * WINAPI CreateInstance(LPUNKNOWN punk, HRESULT *phr);STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);DECLARE_IUNKNOWN;// override pure virtual functionHRESULT CheckInputType(const CMediaType *mtIn);HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut);HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProp);HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);private://ConstructorCYUV2RGBfilter(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr);// member functionVOID ChangeFormat(AM_MEDIA_TYPE* pAdjustedType);DWORD ConvertYUV2toRGB(BYTE* yuv, BYTE* rgb, DWORD dsize);// member variableconst long m_lBufferRequest;CCritSec m_Y2RLock; // To serialise access.};3. 按格式改写构造函数//// CNullInPlace::Constructor//CYUV2RGBfilter::CYUV2RGBfilter(TCHAR *tszName,LPUNKNOWN punk,HRESULT *phr) : CTransformFilter(tszName, punk, CLSID_YUV2toRGB24),m_lBufferRequest(1){ASSERT(tszName);ASSERT(phr);} // CYUV2RGBfilter4. 改写CTransformFilter五个纯虚函数(最重要的地方)HRESULT CheckInputType(const CMediaType *mtIn);HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut);HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES*pProp);HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);HRESULT Transform(IMediaSample *pIn, IMediaSample *pOut);5. 设计自己的私有函数完成一定的功能6. 注册Filter信息// 注册信息//setup dataconst AMOVIESETUP_MEDIATYPEsudPinTypes = { &MEDIATYPE_Video // clsMajorType , &MEDIASUBTYPE_NULL } ; // clsMinorType const AMOVIESETUP_PINpsudPins[] = { { L"Input" // strName, FALSE // bRendered, FALSE // bOutput, FALSE // bZero, FALSE // bMany, &CLSID_NULL // clsConnectsToFilter, L"Output" // strConnectsToPin, 1 // nTypes, &sudPinTypes } // lpTypes, { L"Output" // strName, FALSE // bRendered, TRUE // bOutput, FALSE // bZero, FALSE // bMany, &CLSID_NULL // clsConnectsToFilter, L"Input" // strConnectsToPin, 1 // nTypes, &sudPinTypes } }; // lpTypesconst AMOVIESETUP_FILTERsudYUV2RGB = { &CLSID_YUV2toRGB24 // clsID , L"YUV2RGB" // strName, MERIT_DO_NOT_USE // dwMerit, 2 // nPins, psudPins }; // lpPin//// Needed for the CreateInstance mechanism//CFactoryTemplate g_Templates[1]={ {L"YUV2RGB", &CLSID_YUV2toRGB24, CYUV2RGBfilter::CreateInstance, NULL, &sudYUV2RGB }};int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);编译成功后生成GrayFilter.ax命令行运行regsvr32 GrayFilter.ax注册即可不用反复注册,只用注册一次,如若修改只需将重新编译的.ax覆盖原来的就行了调试最好在graphEdit中经行比较方便。

基于DirectShow的视频处理Filter组件设计与实现

基于DirectShow的视频处理Filter组件设计与实现

基于DirectShow的视频处理Filter组件设计与实现王新蕾;刘乃丰;夏济海【期刊名称】《现代电子技术》【年(卷),期】2016(039)013【摘要】目前市场上支持视频图像处理功能的软件虽然多种多样,但通常涉及行业背景,应用范围狭窄,开放的视频图像处理组件在容错或安全性上表现一般,因此有必要创新和开发特定功能的视频处理组件。

该设计基于DirectShow架构,开发出具有视频处理功能的Filter组件,具有本地图片叠加入视频流、视频编码格式转换、截取画面保存为本地图像等功能。

可在视频图像传递过程中对图像进行实时处理、添加信息、优化或保存画面等,使人们以更加灵便的方式获取、使用或传播视频信息。

测试结果表明,该组件可应用于广播电视传输或视频采集时的图像处理,甚至应用于美颜相机或PC摄像头的趣味叠图等,应用范围广泛,平台兼容性强,填补了市场上该类产品的类型和功能短缺。

%The software supporting video image processing function is various on the market,but it has narrow application range due to the industry background. And the opened video image processing module has poor performance on fault tolerant or security,so it is necessary to innovate and develop the video processing module with specific function. The Filter module with video processing function was developed based on DirectShow framework,which has the functions of local image added into video streaming,video coding format transform,and extracting frames saved as the local image. The module can realize the operations of real⁃time processing,information adding,framesoptimization or frames preservation for the image in video image transfer pro⁃cess,so people can acquire,use or transmit video information with more flexible way. The test results show that the module can be applied to radio and television transmission or image processing while video collection,and beauty camera or funny overlay of PC camera. The module has wide application range and good platform compatibility,which filled the type and function shortage of this product on the market.【总页数】5页(P46-50)【作者】王新蕾;刘乃丰;夏济海【作者单位】东南大学生物科学与医学工程学院,江苏南京 210098; 南京信息工程大学滨江学院,江苏南京 210044;东南大学生物科学与医学工程学院,江苏南京 210098;南京信息工程大学滨江学院,江苏南京 210044【正文语种】中文【中图分类】TN911.73-34【相关文献】1.基于DirectShow的信息提取Source Filter设计 [J], 薛莹莹;曾光裕;胡刚2.基于DirectShow设计视频加密Filter组件 [J], 申华3.基于DirectShow Filter的遥控站架构设计及实现 [J], 周利民;林琳4.利用DirectShow Filter技术开发视频加密组件 [J], 耿俊;刘胜全;张蕾5.基于DirectShow设计视频加密Transform Filter [J], 姚晔;徐正全;李伟因版权原因,仅展示原文概要,查看原文内容请购买。

directshow学习笔记

directshow学习笔记

定义自己的filter,实现编码和解码。

1.字符叠加Filter之功能分析总体需求:在视频流指定的一个时间段内叠加一段字符,要求能够做到实时叠加。

字符的内容、字体类型、大小、颜色、叠加的位置、存在的时间都能够定制,普遍支持RGB各种格式输入。

另外,除了支持静态字符叠加外,还要求支持其他效果的字符(包括滚动字幕,系统时间等)叠加,并且系统设计的扩展性良好。

功能单一化:字符叠加可以在一个filter中实现。

选择一种filter模型:这个filter同时有输入和输出(即在输入的视频帧上叠加完字符后再输出到下一级filter),因此我们的filter是一个Transform Filter。

由于输入和输出的媒体类型一致,而且输入和输出sample的数据大小不会变化,所以我们可以采用“就地”处理的transform Filter。

定义输入和输出我们的filter需要一个输入Pin和一个输出Pin,输入Pin支持的媒体类型有RGB32、RGB24、RGB565、RGB555等,并且输出Pin上的媒体类型与输入Pin保持一致。

接口定义接口方法应该包括设置字符的内容,设置字体的各种属性,选择字体的叠加效果,设置叠加位置,设置字符存在的时间段等。

其他一些特殊要求Filter处理的sample是一一对应的,而且内部不需要另外的使用线程。

这是一个标准的Transform Filter。

当我们要写一个source Filter,并且要将产生的数据“推”出去时,我们一般选择Csource,我们的Filter接收输入数据,经过一定的处理后要再输出数据,我们一般选择CtransformFilter (如果可以“就地”处理就选择CtransInPlaceFilter)。

如果我们的Filter同时有输入和输出,而且它的输入Pin上需要自己“拉”数据,则我们选择CbaseFilter,而在输入Pin上使用工具类CpullPin;当我们的Filter接收输入数据后不再需要输出,我们一般选择CbaseFilter。

directshow教程(新整理)

directshow教程(新整理)

Directshow教程0.11MSDN翻译系列作者:黄丁杰说明:如果有任何问题请联系din-je@。

是本人业余翻译的如果有错误请直接发到我邮箱我会立刻改正,directshow的其他文章我会在以后不断翻译出来。

如果觉得好请帮我作作宣传。

欢迎转载,但是禁止修改。

Directshow起步。

本章主要介绍diirectshow在编写程序时所需的基本概念。

在本章你可以总揽下directshow 技术。

你必须在总体上对本章的编程和媒体有所了解。

本章将介绍。

设置编译环境。

介绍directshow应用程序编程。

如何播放一个文件设置编译环境:你可以编译工程在命令行模式下或者在vs集成环境中头文件所有的directshow应用程序都使用下面的头文件。

Dshow。

H部分directshow接口需要附加的头文件。

这些文件会在接口的注意中给出。

所需的库文件directshow需要如下的库文件strmiidl。

Lib 该库包含CLSIDs和IIDs的接口。

所有的directshow都需要该库。

Quartz。

Lib 该库包含AMGetErrorText函数。

如果你没有调用该函数,该库没有用。

记住在你的编译环境中必须把directx SDK 的头文件库和连接库的目录作为vs优先搜索的路径。

这样可以保证编译的时候用的是最新版本的文件。

介绍directshow应用程序编程本章介绍编写一个directshow程序的基本技术和概念,读完本章你就可以写个你自己的directshow的应用程序了。

滤镜和图像滤镜directshow是由被称作滤镜的东西构成的。

滤镜是一个软件包用来执行对多媒体流的一些操作。

比如directshow的滤镜可以读出一个文件从视频捕捉设备获取视频流解码各种各样的多媒体格式,比如MPEG-1S视频。

传输视频和音频到屏幕和声卡。

滤镜几乎完成视频播放所需要的从输入到输出的所有功能。

比如一个MPEG-1的滤镜。

它可以输入MPEG码流然后输出图像帧用于后续显示在directshow程序中只要执行把滤镜连接在一起就可以了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学习directshow已经有几天了,下面将自己的学习心得写下来,希望对其他的人有帮助。

Filter实质是个COM组件,所以学习开发Filter之前你应该对com的知识有点了解。

Com组件的实质是一个实现了纯虚指针接口的C++对象。

关于com的东西,这里不多讲。

一给vc配置DirectShow的开发环境无论开发Filter还是开发Dshow的应用程序都要配置一下开发环境的,其实就是包含一下dshow用到的头文件和动态库。

选择Tools菜单下面的Options。

在弹出的Option对话框配置如下图1 添加头文件选择动态库文件添加到工程中图2 添加动态库二创建工程以及Filter的入口函数创建工程一般情况下,创建Filter使用一个普通的Win32 DLL项目。

而且,一般Filter项目不使用MFC。

这时,应用程序通过CoCreateInstance函数Filter实例;Filter与应用程序在二进制级别的协作。

另外一种方法,也可以在MFC的应用程序项目中创建Filter。

在vc里新建一个工程,选择win32动态库,如下图图3图4这样生成了一个简单的DLL,只有一个Dllmain入口函数。

下面我要给这个filter添加入口函数了。

Filter是个基于DLL的com组件,所以一般的Filter都要实现下面几个入口函数首先定义导出函数要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。

使用导出函数关键字_declspec(dllexport)创建MyDll.dll就是在 .h文件中定义定义函数如下:为了用.def文件创建DLL,往该工程中加入一个文本文件,命名为MyDll.def,再在该文件中加入如下代码:LIBRARY MyFilter.axEXPORTSDllMain PRIVATEDllGetClassObject PRIVATEDllCanUnloadNow PRIVATEDllRegisterServer PRIVATEDllUnregisterServer PRIVATE其中LIBRARY语句说明该def文件是属于相应DLL的,EXPORTS语句下列出要导出的函数名称。

我们可以在.def文件中的导出函数后加@n,如Max@1,Min@2,表示要导出的函数顺序号,在进行显式连时可以用到它。

该DLL编译成功后,打开工程中的Debug目录,同样也会看到MyDll.dll和MyDll.lib文件。

然后要定义这些函数的实现了,其实这些工作dshow的基类里都已经替我们做好了,我们所要做的就拿来用就是了,最重要的三个函数的实现一般如下STDAPI DllUnregisterServer(){return AMovieDllRegisterServer2(FALSE);}extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved){return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);}其中DllEntryPoint 是在C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\dllentry.cpp定义的,如果感兴趣我们可以去看看它的定义。

AMovieDllRegisterServer2函数是在下面C:\DX90SDK\Samples\C++\DirectShow\BaseClasses\dllsetup.cpp这个文件定义的,具体实现可以自己看看。

到了这里你恐怕要做点工作,还是要设置一下你的项目环境,否则恐怕你编译是通不过的,因为你用到了基类的一些东西,所以你要将你的dshow基类的定义和库文件包含进来。

首先包含#include Streams.h其次在Project –Setting菜单下配置自己的Filter输出的名字和连接的lib文件图5其中library modules里的包含的动态库如下c:\DX90SDK\Samples\C++\DirectShow\BaseClasses\debug\strmbasd.lib msvcrtd.lib quartz.lib vfw32.libwinmm.lib kernel32.lib advapi32.lib version.lib largeint.lib user32.lib gdi32.lib comctl32.lib ole32.lib olepro32.lib oleaut32.lib uuid.lib此时你编译一下,好像还是通不过,它提示有一个全局的用于实现COM接口的变量没有定义,不着急,下面我们就开始实现Filter的com接口。

三如何实现Filter 的类厂对象我们知道一个Filter是一个com组件,所以它com特性的实现其实在其基类中实现的,比如IUnknown 接口,我们直接从基类派生出我们的Filter后,它就支持com接口了,它就是一个com组件了。

所有的com组件为了实现二进制的封装,所以连创建的接口都封装了,因此每个com对象都有个类对象(也叫类厂对象,本身也是com对象,用来创建com组件)来创建com组件。

下面温习一下com组件的创建过程,其中涉及到几个函数1、当客户端要创建一个com组件时,它通过底层的COM API函数CoGetClassObject()使用SCM 的服务,这个函数请SCM把一个指针绑定到客户端请求的com组件的类对象上,其实在CoGetClassObject ()里它装载了该DLL的库,通过该dll的导出函数DllGetClassObject();DllGetClassObject根据客户端提供的com组件CLASSID,返回该com组件类对象的指针。

下面com组件的创建和SCM无关了。

2、客户端利用组件的类对象(类厂对象)的IClassFactory::CreateInstance方法创建com组件。

Filter在这里使用了一个类厂模板类来当作Filter的类厂对象。

下面看看类厂在DShow是怎么工作的。

类厂对象也是一个com组件。

本来DllGetClassObject是应该由我们自己完成一个函数,在directshow 基类里已经完成了,我们不用管它了。

它的功能就是来寻找这个DLL中的类厂对象,看是否有符合客户端请求的类厂对象。

DLL里声明了一个全局的类厂模板数组,当DllGetClassObject请求类厂对象的时候,它就搜索这个数组,看是否有和CLSID匹配的类厂对象。

当它找到一个匹配的CLSID,它就创建一个类厂对象,然后讲类厂指针返回给CoGetClassObject,然后客户端可以根据返回去的类厂指针,调用IClassFactory::CreateInstance方法创建组件,类厂就根据数组里定义的方法创建com组件。

factory template包含下列变量:const WCHAR * m_Name; // Nameconst CLSID * m_ClsID; // CLSIDLPFNNewCOMObject m_lpfnNew; // Function to create an instance of the componentLPFNInitRoutine m_lpfnInit; // Initialization function (optional)const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; // Set-up information (for filters)其中的两个函数指针m_lpfnNew and m_lpfnInit使用下面的定义你可以参照如下的方式定义你的类厂对象CUnknown * WINAPI CMyFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr){CMyFilter *pFilter = new CMyFilter(NAME("my Filter"), pUnk, pHr);if (pFilter== NULL){*pHr = E_OUTOFMEMORY;}return pFilter;}你可以声明自己的类厂数组如下:CFactoryTemplate g_Templates[1] ={{L"my filter", // Name&CLSID_MYFilter, // CLSIDCMyFilter::CreateInstance, // Method to create an instance of MyComponentNULL, // Initialization function&sudInfTee // Set-up information (for filters)}};int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);如果在这个com组件中你要支持多个filter,你可以在这个数组中继续添加就是了。

四如何实现自己的Filter在这里就要讲如何创建自己的Filter了,下面我们以写一个CTransformFilter为例1、选择一个基类,声明自己的类创建filter很简单,你只要根据自己的需要选择不同的基类Filter派生出自己的Filter,它就已经支持com特性了。

从逻辑上考虑,在写Filter之前,选择一个合适的Filter基类是至关重要的。

为此,你必须对几个Filter 的基类有相当的了解。

在实际应用中,Filter的基类并不总是选择CBaseFilter的。

相反,因为我们绝大部分写的都是中间的传输Filter(Transform Filter),所以基类选择CTransformFilter和CTransInPlaceFilter的居多。

如果我们写的是源Filter,我们可以选择CSource作为基类;如果是Renderer Filter,可以选择CBaseRenderer或CBaseVideoRenderer等。

总之,选择好Filter的基类是很重要的。

当然,选择Filter的基类也是很灵活的,没有绝对的标准。

相关文档
最新文档