Need a callback per frame

I've tried using EC_VMR_SURFACE_FLIPPED to get a message on every frame but it never happens. I know I'm doing something wrong but com is so convoluted and I haven't been able to find anyone who has attempted to do what I'm doing. I just need a function call on every frame to sync the dshow frames with another library. Anyone know the best way to do this? I'd like to avoid the overhead of the sample grabber copying the buffer over every frame since I won't use the data.

Thanks,

Jake

[503 byte] By [willowUfgood] at [2008-1-4]
# 1
You can use the Sample grabber for this if you configure it correctly. After you create the sample grabber, and set it's media type, call:

ISampleGrabber::SetCallback( pMyCallback, 0 );

The zero tells the sample grabber to call you back with a pointer to the original media sample. No data copy is made.

See ISampleGrabber::SetCallback docs for more info.

Also see Using the Sample Grabber.

-Nick

nickhaddady at 2007-9-26 > top of Msdn Tech,Software Development for Windows Vista,DirectShow Development...
# 2
Works great. Thanks for the help.

Jake

willowUfgood at 2007-9-26 > top of Msdn Tech,Software Development for Windows Vista,DirectShow Development...
# 3

Read this post and I think that it would help me also. All I need to for a function to be called when the frame is updated (I don't need the buffer) but I'm having a problem with setting up the callback, I want to call VideoFrame() on each frame, but I'm at a loss to set this up (old time C programmer who struggles w/ C++):

void VideoFrame();

BOOL Play(HWND hChildWnd, LPCWSTR szFileName, int top, int left);

IGraphBuilder *pGraph = NULL;

IMediaControl *pMediaControl = NULL;

IMediaEventEx *pEvent = NULL;

IVideoWindow *pVidWin = NULL;

IMediaSeeking *pMediaSeeking = NULL; // For playback speed

IBaseFilter *pGrabberF = NULL;

ISampleGrabber *pGrabber;

BOOL Play(HWND hChildWnd, LPCWSTR szFileName, int top, int left)

{

AM_MEDIA_TYPE mt;

ISampleGrabberCB *pGrabberCB = NULL;

hr = CoInitialize(NULL);

// initialize Graph

hr = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&pGraph );

// Load the File to render

hr = pGraph->RenderFile(szFileName, NULL);

//Add Sample grabber filter and interface

hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pGrabberF);

hr = pGraph->AddFilter(pGrabberF, L"Sample Grabber");

ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = MEDIASUBTYPE_RGB24;

hr = pGrabber->SetMediaType(&mt);

hr = pGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);

hr = pGrabber->SetCallback((ISampleGrabberCB *)VideoFrame,(long)0); <FAILS

//....Sets Events Notification, other stuff

}

void VideoFrame()

{

iVideoFrame++;

}

Thank you,

-- Justin

Chandler at 2007-9-26 > top of Msdn Tech,Software Development for Windows Vista,DirectShow Development...
# 4
Sorry for the late reply, just noticed this. SetCallback is taking in a class, not a function. So you you need to put the code from VideoFrame into the virtual function BufferCB in a class you create that inherits from ISampleGrabberCB. Oh, so you know we actually had to abandon this way of doing things and went with a timer. We kept getting deadlocks from dshow when we tried stopping and starting the graph. Good luck.

Jake

willowUfgood at 2007-9-26 > top of Msdn Tech,Software Development for Windows Vista,DirectShow Development...

Software Development for Windows Vista

Site Classified