Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / C++

Snapshot of Video Overlay

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
10 Aug 2010CPOL2 min read 26.9K   891   13  
Taking snapshots of video overlay using DirectShow

Introduction

This project will show a case to developers on the use of DirectShow to take screen shots of a video playback and dump the image to a folder. The function "InitWindowlessVMR" is picked up from MSDN (I did not see any reason to rewrite it).

Background

All of us have faced problems to take screen shots of video being played back using WMP (in Windows XP), this might help. The reason is that video play back uses an overlay method. (It bypasses the Windows standard rendering method (GDI) which is why print screen does not work.)

Using the Code

Please use the code along with the document. We start by creating the object: IGraphBuilder, we use CComPtr, it saves us the trouble of releasing the pointer (and does other few smart things for us).

C++
CComPtr<IGraphBuilder> pGraph=NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
		IID_IGraphBuilder, (void **)&pGraph); 

We then require to create a window using CreateWindow (no explanation is required for this). We must then set the object to windowless control and target the video rendering to it. This is done by calling "InitWindowlessVMR" and set the clipping window to the handle of the window we have just created by calling:

C++
pWc->SetVideoClippingWindow(hwndApp); 

We must then select the video file for which we are going to take screen shots:

C++
pGraph->RenderFile(L"MyMovie.avi", NULL); 

We will also require objects to control the playback (using IMediaControl). You may even want to use "IMediaSeeking" to jump to the frame for which screen shot is required (please refer to code).

C++
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); 

hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&pSeek);

After this, we start the movie play back using the pControl interface (of the type IMediaControl).

C++
pControl->Run();

Now comes the part to take snap shots

After adjusting the frame number for which the screen shot is being taken using pSeek (of the type IMediaSeeking), we use the windowless control interface (we get this object by calling InitWindowlessVMR) to get the current image.

C++
pWc->GetCurrentImage(&pb)
BITMAPINFOHEADER *pBMIH = (BITMAPINFOHEADER*) pb;

DWORD d=pBMIH->biSize+pBMIH->biSizeImage;

We then make use of DirectX9 to convert this image to a BMP or any other format supported by "D3DXSaveTextureToFile". DX9 is fast and a very efficient way of doing graphics manipulation (though my code does not optimize by creating DX9 objects outside the function scope so as to minimize DX9 creation calls).

Please refer to the attached code.

Notice that I create a texture object on the fly and then save it to the file.

C++
hr=D3DXCreateTextureFromFileInMemory(pd3dDevice,pb,d,&pTexture_Movie);
C++
D3DXSaveTextureToFile(_bstr_t("asif.bmp"),D3DXIFF_BMP ,pTexture_Movie,0); 

Points of Interest

With this, we learn a bit of DirectShow and a tad bit of DirectX9. We can do the same using DX10, DX11 based interfaces (but then that would make it a Windows Vista/7 code only).

You can try something even funkier by using movie textures in your game engines (for those who write DirectX9/10/11 code).

History

  • 10th August, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Instructor / Trainer
India India
Hi,
I have been working with computers since my eight grade, programming the ZX Spectrum. I have always had an interest in assembly language and computer theory (and is still the reason for taking tons of online courses), actively code using C/C++ on Windows (using VS) and Linux (using QT).

I also provide training on data structures, algorithms, parallel patterns library , Graphics (DX11), GPGPUs (DX11-CS,AMP) and programming for performance on x86.
Feel free to call me at 0091-9823018914 (UTC +5:30)



(All views expressed here do not reflect the views of my employer).

Comments and Discussions

 
-- There are no messages in this forum --