Click here to Skip to main content
15,847,077 members
Articles / Desktop Programming / MFC
Article

Extracting bitmaps from movies using DirectShow

Rate me:
Please Sign up or sign in to vote.
4.41/5 (25 votes)
4 Sep 20011 min read 629.6K   11.8K   114   153
An article showing how to extract a frame from a movie using DirectShow

Sample Image - FrameGrabberDemo.gif

Introduction

This article explains how to use the ISampleGrabber interface to grab a frame from a movie. We'll add the SampleGrabber filter to the graphbuilders filter list and use it to extract the bitmap. It'll show the necessary steps how to create the filter, create the graph, start it upp and grab the frame.

Setup the enviroment, we are using ATL smartpointers and DirectShow

#include "AtlBase.h"	// For atl smart pointers
#include "dShow.h"	// DirectShow header
#include "Qedit.h"	// SampleGrabber filter

The project has to be linked with Strmbase.lib

Since we're using COM we have to call CoInitialize() and CoUninitialize() in InitInstance, make sure the dialog destructor is called before CoUninitialize is called.

BOOL CFrameGrabberApp::InitInstance()
{
...
...
	CoInitialize(NULL);
	{
		CFrameGrabberDemoDlg dlg;
		m_pMainWnd = &dlg;
		int nResponse = dlg.DoModal();
	}
	CoUninitialize();
...
...
}

Step 1: Create the GraphBuilder

CComPtr<IGraphBuilder> pGraphBuilder;
HRESULT hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, 
              CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&pGraphBuilder);

Step 2: Create the Grabber filter and add it to the graph builder

CComPtr<IBaseFilter> pGrabberBaseFilter;
CComPtr<ISampleGrabber> pSampleGrabber;
AM_MEDIA_TYPE mt;
hr = ::CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
                        IID_IBaseFilter, (LPVOID *)&pGrabberBaseFilter);
if (FAILED(hr))
	return hr;
pGrabberBaseFilter->QueryInterface(IID_ISampleGrabber, (void**)&pSampleGrabber);
if (pSampleGrabber == NULL)
	return E_NOINTERFACE;
hr = pGraphBuilder->AddFilter(pGrabberBaseFilter,L"Grabber");
if (FAILED(hr))
	return hr;

Step 3: Setup the media type we're interrested in and render the file. The graph builder will now setup all the filters it needs to render the movie including the sample grabber we added.

ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
mt.formattype = FORMAT_VideoInfo; 
hr = pSampleGrabber->SetMediaType(&mt);
if (FAILED(hr)) 
	return hr;
hr = pGraphBuilder->RenderFile(wFile,NULL); 
if (FAILED(hr)) 
	return hr;

Now when the graph is created we need to tell the sample grabber to stop the graph after receiving one sample, we also tell it to copy the sample data into it's internal buffer.

hr = pSampleGrabber->SetBufferSamples(TRUE);
if (FAILED(hr)) 
	return hr; 
hr = pSampleGrabber->SetOneShot(TRUE); 
if (FAILED(hr)) 
return hr;

Step 4: Now we run the graph and collects the data from the sample grabber.

hr = pMediaControl->Run();
if (FAILED(hr)) 
	return hr; 
long evCode;
hr = pMediaEventEx->WaitForCompletion(INFINITE, &evCode); 
if (FAILED(hr)) 
	return hr; 
AM_MEDIA_TYPE MediaType; 
ZeroMemory(&MediaType,sizeof(MediaType)); 
hr = pSampleGrabber->GetConnectedMediaType(&MediaType); 
if (FAILED(hr)) 
	return hr; 
// Get a pointer to the video header. 
VIDEOINFOHEADER *pVideoHeader = (VIDEOINFOHEADER*)MediaType.pbFormat; 
if (pVideoHeader == NULL) 
	return E_FAIL; 
// The video header contains the bitmap information. 
// Copy it into a BITMAPINFO structure. 
BITMAPINFO BitmapInfo; 
ZeroMemory(&BitmapInfo, sizeof(BitmapInfo)); 
CopyMemory(&BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader), 
           sizeof(BITMAPINFOHEADER)); 

// Create a DIB from the bitmap header, and get a pointer to the buffer. 
void *buffer = NULL; 
HBITMAP hBitmap = ::CreateDIBSection(0, &BitmapInfo, DIB_RGB_COLORS, &buffer, 
                                     NULL, 0); 
