动态更改过滤器值而不使用“属性页”

时间:2011-05-18 08:07:04

标签: directshow directshow.net

我刚写了一个简单的 DirectShow过滤器(继承自CTransformFilter)。

But I want to be able to set a variable of my filter dynamically. 
This can be done today using Property Page. 
But what i want is change this property programatically. 

我定义了一个自定义 COM接口来设置过滤器中的变量,但无法弄清楚如何使用它 - 访问它...

How to set a DirectShow filter's properties value without open the 
filter's property page ?

有人有想法吗?

更多详情:

好吧

i) 我刚刚定义的简单界面

DEFINE_GUID(IID_IApplyFilterControl,  X, X, X, X, X, X, X, X, X, X, X);


interface IApplyFilterControl : public IUnknown
{
    STDMETHOD(SetWillApplyFilterX)(bool applyFilter) = 0;
};

ii) 然后在我的过滤器C ++代码中实现此接口

class MyFilter : public CTransformFilter , public IApplyFilterControl 
{
    ....
    STDMETHODIMP SetWillApplyFilter(bool apply)
    {
        CAutoLock lock(&m_csShared);
        willApplyFilter = apply;
        return S_OK;

    }
    ...

}

iii)在我的C#代码中(使用DirectShowNet)

我希望能够访问我的过滤器

IBaseFilter myFilter = 
(IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(myFilterGuid));
....
IApplyFilterControl filterControl = (IApplyFilterControl ) myFilter;
.....

filterControl->SetWillApplyFilter(true)

最后我修复了

接受yms的建议并使用链接中的提示: Some advices about custom filters

来源: http://social.msdn.microsoft.com/Forums/en-US/windowsdirectshowdevelopment/thread/e02aa741-776c-42cf-869f-640747e197e4

i)您的COM接口

// The GUID that identifies your interface
// {13F23FD9-A90C-480d-A597-F46BA20070AC}

static const GUID IIDTransformFilterControl =

{
      0x13f23fd9, 0xa90c, 0x480d, { 0xa5, 0x97, 0xf4, 0x6b, 0xa2, 0x0, 0x70, 0xac }
};

DECLARE_INTERFACE_(ITransformFilterControl, IUnknown)

{
    STDMETHOD(setGreyscale)(bool enable) = 0;
};

ii)您的转换过滤器

class YourTransformFilter : 
public CTransformFilter, public ITransformFilterControl

{
    public:
    STDMETHODIMP    NonDelegatingQueryInterface(REFIID riid, void **ppv);
    STDMETHODIMP    setGreyscale(bool enable);
};

...

STDMETHODIMP  YourTransformFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)

{
    CheckPointer(ppv, E_POINTER);

    if(riid==IIDTransformFilterControl)   
      return GetInterface((ITransformFilterControl*) this, ppv);

    return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}

STDMETHODIMP  YourTransformFilter:: setGreyscale(bool enable)

{
    bGreyscale    = enable;
    return S_OK;
}

iii)最后在您的C#主机应用程序中定义COM接口

[ComImport, System.Security.SuppressUnmanagedCodeSecurity, 
Guid("13F23FD9-A90C-480d-A597-F46BA20070AC"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

public interface ITransformControl

{
        [PreserveSig]
        int setGreyscale(bool enable);
}

iv)并使用您的C#代码

ITransformFilterControl transformControl = 
     yourFilterInstance as ITransformFilterControl;

if(transformControl!=null)

{
    transformControl->setGreyscale(true);
}

1 个答案:

答案 0 :(得分:0)

如果您定义了一个COM接口来访问您的过滤器,那么您现在需要做的就是在C#/ VB.Net或您正在使用的任何.net语言中声明相同的接口(使用相同的GUI)。然后,您可以对新界面进行过滤器的类型转换。这是一个关于如何声明这样一个接口的C#示例:

using System.Runtime.InteropServices;

// Declare IMediaControl as a COM interface which 
// derives from the IDispatch interface. 
[Guid("56A868B1-0AD4-11CE-B03A-0020AF0BA770"),
    InterfaceType(ComInterfaceType.InterfaceIsDual)] 
interface IMediaControl // cannot list any base interfaces here 
{ 
    // Note that the members of IUnknown and Interface are NOT
    // listed here 
    //
    void Run();

    void Pause();

    void Stop();

    void GetState( [In] int msTimeout, [Out] out int pfs);

    void RenderFile(
    [In, MarshalAs(UnmanagedType.BStr)] string strFilename);

    void AddSourceFilter(
    [In, MarshalAs(UnmanagedType.BStr)] string strFilename, 
    [Out, MarshalAs(UnmanagedType.Interface)] out object ppUnk);

    [return : MarshalAs(UnmanagedType.Interface)]
    object FilterCollection();

    [return : MarshalAs(UnmanagedType.Interface)]
    object RegFilterCollection();

    void StopWhenReady(); 
}

修改

关于在投射期间E_NOINTERFACE的问题,它看起来像是一个线程问题。 1-使用Activator创建过滤器不是一个好主意,您应该始终允许DS图形创建过滤器,尝试使用“enumarate filters”。 2-确认您用于过滤器的趋势模型是“两者”。阅读herehere以获取更多信息。