DirectShow应用开发一般步骤
1. DirectShow开发环境的配置(VC 6.0)
一般包含的头文件是 dshow.h 或streams.h 有时还会用到其它头文件,比如:qedit.h
用到的静态连接库文件:strmiids.lib strmbasd.lib(strmbase.lib Release版本) quartz.lib
winmm.lib uuid.lib
路径配置:VC tools\option\
有配置的时候,最后把所有的库文件都包含上去,这样连接的时候就不会出现莫名其妙的错误了。
2. DirectShow应用开发的一般步骤
(1) 创建一个Filter Graph Manager组件
(2) 构造一个完整的Filter Graph
(3) 从 Filter Graph Manager组件得到各种接口,比如:IMediaControl,对程序进行控制
具体如下:
(1) 创建Filter Graph Manager组件的代码如下:
hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_FilterGraph, (void**)&pGraph)
相关接口的查询:
IMediaControl *pControl=NULL;
Hr=pGraph->QueryInterface(IID_IMediaControl,(void**)&pControl):
IVideoWindow* pVW=NULL;
Hr=pGraph->QueryInterface(IID_IVideoWindow,(void**)&pVW);
(2) 之后,创建Filter Graph
这是整个程序最关键的部分
创建Filter Graph 有下面一些方法
IFilterGraph::AddFilter IFilterGraph::ConnectDirect
IGraphBuilder::AddSourceFilter IGraphBuilder::Connect IGraphBuilder::RenderFile
IGraphBuilder::Render
ICaptureGraphBuilder2::RenderStream
一般采用智能连接比较方便,当智能连接不行的时候再自己手动连接
(3) 视频窗口的设置:如果要对视频进行预览的话,那就要设置视频窗口。视频窗口是由Renderer Filter 自动创建出来,我们编程的时候,只需要对它时进行设置就行了
IVideoWindow接口用来专门控制视频窗口,用以下常见的方法:
//put_Owner 为视频窗口指定父窗口,通过这个方法,我们可以将视频窗口嵌到我们自己的窗口,比如一个静态文本控件,
SetWindowPosition 设置视频窗口的位置,
//put_MessageDrain 这个是比较有用的。对视频窗口而言,我们是不能改写它的窗口处理过程,因为它是由DirectShow自动创建的。我们可以通过这个方法将视频窗口收到的消息挂接到一个我们自己的窗口,这样就实现了对视频窗口的消息处理了。
//put_Visible 将视频窗口显示出来
//SetNotifyWindow 当Filter Graph中发生一些事件时,会向应用程序发送一些消息,这个方法是指定处理这此消息的的窗口
//put_WindowStyle 设置Video Window的样式,比如:
long style=0;
get_WindowStyle(&style);
style&=~WS_CAPTION;
put_WindowStyle(style)
这样就可以去掉Video Window的标题栏了
///put_FullScreenMode 设置全屏模式
(4)启动Filter Graph
pGraph->Run();
3. 常用的Filter Graph 的构造
构造Filter Graph,可以GraphEdit这个工具来测试
(1) 本地文件播放
最方便的方法:IGraphBuilder::RenderFile(filename);
只要选择播放的文件,IGraphBuilder就智能地帮你构造出整个Filter Graph
(2) 视频输入设备采集视频的预览
ICaptureGraphBuilder2 * pGB=NULL;
Hr=CoCreateInstance (CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&pGB);
//对于DV面言,它可能有两种视频输出PIN,一种是Interleaved Pin, 一种是Video Pin
//前面一种包含音视频流,后面一种只有视频流,所以我们预览的时候,可以先试一下
Interleaved Pin,如果失败的话,再试一下Video Pin
Hr=pGB->RenderStream(PIN_CATEGORY_PREVIEW,MEDIATYPE_Interleaved,
//pCap,NULL,NULL);
if(FAILED(hr))
{
hr=pGB->RenderStream(PIN_GATEGORY_PREVIEW,MEDIATYPE_Video,pCap,NULL,NULL);
}
if(FAILED(hr))
{
return hr;
}
(3) 采集视频的录制(输出为本地文件)
pGB->SetOutputFileName(&MEDIASUBTYPE_Asf, filename, &pMux,&pSink);
MEDIASUBTYPE_Asf 指定为保存为Asf格式,
MEDIASUBTYPE_Avi 保存为AVI格式
如是要保存为其它格式,要有相应格式的Mux Spliiter 或 Filter Writer,然后传入它的GUID
filename 是保存路径
hr=pGB->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pCap,NULL,pMux);
if(FAILED(hr))
{
hr=pGB->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pCap,NULL,pMux);
}
(4) 模拟电视卡VBI信息的渲染
电视卡的VBI信息,用以下三种:CC(Closed Caption),WST(World Standard Teletext), 忘记了
CC( Closed Caption)
电视卡的VBI信号可能是从VBI PIN输出的,也可能是从CC PIN输出的,所以我们要进行判断。
Hr=pGB->RenderStream(&PIN_CATEGORY_VBI,&MEDIATYPE_Video,pCap,NULL,NULL);
If(FAILED(hr))
{
pGB->RenderStream(&PIN_CATEGORY_CC,&MEDIATYPE_Video,pCap,NULL,NULL);
}
if(FAILED(hr))
{
return hr;
}
RenderStream会帮我们创建整个Filter Graph
RenderStream不支持WST信号的渲染,我们必须手动创建Filter Graph