GdiFlush(); 
// Copy the image into the buffer. 
long size = 0; 
hr = pSampleGrabber->GetCurrentBuffer(&size,(long *)buffer);   
if (FAILED(hr)) 
	return  hr;

Now we have the bitmap handle, the demo program takes the sample one second in the movie and displays it to the user using an picture box.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Sweden Sweden
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: What About Compressed frame? Pin
Jabran Asghar13-Dec-03 1:27
Jabran Asghar13-Dec-03 1:27 
Generalget frame from video capture Pin
Member 34635429-Jul-03 18:31
Member 34635429-Jul-03 18:31 
Generalencounter GetCurrentBuffer fail Pin
YKWang29-Jul-03 1:38
YKWang29-Jul-03 1:38 
GeneralRe: encounter GetCurrentBuffer fail Pin
Markus Axelsson29-Jul-03 7:08
Markus Axelsson29-Jul-03 7:08 
GeneralRe: encounter GetCurrentBuffer fail Pin
YKWang29-Jul-03 18:54
YKWang29-Jul-03 18:54 
Generallink error Pin
franks_cn28-Jul-03 2:33
franks_cn28-Jul-03 2:33 
GeneralRe: link error Pin
Markus Axelsson28-Jul-03 9:37
Markus Axelsson28-Jul-03 9:37 
GeneralFree VideoFrame Extractor to BMP image. Pin
Chiew Heng Wah27-Jul-03 21:43
Chiew Heng Wah27-Jul-03 21:43 
Cool | :cool: Free VideoFrame Extractor to BMP Image.
Requires:
i. Win98 or higher.
ii. DirectX 8

Opens MPG, DAT, WMV, ASF, AVI (various formats including DivX if encoder is installed on machine - "If you can play it, you can extract it") and many more Big Grin | :-D . QuickTime MOV format up to version 2 only (sorry, didn't have sufficient documentation).

Rose | [Rose] BlueShell Studios DownloadsRose | [Rose]
Questionhow can i add a bitmap on the video Pin
muhammad fahad4-Jul-03 16:22
muhammad fahad4-Jul-03 16:22 
GeneralStreem Configuration for Video Profile To Create ASF Files Pin
kirankumar30-Jun-03 23:43
kirankumar30-Jun-03 23:43 
GeneralVMR-9 render to Capture File Pin
_corey_27-Jun-03 19:33
_corey_27-Jun-03 19:33 
QuestionHow to play a vedio file in DesktopWindow Pin
paperfly12-Jun-03 21:04
paperfly12-Jun-03 21:04 
AnswerRe: How to play a vedio file in DesktopWindow Pin
_corey_27-Jun-03 19:25
_corey_27-Jun-03 19:25 
GeneralCaputre frame from device Pin
Emiliano5-Jun-03 5:08
Emiliano5-Jun-03 5:08 
GeneralRe: Caputre frame from device Pin
krssagar15-Oct-03 17:33
krssagar15-Oct-03 17:33 
QuestionHow to convert frames into movies? Pin
Anonymous29-May-03 5:50
Anonymous29-May-03 5:50 
Questionmissing header file? Pin
cityboys9912-Apr-03 16:37
cityboys9912-Apr-03 16:37 
AnswerRe: missing header file? Pin
Anonymous23-Apr-03 5:21
Anonymous23-Apr-03 5:21 
GeneralRe: missing header file? Pin
Anonymous23-Apr-03 23:02
Anonymous23-Apr-03 23:02 
AnswerRe: missing header file? Pin
Anonymous27-Jun-03 19:27
Anonymous27-Jun-03 19:27 
AnswerRe: missing header file? Pin
_corey_27-Jun-03 19:28
_corey_27-Jun-03 19:28 
GeneralRe: missing header file? Pin
persecution20-Oct-03 5:41
persecution20-Oct-03 5:41 
GeneralRe: missing header file? Pin
mgd76062913-Dec-03 7:27
mgd76062913-Dec-03 7:27 
GeneralVideo capture Pin
Oscar Alho28-Mar-03 8:55
Oscar Alho28-Mar-03 8:55 
GeneralRe: Video capture Pin
ee21035217k1-Apr-03 5:40
ee21035217k1-Apr-03 5:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.