学习写DSHOW 框架下的FILTER 之一

时间:8:30 2011-1-4

8:30 --- 9:00
总结与计划

学习怎么样来编写FILTER.

    要从全局的角度思考,以业务流程为具体的执行纲要.

[ DSHOW与FILETR 之间的关系]
    时间:9:44 -- 10:30
在WINDOWS平台上,其在进行多媒体处理的时候,其一般使用DSHOW 框架.

DSHOW框架其的特点:
    简单易用,方便灵活.

对于 使用DSHOW的用户:
    其只要面向DSHOW的FilterGraph, 就可以,

对于 使用FILTER的用户: [ FILTER 的初始业务流程]
准备:
    创建一个DLL性质的工程.因为DSHOW其是管理FILTER的,以FILTER为单位的.在编写实现的时候,FILTER其是以DLL的形式实现的, 因为DSHOW其只是一个工具,其    是APP的来调用使用.其以DLL的形式加载到APP的进程空间当中.

中间:
    0. 确定此FILTER的性质:( source filter, translate filter, render filter)
    1. 确定此FILTER的操作接口.
    1_1. 此FILTER其可能要继承DSHOW FILTER的接口.
    2. 编写此FILTER的类.
    3. 此FILTER的类其接口用户自定义的此FILTER接口,继承DSHOW FILTER的相关接口类

实现:
    4. 此FILTER类,我们只要实现自定义接口就可以,自定义接口当中的实现DSHOW接口,其已经由FILTER类继承的DSHOW FILTER类实现,这就是为什么此FILTER类要继承DSHOW 类.

后期:
    使用工具将此FILTER的信息注册到注册表当中.

实施:
    用户的APP其通过DSHOW的FILTER GRAPHER MANAGER来管理,对于用户而言其只是知道 有这样一个功能的FILTER,与此FILTER的接口与接口的IID_IXXX,FILTER 的CLSID.

注意的问题:
    中间部分的问题:
1. 自己写的FILTER接口,其是要继承哪些DSHOW FILTER接口

2. 自己写的FILTER类,其是要继承哪些DSHOW FITER 类.

    实现部分的问题:
1. 其在实现的时候,其是怎么样操作硬件的.

2. 此FILTER其是怎么样与FILTER GRAPH 当中的FILTER进行的通信联系的呢.按 FILTER GRAPH MANAGER当中的三种FILTER( SOURCE ,TARNSLATE , RENDER) 来讨论:
    SOURCE FTLTER:
其是提供数据源,
    APP用户所感兴趣: 怎么样设置数据源,与对于数据进行初步处理.
    FILTER编写人员:
        1. SOURCE FILTER其来源: 本地文件,网络,直接地从硬件当中读取.
        2. 来源不同其的实现代码也不同. --> [ 自定义的]
        3. source filter 其是怎么样与 translate filter 之间进行的通信
            这是属于DSHOW框架的部分,其应该由DSHOW 提供实现的部分.用户自定义的FILTER 只要使用DSHOW的            此部分接口就可以.
    Translate filter
其是对于数据的中间加工:
    如: 数据进行格式转换,数字图像处理( 其也可以在RENDER FILTER当中进行)

    APP用户所感兴趣:
        1. 其只要设置,对于数据进行什么样的加工处理.( 甚至对于APP用户而言是看不见此FILTER的)
    FILTER编写人员:
        1. 其是怎么样接收来自source filter 当中的数据.( 应该由MS的DSHOW框架实现提供,用户只要使用接口)
        2. 对于数据进行加工处理 ( 自定义的)
        3. 将数据传递给RENDER FILTER,(  应该由MS的DSHOW框架实现提供,用户只要使用接口)
    RENDER FILTER
其是对于数据进行最终的处理:
    如: 显示,保存
    APP用户所感兴趣:
        1. 设置是否保存.保存的路径.
        2. 显示在窗口当中.
    FILTER 编写人员:
        1. 其是怎么要样接收TRANSLATE FILTER的数据, [ 应该由MS的DSHOW框架实现提供)
        2. 显示还是保存,其均要与硬件打交道,    [ 自定义]

[ 突感]
    FILTER其是以FILTER为单位来进行的组合管理,而FILTER之间是以PIN来进行, PIN其要负责数据的接收与发送.
自己写的类,想要成为一个FILTER其就必须继承FILTER的类,其才就具有FILTER的性质.
FILTER其要和外界通信,其还要实现PIN, 其是怎么样来实现PIN的呢.
    1. PIN其只是接口,对于PIN的实现,MS提供了一部分,
    2. PIN其只是接口,对于PIN的实现,用户自定义实现

在上面的FILTER 当中,我们只要在DSHOW框架当中,写自己的FILTER当中的自定义部分就可以.

[ FILTER的编写流程]
    14: 39 --- 14 58
总的思路:
    0. 总编写FILTER的业务流程
    1. 从PC版本上看FILTER的编写流程
    2. 从WINCE上看FILTER的编写流程.

首先看WINCE 6.0 MS 自已提供的DEMO

要求:
    0. 编写业务流程 以上面的 [ FILTER 的初始业务流程] 为指导.
    1. 每15 分钟一个反馈
第一个反馈:
    时间: 14:46 --- 15:01
1. [ FILTER 的初始业务流程] 与DEMO的比较,
2. 具体完成 准备与中间部分   

结果:
准备阶段的结果:
    1. 此FILTER其是属于RENDER FILTER 性质
    2. 此FILER的功能描述
中间阶段的结果:
    1. 其 是属于RENDER FILTER 性质
    2.RENDER FILTER: 其是要求继承哪些类,哪些接口,
反馈:15:39
问题:
     在编译MS自带的FILTER的时候,其能够编译通过,但不能连接通过

分析:
    其应该是少了一个相应的LIB文件. DUMP 其使用了DSHOW的基本类库:
    CBaseFilter,CRenderedInputPin, IFileSinkFilter,CUnknown
    而上面这些类其是在 strmbase.lib 当中. [ 这种说话其应该是错误的], 因为 我觉得
     DirectShow base classes 其只是包括 GRAPH FILTER MANAGER的控制部分.
    而用户自定义写FILTER所继承的类,其应该是由另一个类来提供,
    但当看到
    When you build your run-time image, Strmbase.lib is generated from the publicly available source code located at
    %_WINCEROOT%\Public\DirectX\Sdk\Samples\Dshow\Baseclasses.
    觉得strmbase.lib其已经包含DSHOW所有类的实现.

    CBaseFilter 其类的实现,应该是在   

