zoukankan      html  css  js  c++  java
  • 如何注册Filter 分类: DirectX 2014-09-22 17:31 415人阅读 评论(0) 收藏

    AX文件的一个对外接口DllRegisterServer,由外部调用,比如注册AX的时候:regsvr32 xxx.ax

           通常情况下,我们的filter可能注册在”Direct Show”目录下,那么直接调用
           // Creates registry entries for the DLL
    STDAPIDllRegisterServer()
    {
    return AMovieDllRegisterServer2(TRUE);
    }

    AMovieDllRegisterServer2在DX的帮助文档内的说明如下:
    The AMovieDllRegisterServer2 函数为g_Templates 数组中的每个组件创建注册入口. 然而这个函数有一些限制,

    首先,它给每个filter分配“DirectShow Filters”分类(CLSID_LegacyAmFilterCategory), 但是不是每个filter都属于这个分类. 比如Capture filters and compression filters,有他们自己的分类.

    第二,如果你的fitler支持一个硬件设备,你可能需要去注册两个增加AMovieDLLRegisterServer2 没有处理的信息pieces,: the medium and the pin category. A medium defines a method of communication in a hardware device, such as a bus. The pin category defines the function of a pin. For information on mediums, see KSPIN_MEDIUM in the Microsoft Windows Driver Development Kit (DDK). For a list of pin categories, see Pin Property Set.
          
    如果我们的引擎需要注册到DirectShow之外的目录,又该如何做?
     // 注册Filter到Video Compressor
    REGFILTER2 rf2FilterReg =
    {
        1,                                    // Version 1 (no pin mediums or pin category).
        MERIT_NORMAL,       // Merit.
        1,                                   // Number of pins.
        &sudPins                    // Pointer to pin information.
    };

    //为DLL创建注册入口
    STDAPI DllRegisterServer(void)
    {
        HRESULT hr = E_FAIL;
        IFilterMapper2 *pFM2 = NULL;

        hr = AMovieDllRegisterServer2(TRUE);                // 这个还是要调用的
        if (FAILED(hr))       return hr;
    hr = CoCreateInstance(CLSID_FilterMapper2, NULL,
                                               CLSCTX_INPROC_SERVER,
                                                         IID_IFilterMapper2, (void **)&pFM2);

        if (FAILED(hr))       return hr;

        hr = pFM2->RegisterFilter(CLSID_SomeFilter,                        // Filter CLSID.
                                                        g_wszName,                                   // Filter name.
                                                        NULL,                                               // Device moniker.
                                                       &CLSID_VideoCompressorCategory,           // Video compressor category.
                                                       g_wszName,                                   // Instance data.
                                                       &rf2FilterReg                                    // Pointer to filter information.
                                                       );
        pFM2->Release();
        return hr;
    }

    注销Filter
    注销DirectShow内的引擎
    // Removes registry entries for the DLL
    STDAPI DllUnregisterServer()
    {
    return AMovieDllRegisterServer2(FALSE);
    }

           注销指定目录下的引擎
           // 注销Video Compressor下的引擎
           // Removes registry entries for the DLL
    STDAPI DllUnregisterServer()
    {
        HRESULT hr = E_FAIL;
        IFilterMapper2* pFM2 = NULL;

        hr = AMovieDllRegisterServer2(FALSE);
        if (FAILED(hr))       return hr;

       hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
                                    IID_IFilterMapper2, (void **)&pFM2);
        if (FAILED(hr))       return hr;

        hr = pFM2->UnregisterFilter(&CLSID_VideoCompressorCategory,
                                                 g_wszName, CLSID_SomeFilter);

        pFM2->Release();
        return hr;
    }

    给Filter起个名字
    // Pin的type分为Major Type 和 Subtype
    // 比如,Major Type = Video, Subtype = MPEG-2
    const AMOVIESETUP_MEDIATYPE sudPinTypes =
    {
    &MEDIATYPE_NULL,            // Major type
    &MEDIASUBTYPE_NULL           // Subtype
    };

    const AMOVIESETUP_PIN psudPins[] =
    {
           // 定义Input Pin的信息
    {
    L"Input",                 // String pin name
    FALSE,             // Is it rendered
    FALSE,             // Is it an output
    FALSE,             // Allowed none
    FALSE,             // Allowed many
    &CLSID_NULL,        // Connects to filter
    0           // Connects to pin
    1,                  // Number of types
    &sudPinTypes
    },     // The pin details
    {
    L"Output",          // String pin name
    FALSE,              // Is it rendered
    TRUE,               // Is it an output
    FALSE,              // Allowed none
    FALSE,              // Allowed many
    &CLSID_NULL,        // Connects to filter
    0,          // Connects to pin
    1,                  // Number of types
    &sudPinTypes        // The pin details
           }
    };

    // Declare filter information
    const AMOVIESETUP_FILTER sudFilter =
    {
    &CLSID_MPKiller,       // Filter CLSID
    L"HQ MP Killer",        // Filter name
    0x8800000,                    // Its merit
    2,                      // Number of pins
    psudPins                      // Pin details
    };

    // declare a global array of CFactoryTemplate class instances, named g_Templates. Each
    // CFactoryTemplate class contains registry information for one filter. Several filters can
    // reside in a single DLL; simply include additional CFactoryTemplate entries. You can
    // also declare other COM objects, such as property pages
    // 在同一个DLL或者AX内,可以有多个引擎,比如系统目录下的quartz.dll。
    // 所以,如果有多个引擎,相应的数组的大小就是引擎的个数。
    CFactoryTemplateg_Templates[] =
    {
    {
    L"HQ MP Killer",
    &CLSID_MPKiller,
    CImplement::CreateInstance,
    NULL,
    &sudFilter
    }
    };

    int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);       // 有几个引擎

    允许Filter应用
    // CreateInstance 是CFactory的一个接口,在Filter内部实现它
    CUnknown* WINAPI CImplement::CreateInstance(    LPUNKNOWN pUnk,
                                                                                        HRESULT *pHr)
    {
        CImplement *pFilter = new CImplement ();
        if (!pFilter)
        {
            *pHr = E_OUTOFMEMORY;
        }
        return pFilter;
    }

    Filter的Merit
    Graph 会使用“傻子”机制联接不同的filter,这就要通过filter的merit值的高低进行“傻子”联接。

    该联接要使用IFilterMapper2::EnumMatchingFilters方法。
    Merit:
    enum
    {
        MERIT_PREFERRED     = 0x800000,
        MERIT_NORMAL        = 0x600000,
        MERIT_UNLIKELY      = 0x400000,
        MERIT_DO_NOT_USE    = 0x200000,
        MERIT_SW_COMPRESSOR = 0x100000,
        MERIT_HW_COMPRESSOR = 0x100050
    };
    <= MERIT_DO_NOT_USE的Merit的Filter,系统是不会去“傻子”联接的。当然Merit值可以是任意值,而不一定是枚举出来的。

    确定Filter的用途
    不同的Filter有不同的用途,可以选择不同的基类,实现不同的方法。详见DirectX 文档。Filter的种类,在内进行了详细的描述rootDirectShowDirectShow ReferenceConstants and GUIDsFilter Categories。

    添加属性页
    CFactoryTemplateg_Templates[2] =
    {
        {
                  g_wszArcIPCam,                       // Name
                  &CLSID_ArcIPCam,                  // CLSID
                  CArcIPCam::CreateInstance, // Method to create an instance of MyComponent
                  NULL,                                     // Initialization function
                  &sudArcIPCamSourceFilter      // Set-up information (for filters)
        },

           {
                         // 这些数据,为属性页准备
                  g_wszArcIPCamProperty,
                  &CLSID_ArcIPCamProperty,
                  CArcIPCamProperty::CreateInstance
           }
    };
         
    class CArcIPCam : public xxx, public IArcIPCam, public ISpecifyPropertyPages
    {
    private:
        // Constructor is private because you have to use CreateInstance
        CArcIPCam(IUnknown *pUnk, HRESULT *phr);
        ~CArcIPCam();

        CArcIPCamPin *m_pPin;

    public:
        static CUnknown * WINAPI CreateInstance(IUnknown *pUnk, HRESULT *phr);
        DECLARE_IUNKNOWN;

               // Property Page---
               STDMETHODIMP GetClassID(CLSID *pClsid);
        // Basic COM - used here to reveal our property interface.
        STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
        // return our property pages
        STDMETHODIMP GetPages(CAUUID * pPages);
    }
           这三个函数必须实现。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    玩转树莓派《二》——用python实现动画与多媒体
    pygame(一)
    玩转树莓派(一)
    pythonchallenge(七)
    springmvc定时器
    maven打包成第三方jar包且把pom依赖包打入进来
    mybatis之动态SQL
    黑马12期day01之html&css
    千万级数据表删除特定字断
    自动跳转
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706514.html
Copyright © 2011-2022 走看看