利用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实现
收稿日期: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 的写法,共享我对这一主题的个人观点和理解。
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开发的基本技巧
应用程序可以通知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
如何设计自定义的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组件设计与实现王新蕾;刘乃丰;夏济海【期刊名称】《现代电子技术》【年(卷),期】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学习笔记
定义自己的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教程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程序中只要执行把滤镜连接在一起就可以了。
利用DirectShow开发自己的filter
学习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语句下列出要导出的函数名称。
基于DIRECTSHOW的视频处理FILTER组件设计与实现
中图分类号: tn911.73?34 文献标识码: a 文章编号: 1004?373x(2016)13?0046?050 引言多媒体信息在人们的生活中无处不在,随着网络平台的广泛普及和三网融合的发展[1],音、视频处理以及流媒体传输仍然是当下流行的发展和研究热点。
视频信息因为包含的信息量大、内容生动,易成为人们获取信息的主要方式。
如果能够在视频图像传输过程中对图像进行实时处理,添加信息,优化画面,甚至保存当前画面,将会使人们以更加灵活方便的方式获取、使用和传播视频信息,从而满足进一步的需求。
目前市场上支持图像处理功能的软件多种多样,涉及各种各样的行业应用背景。
但是这些软件往往仅能在本行业工作范围内使用,应用范围狭窄。
例如:直播信号的水印叠加,必须使用相应的直播信号处理软件。
如果在采集视频过程中叠加水印,就必须使用capture相关的软件才能进行。
相同的功能由于应用背景的不同,导致需要使用两款完全不同的软件。
本设计通过设计一个filter组件,外部应用程序仅仅通过调用加载这个组件,即可实现相应的功能,且完全适用于各种应用背景。
按照功能来区分,filter大致分为三类:sourcefilter,transformfilter,renderfilter。
其中sourcefilter主要负责数据获取,数据源可以是文件、网络、采集卡,甚至一个摄像机,然后数据往下传输;transformfilter主要负责数据的格式转换,例如数据流分离/合成、解码/编码等,然后将数据继续往下传输(本设计就属于transformfilter);renderfilter主要负责数据的最终去向――是送往声卡与显卡进行预览还是输出到文件进行本地储存。
2 现有产品介绍smart tee filter的优点是:支持的视频编码格式众多,适配大多数常见的编码格式;预览流链路工作状态堵塞不会影响采集流链路,避免了录制档案丢帧的情况发生。
但其也有不可避免的两个问题:(1)可能导致图像成为倒置或镜像(这取决于视频编码)。
DirectShow的RTP发包(H264)Filter转
DirectShow的RTP发包(H264)Filter转基于DirectShow的框架H.264 RTP Sender Filter开发框架与环境:1.VS2017——⼯具集为V120-VS20132.jrtplib-3.11.1 jthread-1.3.3 编译为32位版3.程序为32位程序4.DirectShow链路图如下(控制台为RTP发送地址与本机端⼝)5.RTP拆包⽅式为FU-A6.x264编码filter为ffdshow codec(本filter⽀持输⼊为H264的sample)7.本程序开源(部分实现借鉴了许多CSDN博客与⼤⽜的程序),请遵守开源协议实现部分有空的话应该会整理个更详细的版本,这⾥主要就说⼀下遇到的问题好了。
实现DirectShow+jrtplib的H264收发包程序,总共⽤时约两周,主要的精⼒和时间花在了RTP协议、RTP拆包与H.264字节流处理、H.264格式的解析上。
1.H.264的NAL单元(NALU)H.264编码实现了⽹络层也就是NAL,其中每⼀个单元(NALU)适⽤于⽹络传输,详细的这⾥不阐述了,捡重点的⽅便⼤家快速理解。
编码器对原始采集视频(图像)进⾏处理后,输出的每⼀帧即是⼀个NALU。
这⾥的每⼀帧包括编码器初始化输出的PPS和SPS。
实际上,我们需要⽤RTP实现的传输,就是从输⼊pin中的数据,提取每⼀帧(NALU),对NALU进⾏打包发送。
H.264编解码,怎样完成?需要怎样保持数据的发送?⾸先,H.264的编码,除了初始化编码器后,输出PPS和SPS外,之后的所有NALU单元,都为I-P-B帧的组合。
其中,I帧为关键帧,解码器遇到这⼀帧后,会清除重置解码器的预测基准(具体请参考H.264编码与运动预测模型),⽽P 帧和B帧则是前向预测帧和双向预测帧。
H.264由于进⾏了运动预测,因此除了I帧外,P帧和B帧仅需要较少的bit进⾏编码,从⽽减少传输的数据量。
Directshow开发笔记
智慧的鱼--------DirctShow SDK 学习笔记
提供了一系列的标准的模块可用于应用开发,开发者也可以开发自己的功能 Filter 来扩展 Directshow 的应用。下面我们用一个例子来说明如何采取 Filter 来播放一个 AVI 的视频文件。 从一个文件读取数据,形成字节流。 (这个工作由源 Filter 完成) 检查 AVI 数据流的头格式,然后通过 AVI 分割 Filter 将视频流和音频流分开。 解码视频流,根据压缩格式的不同,选取不同的 decoder filters 。 重画视频图像,通过 Renderer Filter。 将音频流送到声卡进行播放,一般采用缺省的 DirectSound Device Filter。流程见下图。
所以才想起了要翻译这些东西希望在9状态改变graph中的filter的状态改变应该一致因此应用程序并将状态改变的命令直接发给filter而是将相应的状态改变的命令发送给filtergraphmanager由manager将命令分发给graph中每一个filterseeking也是同样的方式工作首先由应用程序将seeking命令发送到filtergraph管理器然后由其分发给每个filterdirectshow2020开发笔记智慧的鱼irctshowsdk学习笔记1directshow开发笔记翻译个人感觉开发自己的filter还是要对dshow的基类要熟悉一些
1
智慧的鱼--------DirctShow SDK 学习笔记
1 About Directshow 基础
1.1 设置 dshow 的开发环境
如果你用 VC 开发环境,一定要在 Setting 里设置下面的东西 包含头文件 Dshow.h 所有的 dshow 应用必须包含
基于DirectShow设计视频加密Filter组件
鞍山师范学院学报J ou rnal of A nshan N or m a l U niversit y 2008208,10(4):40-43基于Di rectSho w 设计视频加密Filter 组件申 华(鞍山师范学院数学系,辽宁鞍山114007)摘 要:介绍了视频加密的算法和方案,分析了Direc t Sho w 的体系结构,并介绍了利用D irec tSho w 技术开发视频加密F ilt e r 组件的主要步骤.利用此技术开发出的视频加密组件可集成到各类基于DirectSh ow Filte r技术开发的应用程序中,实现对视频的加密.关键词:DirectShow;Filter;视频加密;CO M中图分类号:TP309.7 文献标识码:A 文章篇号:100822441(2008)0420040204 随着网络技术的发展,基于网络的多媒体应用日益广泛.例如,视频会议、视频点播、视频监控、网络聊天,等等.这些应用所包含的信息,往往涉及个人隐私、公司的商业信息,甚至涉及到国计民生和国家安全.因而对数字视频信号的加密技术的研究就显得尤为重要.虽然目前支持实时视频通讯的软件越来越受到广大用户的欢迎,但这类软件中只有少数考虑到对传输的视频数据进行加密的问题,而且使用传统方法对传输的视频数据进行加密,其软件开发周期长、数据处理效率低、模块可复用性差,同时对软件的维护也比较困难.本文叙述了笔者对视频加密所采用的方案,并利用D ir ectShow 提供的F ilter 组件技术,设计开发了一个视频数据加密组件.此组件可集成到各类基于D irectShow 技术开发的应用程序中,实现对视频数据的实时加密.1 视频加密算法及实现方案 视频数据具有数据量大、冗余度高、实时性要求高等特点,为了满足视频的应用要求,视频加密算法在安全性、压缩比、计算复杂度和数据可操作性方面都要有一定的要求[1].目前为止,国内外的学者和研究人员已经提出了很多种视频加密算法,而且大都是针对两种视频压缩国际标准H .26x 和MPEG 系列.可以将这些算法分为两大类:完全加密和选择加密[2]. 完全加密技术是一种最直接的加密方法,它对整个视频流采用标准的加密算法进行加密.该加密算法将整个视频流当作一般的比特流对待,没有考虑视频数据的特殊结构.这种算法的安全性很高,但是加密的数据量大,实时性不好控制;而且由于对同步信息也做了加密,因此不具有格式复合性和数据的可操作性.因此当前的这种视频加密算法还存在缺陷,要应用于视频加密还需要改进.选择性加密是基于信源特征的视频加密方法.被选择提取加密的数据量不大,但是这些数据对图像重建影响很大.本文采用基于分级选择性视频加密方案.此方案充分利用了视频数据的码流结构特点,在不改变码流语法的基础上,对视频数据的关键信息提取后加密,从而达到解码后的图像无法识别的目的[3].本文采用的选择性加密提取的系数有以下几种:(1)帧内块DC 值:帧内块包括I 帧所有块和P B 帧中的intra 块.由于P B 帧中的帧间块是利用运收稿日期作者简介申华(),女,河南人,鞍山师范学院数学系讲师:2007-10-22:1977-.动估计进行差分编码的,所以帧内块DC 系数加密具有扩散作用,PB 帧中的帧间块不加密也难以正确解码.(2)帧内块DC 符号位:帧内块DC 符号位较少,但是加密后的效果不错.经过预测后,加密效果会扩散到P B 帧中的帧间块.(3)AC 符号位:由于AC 系数个数多,所以AC 符号位在码流中的比例较大.但是DC 系数决定一个块的平均亮度和色度,加密AC 系数符号位对图像影响不大,所以只可以作为增强安全性的补充.(4)运动矢量符号位:运动矢量符号位加密后,会影响P B 帧正确解码.但是,I 帧都是帧内块,没有运动矢量,可以正确解码,故不能单独使用.运动矢量符号位数据量小,加密后对图像影响大,所以可以作为增强加密效果的补充.选择性加密不改变码流格式,不会增加码流,加密的数据量小,加密速度快.加密的安全性和加密的效果根据选择提取加密的系数种类有关.提取全部4种参数,可以获得最高的安全性,但是加密的速度会有些影响.提取部分参数,可以获得安全性和加密速度的折中.在使用中可以灵活选择.2 D irectSho w 的体系结构 D ir ectShow 是M ic r os oft 公司开发的多媒体架构,是M icr osoft D irec t X 8.0版(或以上)的组件之一.D irectShow 和D irectX 家族的其他成员一样,是一套完全基于组件对象模型(CO M)的应用系统.D irec t 2Show 是用来在W indow s 平台上开发流媒体应用的一套框架、组件及接口的集合,它为在W indows 平台上开发和实现高质量的音、视频捕获、处理和回放应用程序提供了简洁快捷的手段[4].D irectShow 在系统中所处的层次及其内部数据处理流程如图1所示.图1 DirectS how 系统图1中央最大的一块即是DirectShow 系统,虚线以下是R ing0特权级别的硬件设备,虚线以上是R ing3特权级别的应用层.其核心是Filter Graph 管理器,它负责控制和管理各类自定义或内置的F ilte r 并与用户的应用程序进行交互.Filter 是用于处理数据流的特殊C O M 模块,根据不同功能可以划分为用于媒体数据捕获的源过滤器(Source F ilte r )、用于数据格式处理的转换过滤器(Tr ansf or m F ilter )及用于数据输出的终端过滤器(R ende ring Filter )3类.和其它C O M 组件一样,它通过提供各类接口与应用程序交互.在实际应用中,往往是各类Filter 按一定的顺序连接成一条“流水线”协同工作,共同完成一组复杂的功能.F 的连接实际上是F 上的连接连接的方向总是由上一级F 的输出指向下一级F 的输入也是一种O M 组件,每个上都实现了I 接口,其连接实际是连接双方使用的M Ty (媒体类型)的一个“协商”过程14第4期申 华:基于D irec t Sho w 设计视频加密F ilt e r 组件ilter ilte r P in .ilter Pin ilter Pin .Pin C P in pin edia pe .Filter 之间的数据传送,是由一个封装了一定大小数据内存的称为Sa mp le 的CO M 组件来完成的.一般在一个非压缩格式的Sa mple 中都带有一个帧的图像数据.图2是Filter 之间使用Sa mple 进行数据传送的示意图.以上简要介绍了在应用程序中F ilte r 进行数据处理的实现思想及过程,本文实现的具有视频加密功能的Filter 便是基于Transf or m Filter 框架开发.该Filter 接收前一个Filter 传送来的编码压缩后的视频数据,调用视频加密库函数进行参数提取和加密,然后把加密后的数据传送给下一个F ilte r.图2 Filter 之间数据传送过程3 设计视频加密Filter 组件 开发Filter 组件最好在W indow s 2000操作系统上进行,并且需要安装D irectX Soft w are Deve l opm ent Kit 9.0,其中包括了D irectShow S DK,开发工具宜选用VC ++.具体实现分以下几步:3.1 选择一个合适的基类D ir ectShow S DK 中提供了一套F ilter 的基类源代码,基于这些基类进行Filter 的开发将大大简化开发过程.开发一个Filter,选择一个合适的基类是至关重要的.CBaseFilte r 是F ilter 的最上层的基类.D i 2rec tShow S D K 根据各种不同的应用,从CB aseFilter 派生了很多子类.在很多情况下,可以选择已有的子类作为基类,这样只需重载少数函数即可获得强大功能,大大简化了开发Filter 的工作.本文中视频加密Tr ansf or m F ilte r 选择CTr ansI nP laceF ilter 作为基类.CTransI nPlaceF ilte r 是一个“就地”处理的Transf or m F ilter 类.它的输入和输出P in 上使用相同的媒体类型进行连接,并且可以使用同一个Sa mp le 管理器.从而可以避免Sa mp le 数据从输入P in 到输出Pin 的一次内存复制,实现了程序“就地”处理的高效性.3.2 生成Filter 注册信息Filter 在使用前必须在系统注册.因此,首先要为Filter 生成一个新的CLS I D .C LS I D 可以使用系统中的GuidGen.exe 生成,再把其中的《na me 》换成自己设置的名字,代码如下://{5CF19956-8C B 9-4320-8D51-93CAF3DEA97F}DEF I N E_G U I D (CLSI D _V ideoEnCRYPT,0x5cf19956,0x8cb9,0x4320,0x8d,0x51,0x93,0xca,0xf3,0xde,0xa9,0x7f );然后,填写F ilter 的注册信息.这些信息包括输入、输出Pin 的媒体类型定义、输入、输出Pin 的设置、Filte r 的属性设置;最后,定义两个导出函数D R S 和D U S ,完成O M 组件的自注册33 创建F 对象实例所有的F 必须实例化首先,为派生类增加一个名为I 的静态成员函数,此函数调24鞍山师范学院学报第10卷:ll egister erve r ll nregister erver C ..ilter ilter .C r eate nstance用派生类的构造函数,从而获得派生类的一个实例.然后,告诉基类的类厂(C lass Factory)如何访问这个C r eate I nstance 函数.这可以通过为类厂设置Filter 名称、Filter 的CLS I D 和指向函数C r eate I nstance 的指针来实现.3.4 编写Filter 组件类的成员函数选择CTr ansI nP laceFilter 作为基类,派生一个Filter 子类,至少需要重写Check I nputType 函数、Non 2Delegating QueryInte r face 函数和Transfor m 函数.Check I nputTy pe 函数完成输入P in 上的媒体类型检查.NonDelega ting QueryI nterface 函数可以列出Filter 支持的接口.Tr ansf or m 函数完成调用视频加密接口函数,对sa mp le 缓冲区中的码流数据加密的功能.视频加密Transf or m Filter 大部分功能都在Transf or m 函数中实现.Transf or m 函数的参数中有一个I MediaSa mp le 类型的指针pSa mple,它指向一个Sa mp le 缓冲区.该缓冲区内的数据即为一帧图像压缩编码后的码流数据,对此数据进行参数提取,然后加密就可以实现视频加密的目的.整个过程可以划分为以下3大模块:(1)变长解码得到要提取的参数信息,包括每个参数的起点偏移和所占比特位数.(2)把提取的所有参数放到缓冲区中,调用加密算法对此缓冲区的数据加密.(3)按照提取时候的顺序和信息,把加密后的参数取出,返回到编码的数据区.以上3大模块被做成一个动态库,在该Filter 的构造函数中装载,并在Transf or m 函数中调用.这样,既可以实现代码共享,又可以保证代码的独立性,使代码结构清晰,为调试提供方便.Filter 调试通过后,还要注册到系统中才可以使用.利用注册工具R egsvr 32.exe (位于操作系统目录的syste m32子目录下)可以将Filter 注册至W indow s 的注册表中,完成定制Filter 工作.4 结束语 此类视频加密组件可集成在基于Direc tShow 技术开发的应用程序中,实现对视频数据的安全处理.利用此框架也可以开发出与加密Filter 对应的解密F ilte r,实现对加密视频数据的解密.此类F ilte r 可应用于诸如视频数据版权保护、网络视频数据安全传输等领域,有着广泛的应用前景.参考文献:[1]廉士国,孙金生,王执铨.几种典型视频加密算法的性能评价[J ].中国图像图形学报,2004,9(4):483-489.[2]程万里.视频加密算法研究与工程实现[D ].南京:南京理工大学,2005.[3]姚晔,徐正全,杨志云.基于伪随机序列的宏块置乱视频加密方案[J ].计算机工程,2005,31(20):162-164.[4]陆其明.D irectSho w 开发指南[M ].北京:清华大学出版社,2003.D esi gn i n g V i deo En cr ypt i on F ilter Co m ponen tBa sed on D i r ectShowS HEN Hua(D epa rt m ent of M a t he m atics,Anshan N orma l U niv ersity,Anshan L iaoning 114007,China )Abstrac t:The app r oach of video enc r yp tion,the D irectShow architecture and the m ajor pr ocedures of vide o en 2c r yp ti on filte r component development by using D irectShow are intr oduced in this paper .Such component can be integr ated int o the applicati on ba sed on Direc tShow filter technology t o encrypt video.Key wor ds:D irectSho w;Filter ;V ideo encry p ti on;CO M(责任编辑:张冬冬)34第4期申 华:基于D irec t Sho w 设计视频加密F ilt e r 组件。
directshow音频捕捉(精选5篇)
directshow音频捕捉(精选5篇)第一篇:directshow音频捕捉现在的所谓多媒体电脑一般都会有声卡(软声卡或硬声卡),有声卡就能进行音频的捕捉。
大家一定熟悉Windows自带的附件“录音机”程序,可以通过麦克风进行录音,最终生成一个Wave文件。
读完本文之后,你就会发现,自己使用DirectShow写一个音频捕捉的应用程序,原来也是这么的容易!大家知道,DirectShow对硬件的支持是通过特定的包装Filter来实现的。
声卡使用的是Audio Capture Filter,Filter内部使用以waveIn开头的一套API实现(如waveInOpen等)。
运行GraphEdit,插入Filter时,在“Audio Capture Sources”目录下,我们就能看到所有代表本地机器上的声卡的各个Filter(有的机器装了几张声卡,这里就会有几个Filter)。
在Filter Graph中加入这个Filter,我们发现这个Filter有很多Input pin,如Line In、CD Audio、Microphone、Stereo Mix等等;有一个Capture output pin。
需要说明的是,在Filter Graph中,这些Input pin并没有真正的数据流入,它们只是声卡的各个输入端子的象征性表示;所以这些Input pin永远也不用连接。
下面我们来看一下如何创建一个音频捕捉程序。
首先,当然是加入一个Audio Capture Filter。
大家知道,DirectShow加入一个硬件Filter,都是要靠“枚举”;声卡Filter也不例外。
代表声卡的Filter都注册在CLSID_AudioInputDeviceCategory目录下,使用系统设备枚举器枚举这个目录,就能发现我们想要创建的声卡对象。
(如何枚举这里就不再赘述了。
)当成功加入声卡Filter后,接下去的问题就是要将这个Filter与其他Filter相连。
filter的开发步骤
filter的开发步骤Filter的开发步骤Filter是一种常见的软件开发组件,用于处理和转换数据。
它可以用于数据清洗、数据筛选、数据转换等多种用途。
本文将介绍Filter 的开发步骤,以帮助读者理解如何开发一个高效、稳定的Filter组件。
一、需求分析在开发Filter之前,首先需要进行需求分析。
明确Filter的输入和输出,以及需要进行的数据处理操作。
例如,一个常见的需求是对输入的数据进行过滤,只保留满足特定条件的数据。
具体的需求分析有助于明确开发的目标和方向。
二、设计Filter接口根据需求分析的结果,设计Filter的接口。
接口应该包括输入参数、返回值和可能的异常。
确保接口设计合理,能够满足不同场景的使用需求。
三、编写测试用例在开发Filter之前,编写测试用例是非常重要的。
通过编写测试用例,可以验证Filter的正确性和性能。
测试用例应该覆盖各种边界情况和异常情况,以确保Filter在各种情况下都能正常工作。
四、实现Filter的逻辑在设计和测试用例准备就绪后,可以开始实现Filter的逻辑。
根据需求分析和接口设计,编写代码实现Filter的功能。
在实现过程中,要注意代码的可读性和可维护性,遵循良好的编码规范。
五、编写文档和注释在实现Filter的逻辑之后,需要编写文档和注释。
文档应该包括Filter的使用方法、输入输出参数的说明、可能的异常情况等。
注释应该清晰明了,解释代码的用途和逻辑。
六、测试和调试完成代码实现后,进行测试和调试是必不可少的。
通过运行测试用例,验证Filter的正确性和性能。
如果发现问题,及时进行调试和修复。
七、性能优化在测试和调试过程中,可以对Filter的性能进行优化。
通过分析代码和运行时数据,找出性能瓶颈,并进行相应的优化措施。
例如,可以使用合适的数据结构、算法或并行计算等方式提高Filter的性能。
八、发布和部署当Filter的功能和性能都达到预期后,可以进行发布和部署。
direct show学习笔记
1 About Directshow基础1.1 设置dshow的开发环境如果你用VC开发环境,一定要在Setting里设置下面的东西包含头文件Dshow.h 所有的dshow应用必须包含包含动态库Strmiids.lib 导出所有接口的CLSID 和接口IID定义。
必须包含Quartz.lib1.2 先演示一下dshow使用的一个例子这里暂略。
1.3 Direcshow概述DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。
那么,DirectShow能够做些什么呢?且看,DirectShow为多媒体流的捕捉和回放提供了强有力的支持。
运用DirectShow,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。
另外,DirectShow 还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD的播放,视频的非线性编辑,以及与数字摄像机的数据交换。
更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。
DirectShow的系统组成应用程序与DirectShow组件以及DirectShow所支持的软硬件之间的关系如图1所示。
图1 DirectShow系统框图1.4 Filter Graph及其组成这篇文档中我想给讲述Directshow的主要组成部分,一个概括性的入门文章,对于应用开发或者directshow的开发者都有所帮助。
1 DirectShow的FilterDirectshow是基于模块化,每个功能模块都采取COM组件方式,称为Filter。
Directshow提供了一系列的标准的模块可用于应用开发,开发者也可以开发自己的功能Filter来扩展Directshow的应用。
directshow
directshow 使⽤⼿记(6)directshow ⾥⾯包含有两种特使的filter ⼀种是DMO ⼀种是ACM或ICM 他们和普通的filter⽤法有⼀些差别,你会发现在graphedit的枚举列表中他们的显⽰的颜⾊和普通的filter也是区别的,dmo是绿⾊的,acm是蓝⾊的。
⽽且还看不到这些dmo注册的位置。
这⾥是从其他地⽅摘抄过来的,英⽂的,凑合看应该能看的懂,我都能看的懂,您应该没多⼤问题。
Using DMO In DirectShowEnables Application to use a Directx Media Object(DMO) in a filter graph,The ‘DMO Wrapper’ exposes this interface.To add a DMO to filter graph,You should create an instance dmo wrapper filter and query it for the IDMOWrapperFilter interface. Then call the IDMOWrapperFilter::Init() method to initialize the filter with the dmoUsing :HRESULT Hr;IBaseFilter *pFilter;Hr = CoCreateInstance(CLSID_DMOWrapperFilter,NULL,CLSCTX_INPROC,IID_IBaseFilter,(void **)&pFilter);If(SUCCEEED(Hr)){IDMOWrapperFilter *pWrap;Hr=pFilter->QueryInterface(IID_IDMOWrapperFilter,(void **)&pWrap);If(SUCCEED(Hr)){Hr=pWrap->Init(dmoid,dmocategoryid)pWrap->Release();}}Note: dmoid is the dmo object’s GUID and the dmocategoryid is the dmo’s CateGory’s GUIDRequirements:Include Dmodshow.h. Link to Dmoguids.lib.Other people’s DMO, We can’t get them’s GUID ,Category and MediaType,what we can do for us ?havn’t ways! No,we should enum all DMO if you don’t you the dmo’s category, There are some common categorys in directshow system. them will help you,may be.If you really don’t know this, when you use the function ‘EnumDMO()’ the first parameter you should set GUID_NULL for it.For details about the EumDMO function ,see the Microsoft ‘s web msdn or the directx sdk document. After get the GUID,you may validate in regedit.DMO Category DirectShow EquivalentDMOCATEGORY_AUDIO_ENCODER CLSID_AudioCompressorCategoryDMOCATEGORY_AUDIO_DECODER CLSID_LegacyAmFilterCategoryDMOCATEGORY_VIDEO_ENCODER CLSID_VideoCompressorCategoryDMOCATEGORY_VIDEO_DECODER CLSID_LegacyAmFilterCategoryUsing:IEnumDMO* pEnum = NULL;HRESULT hr = DMOEnum(category, // CategoryDMO_ENUMF_INCLUDE_KEYED, // Included keyed DMOs0, NULL, // Input types (don't care)0, NULL, // Output types (don't care)&pEnum);if (SUCCEEDED(hr)){CLSID clsidDMO;WCHAR* wszName;do{hr = pEnum->Next(1, &clsidDMO, &wszName, NULL);if (hr == S_OK){// Now wszName holds the friendly name of the DMO, // and clsidDMO holds the CLSID.if(!strcmp((char *)wszName,Name)){return TRUE;}// Remember to release wszName!CoTaskMemFree(wszName);}} while (hr == S_OK);pEnum->Release();}。
基于Delphi的DirectShow开发概述2
}
3. 一般使用GraphEdit可以查看到目前正常安装在系统中的Filter,如果是安装在DirectShow目录下的可以通过指定CLSID
用CoCreateInstance来创建。在其它目录下的,必须通过系统枚举来创建。
系统提供了一个CLSID_SystemDeviceEnum,用CoCreateInstance创建,并获取ICreateDevEnum接口。然后
if Found then
begin
cbCategories.ItemIndex := i;
cbCategoriesChange(nil);
lbFilters.ItemIndex := j;
lbFiltersClick(nil);
if FAILED(hr) then begin
ShowMessage('Failed connect mpg Source -> MPEG1Splitter');
exit;
end;
}
2.FilterGraph构建的方法
1)IFilterGraph.AddFilter 该参数提供一个Filter对象,将其加入到FilterGraph中.
(FilterGraph1 as IFilterGraph).AddFilter(Source, 'Source');
(FilterGraph1 as IFilterGraph).AddFilter(MPEG1Splitter, 'MPEG1Splitter');
(FilterGraph1 as IFilterGraph).AddFilter(MpegVcodec, 'MpegVcodec');
DirectShowFilter基础与简单的示例程序
DirectShowFilter基础与简单的⽰例程序DirectShow 是⼀个 Windows 平台上的流媒体框架,提供了⾼质量的多媒体流采集和回放功能。
Filter 实质是⼀个 COM 组件,所以学习开发 Filter 前你应该对 COM 相关知识有点了解。
COM 组件的实质是实现了纯虚指针接⼝的 C++ 对象。
应⽤程序开发者只需要基本的 COM 组件知识:实例化COM组件、调⽤接⼝、管理接⼝的引⽤计数。
Filter 开发者则需要更多。
选择⼀个基类,声明⾃⼰的类。
应该清楚这个 Filter 在整个 Filter Graph 的位置,这个 Filter 的输⼊是什么数据,输出是什么数据,有⼏个输⼊ Pin、⼏个输出 Pin 等,可以画出这个 Filter 的草图。
Win7: DirectShow SDK 做为 Windows SDK(GRMSDK_EN_DVD.iso) 的⼀部分,不再有单独的 DirectX SDK 包。
在 DirectShow 中,应⽤程序要实现功能就必须将这些 Filter 链接在⼀起,因⽽⼀个 Filter 的输出就变成了另⼀个 Filter 的输⼊。
这⼀系列串在⼀起的 Filter 称为 Filter Graph。
使⽤ VS2008 建⽴ Filter 开发⼯程的过程如下:(1) 新建Visual C++/Win32 项⽬,⼯程名如:FilterSample。
点击“确定”进⼊下⼀步;(2) 应⽤程序类型选择:DLL,⼀般不选择 MFC 和 ATL;⼯程的建⽴完成,编译后可以先将输⼊⽂件改名。
⽅法如下:属性页/链接器/常规/输出⽂件,修改为:$(OutDir)/FilterSample.axDirectShow 必须⽤到以下头⽂件的库⽂件:1 #include "streams.h"2 #include "initguid.h"3 strmbasd.lib4 winmm.lib5 uuid.lib6 Quartz.lib 输出 AMGetErrorText 函数,如果不调⽤此函数,此库不是必需的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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的基类也是很灵活的,没有绝对的标准。