Simultaneous Previewing & Video Capture using DirectShow

Introduction

This article explains a method to perform previewing and grabbing simultaneously from a Webcam using DirectShow. Rather than using the conventional ISampleGrabber interface, this application used Directshow VMR filters & IPin interfaces.

There are many solutions for capturing and previewing, but only a few combine both. I tried to make an application that serves this purpose by using the ISampleGrabber and IVideoWindow interfaces. In this this article, I will discuss the "VMR filters & IPin interfaces" method, which worked on Win2000 and WinXP.

The DirectShow "Windowless Sample" (Windowless mode in the Video Mixing Renderer) gives the clue for capturing frames while previewing.

Snap Shot

Using the Code

I had created a class named CVMR_Capture, and then inserted the VMR_Capture.h and VMR_Capture.cpp files into project.

Link strmiids.lib quartz.lib in VC++ Project Settings. Add a static control into your dialog resource. Add a member variable for that static control. Declare a member variable of CVMR_Capture.

Functions and Explanation

The public interfaces provided are:

int EnumDevices(HWND hList);
HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight);
DWORD   GetFrame(BYTE ** pFrame);
BOOL    StopVMR();
BOOL    Pause();
DWORD   ImageCapture(LPCTSTR szFile);
DWORD   GrabFrame();

int EnumDevices(HWND hList); (Optional)

Enumerate the available devices connected to the computer. HWND is the HANDLE to a combo box that displays the connected Devices.

HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight);

Intitializing, "iDeviceID" is the selected device index (from the combo box) and "hWnd" is the handle of the display window. iWidth and iHeight are the expected resolution (eg 320/240). The display will adjust iteself to the size of the window.

DWORD GrabFrame(); DWORD GetFrame(BYTE ** pFrame);

Call this function to get the captured buffer. GrabFrame(); will grab the image, store it in a buffer, and return the value that is the size of the buffer. The user can get the buffer pointer by calling GetFrame(BYTE ** pFrame), whichs return the size of the buffer.

Note: DONT DELETE the "pFrame" BUFFER VALUE, which the class destructor will delete. Use the Pointer(pFrame) for processing or copying the memory to a user-allocated Buffer.

BOOL StopVMR();

Stop previewing.

BOOL Pause();

Pause capturing. Call this method again to restart capturing.

DWORD ImageCapture(LPCTSTR szFile);

Capture and write the raw image BYTES (RGB) to a file provided.

Special Functions and Explanation

bool BindFilter(int deviceId, IBaseFilter **pFilter);
HRESULT InitializeWindowlessVMR(HWND hWnd);
HRESULT InitVideoWindow(HWND hWnd,int width, int height);
void StopCapture();
void CloseInterfaces(void);
void DeleteMediaType(AM_MEDIA_TYPE *pmt);
bool Convert24Image(BYTE *p32Img,BYTE *p24Img,DWORD dwSize32);

bool BindFilter(int deviceId, IBaseFilter **pFilter);

Bind the filter to the given device ID.

HRESULT InitializeWindowlessVMR(HWND hWnd);

VMR intialization to the HWND provided.

HRESULT InitVideoWindow(HWND hWnd,int width, int height);

Adjusts the display video size according to the size of display window.

void StopCapture();

Stop capturing.

void CloseInterfaces(void);

Release & delete the interfaces/allocated memory.

void DeleteMediaType(AM_MEDIA_TYPE *pmt);

Delete media type object.

bool Convert24Image(BYTE *p32Img,BYTE *p24Img,DWORD dwSize32);

The captured image using VMR is a 32-bit RGB. This function will convert the 32-bit RGB to a 24-bit RGB.

Points of Interest

This class has been tested on Windows 2000 & Windows XP with DirectX9.0. Both VMR7 & VMR9 are supported. I haven't included the DirectShow Event Handling part in this sample. Please attach the required exception/error handling mechanism when you use it.

Please drop me an e-mail about any bugs or suggestions to enhance the class. Your suggestions and guidance will be most valuable.



About the Author

Sivasagar K.R

Sivasagar K R , R&D Researcher(Biometrics), Seoul,Korea

Downloads

