没有属性页的情况下动态更改过滤器值 [英] Dynamically change filter value without Property Page
问题描述
我只是写了一个简单的 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
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屋!