Click here to Skip to main content
11,701,461 members (68,210 online)
Rate this: bad
good
Please Sign up or sign in to vote.
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 ); /*************** ~ 2 sec *******************/
 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 ); /******************** ~ 1 s ***********************/
 
 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!
Posted 7-Nov-10 12:15pm
Edited 7-Nov-10 12:16pm
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I don't understand how this can help me with my problem with SampleGrabber...
All I ask is how I can grab multiple frames in a row with SampleGrabber. Setting the SetOneShot() to false and then what else do I have to do?
  Permalink  
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 324
1 Maciej Los 275
2 Sergey Alexandrovich Kryukov 250
3 Mika Wendelius 189
4 CHill60 110
0 OriginalGriff 8,274
1 Sergey Alexandrovich Kryukov 7,317
2 CPallini 4,912
3 Maciej Los 4,146
4 Mika Wendelius 3,556


Advertise | Privacy | Mobile
Web03 | 2.8.150819.1 | Last Updated 11 Nov 2010
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100