directshow 实现视频捕获(源码)vs2005
我用 visual studio 2005 编了一个摄像头预览程序,还可以导出成 avi 文件,前
提是要安装 directshow,并搭建好环境,我安装的是 directx 9.0b,搭建环境
很简单,网上有很多,注意在项目-属性-配置属性-链接器-输入中要加上
strmbasd.lib winmm.lib(中间有空格)。源代码如下:
/*CaptureClass.h*/
#pragma once
#include <atlbase.h>
#include <windows.h>
#include <DShow.h>
#include <qedit.h>//ISampleGrabber 接口要求的
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#endif
class CCaptureClass
{
public:
CCaptureClass(void);
public:
~CCaptureClass(void);
int EnumDevices(HWND hList);
//void SaveGraph(TCHAR *wFileName); //保存滤波器链表
void ConfigCameraPin(HWND hwndParent); //配置摄像头的视频格
式
void ConfigCameraFilter(HWND hwndParent); //配置摄像头的图像参
数
HRESULT CaptureImages(CString inFileName); //捕获保存视频
HRESULT PreviewImages(int iDeviceID , HWND hWnd); //采集预览视频
private:
HWND m_hWnd; //视频显示窗口的句柄
IGraphBuilder *m_pGB; //滤波器链表管理器
ICaptureGraphBuilder2 *m_pCapture; //增强型捕获滤波器链表
管理器
IBaseFilter *m_pBF; //捕获滤波器
IMediaControl *m_pMC; //媒体控制接口
IVideoWindow *m_pVW; //视频显示窗口接口
IBaseFilter *pMux; //写文件滤波器
protected:
bool BindFilter(int deviceId,IBaseFilter **pFilter); //把指定的设备滤波
器捆绑到链表中
void ResizeVideoWindow(); //更改视频显示窗口
HRESULT SetupVideoWindow(); //设置视频显示窗口的特性
HRESULT InitCaptureGraphBuilder(); //创建滤波器链表管理器,
查询其各种控制接口
};
/*CaptureClass.cpp*/
#include "StdAfx.h"
#include "CaptureClass.h"
/********************************************************************
****/
/* 类构造函数实现
*/
/********************************************************************
****/
CCaptureClass::CCaptureClass(void)
{
CoInitialize(NULL); //COM 库初始化
m_hWnd = NULL; //视频显示窗口的句柄
m_pVW = NULL ; //视频窗口接口指针清空
m_pMC = NULL ; //媒体控制接口指针清空
m_pGB = NULL ; //滤波器链表管理器接口指针清空
m_pBF = NULL ; //捕获滤波器接口指针清空
m_pCapture = NULL ; //增强型捕获滤波器链表管理器接口指针清空
}
/********************************************************************
****/
/* 析构函数
*/
/********************************************************************
****/
CCaptureClass::~CCaptureClass(void)
{
if(m_pMC) m_pMC ->Stop(); //首先停止媒体
if(m_pVW){
m_pVW->put_Visible(OAFALSE); //视频窗口不可见
m_pVW->put_Owner(NULL); //视频窗口的父窗口清空
}
SAFE_RELEASE(m_pCapture); //释放增强型捕获滤波器链表管理器接口
SAFE_RELEASE(m_pMC); //释放媒体控制接口
SAFE_RELEASE(m_pGB); //释放滤波器链表管理器接口
SAFE_RELEASE(m_pBF); //释放捕获滤波器接口
CoUninitialize( ); //卸载 COM 库
}
/********************************************************************
****/
/* 把指定采集设备与滤波器捆绑
*/
/********************************************************************
****/
bool CCaptureClass::BindFilter(int deviceId,IBaseFilter **pFilter)
{
if( deviceId < 0) return false ;
//枚举所有的视频捕获设备
ICreateDevEnum *pCreateDevEnum ;
//生成设备枚举器 pCreateDevEnum
HRESULT hr =
CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID
_ICreateDevEnum,(void**)&pCreateDevEnum);
if( hr != NOERROR ) return false ;
IEnumMoniker *pEm;
//创建视频输入设备类枚举器
hr =
pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEm,0);
if( hr != NOERROR ) return false ;
pEm->Reset(); //复位该设备
ULONG cFetched;
IMoniker *pM;
int index = 0 ;
//获取设备
while( hr = pEm->Next(1,&pM,&cFetched),hr == S_OK , index <= deviceId )
{
IPropertyBag *pBag;
//获取该设备的属性集
hr = pM->BindToStorage(0,0,IID_IPropertyBag,(void**)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var ;
var.vt = VT_BSTR; //保存的是二进制的数据
hr = pBag->Read(L"FriendlyName",&var,NULL); //获取 FriendlyName
形式的信息
if( hr == NOERROR )
{
//采集设备与捕获滤波器捆绑
if( index == deviceId )
pM->BindToObject(0,0,IID_IBaseFilter,(void**)pFilter);
SysFreeString(var.bstrVal); //释放二进制数据资源,必须释放
}
pBag ->Release();
}
pM->Release();
index++;
}