Camera Control needed for Tablet
- TimStone
- Posts: 2956
- Joined: Fri Oct 07, 2005 1:45 pm
- Location: Trabuco Canyon, CA USA
- Has thanked: 25 times
- Been thanked: 2 times
- Contact:
Camera Control needed for Tablet
A camera control to go along with the touch features added to FWH would be very helpful.
It would be nice to simply press a button to activate the tablet camera, and when the picture is taken, it can be saved to a location defined within our program.
Right now, I could leave a program, activate the camera, take the picture, and then move it to the location. However it would be nice to have a control button within my program to take the photo, and then to have it auto save to my desired location.
Thanks for considering this.
It would be nice to simply press a button to activate the tablet camera, and when the picture is taken, it can be saved to a location defined within our program.
Right now, I could leave a program, activate the camera, take the picture, and then move it to the location. However it would be nice to have a control button within my program to take the photo, and then to have it auto save to my desired location.
Thanks for considering this.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
Re: Camera Control needed for Tablet
Yes, I have been working on this also.
The twebcam class doesn't work for most tablets. It seems that some tablets only have DirectShow built in.
I tried finding twain driver for webcam but most of them are .net now.
If we could adapt twebcam class or create new one to use DirectShow that would be great.
I found a workaround using 2 different methods.
Method 1 was to use the builtin camera app. I would start the camera app (or bring to top if already running) and place "Press here when done" button on screen. They take the pictures and then press my done button. Then it collects the images and I moves them where I want.
This has been working pretty well but you lose some control over the process.
If you need it I have more information on using Windows 8/10 camera app.
Here is how I call it with Windows 10 and 8
Method 2 is using a little program CommandCam.exe. This app can capture images from webcam from command line. It has command line options you can use.
Users did not like this approach as much. You could put a delay before capture but still hard to sync image position before capture.
The twebcam class doesn't work for most tablets. It seems that some tablets only have DirectShow built in.
I tried finding twain driver for webcam but most of them are .net now.
If we could adapt twebcam class or create new one to use DirectShow that would be great.
I found a workaround using 2 different methods.
Method 1 was to use the builtin camera app. I would start the camera app (or bring to top if already running) and place "Press here when done" button on screen. They take the pictures and then press my done button. Then it collects the images and I moves them where I want.
This has been working pretty well but you lose some control over the process.
If you need it I have more information on using Windows 8/10 camera app.
Here is how I call it with Windows 10 and 8
Code: Select all | Expand
case ::oMain:cWinVer == '10' // GDF Mod Windows 10 8/24/2015
cPathInfo := 'shell:AppsFolder\Microsoft.WindowsCamera_8wekyb3d8bbwe!App'
lMetro := .t.
case ::oMain:cWinVer == '8'
cPathInfo := 'shell:AppsFolder\Microsoft.MoCamera_cw5n1h2txyewy!Microsoft.Camera'
lMetro := .t.
// Then do something like
if lMetro
WinExec( 'C:\Windows\explorer.exe '+cPathInfo, 0 )
else
..
endif
Method 2 is using a little program CommandCam.exe. This app can capture images from webcam from command line. It has command line options you can use.
Users did not like this approach as much. You could put a delay before capture but still hard to sync image position before capture.
Re: Camera Control needed for Tablet
FYI CommandCam provides source code to use Microsoft’s DirectShow API. It would have to be converted from .net
https://batchloaf.wordpress.com/commandcam/
The program is very small only 66k
https://batchloaf.wordpress.com/commandcam/
The program is very small only 66k
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
First steps using Borland (some changes are required for MSVC)
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( &CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
if( pGraph != NULL )
MessageBox( 0, "pGraph seems ok", "ok", 0 );
hr = CoCreateInstance( &CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, &IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
if( pBuilder != NULL )
MessageBox( 0, "pBuilder seems ok", "ok", 0 );
}
#pragma ENDDUMP
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
Next step:
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( &CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, &IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
if( pGraph != NULL )
MessageBox( 0, "pGraph seems ok", "ok", 0 );
hr = CoCreateInstance( &CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, &IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
if( pBuilder != NULL )
MessageBox( 0, "pBuilder seems ok", "ok", 0 );
hr = ( ( ICaptureGraphBuilder * ) pBuilder )->lpVtbl->SetFiltergraph( pBuilder, pGraph );
if( hr != S_OK )
MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
}
#pragma ENDDUMP
- TimStone
- Posts: 2956
- Joined: Fri Oct 07, 2005 1:45 pm
- Location: Trabuco Canyon, CA USA
- Has thanked: 25 times
- Been thanked: 2 times
- Contact:
Re: Camera Control needed for Tablet
I use xHarbour ( .com ) and MSVC, not Borland ...
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
Tim,
Yes, I know it
First we need to make it work, then we may be able to port it to MSVC
Yes, I know it
First we need to make it work, then we may be able to port it to MSVC
- TimStone
- Posts: 2956
- Joined: Fri Oct 07, 2005 1:45 pm
- Location: Trabuco Canyon, CA USA
- Has thanked: 25 times
- Been thanked: 2 times
- Contact:
Re: Camera Control needed for Tablet
OK but I haven't had Borland installed here for many years so I can't really help.
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
Tim,
This version works fine with MSVC. This is a work in progress.
You have to link MS strmiids.lib
This version works fine with MSVC. This is a work in progress.
You have to link MS strmiids.lib
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
if( pGraph != NULL )
MessageBox( 0, "pGraph seems ok", "ok", 0 );
hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
if( pBuilder != NULL )
MessageBox( 0, "pBuilder seems ok", "ok", 0 );
hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
if( hr != S_OK )
MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
if( hr != S_OK )
MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
}
#pragma ENDDUMP
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
I appreciate if you can test it on your tablet.
It does nothing yet. We are just converting code, step by step.
It does nothing yet. We are just converting code, step by step.
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
This version should report the camera name:
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
VARIANT var;
int n = 0;
int device_number = 0;
char device_name[ 100 ];
char char_buffer[100];
strcpy( device_name, "" );
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
if( pGraph != NULL )
MessageBox( 0, "pGraph seems ok", "ok", 0 );
hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
if( pBuilder != NULL )
MessageBox( 0, "pBuilder seems ok", "ok", 0 );
hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
if( hr != S_OK )
MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
if( hr != S_OK )
MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0 );
if( hr != S_OK )
MessageBox( 0, "No video devices found", "ok", 0 );
while(1)
{
// Access next device
hr = pEnum->Next(1, &pMoniker, NULL);
if( hr == S_OK )
n++; // increment device count
else
break;
// If device was specified by name rather than number...
if( device_number == 0 )
{
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (hr == S_OK)
{
// Get current device name
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
// Convert to a normal C string, i.e. char*
sprintf(char_buffer, "%ls", var.bstrVal);
VariantClear(&var);
pPropBag->Release();
pPropBag = NULL;
// Exit loop if current device name matched devname
MessageBox( 0, char_buffer, "device_name", 0 );
if (strcmp(device_name, char_buffer) == 0) break;
}
else
{
MessageBox( 0, "Error getting device names", "ok", 0 );
exit;
}
}
else if (n >= device_number) break;
}
}
#pragma ENDDUMP
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
More
You will get two warnings with verbose info that you can safely ignore
You will get two warnings with verbose info that you can safely ignore
Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>
#import "qedit.dll" raw_interfaces_only named_guids
EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
VARIANT var;
int n = 0;
int device_number = 0;
char device_name[ 100 ];
char char_buffer[100];
DexterLib::ISampleGrabber *pSampleGrabber = NULL;
strcpy( device_name, "" );
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
if( pGraph != NULL )
MessageBox( 0, "pGraph seems ok", "ok", 0 );
hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
if( pBuilder != NULL )
MessageBox( 0, "pBuilder seems ok", "ok", 0 );
hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
if( hr != S_OK )
MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
if( hr != S_OK )
MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0 );
if( hr != S_OK )
MessageBox( 0, "No video devices found", "ok", 0 );
while(1)
{
// Access next device
hr = pEnum->Next(1, &pMoniker, NULL);
if( hr == S_OK )
n++; // increment device count
else
break;
// If device was specified by name rather than number...
if( device_number == 0 )
{
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (hr == S_OK)
{
// Get current device name
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
// Convert to a normal C string, i.e. char*
sprintf(char_buffer, "%ls", var.bstrVal);
VariantClear(&var);
pPropBag->Release();
pPropBag = NULL;
// Exit loop if current device name matched devname
MessageBox( 0, char_buffer, "device_name", 0 );
if (strcmp(device_name, char_buffer) == 0) break;
}
else
{
MessageBox( 0, "Error getting device names", "ok", 0 );
break;
}
}
else if (n >= device_number) break;
}
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
VariantClear(&var);
// Create capture filter and add to graph
hr = pMoniker->BindToObject(0, 0,
IID_IBaseFilter, (void**)&pCap);
if( hr != S_OK )
MessageBox( 0, "Could not create capture filter", "ok", 0 );
// Add capture filter to graph
hr = pGraph->AddFilter(pCap, L"Capture Filter");
if( hr != S_OK )
MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );
// Create sample grabber filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void**)&pSampleGrabberFilter);
if( hr != S_OK )
MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );
// Query the ISampleGrabber interface of the sample grabber filter
hr = pSampleGrabberFilter->QueryInterface(
DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
if( hr != S_OK )
MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );
MessageBox( 0, "done", "ok", 0 );
}
#pragma ENDDUMP
- TimStone
- Posts: 2956
- Joined: Fri Oct 07, 2005 1:45 pm
- Location: Trabuco Canyon, CA USA
- Has thanked: 25 times
- Been thanked: 2 times
- Contact:
Re: Camera Control needed for Tablet
Tried building that with MSVC and get at least 102 errors ...
Tim Stone
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
http://www.MasterLinkSoftware.com
http://www.autoshopwriter.com
timstone@masterlinksoftware.com
Using: FWH 23.10 with Harbour 3.2.0 / Microsoft Visual Studio Community 2022-24 32/64 bit
- Antonio Linares
- Site Admin
- Posts: 42597
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Has thanked: 40 times
- Been thanked: 86 times
- Contact:
Re: Camera Control needed for Tablet
This version shows the camara window 

