Complicated sample of Camera_Net library use. Stranger on television.
This article presents a library
Camera_Net for working with cameras and video-inputs in .NET easily. Library uses DirectShow and includes samples of use: two simple samples and a complicated one.
What is DirectShow?
First of all, in this article, we'll use DirectShow for rendering video streams from cameras. So what is DirectShow? DirectShow is a multimedia framework made by Microsoft guys. This framework was made very powerful and complicated, so it almost allows to make a home semi-pro video studio. But this huge complexity makes it hard to use. You need to make tons of code to simply render video from your web-camera to your application form.
Advantages and disadvantages of DirectShow
It can do everything you need. If not, write your filters and use them in filter graph.
- Part of the Operating System.
All Windows versions (XP, Vista, 7, 8) support it out of box. No need to install anything.
- Supported by all vendors.
Almost every camera you can buy has drivers to work nicely with DirectShow.
- It's not cross-platform.
It's based on COM technology and is not cross-platform. It will work well only on Windows. It's also a proprietary framework as most of stuff Microsoft does.
However, if you're using managed code (e.g. C#), your application is probably already not cross-platform.
- Native code.
The framework doesn't support managed API.
But you can use open source wrappers like DirectShowNet library to overcome this disadvantage.
- Too complicated and low-level to be used.
To render your webcam, you should make a lot of coding work.
But using wrappers like Camera_Net library from this article, you can do a lot of stuff with your camera easily.
So, it's up to you to use DirectShow or not as it has advantages and disadvantages. But if you do, maybe this article is for you.
DirectShow rendering graph
The main idea of audio/video rendering in DirectShow is to build a filter graph and run it. Filter Graph — is a graph with blocks (graph filters). Some of these blocks are video/audio sources (e.g. cameras, tuners), some are renders and others are filters that can change or transform multimedia streams. Also these graph filters have pins — points for connecting filters to each other. So, cameras have output pin or pins, renders have input pins and most of other filters have both types.
To render your camera, you can make a very simple filter graph:
The source filter is connected to simple Video Renderer. The source filter is available because operation system found it, sometimes with the help of vendor's camera drivers. The render is standard filter, you can consider it as a part of DirectShow framework. No additional filters were used.
Let's say we want to take pictures of video-stream and draw over video-output (video overlay). The graph will become more complicated:
Here Tee Filter is a standard filter to duplicate multimedia stream. One output stream of it goes to render and another goes to
SampleGrabber to take pictures (snapshots).
SampleGrabber is a standard filter for getting frames from video stream. In this graph, the Video Mixing Renderer is used instead of simple Video Renderer filter. Video Mixing Renderer is a standard filter that supports video overlay for rendered output.
If the source filter (camera, tuner) has different output multimedia format (media type), it can be necessary to add additional intermediate filters for conversion on the fly. It makes filter graph bigger and more sophisticated:
DirectShow can connect pins with distinct media types in an “intelligent” way by enumerating available intermediate filters installed in operation system and choosing one by itself, but the result sometimes can be not as good as you expected.
Filter graph images were made in an open source tool GraphStudioNext, which I recommend for everyone who is messing with filter graph. It's a great free software tool for building and debugging of filter graphs. It was made as a replacement of outdated buggy GraphEdit from Microsoft.
Managed Library as a Wrapper over DirectShow
To ignore all this mess with DirectShow graph, I would recommend to use a managed wrapper, which will hide all this low-level magic. It will allow you to overcome the third disadvantage of DirectShow — complexity and low-level coding.
In this article, I'll describe usage and features of
Camera_Net library. This library was created because I've failed to find a library among dozens of open source solutions that would support what I wanted: easy use of camera as a managed component, ability to change the camera resolution, take frame snapshots, show overlay images over the frame. So this library was created!
Some of the features of this library:
- Select camera
- Select resolution
- Show camera's output
- Overlay image on the frame
- Take snapshots of the frame
- Change TV mode (PAL, NTSC, etc.)
- Display dialog windows of the camera (from drivers)
- Get a list of available cameras and resolutions
Camera are the main classes in the library.
Camera is a class for interaction with cameras.
CameraControl is a
Camera class, easy to use out of box.
Additionally, there are several
VideoInput, camera selection class, etc. The library uses
DirectShowLib (license LGPL 2.1 or later), which is a very thin wrapper of DirectX COM-interfaces, so that the losses of productivity from the use of managed code instead of the native one are minimal.
All sources of library and examples are available on GitHub. You can post issues, pull requests or forks there.
DirectShow is Windows only, so the library is also available only for Windows.
The most simple way to use this library is to add it in your application as
Control. The class
CameraControl (which is inherited from
UserControl) is responsible for that. This approach is recommended.
The library includes samples of use in WinForms, in particular examples of a simple implementation of the component in your application, and more complicated example that shows almost all features of the library.
So, add the library project or a compiled assembly to references, add
CameraControl to your application and add
Get list of available devices
Firstly, you probably want to get list of available cameras and video inputs in the system:
CameraChoice _CameraChoice = new CameraChoice();
_CameraChoice.Devices includes all available devices (it's
List<DsDevice>). The list will be empty if DirectShow didn't find any devices.
In samples, you can see the whole code with camera and resolution selection via ComboBox-es with human-readable names of cameras. To make this article short, let's simply use the first one (with zero index).
Moniker (device identification)
In terms of DirectShow, the camera device has a unique identification — a Moniker (for more information, please read about
You can get moniker of device via
Mon property of
var moniker = _CameraChoice.Devices[your_index].Mon;
Get list of available resolutions
You can get a list of available resolutions (it camera's driver supports this function) using
ResolutionList resolutions = Camera.GetResolutionList(moniker);
Start camera output
Finally, when you've chosen camera device and resolution you can set camera to
or you can start with default resolution (usually it's a VGA mode 640x480 but not always):
On camera changing or application exit, you can (not always necessary) close current camera:
It will free camera for other applications, dispose DirectShow graph and some other resources.
And a Lot More!
Library allows a lot more:
- Take snapshots of video output
SnapshotOutputImage() or snapshot of source frame
- Show overlay image (bitmap) over video, mixer supports transparency (properties
GDIColorKey and etc).
- Use video input devices with crossbar and work with crossbar (
- Display dialog windows of the camera (from drivers):
- Work with TV mode (PAL, NTSC, etc.):
- Change camera and resolution (use
For more information, you can look at samples included with library.
Simple sample of Camera_Net library use.
Camera_NET library license
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
Camera_Net library is covered by LGPL, the samples are released as PUBLIC DOMAIN. So, you can use code from these samples in your free or proprietary project without any limitations.
The author of this article and the
Camera_Net library is free5lot. All sources of library and examples are available on github.
This project uses a library DirectShowLib (DirectShow.Net library) which is covered by LGPL 2.1 or later.
- PostBuildEvent with release DLL output
- Fixed an problem when moving from one monitor to second one
- .NET2 and .NET3.5 assemblies are available in addition to .NET4.
Some major fixes (see github log). Some cleaning of code. Added new sample — "
A first public open source release of
Links to Related Open Source Projects