下一页 1 2 阅读本文请首先阅读:《VC+DirectShow对视频进行图片处理之一》 开发VideoRenderer Filter Filter要做以下工作:接受24bit RGB格式的图片,这由上级Filter肢解视频得到,并把它处理成32bit ARGB图片,之后传给外部函数进行进一步处理。 我要Filte
阅读本文请首先阅读:《VC+DirectShow对视频进行图片处理之一》
开发VideoRenderer Filter
Filter要做以下工作:接受24bit RGB格式的图片,这由上级Filter肢解视频得到,并把它处理成32bit ARGB图片,之后传给外部函数进行进一步处理。
我要Filter这样工作的理由是:几乎所有的视频Filter都接受24bit RGB格式,不用担心会连接失败;32bit ARGB可以很好地支持MMX加速,如果你会用MMX的话,我在本文中会涉及一点MMX,不过和我水平相同,都是初级的;调用外部函数能提供更多的灵活性,不用费尽心思在Filter中封装图像处理函数,可以在写程序时随能力和水平提高而加入新的处理函数,同时也保证了能够及时处理。
怎么样,Filter要做的很少很简单吧,与此一样,写一个Filter也比想象中的简单,我们一步步地看看。
新建一个简单的DLL项目,设置名称为VR,删除VR.cpp中的DllMain函数,添加VR.h和VR.def两个文件,在VR.def中加入以下代码,以完成函数导出。
LIBRARY VR
EXPORTS
DllMain PRIVATE
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
再做些没有创意的东西 —— Filter注册、类工厂定义等,在VR.cpp中加入,我是从DirectShow的Filter例子中复制,再略加修改得来的。
clearcase/" target="_blank" >cccccc width="90%" align=center bgColor=#e7e9e9 border=1>
#include "stdafx.h" #include "VR.h" #pragma comment(lib,"strmbase.lib") #pragma comment(lib,"winmm.lib")
// Setup data
const AMOVIESETUP_MEDIATYPE sudIpPinTypes = { &MEDIATYPE_Video, // MajorType &MEDIASUBTYPE_NULL // MinorType };
const AMOVIESETUP_PIN sudIpPin = { L"Input", // The Pins name FALSE, // Is rendered FALSE, // Is an output pin FALSE, // Allowed none FALSE, // Allowed many &CLSID_NULL, // Connects to filter NULL, // Connects to pin 1, // Number of types &sudIpPinTypes // Pin details };
const AMOVIESETUP_FILTER sudVRAx = { &CLSID_lwVideoRenderer, // Filter CLSID /**/ L"lwVideoRenderer", // String name /**/ MERIT_NORMAL, // Filter merit 1, // Number of pins &sudIpPin // Pin details };
// List of class IDs and creator functions for the class factory. This // provides the link between the OLE entry point in the DLL and an object // being created. The class factory will call the static CreateInstance // function when it is asked to create a CLSID_VideoRenderer object
CFactoryTemplate g_Templates[] = { { L"lwVideoRenderer" /**/ , &CLSID_lwVideoRenderer /**/ , CVideoRenderer::CreateInstance , NULL , &sudVRAx }, };
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); // DllRegisterServer // Used to register and unregister the filter STDAPI DllRegisterServer() { return AMovieDllRegisterServer2( TRUE ); } // DllRegisterServer
// DllUnregisterServer
STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2( FALSE ); } // DllUnregisterServer
extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
// DllMain
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved); }// DllMain | 经过一番复制后,需要增加一些简单的业务逻辑。我们先来完成Filter的类定义,从CBaseVideoRendeer派生一个新类,重写四个函数就可奠定这个Filter的基本功能,如下,在VR.h中加入。
#include <streams.h>
// 回调类定义
class FunCLS
{public: virtual void procFun(BITMAPINFO* pBmpInfo, BYTE* pb){return;}; };
// 回调函数指针定义
typedef void (CALLBACK* pProcFun)(BITMAPINFO* pBmpInfo,BYTE* pb);
// {F81331DB-2E46-43e7-8709-BE57205D8914} Filter的全局标识符
static const GUID CLSID_lwVideoRenderer = { 0xf81331db, 0x2e46, 0x43e7, { 0x87, 0x9, 0xbe, 0x57, 0x20, 0x5d, 0x89, 0x14 } }; // Filter 类定义 class CVideoRenderer : public CBaseVideoRenderer { public: // 创建进程。 static CUnknown * WINAPI CreateInstance(LPUNKNOWN, HRESULT *); // 构造、释构函数 CVideoRenderer(LPUNKNOWN pUnk,HRESULT* phr); ~CVideoRenderer(); public: // 检查是否有可以接受格式的数据 HRESULT CheckMediaType(const CMediaType* pmt); // 设置具体的数据格式,如视频图像的宽、高等 HRESULT SetMediaType(const CMediaType* pmt); // 递交数据,即显示、呈现数据 HRESULT DoRenderSample(IMediaSample* pMediaSample); private: BITMAPINFO m_bmpInfo; // 图片信息 BYTE* m_pCopyBuffer; // 复制缓冲区 UINT m_pixelNum; // 像素点的数目 FunCLS* m_pFunCLS; // 回调类指针 pProcFun m_pPF; // 回调函数指针 }; |
|