设为首页 加入收藏

TOP

9.3.3 视频图像捕获类CVMR_Capture的实现(1)
2013-10-07 00:41:11 来源: 作者: 【 】 浏览:62
Tags:9.3.3 视频 图像 捕获 CVMR_Capture 实现

9.3.3  视频图像捕获类CVMR_Capture的实现(1)

为完成采集视频、预览视频和捕获图像帧的任务,我们封装了CVMR_Capture类,使用VMR技术流畅显示和捕捉图像帧。根据GraphEdit的滤波器内容和链表的操作,编程(www.cppentry.com)实现使用VMR技术显示、捕捉图像。

 类CVMR_Capture定义在头文件VMR_Capture.h中。

enum PLAYER_STATE {INIT,RUNNING,PAUSED,STOPPED};
class CVMR_Capture
{
public:
CVMR_Capture();                     //类构造器
virtual ~CVMR_Capture();             //类析构器
int EnumDevices(HWND hList);    //枚举设备
HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight);
//根据设备索引号初始化
DWORD GetFrame(BYTE ** pFrame);    //获取捕获的图像帧
BOOL Pause();        //暂停预览、捕获
DWORD GrabFrame();       //截获图像
void CloseInterfaces(void);     //关闭接口,释放资源
void SaveGraph(CString wFileName);           //保存滤波器链表
protected:
IGraphBuilder   *m_pGB;    //滤波器链表管理器
IMediaControl   *m_pMC;    //媒体控制接口
IMediaEventEx   *m_pME;    //媒体事件接口
IVMRWindowlessControl9 *m_pWC;    //VMR-9接口
IPin     *m_pCamOutPin;  //视频采集滤波器引脚
IBaseFilter    *m_pDF;    //视频采集滤波器
PLAYER_STATE        m_psCurrent;
int  m_nWidth;       //图像帧宽度
int  m_nHeight;       //图像帧高度
BYTE *m_pFrame;       //捕获的图像帧数据指针
long m_nFramelen;        //捕获的图像帧数据大小
bool BindFilter(int deviceId, IBaseFilter **pFilter);   //设备与滤波器捆绑
HRESULT InitializeWindowlessVMR(HWND hWnd); //初始化无窗口模式的VMR
HRESULT InitVideoWindow(HWND hWnd,int width, int height); //初始化视频窗口
void StopCapture();
void DeleteMediaType(AM_MEDIA_TYPE *pmt);               //删除媒体类型
bool Convert24Image(BYTE *p32Img,BYTE *p24Img,DWORD dwSize32); //颜色空间转换
private:
};

CVMR_Capture类封装了使用VMR技术的成员函数和成员变量,包括类的构造器、析构器,滤波器链表管理器接口、媒体控制接口、媒体事件接口,图像帧的宽度、高度及操作VMR的保护成员函数等。

类CVMR_Capture有关初始化、析构等,类实现VMR_Capture.cpp文件中。

//释放资源的宏
#define RELEASE_POINTER (x) { if (x) x->Release(); x = NULL; }
/*类构造器*/
CVMR_Capture::CVMR_Capture()
{
CoInitialize(NULL);                 //初始化COM库
//接口指针清空
m_pGB = NULL;       m_pMC = NULL;       
m_pME = NULL;      m_pWC = NULL;
m_pDF =NULL;          m_pCamOutPin =NULL; 
m_pFrame=NULL;        m_nFramelen=0;
m_psCurrent=STOPPED;
}
/*类析构器*/
CVMR_Capture::~CVMR_Capture()
{
CloseInterfaces();                   //清空指针、释放资源
CoUninitialize( );                  //卸载COM库
}
/*释放所有资源,断开链接*/
void CVMR_Capture::CloseInterfaces(void)
{
HRESULT hr;
//停止媒体回放
if(m_pMC) hr = m_pMC->Stop();
m_psCurrent = STOPPED;
//释放并清零接口指针
if(m_pCamOutPin)
m_pCamOutPin->Disconnect();   //断开引脚的链接
RELEASE_POINTER(m_pCamOutPin);   //视频采集滤波器引脚清空
RELEASE_POINTER(m_pMC);      //媒体控制接口清空
RELEASE_POINTER(m_pGB);      //滤波器链表管理器接口清空
RELEASE_POINTER(m_pWC);     //VMR-9接口清空
RELEASE_POINTER(m_pDF);     //视频采集滤波器接口清空
//释放分配的内存
if(m_pFrame!=NULL)
delete []m_pFrame;     //释放图像空间缓存
}

上述程序完成资源释放、指针清空等工作,在退出应用程序时调用此函数。

枚举本地系统的采集设备。

/* 枚举本地系统的采集设备*/
int  CVMR_Capture::EnumDevices(HWND hList)
{
if (!hList) return  -1;
int id = 0;
//枚举所有视频采集设备
ICreateDevEnum *pCreateDevEnum;
     //生成设备枚举器 
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR) return -1;
IEnumMoniker *pEm;
//创建视频类枚举器
hr = pCreateDevEnum->CreateClassEnumerator
(CLSID_VideoInputDeviceCategory,      &pEm, 0);
if (hr != NOERROR) return -1;
pEm->Reset();           //复位设备
ULONG cFetched;
IMoniker *pM;
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) //根据索引获取设备
{
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)
{
id++;
//把该设备的信息添加到组合框
(long)SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)var.
bstrVal);
SysFreeString(var.bstrVal);   //释放资源
}
pBag->Release();        //释放资源
}
pM->Release();          //释放资源
}
return id;
}


回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇9.1 系统分析与设计 下一篇9.3.3 视频图像捕获类CVMR_Captur..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: