DirectShow 是一个 Windows 平台上的流媒体框架,提供了高质量的多媒体流采集和回放功能。
Filter 实质是一个 COM 组件,所以学习开发 Filter 前你应该对 COM 相关知识有点了解。COM 组件的实质是实现了纯虚指针接口的 C++ 对象。
应用程序开发者只需要基本的 COM 组件知识:实例化COM组件、调用接口、管理接口的引用计数。Filter 开发者则需要更多。
选择一个基类,声明自己的类。
应该清楚这个 Filter 在整个 Filter Graph 的位置,这个 Filter 的输入是什么数据,输出是什么数据,有几个输入 Pin、几个输出 Pin 等,可以画出这个 Filter 的草图。
Win7: DirectShow SDK 做为 Windows SDK(GRMSDK_EN_DVD.iso) 的一部分,不再有单独的 DirectX SDK 包。
在 DirectShow 中,应用程序要实现功能就必须将这些 Filter 链接在一起,因而一个 Filter 的输出就变成了另一个 Filter 的输入。这一系列串在一起的 Filter 称为 Filter Graph。
使用 VS2008 建立 Filter 开发工程的过程如下:
(1) 新建 
Visual C++/Win32 项目,工程名如:FilterSample。点击“确定”进入下一步;
(2) 应用程序类型选择:DLL,一般不选择 MFC 和 ATL;
工程的建立完成,编译后可以先将输入文件改名。方法如下:
属性页/链接器/常规/输出文件,修改为:$(OutDir)/FilterSample.ax
DirectShow 必须用到以下头文件的库文件:
 1 #include "streams.h"
 2 #include "initguid.h"
 3 strmbasd.lib
 4 winmm.lib
 5 uuid.lib
 6 Quartz.lib   输出 AMGetErrorText 函数,如果不调用此函数,此库不是必需的。
 7
 8 FilterSample.def 文件的内容:
 9 LIBRARY FilterSample.ax
10 EXPORTS
11 ; 需要定义的导出函数
12 DllMain PRIVATE
13 DllRegisterServer PRIVATE
14 DllUnregisterServer PRIVATE
15 ; 在基类中已经定义的导出函数
16 DllGetClassObject PRIVATE
17 DllCanUnloadNow PRIVATE
18
19 dllmain.cpp 的代码如下:
20 // dllmain.cpp : 定义 DLL 应用程序的入口点。
21 #include "stdafx.h"
22 #include "streams.h"
23
24 // BOOL APIENTRY DllMain( HMODULE hModule,
25 //                        DWORD  ul_reason_for_call,
26 //                        LPVOID lpReserved
27 //           )
28 // {
29 //  switch (ul_reason_for_call)
30 //  {
31 //  case DLL_PROCESS_ATTACH:
32 //  case DLL_THREAD_ATTACH:
33 //  case DLL_THREAD_DETACH:
34 //  case DLL_PROCESS_DETACH:
35 //    break;
36 //  }
37 //  return TRUE;
38 // }
39
40 STDAPI DllRegisterServer()
41 {
42   return AMovieDllRegisterServer2(TRUE);
43 }
44 STDAPI DllUnregisterServer()
45 {
46   return AMovieDllRegisterServer2(FALSE);
47 }
48
49 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
50 BOOL APIENTRY DllMain(HANDLE hModule, DWORD  dwReason,   LPVOID lpReserved)
51 {
52   return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
53 }  

编译时,可能会遇到如下问题:
1>e:\work\sourcecode\testcode\filtersample\dllmain.cpp(23) : error C3861: “AMovieDllRegisterServer2”: 找不到标识符
1>e:\work\sourcecode\testcode\filtersample\dllmain.cpp(27) : error C3861: “AMovieDllRegisterServer2”: 找不到标识符
编译错误, 一般是头文件没有包含。所以,包含: #include "streams.h"
1>dllmain.obj : error LNK2019: 无法解析的外部符号 _AMovieDllRegisterServer2@4,该符号在函数 _DllRegisterServer@0 中被引用
1>dllmain.obj : error LNK2019: 无法解析的外部符号 _DllEntryPoint@12,该符号在函数 _DllMain@12 中被引用
1>E:\Work\SourceCode\TestCode\FilterSample\Debug\FilterSample.dll : fatal error LNK1120: 2 个无法解析的外部命令
链接错误, 一般是库文件没有包含。所以,库输入中包含: strmbasd.lib
1>正在链接...
1>strmbasd.lib(wxdebug.obj) : error LNK2019: 无法解析的外部符号 __imp__timeGetTime@0,该符号在函数 "void __stdcall DbgInitialise(struct HINSTANCE__ *)" (?DbgInitialise@@YGXPAUHINSTANCE__@@@Z) 中被引用
1>strmbasd.lib(wxutil.obj) : error LNK2001: 无法解析的外部符号 __imp__timeGetTime@0
1>strmbasd.lib(wxutil.obj) : error LNK2019: 无法解析的外部符号 __imp__timeSetEvent@20,该符号在函数 "unsigned int __cdecl CompatibleTimeSetEvent(unsigned int,unsigned int,void (__stdcall*)(unsigned int,unsigned int,unsigned long,unsigned long,unsigned long),unsigned long,unsigned int)" (?CompatibleTimeSetEvent@@YAIIIP6GXIIKKK@ZKI@Z) 中被引用
1>E:\Work\SourceCode\TestCode\FilterSample\Debug\FilterSample.dll : fatal error LNK1120: 4 个无法解析的外部命令
包含  winmm.lib, 可以解决 timeGetTime 链接错误的问题
增加头文件 FilterSample.h,其内容如下:
其中 GUID 的生成,需要用到下面的工具: Microsoft SDKs\Windows\v7.1\Bin\guidgen.exe
 1 #ifndef _FILTER_SAMPLE_H_
 2 #define _FILTER_SAMPLE_H_
 3
 4 // {33B57142-BD07-4a77-AE91-A8F6C24A8F40}
 5 DEFINE_GUID(CLSID_FilterSample,
 6     0x33b57142, 0xbd07, 0x4a77, 0xae, 0x91, 0xa8, 0xf6, 0xc2, 0x4a, 0x8f, 0x40);
 7
 8 class CFilterSample: public CCritSec, public CBaseFilter
 9 {
10 public:
11   CFilterSample(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *hr);
12   virtual ~CFilterSample();
13   static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr);
14   CBasePin *GetPin(int n);
15   int GetPinCount();
16 };
17
18 #endif  

FilterSample.cpp 的内容如下:

 1 // FilterSample.cpp : 定义 DLL 应用程序的导出函数。
 2 //
 3
 4 #include "stdafx.h"
 5 #include "streams.h"
 6 #include "initguid.h"
 7
 8 #include "FilterSample.h"
 9
10 // Using this pointer in constructor
11 #pragma warning(disable:4355 4127)
12
13 //
14 // AMOVIESETUP_FILTER 描述一个 Filter
15 // AMOVIESETUP_PIN 描述 pin
16 // AMOVIESETUP_MEDIATYPE 描述数据类型
17 const AMOVIESETUP_MEDIATYPE sudPinTypes =
18 {
19   &MEDIATYPE_NULL,         // Major CLSID
20   &MEDIASUBTYPE_NULL       // Minor type
21 };
22
23 const AMOVIESETUP_PIN psudPins[] =
24 {
25   {
26     L"Input",             // Pin's string name
27     FALSE,                // Is it rendered
28     FALSE,                // Is it an output
29     FALSE,                // Allowed none
30     FALSE,                // Allowed many
31     &CLSID_NULL,          // Connects to filter
32     L"Output",            // Connects to pin
33     1,                    // Number of types
34     &sudPinTypes          // Pin information
35   },
36   {
37     L"Output",            // Pin's string name
38     FALSE,                // Is it rendered
39     TRUE,                 // Is it an output
40     FALSE,                // Allowed none
41     FALSE,                // Allowed many
42     &CLSID_NULL,          // Connects to filter
43     L"Input",             // Connects to pin
44     1,                    // Number of types
45     &sudPinTypes          // Pin information
46   }
47 };
48
49 const AMOVIESETUP_FILTER sudInfTee =
50 {
51   &CLSID_FilterSample,           // CLSID of filter
52   L"Filter Sample Test Lib",     // Filter's name
53   MERIT_DO_NOT_USE,              // Filter merit
54   2,                             // Number of pins
55   psudPins                       // Pin information
56 };
57 //
58
59 CFactoryTemplate g_Templates[1] =
60 {
61   {
62     L"Filter Sample",                // Name
63     &CLSID_FilterSample,             // CLSID
64     CFilterSample::CreateInstance,   // Method to create an instance of MyComponent
65     NULL,                            // Initialization function
66     &sudInfTee                       // Set-up information (for filters)
67   }
68 };
69 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
70
71
72 CFilterSample::CFilterSample(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *hr)
73   :CBaseFilter(NAME("Filter Sample"), pUnk, this, CLSID_FilterSample)
74 {
75 }
76
77 CFilterSample::~CFilterSample()
78 {
79 }
80
81 CBasePin * CFilterSample::GetPin(int n)
82 {
83   return NULL;
84 }
85 int CFilterSample::GetPinCount()
86 {
87   return 0;
88 }
89
90 CUnknown * WINAPI CFilterSample::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
91 {
92   CFilterSample *pFilter = new CFilterSample(NAME("Filter Sample"), pUnk, pHr);
93   if (pFilter== NULL)
94   {
95     *pHr = E_OUTOFMEMORY;
96   }
97   return pFilter;
98 }  

编译时,可能遇到如下问题:
1>FilterSample.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall CBaseFilter::CBaseFilter(wchar_t const *,struct IUnknown *,class CCritSec *,struct _GUID const &)" (??0CBaseFilter@@QAE@PB_WPAUIUnknown@@PAVCCritSec@@ABU_GUID@@@Z),该符号在函数 "public: __thiscall CFilterSample::CFilterSample(wchar_t *,struct IUnknown *,long *)" (??0CFilterSample@@QAE@PA_WPAUIUnknown@@PAJ@Z) 中被引用
1>E:\Work\SourceCode\TestCode\FilterSample\Debug\FilterSample.dll : fatal error LNK1120: 1 个无法解析的外部命令
解决方法: 属性页 常规->字符集 修改为“使用多字节字符集”
编译通过后,如何验证此 Filter 呢?
regsvr32 FilterSample.ax
regsvr32 提示错误:
模块“FilterSample.ax”已加载,但找不到入口点 DllRegisterServer。
请确保“FilterSample.ax”为有效的 DLL 或 OCX 文件,然后重试。
出现此错误的原因,是 FilterSample.def 未链接到工程中。在工程属性页,“链接器”/“输入”/“模块定义文件” 中输入: FilterSample.def 后,重新编译。
然后在命令行执行: regsvr32 FilterSample.ax,则提示成功。
如何确认成功了呢?可通过 Microsoft SDKs\Windows\v7.1\Bin\graphedt.exe 来查看。方法如下:
点击 graphedt.exe 的 Graph 菜单,选择 Insert Filters...。在弹出的对话框: Which filters do you want to insert? 中,选择 Directshow Filters/Filter Sample Test Lib。
这个名字看起来是不是很熟悉?看看上面的代码中是不是有这样的字符串,呵呵...。如果还不确认,请看 Filter Sample Test Lib 的 GUID 和 文件名分别是:
@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{33B57142-BD07-4A77-AE91-A8F6C24A8F40} 和 E:\Filters\FilterSample.ax(具体的目录与执行 regsvr32 时 FilterSample.ax 所在的路径相关)。

转载于:https://www.cnblogs.com/91program/p/5205020.html

