I would like to use a callbackfuntion to the sample grabber for directshow,
this to save an image for every frame.
using Visual C++.net (on Windows XP, directX 9.0 SDK), with Logitech Webcam
I have no errors on my code, but the callback-function is not working, the
file is not saved. The callback function is the same as in the
documentation example.
I ame searching for two days on this same code over and over again and seem
not to find the problem, can please someone help me?
The callback function should create a file c:\Example.bmp , however this is
not happing, but no errors to.
I hope and pray someone can help me?
My application:
1. I create the class to hold the callback function
class SampleGrabberCallback : public ISampleGrabberCB
{
public:
// Fake referance counting.
STDMETHODIMP_(ULONG) AddRef() { return 1; }
STDMETHODIMP_(ULONG) Release() { return 2; }
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
{
if (NULL == ppvObject) return E_POINTER;
if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}
if (riid == __uuidof(ISampleGrabberCB))
{
*ppvObject = static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP SampleCB(double Time, IMediaSample *pSample)
{
return E_NOTIMPL;
}
STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen)
{
if ((g_StillMediaType.majortype != MEDIATYPE_Video) ||
(g_StillMediaType.formattype != FORMAT_VideoInfo) ||
(g_StillMediaType.cbFormat < sizeof(VIDEOINFOHEADER)) ||
(g_StillMediaType.pbFormat == NULL))
{
return VFW_E_INVALIDMEDIATYPE;
}
HANDLE hf = CreateFile("C:\\Example.bmp", GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
if (hf == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
long cbBitmapInfoSize = g_StillMediaType.cbFormat - SIZE_PREHEADER;
VIDEOINFOHEADER *pVideoHeader =
(VIDEOINFOHEADER*)g_StillMediaType.pbFormat;
BITMAPFILEHEADER bfh;
ZeroMemory(&bfh, sizeof(bfh));
bfh.bfType = 'MB'; // Little-endian for "MB".
bfh.bfSize = sizeof( bfh ) + BufferLen + cbBitmapInfoSize;
bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + cbBitmapInfoSize;
// Write the file header.
DWORD dwWritten = 0;
WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
WriteFile(hf, HEADER(pVideoHeader), cbBitmapInfoSize, &dwWritten, NULL);
WriteFile( hf, pBuffer, BufferLen, &dwWritten, NULL );
CloseHandle( hf );
return S_OK;
}
};
2. I define global instance of the class.
SampleGrabberCallback g_StillCapCB;
3. Building graph, graphbuilder, sample grabber, ..
... building graph (ppgraph2), ICaptureGraphBuilder2(ppbuild2), and render
CAPTURE ...
// Create the Sample Grabber.
// Global instance of the class.
// Add the Sample Grabber filter to the graph.
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pSG_Filter);
hr = ppGraph2->AddFilter(pSG_Filter, L"SampleGrab");
// Add the Null Renderer filter to the graph.
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pNull);
hr = ppGraph2->AddFilter(pNull, L"NullRender");
hr = ppBuild2->RenderStream(
&PIN_CATEGORY_STILL, // Connect this pin ...
&MEDIATYPE_Video, // with this media type ...
pCap2, // on this filter ...
pSG_Filter, // to the Sample Grabber ...
pNull); // ... and finally to the Null Renderer.
// Configure the Sample Grabber.
hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
pSG->SetOneShot(FALSE);
pSG->SetBufferSamples(TRUE);
pSG->SetCallback(&g_StillCapCB, 0);
//Get the media type that the still pin used to connect with the Sample
Grabber:
// Store the media type for later use.
hr = pSG->GetConnectedMediaType(&g_StillMediaType);
pSG->Release();
//add media controlers to graph
ppGraph2->QueryInterface(IID_IMediaControl, (void **)&pControl2);
ppGraph2->QueryInterface(IID_IMediaEvent, (void **)&pEvent2);
//query the Filter Graph Manager for the IVideoWindow interface:
ppGraph2->QueryInterface(IID_IVideoWindow, (void **)&pVidWin2);
//assign the handler
pVidWin2->put_Owner((OAHWND)pWnd2->GetSafeHwnd());
//voeg style toe
pVidWin2->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
//stretch window over eigen window
RECT grc;
GetClientRect(pWnd2->GetSafeHwnd(), &grc);
pVidWin2->SetWindowPosition(0, 0, grc.right, grc.bottom);
pControl2->Run();
GreetingZ
Wes
> I would like to use a callbackfuntion to the sample grabber for directshow,
> this to save an image for every frame.
A better approach than the sample grabber, IMO, is to use a custom
renderer.
Have you debugged your program? Are any of the CB methods you expect being
called?
Does the SDK sample work on your machine? If so, what are you doing
differently? (check in the debugger)
--
Please read this before replying:
1. Learn about newsgroups - http://dev.6581.com/newsgroups.html
2. Trim & respond in-line (please don't top post or snip everything)
3. Benefit others - follow up if you are helped or you found a solution
Regarding the sample grabber callback function, I have found what the
problem was. I use the renderstream from the STILL pin, but I did not
trigger the still pin in my code, as soon as I added the code to trigger the
pin, one sample was grabbed from the stream.
So I realized this was not what I need, now I have set my callback function
on the CAPTURE render and it is working beautiful, thx for support.
GreetingZ
Wes
"The March Hare [MVP]" <ph...@ndsm.maps> wrote in message
news:nbotcuhn5vz0.m...@40tude.net...