// Create + setup an device, IGraphBuilder and ICaptureGraphBuilder = user must realease all bool VideoCaptureDirectShow2::initCaptureGraphBuilderForDevice(int device, IBaseFilter** deviceFilter, IGraphBuilder** graphBuilder, ICaptureGraphBuilder2** captureBuilder) { // Setup the ICaptureGraphBuilder2 + IGraphBuilder if(!initCaptureGraphBuilder(graphBuilder, captureBuilder)) { RX_ERROR("Cannot initialize the capture graph builder for a device"); return false; } // Get the device filter that we add to the graph if(!createDeviceFilter(device, deviceFilter)) { RX_ERROR("Cannot find device to setup a graph"); safeReleaseDirectShow(graphBuilder); safeReleaseDirectShow(captureBuilder); return false; } // Add the device to the graph. HRESULT hr = (*graphBuilder)->AddFilter(*deviceFilter, L"Video Capture Device"); if(FAILED(hr)) { RX_ERROR("Error while trying to add the capture device to the graph"); safeReleaseDirectShow(graphBuilder); safeReleaseDirectShow(captureBuilder); safeReleaseDirectShow(deviceFilter); return false; } return true; }
bool VideoCaptureDeviceImpl::initCaptureGraph() { if(!initCaptureGraphBuilder()) { return false; } if (!buildCaptureGraph()) { return false; } if (!initSampleGrabber()) { return false; } if (!initSampleGrabberCallback()) { return false; } if (!initMediaControl()) { return false; } if (!initStreamConfig()) { return false; } initVideoControl(); return true; }
bool MIPDirectShowCapture::open(int width, int height, real_t frameRate, int deviceNumber) { if (m_pGraph != 0) { setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_ALREADYOPEN); return false; } if (!initCaptureGraphBuilder()) return false; if (!getCaptureDevice(deviceNumber)) { clearNonZero(); return false; } std::list<GUID> guids; std::list<GUID>::const_iterator guidIt; if (!listGUIDS(guids)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTLISTGUIDS); return false; } bool haveI420 = false; bool haveYUY2 = false; for (guidIt = guids.begin() ; guidIt != guids.end() ; guidIt++) { if (*guidIt == EMIP_MEDIASUBTYPE_I420) haveI420 = true; if (*guidIt == MEDIASUBTYPE_YUY2) haveYUY2 = true; } if (haveI420) { //std::cout << "Trying I420" << std::endl; m_selectedGuid = EMIP_MEDIASUBTYPE_I420; m_subType = MIPRAWVIDEOMESSAGE_TYPE_YUV420P; } else if (haveYUY2) { //std::cout << "Trying YUY2" << std::endl; m_selectedGuid = MEDIASUBTYPE_YUY2; m_subType = MIPRAWVIDEOMESSAGE_TYPE_YUYV; } else { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTSELECTYUV420PORYUY2); return false; } HRESULT hr; hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,(void **)(&m_pNullRenderer)); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTCREATENULLRENDERER); return false; } hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter,(void **)(&m_pSampGrabFilter)); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTCREATEGRABFILTER); return false; } hr = m_pSampGrabFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_pGrabber); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTCREATEGRABIFACE); return false; } AM_MEDIA_TYPE mt; ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; mt.subtype = m_selectedGuid; hr = m_pGrabber->SetMediaType(&mt); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTSELECTYUV420PORYUY2); return false; } m_pGrabCallback = new GrabCallback(this); hr = m_pGrabber->SetCallback(m_pGrabCallback, 1); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTSETCALLBACK); return false; } hr = m_pGraph->AddFilter(m_pCaptDevice, L"Capture Filter"); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTADDCAPTUREFILTER); return false; } if (!setFormat(width, height, frameRate)) { clearNonZero(); return false; } hr = m_pGraph->AddFilter(m_pNullRenderer, L"Null Renderer"); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTADDNULLRENDERER); return false; } hr = m_pGraph->AddFilter(m_pSampGrabFilter, L"Sample Grabber"); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTADDSAMPLEGRABBER); return false; } hr = m_pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pCaptDevice, m_pSampGrabFilter, m_pNullRenderer); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTBUILDGRAPH); return false; } hr = m_pGrabber->GetConnectedMediaType(&mt); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTGETFRAMESIZE); return false; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mt.pbFormat; m_width = vih->bmiHeader.biWidth; m_height = vih->bmiHeader.biHeight; CoTaskMemFree(mt.pbFormat); hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pControl); if (HR_FAILED(hr)) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTGETCONTROLINTERFACE); return false; } if (m_selectedGuid == EMIP_MEDIASUBTYPE_I420) m_largeFrameSize = (size_t)((m_width*m_height*3)/2); else m_largeFrameSize = (size_t)(m_width*m_height*2); m_pFullFrame = new uint8_t [m_largeFrameSize]; m_pMsgFrame = new uint8_t [m_largeFrameSize]; memset(m_pMsgFrame, 0, m_largeFrameSize); memset(m_pFullFrame, 0, m_largeFrameSize); if (m_subType == MIPRAWVIDEOMESSAGE_TYPE_YUV420P) m_pVideoMsg = new MIPRawYUV420PVideoMessage(m_width, m_height, m_pMsgFrame, false); else // MIPRAWVIDEOMESSAGE_TYPE_YUYV m_pVideoMsg = new MIPRawYUYVVideoMessage(m_width, m_height, m_pMsgFrame, false); if (!m_sigWait.init()) { clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTINITSIGWAIT); return false; } m_captureTime = MIPTime::getCurrentTime(); m_gotMsg = false; m_gotFrame = false; hr = m_pControl->Run(); if (hr != S_OK && hr != S_FALSE) // Apparently S_FALSE is returned if the graph is preparing to run { m_sigWait.destroy(); clearNonZero(); setErrorString(MIPDIRECTSHOWCAPTURE_ERRSTR_CANTSTARTGRAPH); return false; } m_sourceID = 0; return true; }