21,597
社区成员
发帖
与我相关
我的任务
分享
while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr))
{
//add the evCode to a int array[]
}
HRESULT DSComment::CreatFilterGraph(){
HRESULT hr;
cli::pin_ptr<IGraphBuilder *> ppGraphManager = &pGraphManager;
cli::pin_ptr<ICaptureGraphBuilder2 *> ppCapture = &pCapture;
if(!ppGraphManager || !ppCapture){
return E_POINTER;
}
hr = CoCreateInstance (
CLSID_FilterGraph,
NULL,
CLSCTX_INPROC_SERVER, //for add grephedit
IID_IGraphBuilder,
(void **) ppGraphManager
);
if (FAILED(hr)){
MessageBox::Show("Initial IFilterGraph2 failed!");
return E_NOINTERFACE;
}
// Create the capture graph builder
hr = CoCreateInstance (
CLSID_CaptureGraphBuilder2,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2,
(void **) ppCapture
);
if (FAILED(hr)){
MessageBox::Show("Initial ICaptureGraphBuilder2 failed!");
return E_NOINTERFACE;
}
return S_OK;
}
HRESULT DSComment::CreatGrabberFilter(){
HRESULT hr;
cli::pin_ptr<IBaseFilter *> ppGrabberBaseFilter = &pGrabberBaseFilter;
hr = CoCreateInstance(
CLSID_SampleGrabber,
NULL,
CLSCTX_INPROC_SERVER,
IID_IBaseFilter,
(void**)ppGrabberBaseFilter
);
if (FAILED(hr))
{
MessageBox::Show("Couldn't create sample grabber filter base!");
return E_NOINTERFACE;
}
cli::pin_ptr<ISampleGrabber *> ppGrabber = &pGrabber;
pGrabberBaseFilter->QueryInterface(IID_ISampleGrabber, (void**)ppGrabber);
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
FreeMediaType(mt);
return hr;
}
HRESULT DSComment::CreatCaptureFilter(){
HRESULT hr;
ULONG cFetched;
const char* CAPTUREDEVNAME;
CAPTUREDEVNAME = "USB 视频设备";
cli::pin_ptr<IBaseFilter *> ppCaptureBaseFilter = &pCaptureBaseFilter;
// Create the system device enumerator
ICreateDevEnum *pDevEnum =NULL;
hr = CoCreateInstance (
CLSID_SystemDeviceEnum,
NULL,
CLSCTX_INPROC,
IID_ICreateDevEnum,
(void **) &pDevEnum
);
if (FAILED(hr)){
MessageBox::Show("Couldn't create system enumerator!");
return E_NOINTERFACE;
}
// Create an enumerator for the video capture devices
IEnumMoniker *pClassEnum = NULL;
hr = pDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory,
&pClassEnum,
0
);
if (FAILED(hr)){
MessageBox::Show("Couldn't create class enumerator!");
return E_NOINTERFACE;
}
// If there are no enumerators for the requested type, then
// CreateClassEnumerator will succeed, but pClassEnum will be NULL.
if (pClassEnum == NULL){
MessageBox::Show("No video capture device was detected.\r\n\r\n \
This sample requires a video capture device, such as a USB WebCam,\r\n \
to be installed and working properly. The sample will now close. \
No Video Capture Hardware");
return E_FAIL;
}
IMoniker *pMoniker = NULL;
// Use the first video capture device on the device list.
// Note that if the Next() call succeeds but there are no monikers,
// it will return S_FALSE (which is not a failure). Therefore, we
// check that the return code is S_OK instead of using SUCCEEDED() macro.
if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched))){
// Bind Moniker to a filter object
hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)ppCaptureBaseFilter);
IPropertyBag *pPropBag = NULL;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
if (FAILED(hr)){
pMoniker->Release();
return E_NOINTERFACE;
}
VARIANT var;
VariantInit(&var);
// Get description or friendly name.
hr = pPropBag->Read(L"Description", &var, 0);
if (FAILED(hr)){
hr = pPropBag->Read(L"FriendlyName", &var, 0);
}
if (SUCCEEDED(hr)){
String^ strCaptureDevName = String(var.bstrVal).ToString();
if(!strCaptureDevName->CompareTo(String(CAPTUREDEVNAME).ToString())){
hr = S_OK;
}else{
hr = E_FAIL;
return hr;
}
}
pPropBag->Release();
}else{
MessageBox::Show("Unable to access video capture device!");
return E_FAIL;
}
pMoniker->Release();
pClassEnum->Release();
pDevEnum->Release();
return hr;
}
HRESULT DSComment::BuiltFilterGraph(){
HRESULT hr;
pGraphManager->AddFilter(pCaptureBaseFilter, L"Capture Device");
pGraphManager->AddFilter(pGrabberBaseFilter, L"Sample Grabber Filter");
pCapture->SetFiltergraph(pGraphManager);
pCapture->RenderStream(
&PIN_CATEGORY_PREVIEW,
&MEDIATYPE_Video,
pCaptureBaseFilter,
pGrabberBaseFilter,
NULL
);
cli::pin_ptr<IVideoWindow *> ppVW = &pVW;
cli::pin_ptr<IMediaControl *> ppMC = &pMC;
cli::pin_ptr<IMediaEventEx *> ppME = &pME;
hr = pGraphManager->QueryInterface(IID_IMediaControl,(LPVOID *) ppMC);
if (FAILED(hr)){
MessageBox::Show("Initial IMediaControl failed!");
return E_NOINTERFACE;
}
hr = pGraphManager->QueryInterface(IID_IMediaEvent, (LPVOID *) ppME);
if (FAILED(hr)){
MessageBox::Show("Initial IMediaEventEx failed!");
return E_NOINTERFACE;
}
hr = pGraphManager->QueryInterface(IID_IVideoWindow, (LPVOID *) ppVW);
if (FAILED(hr)){
MessageBox::Show("Initial IVideoWindow failed!");
return E_NOINTERFACE;
}
}
BYTE* DSComment::SnapStillImage(long* size){
HRESULT hr;
pMC->Stop();
hr = pGrabber->SetBufferSamples( TRUE );
// Only grab one at a time, stop stream after
// grabbing one sample
//
hr = pGrabber->SetOneShot( FALSE );
pMC->Run();
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××
//就是在这里除了Sleep难道没有别的方法可以保证GetCurrentBuffer成功??
//×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
long cbBuffer;
hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
if (FAILED(hr))
{
MessageBox::Show("GetCurrentBuffer Fail!");
}
BYTE *pBuffer = (BYTE*)CoTaskMemAlloc(cbBuffer);
if (!pBuffer)
{
MessageBox::Show("CoTaskMemAlloc Fail!");
}
hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
if (FAILED(hr))
{
MessageBox::Show("GetCurrentBuffer Fail!");
}
hr = pGrabber->SetOneShot( FALSE );
AM_MEDIA_TYPE mt;
hr = pGrabber->GetConnectedMediaType(&mt);
if (FAILED(hr))
{
MessageBox::Show("GetConnectedMediaType Fail!");
}
VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)mt.pbFormat;
long cbBMI = mt.cbFormat - SIZE_PREHEADER;
long captureSize = cbBMI + cbBuffer + sizeof(BITMAPFILEHEADER);
*size = captureSize;
BYTE *pCaptrue = (BYTE*)CoTaskMemAlloc(captureSize);
BITMAPFILEHEADER bmf = { };
bmf.bfType = 'MB';
bmf.bfSize = captureSize;
bmf.bfOffBits = sizeof(bmf) + cbBMI;
memcpy(pCaptrue, &bmf, sizeof(bmf));
memcpy((pCaptrue + sizeof(bmf)), &pVih->bmiHeader, cbBMI);
memcpy((pCaptrue + sizeof(bmf) + cbBMI), pBuffer, cbBuffer);
return pCaptrue;
}
SetBufferSamples( TRUE ) ;
SetOneShot( TRUE )
也能抓图,只是预览视频的功能停止了。看MSDN上说setoneshot后会给后面的render发一个IPin::endstream(可能不准确,大意是告诉后面的render没有vidoe stream了),这个能否通过操作IPin继续恢复视频预览的功能?
对于GetCurrentBuffer,是不是除了sleep,只能配合setoneshot(TRUE),然后设置IMediaControl::waitforcomple(INFINITE, &EvCode)来完成sample的buffer?不能通过IMediaEvent::getevente或IMediaControl::getstate的方法获得么?
我现在最想知道的是GetCurrentBuffer这条路是否能走的通,实在不行就转callback了,之前也尝试过callback模式,有点问题没有继续深入~~~
再次感此Huntercao的指教