- //捕捉视频设备
- HRESULT Sender::FindCaptureDevice(IBaseFilter ** ppSrcFilter)
- {
- HRESULT hr;
- IBaseFilter * pSrc = NULL;
- CComPtr <IMoniker> pMoniker =NULL;
- ULONG cFetched;
- if (!ppSrcFilter)
- return E_POINTER;
- // Create the system device enumerator
- CComPtr <ICreateDevEnum> pDevEnum =NULL;
- hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
- IID_ICreateDevEnum, (void **) &pDevEnum);
- // Create an enumerator for the video capture devices
- CComPtr <IEnumMoniker> pClassEnum = NULL;
- hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
- // If there are no enumerators for the requested type, then
- // CreateClassEnumerator will succeed, but pClassEnum will be NULL.
- if (pClassEnum == NULL)
- {
- return E_FAIL;
- }
- // 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 nKTAVMulticast.axot 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)))
- {
- pClassEnum->Next (1, &pMoniker, &cFetched);
- // Bind Moniker to a filter object
- hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);
- }
- else
- {
- return E_FAIL;
- }
- // Copy the found filter pointer to the output parameter.
- // Do NOT Release() the reference, since it will still be used
- // by the calling function.
- *ppSrcFilter = pSrc;
- return hr;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //通过显示名字添加filter
- BOOL Sender::AddFilterByDisplayName(
- IGraphBuilder *pGraph,
- WCHAR *wszDisplayName,
- LPCWSTR wszName,
- IBaseFilter **ppF)
- {
- HRESULT hr;
- IMoniker *pMoniker=NULL;
- if(!pGraph)
- return FALSE;
- IBaseFilter *pF=0;
- IBindCtx *pBindCtx;
- hr=CreateBindCtx(0,&pBindCtx);
- ULONG chEaten=0;
- hr= MkParseDisplayName(pBindCtx,wszDisplayName,&chEaten,&pMoniker);
- pBindCtx->Release();
- if(FAILED(hr))
- {
- return FALSE;
- }
- pMoniker->AddRef();
- hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pF);
- if (pF == NULL)
- {
- return FALSE;
- }
- hr = pGraph->AddFilter(pF, wszName);
- if (hr != NOERROR)
- {
- return FALSE;
- }
- *ppF = pF;
- pMoniker->Release();
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //通过CLSID添加Filter
- HRESULT Sender::AddFilterByCLSID(
- IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.
- const GUID& clsid, // CLSID of the filter to create.
- LPCWSTR wszName, // A name for the filter.
- IBaseFilter **ppF) // Receives a pointer to the filter.
- {
- if (!pGraph || ! ppF) return E_POINTER;
- *ppF = 0;
- IBaseFilter *pF = 0;
- HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter, reinterpret_cast<void**>(&pF));
- if (SUCCEEDED(hr))
- {
- hr = pGraph->AddFilter(pF, wszName);
- if (SUCCEEDED(hr))
- *ppF = pF;
- else
- pF->Release();
- }
- return hr;
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- 连接Filter
- HRESULT Sender::ConnectFilters(
- IGraphBuilder *pGraph, // Filter Graph Manager.
- IPin *pOut, // Output pin on the upstream filter.
- IBaseFilter *pDest) // Downstream filter.
- {
- if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
- {
- return E_POINTER;
- }
- #ifdef debug
- PIN_DIRECTION PinDir;
- pOut->QueryDirection(&PinDir);
- _ASSERTE(PinDir == PINDIR_OUTPUT);
- #endif
- // Find an input pin on the downstream filter.
- IPin *pIn = 0;
- HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
- if (FAILED(hr))
- {
- return hr;
- }
- // Try to connect them.
- hr = pGraph->Connect(pOut, pIn);
- pIn->Release();
- return hr;
- }
- HRESULT Sender::ConnectFilters(
- IGraphBuilder *pGraph,
- IBaseFilter *pSrc,
- IBaseFilter *pDest)
- {
- if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
- {
- return E_POINTER;
- }
- // Find an output pin on the first filter.
- IPin *pOut = 0;
- HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
- if (FAILED(hr))
- {
- return hr;
- }
- hr = ConnectFilters(pGraph, pOut, pDest);
- pOut->Release();
- return hr;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //得到未知Pin接口
- HRESULT Sender::GetUnconnectedPin(
- IBaseFilter *pFilter, // Pointer to the filter.
- PIN_DIRECTION PinDir, // Direction of the pin to find.
- IPin **ppPin) // Receives a pointer to the pin.
- {
- *ppPin = 0;
- IEnumPins *pEnum = 0;
- IPin *pPin = 0;
- HRESULT hr = pFilter->EnumPins(&pEnum);
- if (FAILED(hr))
- {
- return hr;
- }
- while (pEnum->Next(1, &pPin, NULL) == S_OK)
- {
- PIN_DIRECTION ThisPinDir;
- pPin->QueryDirection(&ThisPinDir);
- if (ThisPinDir == PinDir)
- {
- IPin *pTmp = 0;
- hr = pPin->ConnectedTo(&pTmp);
- if (SUCCEEDED(hr)) // Already connected, not the pin we want.
- {
- pTmp->Release();
- }
- else // Unconnected, this is the pin we want.
- {
- pEnum->Release();
- *ppPin = pPin;
- return S_OK;
- }
- }
- pPin->Release();
- }
- pEnum->Release();
- // Did not find a matching pin.
- return E_FAIL;
- }
本文介绍使用DirectShow在Windows平台上捕获视频设备的过程,并详细解释了如何通过不同方式添加过滤器到滤波器图,包括根据显示名称和CLSID添加过滤器的方法。

4300

被折叠的 条评论
为什么被折叠?



