然后通过renderstream将still pin ,sample grabber ,null renderer连接起来
hr = pbuild->renderstream(然后调用isamplegrabber指针,来通过这个指针可以分配内存。
&pin_category_still, // connect this pin ...
&mediatype_video, // with this media type ...
pcap, // on this filter ...
psg_filter, // to the sample grabber ...
pnull); // ... and finally to the null renderer.
// configure the sample grabber.设置你的回调对象
isamplegrabber *psg;
hr = psg_filter->queryinterface(iid_isamplegrabber, (void**)&psg);
psg->setoneshot(false);
psg->setbuffersamples(true);
psg->setcallback(&g_stillcapcb, 0); // 0 = use the samplecb callback method获取静态pin和sample grabber之间连接所用的媒体类型
// store the media type for later use.媒体类型包含一个bitmapinfoheader结构来定义图片的格式,在程序退出前一定要释放媒体类型
am_media_type g_stillmediatype;
hr = psg->getconnectedmediatype(&g_stillmediatype);
psg->release();
// on exit, remember to release the media type.看看下面的回调类吧。这个类从isamplegrabber接口派生,但是它没有保持引用计数,因为应用程序在堆上创建这个对象,在整个graph的生存周期它都存在。
freemediatype(g_stillmediatype);
所有的工作都在buffercb函数里完成,当有一个新的sample到来的时候,这个函数就会被sample grabber调用到。在下面的例子里,bitmap被写入到一个文件中
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;}
};