DirectShow源过滤器设计指南

DirectShow是一个强大的多媒体框架,用于在Windows平台上处理视频和音频数据。本文将指导如何设计一个DirectShow的源过滤器。源过滤器是DirectShow架构中的基本组件之一,它负责生成数据流。

在开始开发之前,请确保计算机上安装了DirectShowSDK,并且在Visual C++或Visual Studio环境中正确配置了它。

创建项目

首先,创建一个项目。例如,可以选择“Win32 Dynamic-Link Library”。

添加库

接下来,为项目添加以下库:

strmbasd.lib msvcrtd.lib quartz.lib vfw32.lib winmm.lib

包含头文件

然后,包含需要的头文件:

#include <streams.h> #include <olectl.h> #include <initguid.h> #include "MyStream.h"

注意,"MyStream.h"不是系统的头文件,而是创建的类的头文件。

生成GUID

使用工具"GUIDGEN.EXE"生成一个新的GUID。如果找不到这个工具,可以在网上搜索。启动工具,点击"New GUID"按钮,然后选择"DEFINE_GUID(...)"格式,复制并粘贴到项目中。

设置数据类型

定义主要类型和次要类型:

const AMOVIESETUP_MEDIATYPE sudOpPinTypes = { &MEDIATYPE_Video, &MEDIASUBTYPE_NULL };

对于过滤器,需要一个输出引脚。按照以下步骤设置引脚的属性:

const AMOVIESETUP_PIN sudOpPin = { L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 1, &sudOpPinTypes };

设置过滤器属性

设置过滤器的属性:

const AMOVIESETUP_FILTER sudMyax = { &CLSID_MySourceFilter, L"My Source Filter", MERIT_DO_NOT_USE, 1, &sudOpPin };

创建类

创建一个继承自CSource的类。为什么选择这个类?因为将要开发一个源过滤器,所以必须选择合理的基类。

class CMySourceFilter:public CSource { public: static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr); private: CMySourceFilter(LPUNKNOWN lpunk, HRESULT *phr); };

创建实例

完成源过滤器类后,如何创建新实例?也许可以使用数组,请看以下代码片段:

CFactoryTemplate g_Templates[] = { { L"My Source Filter", &CLSID_MySourceFilter, CMySourceFilter::CreateInstance, NULL, &sudMyax } }; int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);

添加注册和注销函数

添加注册和注销函数:

STDAPI DllRegisterServer() { return AMovieDllRegisterServer2(TRUE); } STDAPI DllUnregisterServer() { return AMovieDllRegisterServer2(FALSE); }

导出函数

为了在DLL中创建过滤器,还需要导出一些函数。创建一个新的DEF文件:

LIBRARY MySourceFilter.ax EXPORTS DllRegisterServer PRIVATE DllUnregisterServer PRIVATE DllGetClassObject PRIVATE DllCanUnloadNow PRIVATE

添加输出引脚

现在需要插入一个新类,继承自CSourceStream。它可以生成样本并将其推送到下一个过滤器。

class CMyStream : public CSourceStream { public: STDMETHOD(Notify)(IBaseFilter * pSender, Quality q); HRESULT CheckMediaType(const CMediaType *pMediaType); HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties); HRESULT FillBuffer(IMediaSample *pms); CMyStream(HRESULT *phr, CSource *pms, LPCWSTR pName); virtual ~CMyStream(); private: CRefTime m_rtSampleTime; int m_iRepeatTime; BITMAPFILEHEADER * pbfh; int xPos, yPos; BOOL xLock, yLock; HBITMAP hBmp; };

引脚如何工作

关于引脚的更多详细信息,请参考MSDN文档。

流线程

流线程运行一个循环,结构如下:

while (!stopped) { 1. Get a media sample from the allocator. 2. Fill the sample with data. 3. Time stamp the sample. 4. Deliver the sample downstream. }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485