我正在尝试在.avi视频的每一帧上应用滤镜,例如对比度,颜色变化,亮度。
使用directshow.net和c#播放视频时很好。
经过几个小时的研究,我发现buffercb不适合做这项工作。显然,EZrgb24是我可以添加到我的图表中的过滤器,它完全符合我的要求。
然而,我无法让它发挥作用。
[DllImport("ole32.dll", EntryPoint = "CoCreateInstance", CallingConvention = CallingConvention.StdCall)]
static extern UInt32 CoCreateInstance([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
IntPtr pUnkOuter, UInt32 dwClsContext, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid,
[MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);
int hr = 0;
IBaseFilter ibfRenderer = null;
ISampleGrabber sampGrabber = null;
IBaseFilter capFilter = null;
IPin iPinInFilter = null;
IPin iPinOutFilter = null;
IPin iPinInDest = null;
Type comType = null;
object comObj = null;
m_FilterGraph = new FilterGraph() as IFilterGraph2;
try
{
// Get the SampleGrabber interface
sampGrabber = new SampleGrabber() as ISampleGrabber;
// Add the video source
hr = m_FilterGraph.AddSourceFilter(_videoPath, "Ds.NET FileFilter", out capFilter);
DsError.ThrowExceptionForHR(hr);
// Hopefully this will be the video pin
IPin iPinOutSource = DsFindPin.ByDirection(capFilter, PinDirection.Output, 0);
IBaseFilter baseGrabFlt = sampGrabber as IBaseFilter;
ConfigureSampleGrabber(sampGrabber);
iPinInFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Input, 0);
iPinOutFilter = DsFindPin.ByDirection(baseGrabFlt, PinDirection.Output, 0);
// Add the frame grabber to the graph
hr = m_FilterGraph.AddFilter(baseGrabFlt, "Ds.NET Grabber");
DsError.ThrowExceptionForHR(hr);
hr = m_FilterGraph.Connect(iPinOutSource, iPinInFilter);
DsError.ThrowExceptionForHR(hr);
// Get the default video renderer
ibfRenderer = (IBaseFilter)new VideoRendererDefault();
// Add it to the graph
hr = m_FilterGraph.AddFilter(ibfRenderer, "Ds.NET VideoRendererDefault");
DsError.ThrowExceptionForHR(hr);
iPinInDest = DsFindPin.ByDirection(ibfRenderer, PinDirection.Input, 0);
// Connect the graph. Many other filters automatically get added here
hr = m_FilterGraph.Connect(iPinOutFilter, iPinInDest);
DsError.ThrowExceptionForHR(hr);
SaveSizeInfo(sampGrabber);
HERE WE WANT TO ADD THE EZRGB FILTER.
/*
// { 8B498501-1218-11cf-ADC4-00A0D100041B }
DEFINE_GUID(CLSID_EZrgb24,
0x8b498501, 0x1218, 0x11cf, 0xad, 0xc4, 0x0, 0xa0, 0xd1, 0x0, 0x4, 0x1b);
*/
unsafe
{
Guid IUnknownGuid = new Guid("00000000-0000-0000-C000-000000000046"); //Can it be written in more pretty style?
Guid ezrgbclsid = new Guid(0x8b498501, 0x1218, 0x11cf, 0xad, 0xc4, 0x0, 0xa0, 0xd1, 0x0, 0x4, 0x1b);
uint hr1 = CoCreateInstance(ezrgbclsid, IntPtr.Zero, (uint)(CLSCTX.CLSCTX_INPROC_HANDLER), ezrgbclsid, out x);//CLSCTX_LOCAL_SERVER
IIPEffect myEffect = (IIPEffect)x;// as IIPEffect;
if (hr1 != 0)
{
int iError = Marshal.GetLastWin32Error();
Console.Write("CoCreateInstance Error = {0}, LastWin32Error = {1}", hr1, iError);
}
myEffect.put_IPEffect(1004, 0, 100); //for this filter, look at resource.h for what the int should be, in this case 1002 is the emboss effect
}
我发现hr1中返回的int值是dll未注册的十六进制值。 这对我来说意味着EZRGB没有在我的电脑上注册。
在一些不起眼的网站上找到并下载了EZRGB.ax。
执行命令: cd \ windows \ syswow64 regsvr32 c:\ ezrgb24.ax
在c:\ ezrgb24.ax中,DllRegisterServer出现了一个消息框。
仍然无效。
我正在使用directshow.net,但是,这也被标记为directshow,因为我觉得该解决方案适用于c#或c ++。
答案 0 :(得分:2)
SampleCB
代替BufferCB
;前者允许您访问进一步流式传输的数据,因此您可以对其进行修改CLSCTX_ALL
或CLSCTX_INPROC_SERVER