Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

c# - IBasicVideo CetCurrentImage catastrophic failure(DirectShow.NET)

I'm trying to grab image from webcam using DirectShow.NET and IBasicVideo CetCurrentImage. But I only get catastrophic failure on second call GetCurrentImage. What I'm doing particularly:

IBasicVideo bv = (IBasicVideo)graph;
IntPtr bvp = new IntPtr();
int size = 0;
int hr = bv.GetCurrentImage(ref size, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
bvp = Marshal.AllocCoTaskMem(size);
hr = bv.GetCurrentImage(ref size, bvp);
DsError.ThrowExceptionForHR(hr);
Bitmap image = new Bitmap(480, 320, 480 * (24 / 8), System.Drawing.Imaging.PixelFormat.Format24bppRgb, bvp);
image.Save(path);

What am I doing wrong?

Prety much all I have:

IGraphBuilder graph = null;
IMediaEventEx eventEx = null;
IMediaControl control = null;
ICaptureGraphBuilder2 capture = null;
IBaseFilter srcFilter = null;
public IVideoWindow videoWindow = null;
IntPtr videoWindowHandle = IntPtr.Zero;

public void GetPreviewFromCam()
{
    graph = (IGraphBuilder)(new FilterGraph());
    capture = (ICaptureGraphBuilder2)(new CaptureGraphBuilder2());
    eventEx = (IMediaEventEx)graph;
    control = (IMediaControl)graph;
    videoWindow = (IVideoWindow)graph;
    videoWindowHandle = hVideoWindow;
    eventEx.SetNotifyWindow(hVideoWindow, WM_GRAPHNOTIFY, IntPtr.Zero);

    int hr;

    // Attach the filter graph to the capture graph
    hr = capture.SetFiltergraph(graph);
    DsError.ThrowExceptionForHR(hr);

    // Find capture device and bind it to srcFilter
    FindCaptureDevice();

    // Add Capture filter to our graph.
    hr = graph.AddFilter(srcFilter, "Video Capture");
    DsError.ThrowExceptionForHR(hr);

    // Render the preview pin on the video capture filter
    // Use this instead of graph->RenderFile
    hr = capture.RenderStream(PinCategory.Preview, MediaType.Video, srcFilter, null, null);
    DsError.ThrowExceptionForHR(hr);

    hr = control.Run();
    DsError.ThrowExceptionForHR(hr);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

IBasicVideo::GetCurrentImage does not have to unconditionally succeed. What it does is forwarding of the call to video renderer in your graph (fails if you don't have one, or you have a weird non-renderer filter which unexpectedly implements the interface), then the renderer would attempt to get you the image. The renderer might fail if it is operating in incompatible mode (windowless video renderers don't have IBasicVideo - might fail here), or the renderer yet did not receive any video frame to have a copy delivered to you, that is the call is premature.

Additionally, there might be a handful of other issues related to obvious bugs - you did not put the graph into active mode, you are under wrong impression about topology you are having, you are using wrong interface, your code has threading issues etc.

With a specter of possibly causes this wide, start with a simple question: at the time of the call, do you have the video frame already presented to you visually?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...