转自 http://blog.sina.com.cn/s/blog_3f86704c0100n95n.html

DirectShow是Windows平台下进行视频处理的第一选择,最近由于学习的需要,我简单研究了一下DirectShow的方法。为了方便大家相互交流提高,现整理如下:

 
1、视频的播放
【类】IGraphBuilder
用于创建一个渲染视频的流图,基本用法如下:
IGraphBuilder* pIGraphBuilder;
CoCreateInstance(CLSID_FilterGraph,
NULL,
CLSCTX_INPROC,
IID_IGraphBuilder,
(LPVOID *)&pIGraphBuilder);
//CoCreateInstance这句,相当于new语句
 
【接口】IVideoWindow
用于控制视频的显示位置和大小,基本用法如下:
IVideoWindow* sourceVideoWindow;
pIGraphBuilder->QueryInterface(IID_IVideoWindow, (LPVOID *) &sourceVideoWindow);
//QueryInterface这句,相当于把IGraphBuilder类型的指针抽象成了IVideoWindow类型的指针;实际上可以看作IGraphBuilder类型实现了IVideoWindow类型的接口,所以就可以抽象成一个IVideoWindow类型的接口,抽象成某种接口就可以调用相应的函数,完成相应的功能;其实其他的接口都可以通过这种转换来得到,这也是DirectShow类结构设计的精髓之处
sourceVideoWindow->put_Owner((int)SourceVideoShow->Handle);
sourceVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
sourceVideoWindow->SetWindowPosition(
SourceVideoShow->ClientRectangle.Left,
SourceVideoShow->ClientRectangle.Top,
SourceVideoShow->ClientRectangle.Width,
SourceVideoShow->ClientRectangle.Height);
 
【接口】IBasicVideo2
用于访问视频流(相应的还有音频流,请参见MSDN),这个比较简单,比如get_SourceWidth就可以得到视频的宽度,get_SourceHeight就可得到视频的高度等等,MSDN上都有,这里就不再赘述了
 
【接口】IMediaControl
用于播放控制(开始、暂停等),这个也比较简单,这里也不再赘述了
 
【接口】IMediaPosition
用于访问和控制媒体流的位置,一般来说主要是3种:
a得到整个媒体的长度 get_Duration
b跳到某一个指定的时间 put_CurrentPosition
c得到当前的播放进度 get_CurrentPosition
 
2、视频的截图和处理
方法一
IBasicVideo2::GetCurrentImage(long* bufferSize, long* ImageBuffer);
这种截图方法最简单,得到当前帧的截图(可以先用IMediaPosition跳到目标位置),缺点就是速度比较慢
 
方法二
IMediaDet::GetBitmapBits(double time, long* bufferSize, char* ImageBuffer, int videoWidth, int videoWidth);
这种截图方法相对来说复杂一点,建议参考MSDN关于IMediaDet的说明,优点是速度比较快
值得注意的是IMediaDet是一个类,而不是接口,对应的初始化方法如下:
IMediaDet* pDet;
CoCreateInstance( CLSID_MediaDet,
NULL,
CLSCTX_INPROC_SERVER,
IID_IMediaDet,
(void**) &pDet );
 
BSTR fileName = L“XXXX”;
pDet->put_Filename(fileName);
long lStreams;
pDet->get_OutputStreams(&lStreams);
 
 
3、视频的编辑
这里所说的视频编辑是在线编辑,如果是离线编辑的话,直接依次获得每一帧的图片,处理之后再显示就行了,但是这样基本上就是慢动作播放了……
 
在线编辑是能够做到实时的,其基本思想是在DirectShow的基本渲染流程中加一个Filter(过滤器 or 滤波器 or 滤镜),根据DirectShow的渲染原理,每一帧图像都会流经这个Filter,然后我们只要在流经的时候处理它就行了……
 
具体实现方法请参见MSDN:
【类】IBaseFilter
【接口】ISampleGrabber
【抽象类】ISampleGrabberCB
【类】IPin
 
因为要手动连接Filter(连接的过程就是像连滤波器一样,一个OutPin连一个InPin),所以不能直接用RenderFile,要用Render来代替。
 
 
----------------------------------------------------------------------------------
更多的具体内容请参见MSDN的DirectShow SDK
欢迎大家批评指正,转载请注明来源,谢谢^_^
posted on 2013-07-24 12:51  竟飞工作室  阅读(711)  评论(0编辑  收藏  举报