视频问题,从摄像头流中捕捉一张图片。用ISampleGrabber方法
用ISampleGrabber方法。 显示窗口已经能显示图像。
HRESULT StartDisplay(HWND hwnd) // 显示
{
HRESULT hr = S_OK;
hr = BuilderSendGraph(); // 建立Graph
//Create Display Windows
pSendWindow->put_Owner((OAHWND)hwnd);
pSendWindow->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
pSendWindow->SetWindowPosition(0,0,300,300);
pSendWindow->put_Visible(OATRUE);
//Begin Send
hr = pSendControl->Run();
SnapStill(); // 此处开始抓取一张图片
}
以下是SnapStill()函数:
HRESULT SnapStill()
{
HRESULT hr;
long cbBuffer = 0;
/********** -->>>>>这句有问题************/
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
char *pBuffer = new char[cbBuffer];
if (!pBuffer) {
// Out of memory. Return an error code.
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
if(FAILED(hr)) return E_FAIL;
...... // 生成bmp文件
}
BuilderSendGraph()中的函数实现:
HRESULT BuilderSendGraph()
{
// 建立 Filter Graph
hr = CoCreateInstance((REFCLSID)CLSID_FilterGraph,NULL,
CLSCTX_INPROC_SERVER,
(REFIID)IID_IGraphBuilder,
(void**)&pSendGraph);
// 建立 Caputer Filter
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,
CLSCTX_INPROC,IID_ICaptureGraphBuilder2,
(void**)&pCaputerBuilder);
hr = pCaputerBuilder->SetFiltergraph(pSendGraph);
// 建立 SampleGrabber Filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pGrabberSample)
// 把pCaputerFilter和pGrabberSample加入filter
hr = pSendGraph->AddFilter(pCaputerFilter,L"Caputer Filter");
hr = pSendGraph->AddFilter(pGrabberSample, L"Sample Grabber");
// 查询各个接口
hr=pSendGraph->QueryInterface(IID_IMediaControl,(void**)&pSendControl);
hr=pSendGraph->QueryInterface(IID_IVideoWindow,(void**)&pSendWindow);
hr=pSendGraph->QueryInterface(IID_IMediaEvent,(void**)&pSendEvent);
hr=pGrabberSample->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
/***请问这里是不是还需要什么代码?***/
// 根据色深设置媒体类型
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
HDC hdc = GetDC(NULL);
int iBitDepth = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(NULL, hdc);
mt.majortype = MEDIATYPE_Video;
switch (iBitDepth)
{
case 8:
mt.subtype = MEDIASUBTYPE_RGB8;
break;
case 16:
mt.subtype = MEDIASUBTYPE_RGB555;
break;
case 24:
mt.subtype = MEDIASUBTYPE_RGB24;
break;
case 32:
mt.subtype = MEDIASUBTYPE_RGB32;
break;
default:
return E_FAIL;
}
hr = pGrabber->SetMediaType(&mt);
if(FAILED(hr)) return E_FAIL;
// 显示本地视频
hr = pCaputerBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,NULL,pCaputerFilter,NULL,NULL);
if(FAILED(hr)) return S_FALSE;
// 准备一祯
hr = pGrabber->SetOneShot(TRUE);
hr = pGrabber->SetBufferSamples(TRUE);
}
问题出在SnapStill()函数中的第一个GetCurrentBuffer处:
cbBuffer得到的值为空,这里hr返回的值VFW_E_WRONG_STATE,
msdn说:The filter has not received any samples yet. To deliver a sample, run or pause the graph.
但是在StartDisplay()中已经hr = pSendControl->Run();了.
请各位兄弟,前辈帮帮忙, 查了一个星期的资料了,又郁闷一个星期了。 谢谢~