Directshow中的视频捕捉[8]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 aoosang 的 blog

然后通过renderstream将still pin ,sample grabber ,null renderer连接起来

 hr = pbuild->renderstream(
&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.
然后调用isamplegrabber指针,来通过这个指针可以分配内存。
  // 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.
am_media_type g_stillmediatype;
hr = psg->getconnectedmediatype(&g_stillmediatype);
psg->release();
媒体类型包含一个bitmapinfoheader结构来定义图片的格式,在程序退出前一定要释放媒体类型
 // on exit, remember to release the media type.
freemediatype(g_stillmediatype);
看看下面的回调类吧。这个类从isamplegrabber接口派生,但是它没有保持引用计数,因为应用程序在堆上创建这个对象,在整个graph的生存周期它都存在。
所有的工作都在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;

}
};

本文关键:Directshow中的视频捕捉
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top