Getting multiple pictures with SampleGrabber

This page shows you how to grab multiple still image files from a video file, using SampleGrabber. Please note that error handling codes are omitted to keep the sample code simple.

Sample code

The following sample code shows how to use VMR9.

This sample saves three image files from a single mpeg video file. I hope this helps you find out how to get multiple frames from a video file.


#include <stdio.h>

#include <dshow.h>
#include <qedit.h> // for SampleGrabber

#define	FILENAME L"C:\\DXSDK\\Samples\\Media\\butterfly.mpg"

int
main()
{
 IGraphBuilder *pGraphBuilder;
 IMediaControl *pMediaControl;

 IBaseFilter *pSampleGrabberFilter;
 ISampleGrabber *pSampleGrabber;
 AM_MEDIA_TYPE am_media_type;

 // initialize COM
 CoInitialize(NULL);

 // create FilterGraph
 CoCreateInstance(CLSID_FilterGraph,
	NULL,
	CLSCTX_INPROC,
	IID_IGraphBuilder,
	(LPVOID *)&pGraphBuilder);

 // create SampleGrabber(Filter)
 CoCreateInstance(CLSID_SampleGrabber,
	 NULL,
	 CLSCTX_INPROC,
	 IID_IBaseFilter,
	 (LPVOID *)&pSampleGrabberFilter);

 // get ISampleGrabber interface from Filter
 pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber,
	 (LPVOID *)&pSampleGrabber);

 // determine the format for connecting SampleGrabber.
 // You can configure the SampleGrabber insertion place
 // by changing the values in this structure.
 // If you use the values in this sample,
 // you can get the video frame data right before
 // it is displayed.
 ZeroMemory(&am_media_type, sizeof(am_media_type));
 am_media_type.majortype = MEDIATYPE_Video;
 am_media_type.subtype = MEDIASUBTYPE_RGB24;
 am_media_type.formattype = FORMAT_VideoInfo;
 pSampleGrabber->SetMediaType(&am_media_type);

 // add SampleGrabber Filter to the Graph
 pGraphBuilder->AddFilter(pSampleGrabberFilter,
	 L"Sample Grabber");

 // get MediaControl interface
 pGraphBuilder->QueryInterface(IID_IMediaControl,
	(LPVOID *)&pMediaControl);

 // create Graph.
 // Graph that contains SampleGrabber
 // will be created automatically.
 pMediaControl->RenderFile(FILENAME);

 // Get connection information.
 // This must be done after the Graph is created
 // by RenderFile.
 pSampleGrabber->GetConnectedMediaType(&am_media_type);
 VIDEOINFOHEADER *pVideoInfoHeader =
     (VIDEOINFOHEADER *)am_media_type.pbFormat;

 // Print the width and height of the image.
 // This is just to make the sample understandable.
 // This is not a required feature.
 printf("size = %dx%d\n",
	 pVideoInfoHeader->bmiHeader.biWidth,
	 pVideoInfoHeader->bmiHeader.biHeight);

 // Print the data size.
 // This is just for understanding too.
 printf("sample size = %d\n",
	 am_media_type.lSampleSize);

 // Configure SampleGrabber to do grabbing.
 // Buffer data can not be obtained if you
 // do not use SetBufferSamples.
 // You can use SetBufferSamples after Run() too.
 pSampleGrabber->SetBufferSamples(TRUE);

 // start playing
 pMediaControl->Run();

 int i;
 for (i = 0; i < 3; i++) {
   // block execution
   MessageBox(NULL,
	"Block Execution",
	"Block",
	MB_OK);
   // BITMAP will be saved after OK is pressed

   // prepare buffer
   long nBufferSize = am_media_type.lSampleSize;
   long *pBuffer = (long *)malloc(nBufferSize);

   // grab image data.
   pSampleGrabber->GetCurrentBuffer(&nBufferSize,
       pBuffer);

   //
   // Save image data as Bitmap.
   // This is just to make this sample easily understandable.
   //
   HANDLE fh;
   BITMAPFILEHEADER bmphdr;
   DWORD nWritten;

   memset(&bmphdr, 0, sizeof(bmphdr));

   bmphdr.bfType = ('M' << 8) | 'B';
   bmphdr.bfSize = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER) + nBufferSize;
   bmphdr.bfOffBits = sizeof(bmphdr) + sizeof(BITMAPINFOHEADER);

   char filename[128];
   _snprintf(filename, sizeof(filename),
             "result%d.bmp", i);
   fh = CreateFile(filename,
                   GENERIC_WRITE, 0, NULL,
                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
   WriteFile(fh, &bmphdr, sizeof(bmphdr), &nWritten, NULL);
   WriteFile(fh,
       &pVideoInfoHeader->bmiHeader,
       sizeof(BITMAPINFOHEADER), &nWritten, NULL);
   WriteFile(fh, pBuffer, nBufferSize, &nWritten, NULL);
   CloseHandle(fh);

   free(pBuffer);
 } // end of for loop

 pMediaControl->Stop();

 // release
 pSampleGrabber->Release();
 pSampleGrabberFilter->Release();
 pMediaControl->Release();
 pGraphBuilder->Release();

 // finalize COM
 CoUninitialize();

 return 0;
}

This sample saves bitmap images as , result0.bmp, result1.bmp, result2.bmp. These bitmap files will be saved when you press the OK button on the MessageBox dialog. Please check the bitmap files created after executing this test application.

  

Copyright (C) GeekPage.JP. All rights reserved.