Comments

  • WaitForCompletion ??

    Posted by techratna on 08/03/2007 01:02pm

    Hi,
    I am new to directshow. Am trying to make a real time audio player. Can you plz tell me why you did not need to call "WaitForCompletion" after "run" call?
    Thanks in advance!

    Reply
  • Directshow filter for 90 degree video rotation

    Posted by nireshdev on 08/24/2006 01:15am

    Hi, I tried your project it is working fine in my pc. I want to create a Directshow filter to create a 90 degree rotated video which is capturing from webcam. and i want to use that filter in Directshow grapedit, for that what should i do please help me. Thanks,

    Reply
  • Can't display image using Logitech webcam

    Posted by chewkokhooi on 06/26/2006 09:47pm

    Hi,
    Previously, I'm using normal monochrome camera to display and capture the image and it works fine. But after I change the camera by using Logitech webcam, it can't display properly the image. Have you encounter this kind of problem before?

    Reply
  • imagecapture( )

    Posted by sup_ho on 01/03/2006 09:35pm

    hi, i was trying to use your program, added a push button to capture the image, and found that it saves a file a corrupt file, the input for this function was "mog.bmp" was just wondering if it was cuz the bmpheader was not defined when i saved the file?

    • bitmap info

      Posted by _mijo on 01/18/2006 02:03pm

      hi, i tried to capture an image using imagecapture() but i have the same problem with the saved file. what exactly do i have to define in order to get a good bitmap?

      Reply
    • bitmap info and header

      Posted by sup_ho on 01/03/2006 10:08pm

      yea.. theses info and headers weren't defined, that's what was cuzing the problem.. even thought they are defined in the showpic

      Reply
    Reply
  • Connecting a Decoder

    Posted by Poorna on 09/17/2005 07:37am

    Hi, I used your code to build my sample application. I am trying to use Encoder and decoder filters as follows Video Capture->H263 Encoder->H263 Decoder->Video Renderer. COnnect() for Encoder output and Decoder input pin fails. Please suggest me how to proceed.

    Reply
  • Big Error

    Posted by khkh on 07/28/2005 10:51am

    This simple can't work with pinnacle AV/DV studio.

    Reply
  • compile error

    Posted by shayirli on 06/14/2005 07:55am

    Hello, I have a problem when I try to build this project as below: Please reply me about this problem: My mail: shayirli@yahoo.com or shayirli@aselsan.com.tr -------------------Configuration: DXCapture - Win32 Release-------------------- Compiling... DXCapture.cpp C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2730) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2736) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2841) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2856) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15359) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15542) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15669) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15674) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16189) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16203) : error C2061: syntax error : identifier 'HEVENT' DXCaptureDlg.cpp C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2730) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2736) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2841) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2856) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15359) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15542) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15669) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15674) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16189) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16203) : error C2061: syntax error : identifier 'HEVENT' VMR_Capture.cpp C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2730) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2736) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2841) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(2856) : error C2061: syntax error : identifier 'HSEMAPHORE' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15359) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15542) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15669) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(15674) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16189) : error C2061: syntax error : identifier 'HEVENT' C:\DERS\TEZ\DIRECTX9\DIRECTX9.0C\INCLUDE\strmif.h(16203) : error C2061: syntax error : identifier 'HEVENT' Generating Code... Error executing cl.exe. DXCapture.exe - 30 error(s), 0 warning(s)

    • strmif.h

      Posted by shayirli on 06/15/2005 07:51am

      I think reason of this problem is DWORD_PTR, it is undefined for this code.Please help me, to define DWORD_PTR for this project.

      Reply
    Reply
  • Requesting specific image dimensions from Sample Grabber possible?

    Posted by Walegwa on 04/06/2005 09:26pm

    Since you mention SampleGrabber, let me ask you this. Is it possible to ask the that filter for a 640 X 480 image, for example? I have a working bitmap grabber but I never know what size image I'm going to get. Some days it's 320 X 240, other days its 720 X 480, depending, I guess, on what side of the bed my camera woke up on. I haven't looked at your code yet so I apologize if the answer is in there.

    • how to process live image

      Posted by aden003 on 04/04/2006 05:17am

      i wan to ask how to process the RGB from the live image and where the buffer

      Reply
    • Re: Requesting specific image dimensions

      Posted by Buddie on 05/06/2005 05:24pm

      yes we can a specific dimension .. HRESULT Init(int iDeviceID,HWND hWnd,int iWidth,int iHeight); Intitializing, "iDeviceID" is the selected device index (from the combo box) and "hWnd" is the handle of the display window. iWidth and iHeight are the expected resolution OFFERED BY THE CAMERA(eg 320/240). The display will adjust iteself to the size of the window. Sorry ..I have been busy of late

      Reply
    Reply
  • Please help me on Directshow +MFC

    Posted by nvnoi76 on 12/01/2004 09:41pm

    Hi, I write a program to play Video files using Directshow and MFC ( Visual C++ 6.0 , DirectX 9.0 ) I compile in DEBUG mode, It runs well and correctly. But when I compile in RELEASE mode. It reports error : "Unhandle exception in Playwnd.exe (MFC42.dll)0xC0000005: Access Violation" Is there any problem on MFC42.dll ? Please help me to correct it. Thank you very much. Noi - nvnoi76@yahoo.com

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds