Click here to Skip to main content
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 13:15pm
Edited 7-Nov-10 13: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 7,800
1 Sergey Alexandrovich Kryukov 7,072
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,790


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 11 Nov 2010
Copyright © CodeProject, 1999-2014
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