1:首先可以直接从directX C++ 9.0 帮助文档中搜索 :《Capturing an Image From a Still Image Pin》这篇文章,里面有详细的讲解。
不过在具体应用中,还是有一点小小的改变,一下做具体讲解。
1:
HRESULT CCaptureVideo::CaptureStillPin()//捕获函数;
{
//m_pMC->Run(); // Run the graph.
IAMVideoControl *pAMVidControl = NULL;
HRESULT hr = m_pBF->QueryInterface(IID_IAMVideoControl, (void**)&pAMVidControl);
if (SUCCEEDED(hr))
{
// Find the still pin.
IPin *pPin = 0;
hr = /*pBuild*/m_pCapture->FindPin(/*pCap*/m_pBF, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, 0, FALSE, 0, &pPin);
if (SUCCEEDED(hr))
{
hr = pAMVidControl->SetMode(pPin, VideoControlFlag_Trigger);
pPin->Release();
}
pAMVidControl->Release();
}
return S_OK;
}
原文中,捕获开始 运行链路m_pMC->Run();
一般情况,会直接先运行链路,当需要的时候直接捕获,所以当链路已经运行了,就不需要每次捕获的时候每次执行m_pMC->Run();
2:关于回调函数class SampleGrabberCallback : public ISampleGrabberCB的类实现,直接复制帮助文档,注意路径的设置;
3:建立连接,捕获图像;
方法在帮助文档中已经提到: 静态pin -》 ISampleGrabber -》 nullrender;
但是这样连接会有小小的问题,就是当颜色空间不是rgb的时候就无法直接捕获图像了;
所以处理方法修改为:
连接filter之前先设置ISampleGrabber的媒体类型为rgb;
{
AM_MEDIA_TYPE mt;
ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
mt.formattype = FORMAT_VideoInfo;
pSG->SetMediaType(&mt);
}
然后在连接;
4:当filter有静态pin,同时还要preview pin 时,要先连接preview pin;
5:下面是简单代码:
{
//2
// Add the Sample Grabber filter to the graph.
IBaseFilter *pSG_Filter;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,IID_IBaseFilter, (void**)&pSG_Filter);
hr = /*pGraph*/m_pGB->AddFilter(pSG_Filter, L"SampleGrab1");
// Add the Null Renderer filter to the graph.
IBaseFilter *pNull;
hr = CoCreateInstance( CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNull);
hr = m_pGB->AddFilter(pNull, L"NullRender1");
//3//这一步放到第六步之前,可以设置媒体类型;
// hr = m_pCapture->RenderStream( &PIN_CATEGORY_STILL, // Connect this pin ...
// &MEDIATYPE_Video, // with this media type ...
// m_pBF, // on this filter ...
// pSG_Filter, // to the Sample Grabber ...
// /*pNull*/NULL); // ... and finally to the Null Renderer.
//ConnectFilters( m_pBF, pNull );
//4
// Configure the Sample Grabber.
//ISampleGrabber *pSG;
hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
pSG->SetOneShot(FALSE);
pSG->SetBufferSamples(TRUE);
//5
pSG->SetCallback(&g_StillCapCB, 1); // 0 = Use the SampleCB callback method.//这一步设置为1,当有数据,直接捕获;
{
AM_MEDIA_TYPE mt;
ZeroMemory(&mt,sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
mt.formattype = FORMAT_VideoInfo;
pSG->SetMediaType(&mt);
}
hr = m_pCapture->RenderStream( &PIN_CATEGORY_STILL, // Connect this pin ...
&MEDIATYPE_Video, // with this media type ...
m_pBF, // on this filter ...
pSG_Filter, // to the Sample Grabber ...
/*pNull*/NULL);
//6
// Store the media type for later use.
//AM_MEDIA_TYPE g_StillMediaType;
hr = pSG->GetConnectedMediaType(&g_StillMediaType);
pSG->Release();
}
m_pMC->Run();//运行整个链路;