5,781,815 members and growing! (13,726 online)
Email Password   helpLost your password?
Multimedia » Audio and Video » DirectShow     Intermediate

Extracting bitmaps from movies using DirectShow

By Markus Axelsson

An article showing how to extract a frame from a movie using DirectShow
VC6, C++, Windows, MFC, Visual Studio, VS6, Dev

Posted: 4 Sep 2001
Updated: 4 Sep 2001
Views: 253,421
Bookmarked: 79 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
32 votes for this Article.
Popularity: 5.70 Rating: 3.79 out of 5
3 votes, 13.6%
1
0 votes, 0.0%
2
4 votes, 18.2%
3
5 votes, 22.7%
4
10 votes, 45.5%
5

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

About the Author

Markus Axelsson



Location: Sweden Sweden

Other popular Audio and Video articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 150 (Total in Forum: 150) (Refresh)FirstPrevNext
Generalerror C2504: 'IDXEffect' and error C2787: 'IVideoWindow' :memberVirex_A15:54 30 Oct '08  
Generalcan't grub from the "*.mp4"memberlaguna_leo6:23 27 Sep '08  
Generalto all - if doesn't run DX9membergrandmasta11:20 26 Aug '07  
QuestionUrgent Problem...memberTushar Jadhav20:22 22 Jun '07  
Generalimage won't fit to picturebox(CStatic)memberEd_lon21:49 17 May '07  
Generalhimembervikram panwar0:54 27 Mar '07  
GeneralRe: himemberrajendra@yahoo.com22:07 27 Mar '07  
GeneralIt Does not run in Win2kmemberrajendra@yahoo.com7:45 22 Mar '07  
QuestionThe other way aroundmembershfnet5:29 13 Mar '07  
AnswerRe: The other way aroundmembertanvon malik18:57 21 Nov '07  
Generalhow vedio file(mpeg4) is streamedmember19:38 15 Feb '07  
GeneralProblem opening file with bad indexesmemberSbarBaz7:07 29 Sep '06  
GeneralConflict between directshow and wmplayer. Help!memberaritosteles13:13 10 Sep '06  
GeneralError when compilingmemberarindam_stcet5:19 3 May '06  
GeneralError: Could not grab the frame.memberVenu Gopal Lolla20:09 13 Feb '06  
GeneralRe: Error: Could not grab the frame.memberbeatbox3:50 24 Mar '06  
QuestionTheoretical misunderstanding of a processmemberwhitesail14:25 6 Dec '05  
Generalcouldnt compilememberUsman mani23:50 16 Mar '05  
GeneralError saving the grabbed frame to bmp filememberA. Asif Raza11:38 15 Mar '05  
Generalhow to grab images from .mov filesmembersrkrishna5:23 25 Jan '05  
GeneralNo Video and Audiomemberbozitaai20:32 11 Jan '05  
Generali got this error while building this projectmemberslucky16:19 18 Dec '04  
GeneralRe: i got this error while building this projectmemberJohn4421:59 20 Dec '04  
GeneralRe: i got this error while building this projectmemberpig head xiaoma18:38 8 Jun '05  
GeneralRe: i got this error while building this projectmemberJohn440:36 10 Jun '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 4 Sep 2001
Editor: Chris Maunder
Copyright 2001 by Markus Axelsson
Everything else Copyright © CodeProject, 1999-2009
Web13 | Advertise on the Code Project