DirectShow Filter 基础与简单的示例程序相关推荐

  1. BizTalk 2006 简单入门示例程序(附源项目文件下载)

    BizTalk 2006 简单入门示例程序(附源项目文件下载) 为初学BizTalk Server 2006的开发人员,提供一个简单入门的示例程序,包括一个Receive Port.Send Port ...

  2. C++ Boost库:简介和第一个示例程序

    文章目录 1. 简介 2. Boost库开发环境搭建 3. 一个简单的示例程序 4. hpp文件简介 C++ Boost库:简介和第一个示例程序 C++ Boost库:数值转换 lexical_cas ...

  3. intel Pin简要介绍及示例程序

    Intel PIN Intel PIN References 二进制动态插桩简介 源插桩与二进制插桩 静态插桩与动态插桩 常见的动态插桩工具 Intel Pin简介 Intel pin动态插桩框架 简 ...

  4. Python 程序示例 - 初学者的简单代码示例

    马克吐温说过,出人头地的秘诀就是开始.编程对于初学者来说似乎令人望而生畏,但最好的入门方式是直接投入并开始编写代码. 简单的代码示例是初学者入门和学习编程基础知识的好方法.在本文中,我将提供一系列非常 ...

  5. python推荐系统-用python写个简单的推荐系统示例程序

    用python写个简单的推荐系统示例程序 作者:阿俊 发布于:2011-11-26 16:03 Saturday 分类:推荐系统 python这门语言写程序代码量非常少,短短几行就可以把程序写的很清楚 ...

  6. 通信软件基础B-重庆邮电大学-Java-编程实现一个简单的聊天程序-多线程编程实现

    实验任务六 编程实现一个简单的聊天程序-多线程编程实现 1. 系统设计要求 编程实现一个简单的聊天程序,实现两台计算机间的信息交互,使用多线程编程实现:可同时连接多个客户端,服务器收到客户端发送的消息 ...

  7. dbus的代码范例 linux_Dbus简介与简单的收发示例程序

    Dbus简介与简单的收发示例程序. D-BUS 是一个大有前途的消息总线和活动系统,正开始深入地渗透到 Linux® 桌面之中.了解创建它的原因.它的用途以及发展前景. D-BUS 本质上是 进程间通 ...

  8. ASP.NET AJAX示例程序:实现IDragSource和IDropTarget接口将商品拖放至购物车中

    本文来自<ASP.NET AJAX程序设计--第II卷:客户端Microsoft AJAX Library相关>第9章第3节. 9.3 示例程序:实现IDragSource和IDropTa ...

  9. 示例程序:关于双目视觉,标定,立体匹配(视差算法),点云,双目三维重建的原理以及代码

    Evision双目视觉 关于双目视觉的一些总结 说明 前言 相机模型 标定 视差算法:立体匹配 测量,三维重建 示例程序 参考文献 关于双目视觉的一些总结 说明 如果读者对于本文或者Evision程序 ...

最新文章

  1. MVC框架内容-视图
  2. RiboFR-Seq:将16S rRNA与宏基因组连接的方法
  3. Ubuntu 循环显示登录界面
  4. java 贪吃蛇 控制台_控制台游戏贪吃蛇Java版
  5. pythonyaml参数_使用python检查yaml配置文件是否符合要求
  6. python创建一个有序链表_Python实现单向有序链表(Singly linked list)
  7. 软件测试必学之python+unittest+requests+HTMLRunner编写接口自动化测试集
  8. 计算机行业没有获奖证书简历怎么填,小升初没有奖项证书该如何写简历
  9. 在进行ISO14001认证审核之前,需要注意什么?
  10. [1007]魔法少女小Scarlet(洛谷 P4924)
  11. 小伙深夜加班骑车逆行了,被拦了,爆发了,下跪了,大哭了,压力真的好大!
  12. 计算机的电子邮件地址怎么看,电脑使用小技巧:如何找出网站上隐藏的电子邮件地址?...
  13. 制作旅行英语图书封面
  14. js 递归创建文件夹
  15. c语言中f5的作用,3G的AKA协议中F1至F5的UE端的实现(附代码C语言)
  16. 人工智能之python打卡学习100天计划-day11
  17. vue组件之this指向问题
  18. Simulink —— 三相交流控制系统中的坐标变换
  19. origin相关绘图操作
  20. TCP协议:SYN、ACK、ISN、SeqNumber

热门文章

  1. 关于程序多开的尝试。CreateMutex,OpenMuxtex,ReleaseMutex
  2. opencv Mat类
  3. 分计算iv值_机器学习-变量筛选之IV值和WOE
  4. vant 项目_如何搭建mpvue框架搭配vant组件库的小程序项目
  5. 单片机c语言编程300例_趣味c语言编程100例(四)
  6. python爬取天气_python3爬取各类天气信息
  7. 管道 过滤器风格 java_完成基于管道过滤器风格的KWI实现.doc
  8. 个人知识体系思维导图_高中数学知识点思维导图
  9. css电子商务管理_从毕业生的角度看电子商务专业
  10. css中的代码图标,认识CSS中字体图标(示例代码)