zoukankan      html  css  js  c++  java
  • 3How to Register DirectShow Filters.

    3How to Register DirectShow Filters.
    Directshow的filter一般都注册在两个地方
    1 包含filter的DLL一般都注册为filter的COM 服务器,当用户调用CoCreateInstance来创建一个filter的时候,微软的COM库就从这个注册表的入口加载DLL。
    2 另外,filter可以注册到filter 种类里,这样,System Device Enumerator and the Filter Mapper就可以找到filter了。
    第二种注册不是必须的,只要filter注册成为com服务器,一个应用程序就可以创建一个filter 并将它加入到 filter Graph中,但是,如果你想要你的filter 可以被System Device Enumerator and the Filter Mapper发现,你必须注册到filter 种类里。
    Com服务器的入口注册有下列以些键值
    HKEY_CLASSES_ROOT
    CLSID
    Filter CLSID
    REG_SZ: (Default) = Friendly name

    InprocServer32
    REG_SZ: (Default) = File name of the DLL
    REG_SZ: ThreadingModel = Both
    注册成filter 种类里需要下面的键值
    HKEY_CLASSES_ROOT
    CLSID
    Category
    Instance
    Filter CLSID
    REG_SZ: CLSID = Filter CLSID
    REG_BINARY: FilterData = Filter information
    REG_SZ: FriendlyName = Friendly name
    Category is the GUID of a filter category.
    所有的filter信息在注册表的filter种类都如下所示
    HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11d0-BD50-00A0C911CE86}\Instance
    1 声明filter信息Declaring Filter Information
    第一步要声明filter的信息,directshow定义了如下的结构来声明filter ,pin和media Types
    Structure Description
    AMOVIESETUP_FILTER Describes a filter.
    AMOVIESETUP_PIN Describes a pin.
    AMOVIESETUP_MEDIATYPE Describes a media type.
    这些结构是必须的。
    AMOVEIESETUP_FILTER结构包含一个指针指向AMOVIESETUP_PIN结构数组,这两个结构中都有一个指针指向AMOVEIESETUP_MEDIATYPE。这些结构提供了足够的信息可以让IFilterMapper2指针找到filter 的位置。但是,这并不能完全描述一个filter,例如,如果一个filter创建了一个pin的多个实例,你只需要声明一个AMOVIESETUP_PIN结构即可。同样,一个filter 没有必须支持注册的所有的媒体类型,也没有必要注册所有的媒体类型。
    在你的DLL中声明一些全局的Set_up结构变量,如下
    static const WCHAR g_wszName[] = L"Some Filter";

    AMOVIESETUP_MEDIATYPE sudMediaTypes[] = {
    { &MEDIATYPE_Video, &MEDIASUBTYPE_RGB24 },
    { &MEDIATYPE_Video, &MEDIASUBTYPE_RGB32 },
    };

    AMOVIESETUP_PIN sudOutputPin = {
    L"", // Obsolete, not used.
    FALSE, // Is this pin rendered?
    TRUE, // Is it an output pin?
    FALSE, // Can the filter create zero instances?
    FALSE, // Does the filter create multiple instances?
    &GUID_NULL, // Obsolete.
    NULL, // Obsolete.
    2, // Number of media types.
    sudMediaTypes // Pointer to media types.
    };

    AMOVIESETUP_FILTER sudFilterReg = {
    &CLSID_SomeFilter, // Filter CLSID.
    g_wszName, // Filter name.
    MERIT_NORMAL, // Merit.
    1, // Number of pin types.
    &sudOutputPin // Pointer to pin information.
    };
    Filter的名字被声明成静态全局变量,因为它有可能在其它地方用到。
    2 声明类厂模板数组Declaring the Factory Template
    CFactoryTemplate g_Templates[] = {
    {
    g_wszName, // Name.上面定义的全局变量
    &CLSID_SomeFilter, // CLSID.
    CSomeFilter::CreateInstance, // Creation function.
    NULL,
    &sudFilterReg // Pointer to filter information.
    }
    };
    int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
    3生成DllRegisterServer
    最后一步是生成DllRegisterServer函数,包含组件的DLL必须导出这个函数,这个函数在安装的时候被调用,或者当用户运行Regsvr32.exe时调用到。
    简单的实现如下
    STDAPI DllRegisterServer(void)
    {
    return AMovieDllRegisterServer2(TRUE);
    }
    AMovieDllRegisterServer2对于g_Templates数组中的所有组件都创建注册表入口,但是这个函数有一些限制,第一,它将所有的filter都注册到"DirectShow Filters"类下(CLSID_LegacyAmFilterCategory),其实并非所有的filter都属于这个种类。例如,捕捉filter和压缩filter就有他们自己的种类,第二,如果你的filte支持一个硬件设备,你必须要注册额外的两个信息the medium and the pin category.,但是AMovieDLLRegisterServer2并不支持,pin 的种类定义了一个pin的函数方法。Mediums和硬件的驱动有关。
    如果你要注册filter的种类,medium或者pin的种类,你可以在DllRegisterServer()中调用IFilterMapper2::RegisterFilter,这个方法有个REGFILTER2结构,包含了filter的信息。
    为了支持复杂的情况,REGFILTER2结构支持两种不同格式pin的注册,dwVersion表示两种格式
    如果dwVersion为1,pin的类型就是AMOVIESETUP_PIN
    如果dwVersion为2,拼得类型就是REGFILTERPINS2.
    REGFILTERPINS2.结构中包含mediums和pin的categories
    下面的例子演示了,如何在DllRegistServer中调用IFilterMapper2::RegisterFilter
    REGFILTER2 rf2FilterReg = {
    1, // Version 1 (no pin mediums or pin category).
    MERIT_NORMAL, // Merit.
    1, // Number of pins.
    &sudPins // Pointer to pin information.
    };

    STDAPI DllRegisterServer(void)
    {
    HRESULT hr;
    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;
    }
    4filter注册指南
    Filter的注册信息决定了,在filter Graph管理器中如何Intelligent Connect.。因此,你必须要遵从下列的规则,使得你的filter能够正常运行。
    1 你是否需要在注册表中保存你的filter数据,对于许多filter来说,没有必要让filter Mapper和System Device Enumerator来发现你的filter,只要你注册了你的filter,你的应用程序通过
    ConCreateInstance方法来创建你的filter,此时,忽略了类厂模板中的AMOVIESETUP_FILTER结构,缺点是,在GraphEdit中看不到你的filter。
    2选择正确的filter 种类,缺省的Directshow Filters可能适用于大多数的filter,但是如果你的filter有特殊的用处,你要选择一个恰当的种类
    3避免在pin的AMOVIESETUP_MEDIATYPE结构中使用MEDIATYPE_None, MEDIASUBTYPE_None, or GUID_NULL,IFilterMapper2会将这些视做通配符。
    4下面是一些建议的最小******不明白
    Type of filter Recommended merit
    Default renderer MERIT_PREFERRED. For standard media types, however, a custom renderer should never be the default.
    Non-default renderer MERIT_DO_NOT_USE or MERIT_UNLIKELY
    Mux MERIT_DO_NOT_USE
    Decoder MERIT_NORMAL
    Spitter, parser MERIT_NORMAL or lower
    Special purpose filter; any filter that is created directly by the application MERIT_DO_NOT_USE
    Capture MERIT_DO_NOT_USE
    "Fallback" filter; for example, the Color Space Converter Filter
    MERIT_UNLIKELY

    5不要将接受24位RGB的filter注册到Directshow filter,你的filter将会干扰Color Space Converter filter.工作
    5 反注册
    为了反注册filter,
    要提供一个DllUnregisterServer方法,在这个方法中,调用AMovieDllRegisterServer2,注意传递参数,FASLE,如果你是使用IFilterMapper2::RegisterFilter注册的你的filter,那么你必须要用IFilterMapper2::UnregisterFilter方法来反注册你的filter。如下
    STDAPI DllUnregisterServer()
    {
    HRESULT hr;
    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;
    }

  • 相关阅读:
    JVM类加载(3)—初始化
    JVM类加载(1)—加载
    SQL笔记
    html5离线Web应用
    推荐3个很好的html5 网址
    HTML 5 File API应用实例
    异常与错误的区别
    html5Local Storage(本地存储)
    HTML5 js api 新的选择器
    5个HTML5 API
  • 原文地址:https://www.cnblogs.com/wqj1212/p/2443076.html
Copyright © 2011-2022 走看看