BuildGraph.cpp
上传用户:bxq2008bxq
上传日期:2022-07-18
资源大小:6138k
文件大小:7k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "BuildGraph.h"
  3. CBuildGraph::CBuildGraph(void)
  4. :pGraph(NULL)
  5. ,pGrabber(NULL)
  6. ,pControl(NULL)
  7. ,pEvent(NULL)
  8. ,pF(NULL)
  9. ,pNull(NULL)
  10. ,cbBuffer(0)
  11. {
  12. }
  13. CBuildGraph::~CBuildGraph(void)
  14. {
  15. if(pControl)
  16. pControl->Stop();
  17. if(pGraph)
  18. pGraph->Release();
  19. if(pGrabber)
  20. pGrabber->Release();
  21. if(pControl)
  22. pControl->Release();
  23. if(pEvent)
  24. pEvent->Release();
  25. if(pF)
  26. pF->Release();
  27. if(pNull)
  28. pNull->Release();
  29. }
  30. HRESULT CBuildGraph::GetUnconnectedPin(
  31.     IBaseFilter *pFilter,   // Pointer to the filter.
  32.     PIN_DIRECTION PinDir,   // Direction of the pin to find.
  33.     IPin **ppPin)           // Receives a pointer to the pin.
  34. {
  35.     *ppPin = 0;
  36.     IEnumPins *pEnum = 0;
  37.     IPin *pPin = 0;
  38.     HRESULT hr = pFilter->EnumPins(&pEnum);
  39.     if (FAILED(hr))
  40.     {
  41.         return hr;
  42.     }
  43.     while (pEnum->Next(1, &pPin, NULL) == S_OK)
  44.     {
  45.         PIN_DIRECTION ThisPinDir;
  46.         pPin->QueryDirection(&ThisPinDir);
  47.         if (ThisPinDir == PinDir)
  48.         {
  49.             IPin *pTmp = 0;
  50.             hr = pPin->ConnectedTo(&pTmp);
  51.             if (SUCCEEDED(hr))  // Already connected, not the pin we want.
  52.             {
  53.                 pTmp->Release();
  54.             }
  55.             else  // Unconnected, this is the pin we want.
  56.             {
  57.                 pEnum->Release();
  58.                 *ppPin = pPin;
  59.                 return S_OK;
  60.             }
  61.         }
  62.         pPin->Release();
  63.     }
  64.     pEnum->Release();
  65.     // Did not find a matching pin.
  66.     return E_FAIL;
  67. }
  68. HRESULT CBuildGraph::GetCapturePin(
  69. IBaseFilter *pFilter,   // Pointer to the filter.
  70. PIN_DIRECTION PinDir,   // Direction of the pin to find.
  71. IPin **ppPin)           // Receives a pointer to the pin.
  72. {
  73.     *ppPin = 0;
  74.     IEnumPins *pEnum = 0;
  75.     IPin *pPin = 0;
  76.     HRESULT hr = pFilter->EnumPins(&pEnum);
  77.     if (FAILED(hr))
  78.     {
  79.         return hr;
  80.     }
  81.     while (pEnum->Next(1, &pPin, NULL) == S_OK)
  82.     {
  83.         PIN_DIRECTION ThisPinDir;
  84.         pPin->QueryDirection(&ThisPinDir);
  85.         if (ThisPinDir == PinDir)
  86.         {
  87.             IPin *pTmp = 0;
  88.             hr = pPin->ConnectedTo(&pTmp);
  89.             if (SUCCEEDED(hr))  // Already connected, not the pin we want.
  90.             {
  91.                 pTmp->Release();
  92.             }
  93. else  // Unconnected, this is the pin we want.
  94. {
  95. pEnum->Release();
  96. GUID TempGuid;
  97. hr = GetPinCategory(pPin,&TempGuid);
  98. if(hr == S_OK)
  99. {
  100. if(TempGuid == PIN_CATEGORY_CAPTURE)
  101. {
  102. *ppPin = pPin;
  103. return S_OK;
  104. }
  105. }
  106. }
  107. }
  108.         pPin->Release();
  109.     }
  110.     pEnum->Release();
  111.     // Did not find a matching pin.
  112.     return E_FAIL;
  113. }
  114. HRESULT CBuildGraph::ConnectFilters(
  115.     IGraphBuilder *pGraph, // Filter Graph Manager.
  116.     IPin *pOut,            // Output pin on the upstream filter.
  117.     IBaseFilter *pDest)    // Downstream filter.
  118. {
  119.     if ((pGraph == NULL) || (pOut == NULL) || (pDest == NULL))
  120.     {
  121.         return E_POINTER;
  122.     }
  123. #ifdef debug
  124.         PIN_DIRECTION PinDir;
  125.         pOut->QueryDirection(&PinDir);
  126.         _ASSERTE(PinDir == PINDIR_OUTPUT);
  127. #endif
  128.     // Find an input pin on the downstream filter.
  129.     IPin *pIn = 0;
  130.     HRESULT hr = GetUnconnectedPin(pDest, PINDIR_INPUT, &pIn);
  131.     if (FAILED(hr))
  132.     {
  133.         return hr;
  134.     }
  135.     // Try to connect them.
  136.     hr = pGraph->Connect(pOut, pIn);
  137.     pIn->Release();
  138.     return hr;
  139. }
  140. HRESULT CBuildGraph::ConnectFilters(
  141.     IGraphBuilder *pGraph, 
  142.     IBaseFilter *pSrc, 
  143.     IBaseFilter *pDest)
  144. {
  145.     if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
  146.     {
  147.         return E_POINTER;
  148.     }
  149.     // Find an output pin on the first filter.
  150.     IPin *pOut = 0;
  151.     HRESULT hr = GetUnconnectedPin(pSrc, PINDIR_OUTPUT, &pOut);
  152.     if (FAILED(hr)) 
  153.     {
  154.         return hr;
  155.     }
  156.     hr = ConnectFilters(pGraph, pOut, pDest);
  157.     pOut->Release();
  158.     return hr;
  159. }
  160. HRESULT CBuildGraph::ConnectCaptureFilters(
  161.     IGraphBuilder *pGraph, 
  162.     IBaseFilter *pSrc, 
  163.     IBaseFilter *pDest)
  164. {
  165.     if ((pGraph == NULL) || (pSrc == NULL) || (pDest == NULL))
  166.     {
  167.         return E_POINTER;
  168.     }
  169.     // Find an output pin on the first filter.
  170.     IPin *pOut = 0;
  171.     HRESULT hr = GetCapturePin(pSrc, PINDIR_OUTPUT, &pOut);
  172.     if (FAILED(hr)) 
  173.     {
  174.         return hr;
  175.     }
  176.     hr = ConnectFilters(pGraph, pOut, pDest);
  177.     pOut->Release();
  178.     return hr;
  179. }
  180. HRESULT CBuildGraph::GetPinCategory(IPin *pPin, GUID *pPinCategory)
  181. {
  182.     HRESULT hr;
  183.     IKsPropertySet *pKs;
  184.     hr = pPin->QueryInterface(IID_IKsPropertySet, (void **)&pKs);
  185.     if (FAILED(hr))
  186.     {
  187.         // The pin does not support IKsPropertySet.
  188.         return hr;
  189.     }
  190.     // Try to retrieve the pin category.
  191.     DWORD cbReturned;
  192.     hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, 
  193.         pPinCategory, sizeof(GUID), &cbReturned);
  194.     // If this succeeded, pPinCategory now contains the category GUID.
  195.     pKs->Release();
  196.     return hr;
  197. }
  198. HRESULT CBuildGraph::InitCaptureVideo(IBaseFilter *pSrc)
  199. {
  200. HRESULT hr;
  201. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,IID_IGraphBuilder, (void **) &pGraph);
  202. hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
  203. IID_IBaseFilter, (void **)&pF);
  204. hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
  205. IID_IBaseFilter, reinterpret_cast<void**>(&pNull));
  206. hr = pF->QueryInterface(IID_ISampleGrabber,(void **)&pGrabber);
  207. hr = pGraph->QueryInterface(IID_IMediaControl,(LPVOID *)&pControl);
  208. hr = pGraph->QueryInterface(IID_IMediaEvent,(LPVOID *)&pEvent);
  209. hr = pGraph->AddFilter(pF, L"SampleGrabber");
  210. hr = pGraph->AddFilter(pSrc, L"Video Capture");
  211. hr = pGraph->AddFilter(pNull, L"NullRenderer");
  212. AM_MEDIA_TYPE  pmt;
  213. ZeroMemory(&pmt, sizeof(AM_MEDIA_TYPE));
  214. pmt.majortype = MEDIATYPE_Video;
  215. pmt.subtype = MEDIASUBTYPE_RGB24;
  216. hr = pGrabber->SetMediaType(&pmt);
  217. hr = ConnectCaptureFilters(pGraph,pSrc, pF);
  218. hr = ConnectFilters(pGraph, pF, pNull);
  219. pControl->Run();
  220. hr = pGrabber->SetOneShot(TRUE);
  221. hr = pGrabber->SetBufferSamples(TRUE);
  222. long evCode;
  223. hr = pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till it's done.
  224. hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
  225. hr = pGrabber->SetOneShot(FALSE);
  226. OAFilterState pfs;
  227. hr = pControl->Stop();
  228. hr = pControl->GetState(INFINITE, &pfs);
  229. hr = pControl->Run();
  230. hr = pControl->GetState(INFINITE, &pfs);
  231. if(pfs == State_Running&&hr == S_OK)
  232. {
  233.          hr = S_OK;
  234. }
  235. else
  236. {
  237.          hr = E_FAIL;
  238. }
  239. return hr;
  240. }