Code: Select all | Expand
#include "FiveWin.ch"
function Main()
DShowCamera()
return nil
#pragma BEGINDUMP
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>
#import "qedit.dll" raw_interfaces_only named_guids
EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;
HB_FUNC( DSHOWCAMERA )
{
HRESULT hr;
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IPropertyBag *pPropBag = NULL;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuilder = NULL;
IBaseFilter *pCap = NULL;
IBaseFilter *pSampleGrabberFilter = NULL;
IBaseFilter *pNullRenderer = NULL;
IMediaControl *pMediaControl = NULL;
char *pBuffer = NULL;
VARIANT var;
int n = 0;
int device_number = 0;
char device_name[ 100 ];
char char_buffer[100];
DexterLib::ISampleGrabber *pSampleGrabber = NULL;
strcpy( device_name, "" );
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
if( hr != S_OK )
MessageBox( 0, "CoInitializeEx error", "ok", 0 );
hr = CoCreateInstance( CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
( void ** ) &pGraph );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance error", "ok", 0 );
hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
( void ** ) &pBuilder );
if( hr != S_OK )
MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );
hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
if( hr != S_OK )
MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 );
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
if( hr != S_OK )
MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory, &pEnum, 0 );
if( hr != S_OK )
MessageBox( 0, "No video devices found", "ok", 0 );
while(1)
{
// Access next device
hr = pEnum->Next(1, &pMoniker, NULL);
if( hr == S_OK )
n++; // increment device count
else
break;
// If device was specified by name rather than number...
if( device_number == 0 )
{
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
if (hr == S_OK)
{
// Get current device name
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
// Convert to a normal C string, i.e. char*
sprintf(char_buffer, "%ls", var.bstrVal);
VariantClear(&var);
pPropBag->Release();
pPropBag = NULL;
// Exit loop if current device name matched devname
// MessageBox( 0, char_buffer, "device_name", 0 );
if (strcmp(device_name, char_buffer) == 0) break;
}
else
{
MessageBox( 0, "Error getting device names", "ok", 0 );
break;
}
}
else if (n >= device_number) break;
}
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
// MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
VariantClear(&var);
// Create capture filter and add to graph
hr = pMoniker->BindToObject(0, 0,
IID_IBaseFilter, (void**)&pCap);
if( hr != S_OK )
MessageBox( 0, "Could not create capture filter", "ok", 0 );
// Add capture filter to graph
hr = pGraph->AddFilter(pCap, L"Capture Filter");
if( hr != S_OK )
MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );
// Create sample grabber filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void**)&pSampleGrabberFilter);
if( hr != S_OK )
MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );
// Query the ISampleGrabber interface of the sample grabber filter
hr = pSampleGrabberFilter->QueryInterface(
DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
if( hr != S_OK )
MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );
// Enable sample buffering in the sample grabber filter
hr = pSampleGrabber->SetBufferSamples(TRUE);
if( hr != S_OK )
MessageBox( 0, "Could not enable sample buffering in the sample grabber", "ok", 0 );
// Set media type in sample grabber filter
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pSampleGrabber->SetMediaType((DexterLib::_AMMediaType *)&mt);
if( hr != S_OK )
MessageBox( 0, "Could not set media type in sample grabber", "ok", 0 );
// Add sample grabber filter to filter graph
hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
if( hr != S_OK )
MessageBox( 0, "Could not add Sample Grabber to filter graph", "ok", 0 );
// Create Null Renderer filter
hr = CoCreateInstance(CLSID_NullRenderer, NULL,
CLSCTX_INPROC_SERVER, IID_IBaseFilter,
(void**)&pNullRenderer);
if( hr != S_OK )
MessageBox( 0, "Could not create Null Renderer filter", "ok", 0 );
// Add Null Renderer filter to filter graph
hr = pGraph->AddFilter(pNullRenderer, L"NullRender");
if( hr != S_OK )
MessageBox( 0, "Could not add Null Renderer to filter graph", "ok", 0 );
// Connect up the filter graph's capture stream
hr = pBuilder->RenderStream(
&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
pCap, pSampleGrabberFilter, pNullRenderer);
if( hr != S_OK )
MessageBox( 0, "Could not render capture video stream", "ok", 0 );
hr = pBuilder->RenderStream(
&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
pCap, NULL, NULL);
if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
MessageBox( 0, "Could not render preview video stream", "ok", 0 );
// Get media control interfaces to graph builder object
hr = pGraph->QueryInterface(IID_IMediaControl,
(void**)&pMediaControl);
if( hr != S_OK )
MessageBox( 0, "Could not get media control interface", "ok", 0 );
// Run graph
while(1)
{
hr = pMediaControl->Run();
// Hopefully, the return value was S_OK or S_FALSE
if (hr == S_OK) break; // graph is now running
if (hr == S_FALSE) continue; // graph still preparing to run
// If the Run function returned something else,
// there must be a problem
// fprintf(stderr, "Error: %u\n", hr);
MessageBox( 0, "Could not run filter graph", "ok", 0 );
}
MessageBox( 0, "done", "ok", 0 );
}
#pragma ENDDUMP