Click here to Skip to main content
Licence 
First Posted 4 Sep 2001
Views 419,806
Bookmarked 104 times

Extracting bitmaps from movies using DirectShow

By | 4 Sep 2001 | Article
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

About the Author

Markus Axelsson



Sweden Sweden

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questionselect output device Pin Pinmemberkinani6:32 11 Aug '11  
GeneralThank you PinmemberXiaohu Shao17:08 26 Jul '10  
Generalerror C2504: 'IDXEffect' and error C2787: 'IVideoWindow' : PinmemberVirex_A14:54 30 Oct '08  
Generalcan't grub from the "*.mp4" Pinmemberlaguna_leo5:23 27 Sep '08  
Generalto all - if doesn't run DX9 Pinmembergrandmasta10:20 26 Aug '07  
QuestionUrgent Problem... PinmemberTushar Jadhav19:22 22 Jun '07  
Generalimage won't fit to picturebox(CStatic) PinmemberEd_lon20:49 17 May '07  
Generalhi Pinmembervikram panwar23:54 26 Mar '07  
GeneralRe: hi Pinmemberrajendra@yahoo.com21:07 27 Mar '07  
GeneralIt Does not run in Win2k Pinmemberrajendra@yahoo.com6:45 22 Mar '07  
QuestionThe other way around Pinmembershfnet4:29 13 Mar '07  
AnswerRe: The other way around Pinmembertanvon malik17:57 21 Nov '07  
Questionhow vedio file(mpeg4) is streamed PinmemberMember #248359418:38 15 Feb '07  
GeneralProblem opening file with bad indexes PinmemberSbarBaz6:07 29 Sep '06  
GeneralConflict between directshow and wmplayer. Help! Pinmemberaritosteles12:13 10 Sep '06  
GeneralError when compiling Pinmemberarindam_stcet4:19 3 May '06  
GeneralError: Could not grab the frame. PinmemberVenu Gopal Lolla19:09 13 Feb '06  
GeneralRe: Error: Could not grab the frame. Pinmemberbeatbox2:50 24 Mar '06  
QuestionTheoretical misunderstanding of a process Pinmemberwhitesail13:25 6 Dec '05  
Generalcouldnt compile PinmemberUsman mani22:50 16 Mar '05  
GeneralError saving the grabbed frame to bmp file PinmemberA. Asif Raza10:38 15 Mar '05  
I used the given code in my application. The filter graph seems to be working fine and i dont get any error at compile or run time. To test whether the frame is grabbed successfuly or not I am using the following code to write the grabbed frame to a bmp file:
 

BOOL CMainDialog::WriteDIB(LPTSTR szFile, HANDLE hDIB)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
 
if (!hDIB)
{
OutputDebugString(TEXT("No image in hDIB\n"));
return FALSE;
}
 
CFile file;
if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
{
OutputDebugString(TEXT("Error opening the file..\n"));
return FALSE;
}
 
lpbi = (LPBITMAPINFOHEADER)hDIB;
 
int nColors = 1 << lpbi->biBitCount;
 
// Fill in the fields of the file header
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biBitCount +
nColors * sizeof(RGBQUAD));
 
// Write the file header
file.Write( &hdr, sizeof(hdr) );
 
// Write the DIB header and the bits
file.Write( lpbi, GlobalSize(hDIB) );
 
return TRUE;
}

 
I pass the bmp file name and the hBitmap handle to the above function, and i get the following error at run-time:
 
First-chance exception at 0x0041c600 in LPR.exe: 0xC0000005: Access violation reading location 0xccccccda.
Unhandled exception at 0x0041c600 in LPR.exe: 0xC0000005: Access violation reading location 0xccccccda.
 
on line:
int nColors = 1 << lpbi->biBitCount;
 
I've been trying to figure out what have i done wrong and where.. but so far i am unable to find out. So any help regarding this shall be highly appreciated.
 
[The above code has been taken from: http://www.codeguru.com/Cpp/G-M/bitmap/article.php/c1697/ ]
Questionhow to grab images from .mov files Pinmembersrkrishna4:23 25 Jan '05  
GeneralNo Video and Audio Pinmemberbozitaai19:32 11 Jan '05  
Generali got this error while building this project Pinmemberslucky15:19 18 Dec '04  
GeneralRe: i got this error while building this project PinmemberJohn4420:59 20 Dec '04  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120528.1 | Last Updated 5 Sep 2001
Article Copyright 2001 by Markus Axelsson
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid