Im Grunde wollen Sie so etwas verbinden:
Source -> Sample Grabber -> Null renderer
Herunterladen GraphEdit oder GraphEdit + und Sie können visuell darstellen diese Filter. Als Beispiel habe ich ein Diagramm von meiner lokalen Webcam zu einem Sample-Grabber erstellt, der mit einem Null-Renderer verbunden ist. Das C# -Code erzeugt durch GraphEdit + ist dies:
//Don't forget to add reference to DirectShowLib in your project.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using DirectShowLib;
namespace graphcode
{
class Program
{
static void checkHR(int hr, string msg)
{
if (hr < 0)
{
Console.WriteLine(msg);
DsError.ThrowExceptionForHR(hr);
}
}
static void BuildGraph(IGraphBuilder pGraph)
{
int hr = 0;
//graph builder
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = pBuilder.SetFiltergraph(pGraph);
checkHR(hr, "Can't SetFiltergraph");
Guid CLSID_SampleGrabber = new Guid("{C1F400A0-3F08-11D3-9F0B-006008039E37}"); //qedit.dll
Guid CLSID_NullRenderer = new Guid("{C1F400A4-3F08-11D3-9F0B-006008039E37}"); //qedit.dll
//add Integrated Camera
IBaseFilter pIntegratedCamera = CreateFilter(@"@device:pnp:\\?\usb#vid_04f2&pid_b221&mi_00#7&34997cec&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global");
hr = pGraph.AddFilter(pIntegratedCamera, "Integrated Camera");
checkHR(hr, "Can't add Integrated Camera to graph");
//add SampleGrabber
IBaseFilter pSampleGrabber = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_SampleGrabber));
hr = pGraph.AddFilter(pSampleGrabber, "SampleGrabber");
checkHR(hr, "Can't add SampleGrabber to graph");
//add Null Renderer
IBaseFilter pNullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_NullRenderer));
hr = pGraph.AddFilter(pNullRenderer, "Null Renderer");
checkHR(hr, "Can't add Null Renderer to graph");
//connect Integrated Camera and SampleGrabber
hr = pGraph.ConnectDirect(GetPin(pIntegratedCamera, "Capture"), GetPin(pSampleGrabber, "Input"), null);
checkHR(hr, "Can't connect Integrated Camera and SampleGrabber");
//connect SampleGrabber and Null Renderer
hr = pGraph.ConnectDirect(GetPin(pSampleGrabber, "Output"), GetPin(pNullRenderer, "In"), null);
checkHR(hr, "Can't connect SampleGrabber and Null Renderer");
}
static void Main(string[] args)
{
try
{
IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
Console.WriteLine("Building graph...");
BuildGraph(graph);
Console.WriteLine("Running...");
IMediaControl mediaControl = (IMediaControl)graph;
IMediaEvent mediaEvent = (IMediaEvent)graph;
int hr = mediaControl.Run();
checkHR(hr, "Can't run the graph");
bool stop = false;
int n = 0;
while (!stop)
{
System.Threading.Thread.Sleep(500);
Console.Write(".");
EventCode ev;
IntPtr p1, p2;
if (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
{
if (ev == EventCode.Complete || ev == EventCode.UserAbort)
{
Console.WriteLine("Done!");
stop = true;
}
else
if (ev == EventCode.ErrorAbort)
{
Console.WriteLine("An error occured: HRESULT={0:X}", p1);
mediaControl.Stop();
stop = true;
}
mediaEvent.FreeEventParams(ev, p1, p2);
}
// stop after 10 seconds
n++;
if (n > 20)
{
Console.WriteLine("stopping..");
mediaControl.Stop();
stop = true;
}
}
}
catch (COMException ex)
{
Console.WriteLine("COM error: " + ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.ToString());
}
}
public static IBaseFilter CreateFilter(string displayName)
{
int hr = 0;
IBaseFilter filter = null;
IBindCtx bindCtx = null;
IMoniker moniker = null;
try
{
hr = CreateBindCtx(0, out bindCtx);
Marshal.ThrowExceptionForHR(hr);
int eaten;
hr = MkParseDisplayName(bindCtx, displayName, out eaten, out moniker);
Marshal.ThrowExceptionForHR(hr);
Guid guid = typeof(IBaseFilter).GUID;
object obj;
moniker.BindToObject(bindCtx, null, ref guid, out obj);
filter = (IBaseFilter)obj;
}
finally
{
if (bindCtx != null) Marshal.ReleaseComObject(bindCtx);
if (moniker != null) Marshal.ReleaseComObject(moniker);
}
return filter;
}
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
[DllImport("ole32.dll")]
public static extern int MkParseDisplayName(IBindCtx pcb, [MarshalAs(UnmanagedType.LPWStr)] string szUserName, out int pchEaten, out IMoniker ppmk);
static IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}
}
}
Sie würden immer noch brauchen, um das Sample Rahmen zu erfassen, sondern wie im Beitrag erwähnt wurde über Sie das sampleGrabber SDK auf MSDN aussehen in können um herauszufinden, wie man das macht.
möglich Duplikat von [Kann ich rohe Videorahmen von DirectShow ohne Wiedergabe erhalten] (http://stackoverflow.com/questions/8924355/can-i-get-raw-video-frames-from-directshow-witound-playback) – karlphillip
Ja, ich habe diesen Thread nicht gefunden, danke! – Nikita