1>dump.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl CBaseFilter::CBaseFilter(wchar_t const *,struct IUnknown *,class CCritSec *,struct _GUID const &)" (??0CBaseFilter@@QAA@PB_WPAUIUnknown@@PAVCCritSec@@ABU_GUID@@@Z),该符号在函数 "public: __cdecl CDumpFilter::CDumpFilter(class CDump *,struct IUnknown *,class CCritSec *,long *)" (??0CDumpFilter@@QAA@PAVCDump@@PAUIUnknown@@PAVCCritSec@@PAJ@Z) 中被引用
1>dump.obj : error LNK2001: 无法解析的外部符号 "public: virtual unsigned long __cdecl CBaseFilter::NonDelegatingRelease(void)" (?NonDelegatingRelease@CBaseFilter@@UAAKXZ)
1>dump.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CBaseFilter::FindPin(wchar_t const *,struct IPin * *)" (?FindPin@CBaseFilter@@UAAJPB_WPAPAUIPin@@@Z)
1>dump.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CBaseFilter::JoinFilterGraph(struct IFilterGraph *,wchar_t const *)" (?JoinFilterGraph@CBaseFilter@@UAAJPAUIFilterGraph@@PB_W@Z)
1>dump.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CBaseFilter::QueryVendorInfo(wchar_t * *)" (?QueryVendorInfo@CBaseFilter@@UAAJPAPA_W@Z)
1>dump.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl CRenderedInputPin::CRenderedInputPin(wchar_t *,class CBaseFilter *,class CCritSec *,long *,wchar_t const *)" (??0CRenderedInputPin@@QAA@PA_WPAVCBaseFilter@@PAVCCritSec@@PAJPB_W@Z),该符号在函数 "public: __cdecl CDumpInputPin::CDumpInputPin(class CDump *,struct IUnknown *,class CBaseFilter *,class CCritSec *,class CCritSec *,long *)" (??0CDumpInputPin@@QAA@PAVCDump@@PAUIUnknown@@PAVCBaseFilter@@PAVCCritSec@@3PAJ@Z) 中被引用
1>dump.obj : error LNK2001: 无法解析的外部符号 "public: virtual long __cdecl CBasePin::QueryId(wchar_t * *)" (?QueryId@CBasePin@@UAAJPAPA_W@Z)
1>dump.obj : error LNK2019: 无法解析的外部符号 "void __cdecl DbgLogInfo(unsigned long,unsigned long,wchar_t const *,...)" (?DbgLogInfo@@YAXKKPB_WZZ),该符号在函数 "public: virtual long __cdecl CDumpInputPin::Receive(struct IMediaSample *)" (?Receive@CDumpInputPin@@UAAJPAUIMediaSample@@@Z) 中被引用
1>dump.obj : error LNK2001: 无法解析的外部符号 dpCurSettings
1>dump.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl CUnknown::CUnknown(wchar_t const *,struct IUnknown *)" (??0CUnknown@@QAA@PB_WPAUIUnknown@@@Z),该符号在函数 "public: __cdecl CDump::CDump(struct IUnknown *,long *)" (??0CDump@@QAA@PAUIUnknown@@PAJ@Z) 中被引用
1>dump.obj : error LNK2019: 无法解析的外部符号 "public: __cdecl CPosPassThru::CPosPassThru(wchar_t const *,struct IUnknown *,long *,struct IPin *)" (??0CPosPassThru@@QAA@PB_WPAUIUnknown@@PAJPAUIPin@@@Z),该符号在函数 "private: virtual long __cdecl CDump::NonDelegatingQueryInterface(struct _GUID const &,void * *)" (?NonDelegatingQueryInterface@CDump@@EAAJABU_GUID@@PAPAX@Z) 中被引用
1>806s (ARMV4I)\Debug/DumpRenderFilter.dll : fatal error LNK1120: 11 个无法解析的外部命令

http://topic.csdn.net/u/20090829/01/d8985122-9e16-41ea-96ae-a4c13c00e8a9.html

[2] 在WINCE平台上,使用PB来编译DSHOW的BASECLASSES.
http://www.armce.com/bbs/viewthread.php?tid=659&page=1#pid6490

反馈: 19:01
之前一直在解法上面的连接问题,其早已经找出了问题的原则,但我们要分清楚问题的本质.
现在需要解决的问题与现所遇到的问题.之间要进行平抑处理.

==>已经解决了上面的问题,
在WINCE 上编写自己的FILTER的时候,最好是重新的编译一个BASECLASSED,
DSHOW其是独立于硬件的,所以PC机上DSHOW资料也可以用在WINCE上

http://blog.csdn.net/SuperKan/archive/2008/02/14/2095638.aspx
请教wince5 下开发filter的流程
http://topic.csdn.net/u/20080607/13/3eb0ef0e-1f2c-44ac-9189-f02dad9a8cf3.html

参考Page
[1]
http://msdn.microsoft.com/en-us/library/aa451221.aspx

参考Page
[1]
http://msdn.microsoft.com/en-us/library/dd388553(VS.85).aspx

[ 在DSHOW当中,播放文件不使用RenderFile(),而是自己创建]
    在播放视频的时候,自己组建的FILTER GRAPH MANAGER其是怎么样播放视频文件的.

1. 创建FILTER GRAPH MANAGER
2. 创建各种FILTER ( 其当中的SOURCER FILTER其应该实现 IFileSourceFilter接口)
3. 通过 graph builder来按规则(具体的应用而定的) 连接各个FILTER
4. 通过 SOURCE FILTER 来查找 IFileSourceFilter接口.
5. 通过 IFileSourceFilter::Load() 来加载文件.

6.通过IID_IMediaControl::Run()来运行程序或其它方法来控制播放

参考PAGE:
[1]
http://www.cnblogs.com/justin/archive/2005/04/29/147409.html
[2]
http://msdn.microsoft.com/en-us/library/dd389981(v=vs.85).aspx
[3]
http://msdn.microsoft.com/en-us/library/aa916593.aspx

原文地址:https://www.cnblogs.com/pengxinglove/p/1926716.html