基于Windows的几种视频采集方法设计与实现

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

基于Windows的几种视频采集方法设计与实现
作者:李钦存王春明段海龙
来源:《硅谷》2008年第21期
[摘要]分别介绍在Windows操作系统下的三种实时视频数据采集的方法,即基于VFW的实时视频采集,基于DirectShow的实时视频采集和基于视频卡附带软件开发工具箱(SDK)的实时视频采集,并给出实现的核心代码。

[关键词]视频采集 VFW DirectShow SDK
中图分类号:TP391文献标识码:A 文章编号:1671-7597(2008)1110067-02
随着计算机网络和多媒体计算的迅猛发展,许多应用系统,如可视电话系统、电视会议系统、远程监控系统等要求能够实时获取视频信息;同样,若想进行图像处理也必须进行视频流捕获和单帧图像采集。

因此,如何实时获取视频数据便成为应用中的重要环节和关键前提[2]。

一、基于VFW的实时视频数据采集
VFW(Video For Windows)是Microsoft推出的关于数字视频的一个软件包,该软件包能使应用程序数字化并播放从传统模拟视频源得到的视频剪辑。

VFW的一个关键思想是播放时不需要专用硬件,为了解决数字视频数据量大的问题,需要对数据进行压缩。

软件包引进了一种叫AVI的文件标准,该标准未规定如何对视频进行捕获,压缩仅规定视频和音频该如何存储在硬盘上,在AVI文件中交替存储视频帧和与之相匹配的音频数据。

VFW给程序员提供VBX 和AVICap窗口类的高级编程工具,使程序员能通过发送消息或设置属性来捕获、播放和编辑视频剪辑。

Windows98以上系统都自动安装配置视频所需的组件,如设备驱动程序,视频压缩程序等[3]。

VFW主要由以下6个模块组成:
AVICAP.DLL: 处理视频捕获,为AVI文件输入输出和视频、音频设备驱动程序提供一个编程接口。

MSVIDEO.DLL: 用DrawDib函数处理屏幕上的视频操作。

MCIAVI.DRV: 包含对VFW的MCI命令的解释器。

AVIFILE.DLL: 支持由标准多媒体I/O函数提供的更高的命令来访问AVI文件。

ICM:压缩管理器,管理用于视频压缩/解压的编码器。

ACM:音频压缩管理器,管理用于波形音频压缩/解压的编解码器。

在这里介绍采用窗口类AVICap 实现视频捕获的方法。

AVICap支持实时的视频流捕获和单帧捕获并提供对视频源的控制。

它能直接访问视频缓冲区,不需要生成中间文件,实时性很强,效率很高[4]。

同时,它也可将视频捕获到文件。

视频数据的实时采集主要是通过调用AVICap32.dll创建AVICAP窗口类,由AVICAP窗口类中的消息、宏函数、结构以及回调函数来完成。

VFW的视频采集功能函数主要包括捕获视频流至AVI文件(capCaptureSequence)、捕获视频流至缓存(capCaptureSequenceNoFile)、捕获视频流的具体帧至AVI文件(cap-CaptureSingleFrame)、本地预览(capPreview/capOverlay)和捕获单帧预览(capGrabFrame/cap- GrabFrameN
-oStop)等。

VFW还提供了回调函数,允许应用程序精确控制视频流的捕获、检测错误、监控状态变化,以及在捕获两帧数据的空隙和每捕获新帧时对实时视频数据进行处理。

具体的采集流程如图1所示。

