lars k.
lars k.

Reputation: 592

Task for taking webcam snapshots without display

I want to take webcam snapshots on windows with DirectShow. These snapshots will be saved to disk without any display of these images. I want to start the snapshot process that takes a snapshot every second until I stop it, while the main process continues.

So I choose Yet Another Web Camera Control for DirectShow to use it with C#, and the demo works fine.
But I got problem when I use the wrapper in an own task, I get the typical threading error The calling thread cannot access this object because a different thread owns it.

The calling code looks like this:

Task.Run(() =>
{
    using (var cam1 = new SnapshotCam(camList.First(), "person", webCameraControl))
    {
        // Act
        Bitmap image = null;
        if (!cam1._wcc.IsCapturing)
        {
            cam1._wcc.StartCapture(cam1._cameraId);
            Task.Delay(500).Wait();
        }
        image = cam1._wcc.GetCurrentImage();
        // Assert
        Assert.NotNull(image);
    }
}).Wait();

The difficult object for me to handle is the webCameraControl stored in cam1._wcc: This object inherits from System.Windows.Controls.UserControl and could be attached to a UI. But in my case I do not have any UI, the snapshots have to be taken in a "headless" style.

So the trouble begins when I want to use the _wcc-object. I tried already to call the _wcc.Dispatcher for the corresponding thread but didn't succeed.

How can I call the code above in an own task/thread independent from the rest of the code?

Upvotes: 0

Views: 694

Answers (2)

Roman Ryltsov
Roman Ryltsov

Reputation: 69687

The problem you are hitting immediately is threading related, but eventually it was an unlucky choice of library for webcam capture. You don't need camera frame displaying but the library is implementing taking the stills by rendering video stream to Direct3D device (sort of presentation even if it is "invisible") with copying of last known frame on request.

Perhaps you should rather prefer DxSnap sample application from DirectShow.NET package. Even though not ideal either:

  • it extracts frame data using Sample Grabber without need of displaying filter
  • it shows how to pass data between threads accurately, see here
  • you avoid over-complications with multi-layered external control library

See also:

Upvotes: 1

NibblyPig
NibblyPig

Reputation: 52942

If you don't have a UI then you probably don't need to wrap your code in a Task.Run unless you're trying to do something simultaneously while it's running - and since you're not using await it doesn't /look/ like that's the case.

If you wanted to keep it in a Task.Run then you'd use the Invoke method on your form, which would allow you to access the camera control in the correct thread, however I don't see how it would solve the problem of running it asynchronously.

If you're not using the control as an actual UI element I don't see why you couldn't create it on a separate thread and use it on that thread, although it doesn't sound like that's how it's intended to be used.

Upvotes: 0

Related Questions