Menu

View and capture webcam input

2009-11-20
2012-10-29
  • Sebastian-Nicolae Matei

    Hello,

    I started working with the InfTee to preview and capture the input of a
    webcam. Somehow I didn't manage getting it to work.
    This is what I have up to now:

    private IBaseFilter FindCaptureDevice()
    {
    UCOMIEnumMoniker classEnum = null;
    UCOMIMoniker moniker = new UCOMIMoniker;
    object source = null;
    ICreateDevEnum devEnum = (ICreateDevEnum)(new CreateDevEnum());
    int hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out
    classEnum, CDef.None);
    DsError.ThrowExceptionForHR(hr);
    Marshal.ReleaseComObject(devEnum);

    if (classEnum == null)
    {
    throw new ApplicationException("No video capture device was
    detected.\r\n\r\n" + "This sample requires a video capture device, such as
    a USB WebCam,\r\nto be installed and working properly. The sample will now
    close.");
    }

    int none = 0;

    if (classEnum.Next(moniker.Length, moniker, out none) == 0)
    {
    Guid iid = typeof(IBaseFilter).GUID;
    moniker.BindToObject(null, null, ref iid, out source);
    }
    else
    {
    throw new ApplicationException("Unable to access video capture device!");
    }

    Marshal.ReleaseComObject(moniker);
    Marshal.ReleaseComObject(classEnum);

    return (IBaseFilter)source;
    }
    The function posted above gives me the webcam I use for input. Then I want to
    start previewing and save the file to harddisk by calling CaptureVideo()

    private void CaptureVideo()
    {
    int hr = 0;
    IBaseFilter sourceFilter = null;
    try
    {
    sourceFilter = FindCaptureDevice();
    this.graphBuilder = (IGraphBuilder)(new FilterGraph());
    this.captureGraphBuilder = (ICaptureGraphBuilder2)(new
    CaptureGraphBuilder2());
    this.mediaControl = (IMediaControl)this.graphBuilder;
    this.videoWindow = (IVideoWindow)this.graphBuilder;
    this.mediaEventEx = (IMediaEventEx)this.graphBuilder;

    graphBuilder.AddFilter((IBaseFilter)tee, "Tee");

    IPin teeInput = DsFindPin.ByDirection((IBaseFilter)tee, PinDirection.Input,
    0);
    IPin vidOutput = DsFindPin.ByDirection(sourceFilter, PinDirection.Output, 0);

    hr = graphBuilder.Connect(vidOutput, teeInput);
    DsError.ThrowExceptionForHR(hr);

    hr = this.mediaEventEx.SetNotifyWindow(this.Handle, WM_GRAPHNOTIFY,
    IntPtr.Zero);

    DsError.ThrowExceptionForHR(hr);
    bool enregistrerLaVideo = false;
    IPin teeOutput2 = DsFindPin.ByDirection((IBaseFilter)tee, PinDirection.Output,
    0);
    IBaseFilter MultiplexerF;
    IFileSinkFilter FileSinkWriter;

    string sFileName = "D:/result.avi";
    hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, sFileName, out
    MultiplexerF, out FileSinkWriter);
    DsError.ThrowExceptionForHR(hr);

    if (enregistrerLaVideo)
    {
    hr = captureGraphBuilder.RenderStream(null, MediaType.Video, teeOutput2, null,
    MultiplexerF);
    DsError.ThrowExceptionForHR(hr);
    }

    hr = this.captureGraphBuilder.SetFiltergraph(this.graphBuilder);
    DsError.ThrowExceptionForHR(hr);

    IVideoWindow videoWindow = captureGraphBuilder as IVideoWindow;
    hr = videoWindow.put_Owner(this.Handle);
    DsError.ThrowExceptionForHR(hr);

    hr = videoWindow.put_WindowStyle(WindowStyle.Child |
    WindowStyle.ClipChildren);
    DsError.ThrowExceptionForHR(hr);

    hr = videoWindow.put_Visible(OABool.True);
    DsError.ThrowExceptionForHR(hr);
    }
    catch (Exception ex)
    {
    MessageBox.Show("An unrecoverable error has occurred.\r\n" + ex.ToString());
    }
    }

    The problem is, that I get an exception with the code 0x8004025F when I want
    the graphBuilder to connect teeInput with vidOutput.

    Why?

    Greetings,
    Sebastian.

     
  • Drew

    Drew - 2009-11-25

    Have you looked at the DXWebCam sample? This shows how to do what you are
    doing as well as a samplegrabber for the video.

     
  • Sebastian-Nicolae Matei

    Hello,

    I compiled that example right now, but do not get it running. If I enter
    LOCALHOST as server name or the name of the computer hosting the webcam, I
    get: "No connection possible. Connection was refused by target system."
    (Translated from the german error message I get).

     
  • Drew

    Drew - 2009-11-25

    I think from memory that you need to run the server app from the exe and then
    the client app from ide.

    Though, isn't the samplegrabber capture part the main bit your after?

     
  • Drew

    Drew - 2009-11-25

    Sorry the other way around. just tested by compiling and running the server.
    then running the client exe. I only put the ip address of my machine.

     
  • Sebastian-Nicolae Matei

    If I try running the service by calling WebCamService.exe as admin I get the
    error that the service cannot run and needs to be installed first. If I set
    the WebCamService-2005 as startup project, it compiles and exits immediately.
    Hmm...

     
  • Drew

    Drew - 2009-11-25

    The service is just that. it runs in the background and captures frames from
    your webcam. the client just receives the packets and shows them as jpegs. Run
    the service from your compile/run and the client from the exe.

     
  • Sebastian-Nicolae Matei

    That's what I did, but like I said before, the compiler stops immediately
    after having compiled the project and enters back to the development
    environment.

     
  • Drew

    Drew - 2009-11-25

    Mmm.

    Maybe try to add a breakpoint where it looks for your cam device. Might be
    something there not finding your cam. If you add breakpoints all the way down
    the buildgraph, you might see where it's falling over.

     
  • Sebastian-Nicolae Matei

    I will try that. Are you sure I do not need to register it as a service if I
    want to run it by calling the .exe?

     
  • snarfle

    snarfle - 2009-11-25

    Sounds like a firewall problem? Also, try using the machine's actual IP
    address instead of using localhost.

     

Log in to post a comment.

Auth0 Logo