采集的核心代码[5]:
{
HWND hWnd=capCreateCaptureWindow(“视频捕获窗口”,
WS_CHILD|WS_VISIBLE,//设置指定窗口的风格
Rect.left,Rect.top,Rect.Right-Rect.left,Rect.bottom-Rect.top,//设置显式帧窗口的大小
NULL,NULL);//创建捕获窗口并将获取的句柄赋予hWnd
//注册系统回调函数
CapSetCallbackOnError(hWnd,(FARPROC)ErrorCallbackProc;
//在采集过程中出错时被调用
CapSetCallbackOnStatus(hWnd,(FARPROC)StatusCallbackProc;
//在采集窗口发生改变时被调用
CapSetCallbackOnFrame(hWnd,(FARPROC)FrameCallbackProc);
//在每采集完一帧时调用
capDriverConnect( hWnd ,0);//窗口与驱动设备相连接
capOverlay(hWnd,TRUE);//将显示设置成Overlay模式,开始捕获视频流
capCaptureSequenceNoFile(hWnd);
}
设置调用函数:
LRESULT CALLBACK FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
{
//采集到的视频数据放在VIDEOHDR数据块结构中
//这样就可以在这里捕获每帧的视频数据作进一步的处理。

如显示在新的窗口或者发送到远端计算机,或//进行相应的图像处理。

}
LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText)
{//在这里作相应的处理}
LRESULT CALLBACK StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText)
{//在这里作相应的处理}
二、基于DirectShow的实时视频数据采集
DirectShow是微软根据对来自许多不同的媒体资源的流视频和音频的需要,开发的一个解决办法,它设计提供所有高质量的视频回放以及捕获特性。

DirectShow还提供了广泛的支持结构模型,这种模型可以将新的媒体类型轻松地添加到自己的结构中。

DirectShow是一种基于COM技术的多媒体编程接口,它给出了一种全新的多媒体数据处理模型,并封装了采集、压缩和解压缩等一系列算法,为视频监控、视频会议等多媒体应用系统的开发提供了良好的平台[1]。

DirectShow是位于DirectX(DirectDraw,DirectSound,Direct3D等)基础之上的媒体层。

它主要提供播放本地文件或Internet服务器上的多媒体数据,以及从视频采集卡等硬件设备中捕获多媒体流的功能。

它能够播放多种压缩格式的视音频文件(或流),包括MPEG,Quick Time,AVI,WAV以及基于VFW和WDM 的视音频捕获流。

DirectShow的实质是以“过滤器
(Filters)”组件为核心的模块化系统。

用各种过滤器构造成不同的过滤器图表(Filter Graph)就可以完成回放采集等不同任务,一个称为“过滤器图表管理器”(Filter Graph Manager)的组件负责Filter之间的连接和媒体流的调度,应用程序通过它来控制Filter Graph。

一般情况下,一个完整的过滤器图表以一个源过滤器开始(Source filter),一个递交过滤器(renderer filter)结束,如果已知一个源过滤器,过滤器图表管理器会根据源过滤器的类型自动生成相应的Filter Graph。

它的过滤器连接示意图如图2所示。

值得说明的是,开发人员在开始编码前,可以使用DirectX SDK提供的GraphEdit应用程序来对选用的过滤器进行测试,按照系统需求选用的过滤器图表能否工作,在GraphEdit程序中就能够测试出来,而且可以不必编写一行代码。

下面介绍用DirectShow来进行实时视频采集需要的一些函数和COM编程的方法。

用IGraphBuilder接口来建立过滤器图表管理器,建立好管理器之后,可以调用IGraphBuilder::AddFilter方法将自己需要的过滤器加入到过滤器图表管理器中。

IGraphBuilder::QueryInterface是查询选定的过滤器组件是否支持某个特定的接口。

用ICaptureGraphBuilder2接口提供的方法来建立采集图像。

其中与视频采集有关的方法有m_pCaptureGraphBuilder::SetFiltergraph,指定一个过滤器图表来生成采集图像。

m_pCaptureGraphBuilder::RenderStream将源程序和接收过滤器连接起来。

使用IVideoWindow接口来控制显示视频的窗口的属性,如高度位置等信息。

CoCreateInstance这个Win32API函数创建并返回COM组件的一个实例,将开发人员自己设定的对象与COM组件联系起来。

如下面的代码:
IGraphBuilder*m_pGraphBuilder;
hr=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
IID_IGraphBuilder,(void **)& m_pGraphBuilder);
CoInitialize和CoUninitialize,在使用COM库前必须使用CoInitialize来初始化,使用完毕后用CoUninitialize来释放。

采集的核心代码[5]:
HRESULT CaptureVideo()
{
HRESULThr;
IBaseFilter*pBaseFilter=NULL;
ImediaControl*m_pMediaControl;
IGraphBuilder m_pGraphBuilder;
ICaptureBuilder2 *m_pCaptureGraphBuilder;
IVideoWindow *m_pViewWindow;
//初始化COM库
CoInitialize(NULL);
/*使用自定义函数GetDeviceInterfaces()获取DirectShow提供的接口,函数主要是利用CoCreateInstance方法建立IGraphBuilder,
ICaptureGraphBuilder2的实例,并使用QueryInterface方法查询系统是否支持所选的组件*/
hr=GetDeviceInterface();
//把采集图表与过滤器图表联系在一起
Hr=m_pCaptureGraphBuilder->SetFilterGraph(m_pGraphBuilder);
//主要使用ICreateDevEnum接口提供的CreateClassEnumerator方法来对系统已有的采集设备进行枚举,找到可供使用的设备。

hr=FindCaptureDevice(&pBaseFilter);
//将上一步找到的视频过滤器加入到过滤器图表管理器中
hr=m_pGraphBuilder->AddFilter(pBaseFilter,L"Video Capture");
//用RenderStream将视频管理器和预览管理器连接起来
hr=m_pCattureGraphBuilder-
>RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pBaseFilter,NULL,NULL); //将采集到的视频图像保存到文件中
Hr=m_pCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE
_Avi,L”c:\example.avi",&ppf,NULL);
//设置视频窗口的样式
hr=SetupVideoWindow();
//开始预览采集到的视频数据
hr=m_pMediaControl->Run();
return S_OK;
}
三、基于视频设备附带的SDK的实时视频数据采集
有的开发工作会在特定厂家提供的视频采集卡上来进行,这时就可利用厂家提供的软件开发工具箱SDK来开发应用程序。

