科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件VC+DirectShow对视频进行图片处理之二

VC+DirectShow对视频进行图片处理之二

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Filter要做以下工作:接受24bit RGB格式的图片,这由上级Filter肢解视频得到,并把它处理成32bit ARGB图片,之后传给外部函数进行进一步处理。

作者:longway 来源:天极开发 2007年10月16日

关键字: 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例子中复制,再略加修改得来的。

#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; // 回调函数指针
 };
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章