VC+DirectShow对视频进行图片处理之二
2007-03-15 21:48:41 来源:WEB开发网核心提示: // {244DF760-7E93-4cf0-92F4-DCB79F646B7E} 接口的 GUIDstatic const GUID IID_IVRControl = {0x244df760, 0x7e93, 0x4cf0, {0x92, 0xf4, 0xdc, 0xb7, 0x9f,
// {244DF760-7E93-4cf0-92F4-DCB79F646B7E} 接口的 GUID
static const GUID IID_IVRControl = {0x244df760, 0x7e93, 0x4cf0, {0x92, 0xf4, 0xdc, 0xb7, 0x9f, 0x64, 0x6b, 0x7e}};
// 接口定义
DECLARE_INTERFACE_(IVRControl, IUnknown)
{
STDMETHOD(GetBmpInfo) (THIS_ // 方法一:获取图片信息
BITMAPINFO** ppBmpInfo ) PURE;
STDMETHOD(GetPointer) (THIS_ // 方法二:获取缓冲区指针
BYTE** ppb // 缓冲区指针的指针 ) PURE;
STDMETHOD(SetFunCLS) (THIS_ // 方法三:设置回调类
FunCLS* pFunCLS // 回调类指针 ) PURE;
STDMETHOD(SetFun) (THIS_ // 方法四:设置回调函数
pProcFun pPF ) PURE;
};
写完接口后就要实现它,在VR.h 中添加 #include "IVRControl.h",而把接口作为Filter 类的一个基类,像这样:
class CVideoRenderer : public CBaseVideoRenderer, public IVRControl
在CVideoRenderer 类中加入接口函数和询问接口函数:
// 询问接口,一般可以不要的,但这里需要使用接口,也重载了
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
// 接口函数
DECLARE_IUNKNOWN;
STDMETHODIMP GetBmpInfo(BITMAPINFO** ppBmpInfo);
STDMETHODIMP GetPointer(BYTE** ppb);
STDMETHODIMP SetFunCLS(FunCLS* pFunCLS);
STDMETHODIMP SetFun(pProcFun pPF);
再在VR.cpp 中加入上述函数的具体实现代码:
//===========================================================
// 询问接口
STDMETHODIMP CVideoRenderer::NonDelegatingQueryInterface(REFIID riid,void** ppv)
{
CheckPointer(ppv,E_POINTER);
if(riid == IID_IVRControl){
// 返回接口。这里有个细节:返回接口时,Filter 的引用计数会增一,所以外部程序用完接口后也要对它进行释放
return GetInterface((IVRControl*) this,ppv);
}else{
return CBaseVideoRenderer::NonDelegatingQueryInterface(riid,ppv);
}
}
//===========================================================
// 以下为接口函数的具体实现,只是简单的赋值
STDMETHODIMP CVideoRenderer::GetBmpInfo(BITMAPINFO** ppBmpInfo)
{
*ppBmpInfo = &this->m_bmpInfo;
return S_OK;
}
STDMETHODIMP CVideoRenderer::GetPointer(BYTE** ppb)
{
*ppb = m_pCopyBuffer;
return S_OK;
}
STDMETHODIMP CVideoRenderer::SetFunCLS(FunCLS* pFunCLS)
{
m_pFunCLS = pFunCLS;
return S_OK;
}
STDMETHODIMP CVideoRenderer::SetFun(pProcFun pPF)
{
m_pPF = pPF;
return S_OK;
}
不知您注意到了没有:接口其实就是一个虚基类。类在 C++ 等现代编程语言中无处不在,也没什么好惊奇的,只是有利于更好理解。再有一个,看似功能强大的接口可能偏偏很容易实现,它依附于对象,它的复杂可能都隐藏在对象内了。
可以看出在接口定义中也要用到回调类和回调函数指针的定义,所以我把它们连同 Filter CLSID 的定义一起移到 IVRControl.h 文件的开头,使用到此 Filter 时只把 IVRControl.h 这一个文件包含进去就行了。
不错,我们已经一步步、一个个函数的把设想中的 Filter 写出来了,已成功完成了Filter,以 Release 模式把它编译出来足有80多K,用 UPX 压缩后就是30 多K。这样把代码铺出来看,好像蛮多的,不过我在敲代码时一点也不觉得,因为每个函数所做的的确很少,循着逻辑规矩、步步为营地写真的很easy。
Tags:VC DirectShow 视频
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接