由于各个厂家提供的SDK不经相同,因此要具体分析。

一般提供的SDK以DLL的形式给出,这就要求把设备提供的动态链接库链接到开发的应用程序中。

在这里主要介绍一下动态链接的调用方法。

调用动态链接库,有显式链接和隐式链接两种方式。

显式链接是应用程序在运行时通过函数调用来显式装载和下载DLL,并通过函数指针来调用DLL的导出函数。

调用LoadLibrary函数装载DLL并得到模块句柄。

调用GetProcAddress来获取导出函数的指针。

语法规则如下:
FARPROC GetProcAddress{
HMODULEhModule; //DLL模块的句柄
LPCSTR lpProcName; //要获取的函数的名字
};
这个函数通过给定的lpProcName函数的名字获取要调用的函数的指针,以后在程序中要调用这个函数,就可以通过这个函数的指针来调用。

在使用完毕后,调用FreeLibrary函数来释放DLL。

使用显式链接,不需要DLL项目提供DLL的头文件,而是使用函数指针来调用,很容易发生错误;而且调用每个导出函数都要使用GetProcAddress
来获取该函数的指针,当要调用DLL里多个导出函数时,使用很不方便。

而隐式链接的使用,虽然需要在应用程序中加入含有导出函数信息的头文件,但正因为这样,在调用导出函数时就跟调用类的函数完全一样,因此这种方式调用函数非常方便,而且不易出错。

要使用隐式链接,应用程序必需能够获取以下信息:(1)包含导出函数以及类声明的头文件,因为在程序开发时要知道函数名和函数接口信息。

(2)DLL的导入库文件。

应用程序在编译时需要。

(3)实际的DLL文件,应用程序运行时使用。

四、结束语
本文分别介绍了在Windows操作系统下的三种实时视频数据采集的方法,即基于VFW的实时视频采集,基于DirectShow的实时视频采集和基于视频卡附带软件开发工具箱(SDK)的实时视频采集,并给出了实现的核心代码。

利用本文方法,可以在很小的硬件投资下就能进行视频邮件,网络电话等多媒体视频应用的开发,对实际工程建设具有一定的指导作用。

参考文献:
[1]倪绪能、胡涛、张志刚,利用VC++实现基于DirectShow的视频捕获,数字电视与数字视频,2003(10):15~17.
[2]任观就、张永林,实时视频图像捕获的实现方法,计算机工程,2002(8):268~270.
[3]陈珲、张会汀、周杰华,利用VFW实现视频捕获及其应用,计算机应用,2003(8):141~143.
[4]贺添、张建州,基于VFW贺DirectShow的实时视频采集和压缩,计算机应用研究,2004(5):175~177.
[5]胡晓军、邓波、高宏伟等,Visual C++高级开发范例解析,电子工业出版社,2002(7):180~181.
作者简介:
李钦存,男,汉,信息工程大学在读硕士研究生,主要研究方向:计算机应用。

相关文档
最新文档