Sign in to follow this  
Skute

DirectShow: Getting a preview bitmap of a movie

Recommended Posts

Hi, Does anyone know how (or where i can start looking) i can create a preview bitmap of a movie in directshow? For example, when you click on a movie in windows, a little preview appears on the left hand pane of explorer. the preview image is the first frame of the movie. Any help would be gratefully received!! Cheers Skute

Share this post


Link to post
Share on other sites
Set up the filters etc. as you would to play the movie normally, but in your DoRenderSample() method (of your CBaseVideoRenderer-derived class) call
m_pMediaEventSink->Notify(EC_COMPLETE, S_OK, 0);
as soon as you receive a frame. So basically you play the movie, and stop it after you get the first frame.

At least, that's how I did it.

Share this post


Link to post
Share on other sites
Hmm, was hoping for a much simpler way of doing it than that, but thanks.

Im just taking a look at the IMediaDet interface at the moment, because its got a GetBitmapBits() function which im hoping will do the trick!

Cheers

Share this post


Link to post
Share on other sites
Another option if you don't want to have to implement your own renderer class is to set-up a graph like this.

File --> AVI Decoder --> Sample Grabber --> Null Renderer

You can simply set the Mediaposition to 0 and then tell MediaControl to pause the graph.

Then just get the first frame from the sample grabber.

For more details look at this post.

http://www.gamedev.net/community/forums/topic.asp?topic_id=275843

If you need any help with the code give me a shout, also CodeMunkie is infinately more knowledgable about this sort of thing and I am sure he is around somewhere..!

Mark Coleman

Share this post


Link to post
Share on other sites
You can do that?

I did mine the way I did because I couldn't get SampleGrabber to work... never did find out why. I just ended up implementing my own stuff based on CBaseVideoRenderer...

Share this post


Link to post
Share on other sites
Try this code, it accepts the filename of a movie to preview, and returns a handle to a bitmap:

Certainly works well for me!


HBITMAP CDirectShow::MakePreviewBitmap(const char* pszFileName)
{
HBITMAP hPreviewBMP = NULL;
IMediaDet* pMediaDet = NULL;
HRESULT hrReturn = CoCreateInstance(CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, IID_IMediaDet, reinterpret_cast<void **>(&pMediaDet));

if (SUCCEEDED(hrReturn))
{
WCHAR wszFileName[MAX_PATH];

MultiByteToWideChar(CP_ACP, 0, pszFileName, -1, wszFileName, MAX_PATH);

hrReturn = pMediaDet->put_Filename(static_cast<BSTR>(wszFileName));

if (SUCCEEDED(hrReturn))
{
long lSize = 0;
hrReturn = pMediaDet->GetBitmapBits(0, &lSize, 0, DEFAULT_TRACKITEM_SIZE, DEFAULT_TRACKITEM_SIZE);

if (SUCCEEDED(hrReturn))
{
char* pBuffer = new char[lSize];

hrReturn = pMediaDet->GetBitmapBits(0, NULL, pBuffer, DEFAULT_TRACKITEM_SIZE, DEFAULT_TRACKITEM_SIZE);
if (SUCCEEDED(hrReturn))
{
BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)pBuffer;
HDC hdcDest = GetDC(NULL);
void *pData = pBuffer + sizeof(BITMAPINFOHEADER);

BITMAPINFO bmi;
ZeroMemory(&bmi, sizeof(BITMAPINFO));
CopyMemory(&(bmi.bmiHeader), bmih, sizeof(BITMAPINFOHEADER));
hPreviewBMP = CreateDIBitmap(hdcDest, bmih, CBM_INIT, pData, &bmi, DIB_RGB_COLORS);
}

SAFE_ARRAY_DELETE(pBuffer);
}
}
}

return hPreviewBMP;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this