I'm trying to apply filter such as contrast, color change, brightness on every frame of a .avi video.
The video is playing just fine with directshow.net and c#.
after a couple hours of research, I found out that buffercb was not the way to go to do the job.
Apparantly, EZrgb24 is a filter I can add to my graph that does exactly what I want.
However, I can't get it to work.
[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
}
I found out that the int value returned in hr1, is the hexadecimal value for dll not registred. Which means to me that EZRGB is not registred on my computer.
Found and downloaded EZRGB.ax on some obscure web site.
executed the command : cd \windows\syswow64 regsvr32 c:\ezrgb24.ax
A message box appeared with DllRegisterServer in c:\ezrgb24.ax succeeded.
Still doesn't work.
I am using directshow.net, however, this is also tagged both directshow as I feel the solution will work for either c# or c++.
SampleCB
instead of BufferCB
; the former provides you access to data which is streamed further, so you can modify itCLSCTX_ALL
or CLSCTX_INPROC_SERVER