20

I want to develop a virtual webcam driver which from User mode I'll pass image to it and it will display as webcam output.

I don't want to use DirectX filter and CSourceStream etc. Because they don't work on some programs which doesn't use DirectX for capturing webcam image.

I have to write a kernel mode device driver so.

Any ideas? I tried testcap from DDK samples, but it doesn't process image from user mode and doesn't get any input, just it displays 7 colors in webcam...

Any help would be greatly appreciated. Thanks


Thank you all!

I tried code from here: http://tmhare.mvps.org/downloads.htm (find Capture Source Filter)

It worked well when I compiled it in Yahoo, MSN, but it crashed AIM, Internet Explorer Flash Webcam, Firefox Flash webcam and Skype... I got crash in QueryInterface after 8 time call to that, I found it with tracing it with a lot of tricks..

Now I know, it crashes on 8th call to HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)

8th call when it reaches to last if, I mean: return CSourceStream::QueryInterface(riid, ppv);

It's in 17th line of Filters.cpp

Why do you think I'm getting crash??

Thank you all for guiding me to find correct solution which is DirectShow, not driver

Roman R.
  • 64,446
  • 5
  • 83
  • 139
Franklin
  • 289
  • 2
  • 3
  • 5
  • You mean WDK and not DDK, right? Also, to get a better idea what you're looking for, where's testcap located in the samples, I can't find it. – mrduclaw Oct 26 '09 at 21:51
  • Once again. Do not try to write a driver, because drivers tend to be really really big. I will try to look into my code to register software devices, and show it here. – Christopher Oct 26 '09 at 22:06
  • If you really have to go the windows driver way ... See [this question](http://stackoverflow.com/questions/1137540/connecting-windows-driver-to-userland-service) for a description on how to communicate with a device driver. Good luck. – Christopher Oct 27 '09 at 11:30
  • 1
    If you just want to avoid some crashes I've refined that stuff a bit here: https://github.com/rdp/screen-capture-recorder-to-video-windows-free (not a kernel mode camera of course, but might be useful) cheers! – rogerdpack May 27 '16 at 11:54

2 Answers2

18

There are several APIs from Microsoft which provide access to image data.

  • Twain: Used for single image capture from scanners, etc.
  • WIA: This seems to have degenerated to a single image codec library.
  • VfW: A very old (Win16) API which really works only Video-File encoding/decoding, but has support for some video acquisition.
  • DirectShow: previously part in the DirectX SDK, currently in the Platform SDK. This is the place to go for current (general) streaming solutions.
  • Windows Media/Media Foundation: This seems more to be geared at video playback/reencoding.
  • Manufacturer Specific Libraries: Pylon/Halcon/Imaging Control/...

DirectShow specific :

To create image acquisition devices under windows, you have to provide either a device (driver) which implements the streamclasses interfaces (or newer Avstream) or you have to write a usermode COM object which has to be added to the VideoInputCategory enumerator.

The Avstream sample provides everything for a real image acquisition device. Only the lower layer for the actual device really is missing.

If you can design a device, you should either create it DCAM or UVC compatible. For both there are built-in drivers supplied by windows.


How to write a software source device :

You have to create a DirectShow filter which provides at least one output pin and register this under the VideoInputCategory. There may be several interfaces certain applications require from a capture application, but these depend on the application itself. Simple applications to try out filters are GraphEdit and AMCap which are supplied in the Plattform SDK.

Some code :

#include <InitGuid.h>
#include <streams.h>


const AMOVIESETUP_MEDIATYPE s_VideoPinType =
{
    &MEDIATYPE_Video,   // Major type
    &MEDIATYPE_NULL     // Minor type
};

const AMOVIESETUP_PIN s_VideoOutputPin =
{
    L"Output",              // Pin string name
    FALSE,                  // Is it rendered
    TRUE,                   // Is it an output
    FALSE,                  // Can we have none
    FALSE,                  // Can we have many
    &CLSID_NULL,            // Connects to filter
    NULL,                   // Connects to pin
    1,                      // Number of types
    &s_VideoPinType         // Pin details
};

const AMOVIESETUP_FILTER s_Filter =
{
    &CLSID_MyFilter,        // Filter CLSID
    L"bla",         // String name
    MERIT_DO_NOT_USE,               // Filter merit
    1,                              // Number pins
    &s_VideoOutputPin               // Pin details
};

    REGFILTER2 rf2;
    rf2.dwVersion = 1;
    rf2.dwMerit = MERIT_DO_NOT_USE;
    rf2.cPins = 1;
    rf2.rgPins = s_Filter.lpPin;

    HRESULT hr = pFilterMapper->RegisterFilter( CLSID_MyFilter, _FriendlyName.c_str(), 0, 
        &CLSID_VideoInputDeviceCategory, _InstanceID.c_str(), &rf2 );
    if( FAILED( hr ) )
    {
        return false;
    }

    std::wstring inputCat = GUIDToWString( CLSID_VideoInputDeviceCategory );
    std::wstring regPath = L"CLSID\\" + inputCat + L"\\Instance";
    win32_utils::CRegKey hKeyInstancesDir;
    LONG rval = openKey( HKEY_CLASSES_ROOT, regPath, KEY_WRITE, hKeyInstancesDir );
    if( rval == ERROR_SUCCESS )
    {
        win32_utils::CRegKey hKeyInstance;
        rval = createKey( hKeyInstancesDir, _InstanceID, KEY_WRITE, hKeyInstance );

        ....

_InstanceID is a GUID created for this 'virtual device' entry.

Christopher
  • 8,656
  • 3
  • 30
  • 37
  • 2
    related article on doing this from within C# http://www.codeproject.com/Articles/437617/DirectShow-Virtual-Video-Capture-Source-Filter-in – David Jeske Feb 06 '15 at 04:34
  • please answer https://stackoverflow.com/questions/65912468/directshow-based-virtual-camera-using-ibasefilter-and-ipin-interfaces – Alok Singh Mahor Jan 27 '21 at 05:51
4

You can not decide how other program would call your driver. Most of programs will use DirectShow. Some would use the win3.x technology VFW. Many new programs, including Windows XP's scanner and camera wizard, may call you via the WIA interface. If you do not want to implement all that, you need to at least provide the DirectShow interface via WDM and let vfwwdm32.dll gives you a VFW interface, or write your own VFW driver.

Sheng Jiang 蒋晟
  • 14,859
  • 2
  • 26
  • 44