首页 关于DirectShow在Video视频处理方面的的一些基本应用

关于DirectShow在Video视频处理方面的的一些基本应用

举报
开通vip

关于DirectShow在Video视频处理方面的的一些基本应用关于DirectShow在Video视频处理方面的的一些基本应用 关于DirectShow在Video视频处理方面的的一些基本应用 作者:佚名 文章来源:不详 点击数: 8017 更新时间:2005-10-6 关于DirectShow在Video视频处理方面的的一些基本应用 DirectShow是微软提供的DirectX软件开发包中的一员,主要以处理流媒体数据为重点开发的一套windows下的编程接口,为了高效地处理音视频数据,它向应用提供了直接访问系统底层功能的接口,可以使应用直接控制从数据采集到数据演播的各个中...

关于DirectShow在Video视频处理方面的的一些基本应用
关于DirectShow在Video视频处理方面的的一些基本应用 关于DirectShow在Video视频处理方面的的一些基本应用 作者:佚名 文章来源:不详 点击数: 8017 更新时间:2005-10-6 关于DirectShow在Video视频处理方面的的一些基本应用 DirectShow是微软提供的DirectX软件开发包中的一员,主要以处理流媒体数据为重点开发的一套windows下的编程接口,为了高效地处理音视频数据,它向应用提供了直接访问系统底层功能的接口,可以使应用直接控制从数据采集到数据演播的各个中间环节,如数据压缩和解压缩格式等。 DirectShow是以一种比较新的概念来操作媒体流运行的,他有点类似于计算机硬件的管脚Pin的概念,并且引进了滤波器Filter和流图Graph等原理。媒体流通过流图中的各个滤波器,最后到达输出界面,期间经过各个滤波器的转化和控制使最终数据达到一定的要求。通过DirectShow的基本接口,应用可以自行 设计 领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计 自己的各种滤波器完成数据在流动中的特殊处理需求,比如视频数据流的格式从MPEG到RGB的变换(解压缩)或象素格式从YUV到RGB的变换等。 DirectShow本身是一个比较复杂的系统,其中包含了许多的概念,对于一个初涉的编程人员,需要学习许多新的知识,特别是对于使用非VC进行应用开发的人员,想要实际使用DirectShow的功能其困难程度是可想而知的。为此,我这里提供一个折中的解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,使得非VC的开发人员也能方便的使用DirectShow提供的各种功能,同时也为所有希望进入视频编程领域的开发人员提供一个DirectShow的入门级引导。这篇文章和相关源码或许能对感兴趣的读者提供一些帮助。   一、           DirectShow的graph原理 Graph实际上是一个filters的容器,Dshow提供一个Graph控件(Com),应用可以用CoCreateInstance来建立一个graph对象。在Dshow中还有一个用于创建和操作Graph,这就是Builder对象,一般来讲,应用应该首先创建Builder对象,它是Dshow流控制的关键,Builder接口提供的方法包含了智能创建Graph中filters的能力,当未知媒体流格式时,使用Builder连接Filter时,将智能添加系统中的格式转换Filter到Graph的Filters链中产生目标格式的最佳转换链。 建立Builder和Graph后,将Graph加入到Builder中,便可以往Graph中添加指定的Filter了,一般系统中的Video设备是由设备枚举过程获得的,系统中的每一种视频驱动,都定义为一个视频设备(音频设备也是如此)。函数: CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); 建立系统设备枚举器对象,其中: ICreateDevEnum * pCreateDevEnum; //设备枚举器对象指针 GUID IID_IcreateDevEnum //设备枚举器接口的GUID Const CLSCTX_INPROC_SERVER//被建立对象的进程特征 GUID CLSID_SystemDeviceEnum //枚举器对象类的GUID 注意:GUID包含在Dshow头文件UUID.h中。 利用设备枚举对象列出系统中已经安装的设备,每一个设备类形成一个IenumMoniker对象然后枚举该类设备在系统中的安装个数: //建立视频输入设备枚举器 IEnumMoniker *pEm; pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0); pEm是已经建立的视频设备每举器,通过该对象枚举系统的视频设备。 IMoniker * pM;//枚举视频设备 pEm->Next(1, &pM, &cFetched), hr==S_OK)//获得一个Imoniker接口 Dshow通过设备的Imoniker接口操作系统中的设备。同样步骤可以获得系统中的音频设备,它们统称为系统的输入设备。(关于函数的参数定义可以查看VC的帮助,非VC开发人员,只需了解基本原理就可以了) Imoniker对象通过提供的BindToObject方法可以获得输入设备的Filter对象   pM –>BindToObject(0, 0, IID_IBaseFilter, (void**)&pVCap);   pVCap就是视频输入设备对象,利用QueryInterface函数可以获得特殊输入设备的接口对象(因为pVCap仅反映出一个基本的滤波器对象,因此不能反映一些特殊的方法,查询特殊接口需要知道接口的GUID,这可以通过设备购买时提供的资料获得,一般而言不需特殊接口功能,使用基本功能可以保证应用系统的兼容性和广泛可用性。 取得设备后将其加入到Graph中,然后使用智能连接的系统默认Render   pGraph->AddFilter(pVCap, NULL)   pBuilder->RenderStream( &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pACap, NULL, NULL); 就可以形成一条从输入开始到系统默认Render的视频播放filters链路了,启动这个链路,则可以在显示器上看到视频图象。当然还需要设置显示窗口的大小和位置。这个播放链路是建立在视频输入设备的Capture管脚上的,如果设备不存在Capture管脚,链路建立则不能成功,也可以将播放链路建立在Preview管脚上(PIN_CATEGORY_PREVIEW)。滤波器链路原理如图所示: 这是一个USB小摄象头作为视频输入设备的滤波器播放链路,在指定显示窗口大小的情况下,可以播放视频数据流。Graph基本概念框图如下: 其中:Filter1..是应用自己加入的特殊Filter来进行视频数据流的特殊处理,比如嵌入字模,滚动视频和实时取图等,也可以进行视频数据的特殊压缩和解压缩处理。视频数据流以pSample缓冲的方式逐级经过各个filter,最后到达render进行显示处理,pSample是filter数据交换缓冲区指针,应用通过自己的filter改变pSample的数据达到改变视频流显示的目的。                     二、             建立和使用Filter 建立滤波器,就是建立一个滤波器对象类,并且输出一个接口方法组,根据滤波器的用途选择合适的父类,一般Dshow提供各种供选择的父类对象和接口,比如Graber用途的滤波器,可以直接抓取内存中的帧图象,比使用window API的cap类函数抓图要强很多。定义接口方法: DECLARE_INTERFACE_(IGrabberIPP, IUnknown){ STDMETHOD(put_MediaType) (THIS_ CMediaType *pmt ) PURE; /* [in] */ // the media type selected STDMETHOD(get_MediaType) (THIS_ CMediaType **pmt) PURE; /* [out] */ // the media type selected STDMETHOD(get_IPin) (THIS_ IPin **pPin ) PURE; /* [out] */ // the source pin STDMETHOD(get_State) (THIS_ FILTER_STATE *state ) PURE; /* [out] */ // the filter state STDMETHOD(get_FilterIPin) (THIS_ int n,IPin **pPin ) PURE;/*[in][out] */ // the in/out pin STDMETHOD(get_ImageSize) (THIS_ long * outWidth, long * outHeight, long * outBitCount) PURE; STDMETHOD(get_FrameSize) (THIS_ long * outFrameSize) PURE; STDMETHOD(get_BitmapInfoHeader) (THIS_ BITMAPINFOHEADER * outBitmapInfo) PURE; STDMETHOD(get_Is16BitsRGB) (THIS_ long * outIsRGB565) PURE; STDMETHOD(put_IsFieldPicture) (THIS_ BOOL inIsField) PURE; STDMETHOD(Snapshot) (THIS_ BYTE * outBuffer, BOOL inIsSyncMode) PURE; STDMETHOD(IsAsyncSnapshotFinished) (THIS_ BOOL * outFinished) PURE; STDMETHOD(CancelAllPending) (THIS) PURE; }; //--------------------------------------------------------------- 定义滤波器对象: class CGrabberInPlace : public CtransInPlaceFilter, public IGrabberIPP {……}; //--------------------------------------------------------------- 写一个滤波器对象和输出接口方法后,便可以用regsvr32注册滤波器到系统中,应用便可以使用该滤波器: 1、  用CoCreateInstance建立接口实例,使用基本滤波器对象类的GUID。 CoCreateInstance ( CLSID_GrabberInPlace, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pBf); CLSID_GrabberInPlace //指定滤波器的类GUID,在你自己的滤波器中定义 IID_IbaseFilter//基本滤波器对象接口GUID,它是所有滤波器的父类 此时,你获得的是一个包含你自己的滤波器的基本滤波器指针(特殊的方法函数是不出现在该接口中的),当你需要使用特殊方法时,使用QueryInterface,查询得到特殊接口指针: pBf->QueryInterface(IID_GrabberIPP, (void **)&pGf); IID_GrabberIPP //特殊滤波器的接口GUID PGf //特殊滤波器接口指针 使用pGf,就可以操作特殊滤波器处理视频数据。注意:在你编写自己的特殊滤波器方法时,需要精确了解滤波器父类各层对象的操作关系和方法,这样才能灵活的处理各种情况的发生,滤波器是系统应用层以下的系统程序,它的任何异常都可能导致系统的崩溃,因此在调试阶段应该仔细处理各种情况。   三、VideoDll的输出函数 动态库输出函数: 启动Com和枚举系统设备 bool _stdcall fnVideoDll_Initial(void); 将系统中安装的音视频设备枚举出来,列成一张 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf ,以供操作选择 销毁所有系统设备和已经建立的设备对象 bool _stdcall fnVideoDll_Finally(void); 销毁已经建立的设备对象,终止动态库操作 取得当前系统设备个数 int _stdcall fnVideoDll_GetVideoDeviceNumber(bool IsVideo); IsVideo:true 表示取得视频设备数,否则取得音频设备数 取得系统中指定类型(音/视频)设备的个数 获得指定系统设备的参数 bool _stdcall fnVideoDll_GetVideoDeviceParms(long DevIndex, TParms * pParms, bool IsVideo);bool_stdcall DevIndex 指定设备的索引号,多设备存在时为设备序号。 PParms 设备参数缓冲指针,接收设备参数 IsVideo:true 表示取得视频设备数,否则取得音频设备数   设置指定系统设备的参数 fnVideoDll_SetVideoDeviceParms(long DevIndex,TParms * pParms,bool IsVideo);   选择指定设备建立设备对象(根据指定参数) bool _stdcall fnVideoDll_SelectVideoAudioDev(int DevIndex, HWND AppHandle, RECT rc, int SelFlag); DevIndex 指定设备的索引号,多设备存在时为设备序号。 AppHandle 操作设备的窗口handle Rc 视频显示位置 SelFlag 设备选择标志,0=视频设备,1=音频设备,2=音视频设备 选择指定设备建立Graph链路,并开始播放。 关闭指定设备 bool _stdcall fnVideoDll_CloseVideoAudioDev(int DevIndex); 将指定设备及其建立的音视频Graph对象全部关闭,设备恢复到原始状态。   图象采集函数(将帧图象采集到缓冲区中) 设置显示矩形 bool _stdcall fnVideoDll_SetDisplayRect(int DevIndex,RECT rc); 更改指定设备的显示矩形位置和大小,用新指定的矩形代替原矩形。 取得抓图缓冲区的尺寸 bool _stdcall fnVideoDll_ImgGrabberGetSize(int DevIndex, int * ImgSize); 取得当前图象数据 bool _stdcall fnVideoDll_ImgGrabberGetImg(int DevIndex,void * ImgBuffer); 取得当前帧图象的格式信息 bool _stdcall fnVideoDll_ImgGrabberGetBmpHdr(int DevIndex, BITMAPINFOHEADER * outBitmapInfo); 取得捕捉设备的视频流格式 bool _stdcall fnVideoDll_GetGraphFormat(int DevIndex, BITMAPINFOHEADER *FormatInfo); 设置捕捉设备的视频流格式 bool _stdcall fnVideoDll_SetGraphFormat(int DevIndex, BITMAPINFOHEADER *FormatInfo);         参数结构定义: typedef struct _TParms_ { long DevIndex;//系统采集设备枚举索引 WCHAR szDevDisplayName[1024];//显示名 WCHAR szFriendlyName[1024];//设备名 BOOL fWantPreview;//是否可以预览 BOOL fUseFrameRate;//是否指定每秒帧数 double FrameRate; //每秒帧数 DWORD dwWidth; //视频图面宽度(设备设置的) DWORD dwHeight; //视频图面高度(设备设置的) BOOL CanGrabber; //是否进行抓图操作 long PinSel; //连接pin的选择:0-->Capture,1-->Preview,2-->自适应 BOOL HasDecompress;//是否指定解压缩filters(以下参数未使用) TDECOMP decomFlt[10]; //解压缩filters long czGuid; //数组记数 } TParms, *pTParms;   四、             非VC开发人员使用方法(针对delphi进行说明)   在delphi中,使用动态库的方法是将将动态库函数进行声明(Pasical格式),因此只要声明了Dll的输出函数,就可以使用该动态库。Delphi中函数声明如下: 1、结构声明 type PParms = ^TParms; TParms = record DevIndex :Integer;//系统采集设备枚举索引 szDevDisplayName :array[0..1023] of WCHAR;//显示名 szFriendlyName :array[0..1023] of WCHAR;//设备名 fWantPreview :Integer;//是否可以预览 fUseFrameRate :Integer;//是否指定每秒帧数 FrameRate :Double; //每秒帧数 dwWidth :DWORD; //视频图面宽度(设备设置的) dwHeight :DWORD; //视频图面高度(设备设置的) CanGrabber :Integer;//是否进行抓图操作 PinSel :Integer;//连接pin的选择:0-->Capture,1-->Preview,2-->自适应 HasDecompress :Integer;//是否指定解压缩filters decomFlt :array[0..9]of TDECOMP;//解压缩filters czGuid :Integer;//数组记数 end;   2、动态库输出函数 function fnVideoDll_Initial:boolean;stdcall; function fnVideoDll_Finally:boolean;stdcall; function fnVideoDll_GetVideoDeviceNumber(IsVideo:boolean):Integer;stdcall; function fnVideoDll_GetVideoDeviceParms(DevIndex:Integer; var pParms:TParms;IsVideo:boolean):boolean;stdcall; function fnVideoDll_SetVideoDeviceParms(DevIndex:Integer; var pParms:TParms;IsVideo:boolean):boolean;stdcall; function fnVideoDll_SelectVideoAudioDev(DevIndex:Integer; AppHandle:HWND;rc:TRECT;SelFlag:Integer):boolean;stdcall; function fnVideoDll_CloseVideoAudioDev(DevIndex:Integer):boolean;stdcall;   function fnVideoDll_SetDisplayRect(DevIndex:Integer;rc:TRECT):boolean;stdcall; function fnVideoDll_ImgGrabberGetSize(DevIndex:Integer; var ImgSize:Integer):boolean;stdcall; function fnVideoDll_ImgGrabberGetImg(DevIndex:Integer; ImgBuffer:PChar):boolean;stdcall; function fnVideoDll_ImgGrabberGetBmpHdr(DevIndex:Integer; var BitmapInfo:TBITMAPINFOHEADER):boolean;stdcall; function fnVideoDll_GetGraphFormat(DevIndex:Integer; var FormatInfo:TBITMAPINFOHEADER):boolean;stdcall; function fnVideoDll_SetGraphFormat(DevIndex:Integer; var FormatInfo:TBITMAPINFOHEADER):boolean;stdcall; 实现部分 implementation function fnVideoDll_Initial:boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_Initial'; function fnVideoDll_Finally:boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_Finally'; function fnVideoDll_GetVideoDeviceNumber(IsVideo:boolean):Integer;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_GetVideoDeviceNumber'; function fnVideoDll_GetVideoDeviceParms(DevIndex:Integer; var pParms:TParms;IsVideo:boolean):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_GetVideoDeviceParms'; function fnVideoDll_SetVideoDeviceParms(DevIndex:Integer; var pParms:TParms;IsVideo:boolean):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_SetVideoDeviceParms'; function fnVideoDll_SelectVideoAudioDev(DevIndex:Integer;AppHandle:HWND; rc:TRECT;SelFlag:Integer):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_SelectVideoAudioDev'; function fnVideoDll_CloseVideoAudioDev(DevIndex:Integer):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_CloseVideoAudioDev'; function fnVideoDll_SetDisplayRect(DevIndex:Integer;rc:TRECT):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_SetDisplayRect'; function fnVideoDll_ImgGrabberGetSize(DevIndex:Integer; var ImgSize:Integer):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_ImgGrabberGetSize'; function fnVideoDll_ImgGrabberGetImg(DevIndex:Integer;ImgBuffer:PChar):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_ImgGrabberGetImg'; function fnVideoDll_ImgGrabberGetBmpHdr(DevIndex:Integer; var BitmapInfo:TBITMAPINFOHEADER):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_ImgGrabberGetBmpHdr'; function fnVideoDll_GetGraphFormat(DevIndex:Integer; var FormatInfo:TBITMAPINFOHEADER):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_GetGraphFormat'; function fnVideoDll_SetGraphFormat(DevIndex:Integer; var FormatInfo:TBITMAPINFOHEADER):boolean;stdcall; external 'VideoDll.Dll' name 'fnVideoDll_SetGraphFormat';     五、             VC开发环境的设置 1、  安装directX开发环境 2、  指定include目录: directX安装目录下的include directX安装目录下的SAMPLES\MULTIMEDIA\COMMON\INCLUDE directX安装目录下的SAMPLES\MULTIMEDIA\DIRECTSHOW\BASECLASSES 一般安装目录根据directX的版本可能会有差异,选择对应目录。 3、  库目录library directX安装目录下的lib directX安装目录下的 SAMPLES\MULTIMEDIA\DIRECTSHOW\BASECLASSES\DEBUG 4、  库Library的指定 在项目设置setting下的link中一定要指定下面的库, uuid.lib winmm.lib msacm32.lib strmiids.lib strmbasd.lib 有时还需要删除这些库前面的路径,因为在路径中已经指定了库的路径。 5、  运行编译前首先要编译连接基本类,生成strmbasd.lib到指定位置。     结束语 本Dll及其程序是经过本人一段时间的视频开发获得的一个附属模块程序,对于非VC开发人员,特别是希望控制视频操作的delphi开发人员,是一个方便的抓图处理工具,可以很轻松的将视频功能结合进应用之中,比如在各种图象识别过程中,可以直接获得当前帧图象数据进行处理。使用其他语言开发应用的朋友也可以很方便的改写输出函数的声明,使用本动态库处理视频数据。 对于希望了解DirectShow开发过程的开发人员,使用本动态库开发框架,能够获得入门级知识,为进一步的开发打下良好的基础,在动态库框架下,很容易就可以扩展特殊的处理功能,比如播放指定的AVI文件,捕捉视频数据到文件等。本着付费使用的软件精神,也是为了更好地促进软件事业的发展,本人决定对源码进行收费,全套源码收费10元。其中包括: 一个抓图filter(VC), 一个动态库(VC), 一个Pas单元, 一个Pas实例程序。 以及一些说明文档。 通过实验本套程序,相信你很快就能进入DirectShow引领下的视频媒体流领域和图象处理领域。   付费方式:通过邮局汇款,在汇单中一定要注明你的电子邮箱地址,用于接收程序代码。 汇款地址:沈阳市,大东区,和睦北二路7号4-4-2室 郑女士
本文档为【关于DirectShow在Video视频处理方面的的一些基本应用】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_956996
暂无简介~
格式:doc
大小:79KB
软件:Word
页数:14
分类:互联网
上传时间:2014-02-19
浏览量:26