Hi,
I need a program which reads an image from a USB webcam every second (or even faster, if that's possible) and write it to harddisk as JPEG.
My only problem is, that my program is too slow. Getting the picture from the webcam needs about 3 seconds... (Render() and WaitForCompletion() are the slow functions)
Here is a part of the source code I use (in a loop):
CComPtr< ISampleGrabber > pGrabber;
CComPtr< IBaseFilter > pSource;
CComPtr< IGraphBuilder > pGraph;
CComPtr< IVideoWindow > pVideoWindow;
pGrabber.CoCreateInstance( CLSID_SampleGrabber );
CComQIPtr< IBaseFilter, &IID_IBaseFilter > pGrabberBase( pGrabber );
GetDefaultCapDevice(&pSource);
pGraph.CoCreateInstance( CLSID_FilterGraph );
pGraph->AddFilter( pSource, L"Source" );
pGraph->AddFilter( pGrabberBase, L"Grabber" );
AM_MEDIA_TYPE am_media_type;
ZeroMemory(&am_media_type, sizeof(am_media_type));
am_media_type.bFixedSizeSamples = TRUE;
am_media_type.lSampleSize = 1;
am_media_type.majortype = MEDIATYPE_Video;
am_media_type.subtype = MEDIASUBTYPE_RGB24;
am_media_type.formattype = FORMAT_VideoInfo;
pGrabber->SetMediaType( &am_media_type );
CComPtr< IPin > pSourcePin;
CComPtr< IPin > pGrabPin;
pSourcePin = GetOutPin( pSource, 0 );
pGrabPin = GetInPin( pGrabberBase, 0 );
pGraph->Connect( pSourcePin, pGrabPin );
AM_MEDIA_TYPE mt;
pGrabber->GetConnectedMediaType( &mt );
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat;
CB.Width = vih->bmiHeader.biWidth;
CB.Height = vih->bmiHeader.biHeight;
_FreeMediaType( mt );
memset( &(cbInfo.bih), 0, sizeof( cbInfo.bih ) );
cbInfo.bih.biSize = sizeof( cbInfo.bih );
cbInfo.bih.biWidth = CB.Width;
cbInfo.bih.biHeight = CB.Height;
cbInfo.bih.biPlanes = 1;
cbInfo.bih.biBitCount = 24;
CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
pGraph->Render( pGrabOutPin );
pGrabber->SetBufferSamples( FALSE );
pGrabber->SetOneShot( TRUE );
pGrabber->SetCallback( &CB, 1 );
CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
pControl->Run( );
CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
long EvCode = 0;
pEvent->WaitForCompletion( INFINITE, &EvCode );
CHAR *BitmapData = NULL;
cbInfo.biSize = CalcBitmapInfoSize(cbInfo.bih);
ULONG Size = cbInfo.biSize + cbInfo.lBufferSize;
*BitmapSize = Size;
if(Bitmap)
{
*Bitmap = (BITMAPINFO *) new BYTE[Size];
if(*Bitmap)
{
(**Bitmap).bmiHeader = cbInfo.bih;
BitmapData = (CHAR *)(*Bitmap) + cbInfo.biSize;
memcpy(BitmapData, cbInfo.pBuffer, cbInfo.lBufferSize);
}
}
What do I need to do, if I want at least 1 webcam image per second?
I already tried setting SetOneShot() to false, but then the whole program doesn't work anymore...
And what does SetBufferSamples() do?
Thanks in advance for your help!