一些很好用的DirectShow自定义函数

本文介绍使用DirectShow在Windows平台上捕获视频设备的过程,并详细解释了如何通过不同方式添加过滤器到滤波器图,包括根据显示名称和CLSID添加过滤器的方法。
Code:
  1. //捕捉视频设备   
  2.   
  3. HRESULT Sender::FindCaptureDevice(IBaseFilter ** ppSrcFilter)   
  4. {   
  5.     HRESULT hr;   
  6.     IBaseFilter * pSrc = NULL;   
  7.     CComPtr <IMoniker> pMoniker =NULL;   
  8.     ULONG cFetched;   
  9.   
  10.     if (!ppSrcFilter)   
  11.         return E_POINTER;   
  12.       
  13.     // Create the system device enumerator   
  14.     CComPtr <ICreateDevEnum> pDevEnum =NULL;   
  15.   
  16.     hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,   
  17.                            IID_ICreateDevEnum, (void **) &pDevEnum);   
  18.   
  19.     // Create an enumerator for the video capture devices   
  20.     CComPtr <IEnumMoniker> pClassEnum = NULL;   
  21.   
  22.     hr = pDevEnum->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &pClassEnum, 0);   
  23.   
  24.   
  25.     // If there are no enumerators for the requested type, then    
  26.     // CreateClassEnumerator will succeed, but pClassEnum will be NULL.   
  27.     if (pClassEnum == NULL)   
  28.     {   
  29.         return E_FAIL;   
  30.     }   
  31.   
  32.     // Use the first video capture device on the device list.   
  33.     // Note that if the Next() call succeeds but there are no monikers,   
  34.     // it will return S_FALSE (which is nKTAVMulticast.axot a failure). Therefore, we   
  35.     // check that the return code is S_OK instead of using SUCCEEDED() macro.   
  36.     if (S_OK == (pClassEnum->Next (1, &pMoniker, &cFetched)))   
  37.     {   
  38.    pClassEnum->Next (1, &pMoniker, &cFetched);   
  39.         // Bind Moniker to a filter object   
  40.         hr = pMoniker->BindToObject(0,0,IID_IBaseFilter, (void**)&pSrc);   
  41.     }   
  42.     else  
  43.     {    
  44.         return E_FAIL;   
  45.     }   
  46.   
  47.     // Copy the found filter pointer to the output parameter.   
  48.     // Do NOT Release() the reference, since it will still be used   
  49.     // by the calling function.   
  50.     *ppSrcFilter = pSrc;   
  51.   
  52.     return hr;   
  53. }   
  54.   
  55. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  56.   
  57. //通过显示名字添加filter   
  58. BOOL Sender::AddFilterByDisplayName(   
  59.     IGraphBuilder *pGraph,    
  60.     WCHAR *wszDisplayName,   
  61.     LPCWSTR wszName,   
  62.     IBaseFilter **ppF)    
  63. {   
  64. HRESULT hr;   
  65. IMoniker *pMoniker=NULL;   
  66.   
  67. if(!pGraph)   
  68.    return FALSE;    
  69.   
  70. IBaseFilter *pF=0;   
  71.   
  72.   
  73. IBindCtx *pBindCtx;   
  74.   
  75. hr=CreateBindCtx(0,&pBindCtx);   
  76. ULONG chEaten=0;   
  77. hr= MkParseDisplayName(pBindCtx,wszDisplayName,&chEaten,&pMoniker);   
  78. pBindCtx->Release();   
  79.   
  80. if(FAILED(hr))   
  81. {   
  82.    return FALSE;   
  83. }   
  84.   
  85. pMoniker->AddRef();   
  86.   
  87. hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pF);   
  88. if (pF == NULL)    
  89. {   
  90.    return FALSE;   
  91. }   
  92.   
  93. hr = pGraph->AddFilter(pF, wszName);   
  94. if (hr != NOERROR)   
  95. {   
  96.      
  97.    return FALSE;   
  98. }   
  99. *ppF = pF;   
  100. pMoniker->Release();    
  101. return TRUE;    
  102. }   
  103.   
  104. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  105.   
  106. //通过CLSID添加Filter   
  107.   
  108. HRESULT Sender::AddFilterByCLSID(   
  109.     IGraphBuilder *pGraph, // Pointer to the Filter Graph Manager.   
  110.     const GUID& clsid,      // CLSID of the filter to create.   
  111.     LPCWSTR wszName,        // A name for the filter.   
  112.     IBaseFilter **ppF)      // Receives a pointer to the filter.   
  113. {   
  114.     if (!pGraph || ! ppF) return E_POINTER;   
  115.     *ppF = 0;   
  116.     IBaseFilter *pF = 0;   
  117.     HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,   
  118.         IID_IBaseFilter, reinterpret_cast<void**>(&pF));   
  119.     if (SUCCEEDED(hr))   
  120.     {   
  121.         hr = pGraph->AddFilter(pF, wszName);   
  122.         if (SUCCEEDED(hr))   
  123.             *ppF = pF;   
  124.         else  
  125.             pF->Release();   
  126.     }   
  127.     return hr;   
  128. }   
  129.   
  130. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  131.   
  132. 连接Filter   
  133.   
  134. HRESULT Sender::ConnectFilters(   
  135.     IGraphBuilder *pGraph, // Filter Graph Manager.   
  136.     IPin *pOut,            // Output pin on the upstream filter.   
  137.     IBaseFilter *pDest)    // Downstream filter.   
  138. {   
  139.     if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))   
  140.     {   
  141.         return E_POINTER;   
  142.     }   
  143. #ifdef debug   
  144.         PIN_DIRECTION PinDir;   
  145.         pOut->QueryDirection(&PinDir);   
  146.         _ASSERTE(PinDir == PINDIR_OUTPUT);   
  147. #endif   
  148.   
  149.     // Find an input pin on the downstream filter.   
  150.     IPin *pIn = 0;   
  151.     HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);   
  152.     if (FAILED(hr))   
  153.     {   
  154.         return hr;   
  155.     }   
  156.     // Try to connect them.   
  157.     hr = pGraph->Connect(pOut, pIn);   
  158.     pIn->Release();   
  159.     return hr;   
  160. }   
  161.   
  162. HRESULT Sender::ConnectFilters(   
  163.     IGraphBuilder *pGraph,    
  164.     IBaseFilter *pSrc,    
  165.     IBaseFilter *pDest)   
  166. {   
  167.     if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))   
  168.     {   
  169.         return E_POINTER;   
  170.     }   
  171.   
  172.     // Find an output pin on the first filter.   
  173.     IPin *pOut = 0;   
  174.     HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);   
  175.     if (FAILED(hr))    
  176.     {   
  177.         return hr;   
  178.     }   
  179.     hr = ConnectFilters(pGraph, pOut, pDest);   
  180.     pOut->Release();   
  181.     return hr;   
  182. }   
  183. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  184.   
  185. //得到未知Pin接口   
  186. HRESULT Sender::GetUnconnectedPin(   
  187.     IBaseFilter *pFilter,   // Pointer to the filter.   
  188.     PIN_DIRECTION PinDir,   // Direction of the pin to find.   
  189.     IPin **ppPin)           // Receives a pointer to the pin.   
  190. {   
  191.     *ppPin = 0;   
  192.     IEnumPins *pEnum = 0;   
  193.     IPin *pPin = 0;   
  194.     HRESULT hr = pFilter->EnumPins(&pEnum);   
  195.     if (FAILED(hr))   
  196.     {   
  197.         return hr;   
  198.     }   
  199.     while (pEnum->Next(1, &pPin, NULL) == S_OK)   
  200.     {   
  201.         PIN_DIRECTION ThisPinDir;   
  202.         pPin->QueryDirection(&ThisPinDir);   
  203.         if (ThisPinDir == PinDir)   
  204.         {   
  205.             IPin *pTmp = 0;   
  206.             hr = pPin->ConnectedTo(&pTmp);   
  207.             if (SUCCEEDED(hr)) // Already connected, not the pin we want.   
  208.             {   
  209.                 pTmp->Release();   
  210.             }   
  211.             else // Unconnected, this is the pin we want.   
  212.             {   
  213.                 pEnum->Release();   
  214.                 *ppPin = pPin;   
  215.                 return S_OK;   
  216.             }   
  217.         }   
  218.         pPin->Release();   
  219.     }   
  220.     pEnum->Release();   
  221.     // Did not find a matching pin.   
  222.     return E_FAIL;   
  223. }   
  224.   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值