3

I'm working on Visual Studio 2012 and using C#, I'm using the library DirectShowLib to take pictures from my webcam, but I can only take one picture, if I try to take another one I get an exception:

   DirectShowLib.DsError.ThrowExceptionForHR(Int32 hr)
   at SnapShot.Capture.SetupGraph(DsDevice dev, Int32 iWidth, Int32 iHeight, Int16 iBPP, Control hControl) in c:\Users\devel_000\Documents\Visual Studio 2012\Projects\ControlAcceso\ControlAcceso\Capture.cs:line 323
   at SnapShot.Capture..ctor(Int32 iDeviceNum, Int32 iWidth, Int32 iHeight, Int16 iBPP, Control hControl) in c:\Users\devel_000\Documents\Visual Studio 2012\Projects\ControlAcceso\ControlAcceso\Capture.cs:line 86
   at ControlAcceso.PhotoWindow..ctor() in c:\Users\devel_000\Documents\Visual Studio 2012\Projects\ControlAcceso\ControlAcceso\PhotoWindow.cs:line 32
   at ControlAcceso.CheckWindow.pbPhoto_Click(Object sender, EventArgs e) in c:\Users\devel_000\Documents\Visual Studio 2012\Projects\ControlAcceso\ControlAcceso\CheckWindow.cs:line 108
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at ControlAcceso.Program.Main() in c:\Users\devel_000\Documents\Visual Studio 2012\Projects\ControlAcceso\ControlAcceso\Program.cs:line 18
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

I'm using the DxSnap example [link] to take the pictures. the exception is thrown in the method SetupGraph [link]

The line DirectShowLib.DsError.ThrowExceptionForHR(Int32 hr) caught my attention, what does it mean? How can I fix this?

Uriel Arvizu
  • 1,876
  • 6
  • 37
  • 97
  • 1
    You need the value of `hr` - it describes the error. – Roman R. Aug 24 '12 at 16:24
  • I traced the error and it's thrown in the line 145 from the method setupgraph [link](http://pastebin.com/mszs73UP), which is the following `hr = mediaCtrl.Run();` instead of returning 1 as when I took the first picture, the return value was -2147023446. – Uriel Arvizu Aug 24 '12 at 17:24
  • FYI `-2147023446` is `0x800705AA` `ERROR_NO_SYSTEM_RESOURCES` "Insufficient system resources exist to complete the requested service." (see [this post and tool](http://alax.info/blog/1383) on reading `HRESULT` values). I would say most likely you are trying to open second pipeline without closing first. And video capture devices are opened exclusively, hence the error. – Roman R. Aug 24 '12 at 18:11
  • The DxSnap have this line `if (m_ip != IntPtr.Zero) { Marshal.FreeCoTaskMem(m_ip); m_ip = IntPtr.Zero; }` before taking a picture it is supposed to clear any previous buffer, or how can I make sure I'm closing the pipeline? – Uriel Arvizu Aug 24 '12 at 18:21
  • No this is irrelevant. Imprortant is to call `IMediaControl.Stop` and do `Marshal.ReleaseComObject` on interfaces you hold. It needs debugging on your side, to possibly step through code and at some point running another capture tool side by side to see if device is locked by your app or not. – Roman R. Aug 24 '12 at 20:06
  • in my Capture class' Dispose method I had the `IMediaControl.Stop`but somehow it didn't get called when I destroyed the object, so I had to force call it and now it works, I'll just have to adjust the code to restart it, thanks for the help, you should put the answer so I can mark it. – Uriel Arvizu Aug 24 '12 at 20:18

1 Answers1

7

The error -2147023446 is 0x800705AA, ERROR_NO_SYSTEM_RESOURCES "Insufficient system resources exist to complete the requested service." (see this post and tool on reading HRESULT values easily and in convenient way).

I would say most likely you are trying to open second pipeline without closing first. And video capture devices are opened exclusively, hence you cannot start a pipeline if there is another one still active. The error code is suggesting exactly this.

In order to work this around, you need to make sure you call IMediaControl.Stop on previous filter graph, and release COM interfaces you don't need anymore with Marshal.ReleaseComObject.

Roman R.
  • 68,205
  • 6
  • 94
  • 158