没有属性页的情况下动态更改过滤器值 [英] Dynamically change filter value without Property Page

查看:88
本文介绍了没有属性页的情况下动态更改过滤器值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just wrote a simple DirectShow Filter (which inherits from 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接口,用于在过滤器中设置变量,但是无法弄清楚如何使用它-访问它...

I defined a custom COM interface to set a variable in the filter but can not figure out how to use it -access it...

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) 然后在我的Filter C ++代码中实现interface

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

    }
    ...

}

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

iii) In my C# Code (using DirectShowNet)

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

I want to able to access my filter

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

filterControl->SetWillApplyFilter(true)

最后我修复它

接受yms的建议并使用链接中的提示:
有关自定义过滤器的一些建议

Take the advice of yms and use hints from the link : 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);
}


推荐答案

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

If you defined a COM interface to access your filter, all you need to do now is to declare the same interface (using the same GUIs) in C#/VB.Net or whatever .net language you are using. Then you can do a type cast of your filter to the new interface. Here is a C# example on how to declare such an interface:

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图创建过滤器,而应尝试使用枚举过滤器。
2-确认用于过滤器的踩踏模型是 Both。阅读此处此处以获取更多信息。

About the issue with E_NOINTERFACE during casting, it looks like a threading problem. 1- Creating your filter with Activator is not a good idea, you should always allow your DS graph to create your filters, try using "enumarate filters" instead. 2- Verify that the treading model you are using for your filter is "Both".Read here and here for some more information.

这篇关于没有属性页的情况下动态更改过滤器值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