CFilterGraph.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:7k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // CFilterGraph.cpp: implementation of the CFilterGraph class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "streams.h"
  6. #include "CFilterGraph.h"
  7. #include "CDataAdmin.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. CFilterGraph::CFilterGraph(CDataAdmin *inBuffer)
  17. {
  18. // Filter graph running status
  19. m_bRun  = false;
  20. m_bInit = false;
  21. // Interfaces
  22. m_pGB   = NULL;
  23. m_pMC   = NULL;
  24. m_pVW   = NULL;
  25. m_pME   = NULL;
  26. m_pMS   = NULL;
  27. m_pBA   = NULL;
  28. m_hOwner   = NULL;
  29. m_nLeft    = 0;
  30. m_nTop     = 0;
  31. m_nWidth   = 100;
  32. m_nHeight  = 100;
  33. m_dwGraphRegister = 0;
  34. // Data buffer pointer
  35. m_pDataList = inBuffer;
  36. }
  37. CFilterGraph::~CFilterGraph()
  38. {
  39. m_bRun = false;
  40. ReleaseGraph();
  41. m_pDataList = NULL;
  42. }
  43. void CFilterGraph::ReleaseGraph(void)
  44. {
  45. // Stop filter graph first
  46. HRESULT  hr;
  47. if (m_pMC != NULL)
  48. {
  49. hr = m_pMC->Stop(); 
  50. }
  51.     // Relinquish ownership (IMPORTANT!) after hiding video window
  52.     if(m_pVW != NULL)
  53.     {
  54.         hr = m_pVW->put_Visible(OAFALSE);
  55.         hr = m_pVW->put_Owner(NULL);
  56.     }
  57. if (m_pGB != NULL)
  58. {
  59. // Unregister....
  60. RemoveGraphFromRot(m_dwGraphRegister);
  61. // remove the filter added before
  62. m_pGB->RemoveFilter(m_pSourceReader);
  63. // media event interface
  64. SAFE_RELEASE(m_pME)
  65. // media seeking interface
  66. SAFE_RELEASE(m_pMS)
  67. // media control interface
  68. SAFE_RELEASE(m_pMC)
  69. // basic audio interface
  70. SAFE_RELEASE(m_pBA)
  71. // video window interface
  72. SAFE_RELEASE(m_pVW)
  73. // graph builder interface
  74. SAFE_RELEASE(m_pGB)
  75. SAFE_DELETE(m_pSourceStream)
  76. SAFE_DELETE(m_pSourceReader)
  77. }
  78. }
  79. bool CFilterGraph::BuildGraph(void)
  80. {
  81. m_bInit = false;
  82. //  Create filter graph
  83.     HRESULT hr = CoCreateInstance(CLSID_FilterGraph,
  84.                                   NULL,
  85.                                   CLSCTX_INPROC,
  86.                                   IID_IGraphBuilder,
  87.                                   (void**)&m_pGB);
  88. if (SUCCEEDED(hr))
  89. {
  90. m_bInit = true;
  91. // Register...
  92. AddGraphToRot((IUnknown *)m_pGB, &m_dwGraphRegister);
  93. }
  94. if (m_bInit)
  95. {
  96. // Media control interface
  97. hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
  98. if (FAILED(hr))
  99. {
  100. m_bInit = false;
  101. }
  102. }
  103. if (m_bInit)
  104. {
  105. // Media event interface
  106. hr = m_pGB->QueryInterface(IID_IMediaEvent, (void **)&m_pME);
  107. if (FAILED(hr)) 
  108. {
  109. m_bInit = false;
  110. }
  111. }
  112. if (m_bInit)
  113. {
  114. // Media video window interface
  115. hr = m_pGB->QueryInterface(IID_IVideoWindow, (void **)&m_pVW);
  116. if (FAILED(hr)) 
  117. {
  118. m_bInit = false;
  119. }
  120. }
  121. if (m_bInit)
  122. {
  123. // Media basic audio interface
  124. hr = m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA);
  125. if (FAILED(hr)) 
  126. {
  127. m_bInit = false;
  128. }
  129. }
  130. if (m_bInit)
  131. {
  132. // Media seeking interface
  133. hr = m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS);
  134. if (FAILED(hr)) 
  135. {
  136. m_bInit = false;
  137. }
  138. }
  139. // construct source filter
  140. // Media type
  141. if (m_bInit)
  142. {
  143. CMediaType   mt;      
  144. mt.majortype = MEDIATYPE_Stream;
  145. mt.subtype   = MEDIASUBTYPE_MPEG1System;
  146. m_pSourceStream  = new CMemStream(m_pDataList);
  147. m_pSourceReader  = new CMemReader(m_pSourceStream, &mt, &hr);
  148. m_pSourceReader->AddRef();
  149. //  Add our filter
  150. hr = m_pGB->AddFilter(m_pSourceReader, NULL);
  151. if (FAILED(hr)) 
  152. {
  153. m_bInit = false;
  154. }  
  155. }
  156. if (m_bInit)
  157. {
  158. // Waiting for event to start filter graph
  159. ::AfxBeginThread((AFX_THREADPROC)CFilterGraph::WaitingThrd, this);
  160. }
  161. return m_bInit;
  162. }
  163. void CFilterGraph::SetWindowPosition(int nLeft, int nTop, int nWidth, int nHeight)
  164. {
  165. m_nLeft    = nLeft;
  166. m_nTop     = nTop;
  167. m_nWidth   = nWidth;
  168. m_nHeight  = nHeight;
  169. }
  170. bool CFilterGraph::StartGraph(void)
  171. {
  172. if (m_bInit)
  173. {
  174. m_bRun = true;
  175. HRESULT hr  = m_pGB->Render(m_pSourceReader->GetPin(0));
  176. if (FAILED(hr))
  177. {
  178. m_bRun = false;
  179. return false;
  180. }
  181. hr = m_pVW->put_Visible(OAFALSE);
  182. hr = m_pVW->put_Owner((OAHWND)m_hOwner);
  183. hr = m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
  184. hr = m_pVW->SetWindowPosition(m_nLeft, m_nTop, m_nWidth, m_nHeight);
  185. // Enable the parent window to get the mouse and keyboard event in the video window
  186. hr = m_pVW->put_MessageDrain((OAHWND)m_hOwner);
  187. hr = m_pVW->put_Visible(OATRUE);
  188. // run the filter graph
  189. hr = m_pMC->Run();
  190. return true;
  191. }
  192. return false;
  193. }
  194. void CFilterGraph::SetVideoWndOwner(HWND inWnd)
  195. {
  196. m_hOwner = inWnd;
  197. }
  198. bool CFilterGraph::IsInit(void)
  199. {
  200. return m_bInit;
  201. }
  202. bool CFilterGraph::IsRunning(void)
  203. {
  204. return m_bRun;
  205. }
  206. void CFilterGraph::AdjustLength(LONGLONG inAdd)
  207. {
  208. if (m_pSourceStream)
  209. {
  210. m_pSourceStream->AddAvailableLength(inAdd);
  211. }
  212. }
  213. // When data buffer enough, start the filter graph
  214. UINT CFilterGraph::WaitingThrd(void * pParam)
  215. {
  216. CFilterGraph * pGraph = (CFilterGraph *) pParam;
  217. if (pGraph != NULL && pGraph->m_pDataList != NULL)
  218. {
  219. ::WaitForSingleObject(pGraph->m_pDataList->m_hBufEnough, INFINITE);
  220. if (!pGraph->IsRunning())
  221. {
  222. pGraph->StartGraph();
  223. }
  224. }
  225. return 1;
  226. }
  227. bool CFilterGraph::ResetGraph(void)
  228. {
  229. if (m_bRun)
  230. {
  231. // If the filter graph running, release it first
  232. ReleaseGraph();
  233. }
  234. // Reset the datalist
  235. if (m_pDataList != NULL)
  236. {
  237. m_pDataList->ResetList();
  238. ResetEvent(m_pDataList->m_hBufEnough);
  239. }
  240. // Build a new filter graph
  241. BuildGraph();
  242. return true;
  243. }
  244. ///////////////////////////////////////////////////////////////////////////
  245. HRESULT CFilterGraph::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
  246. {
  247.     IMoniker * pMoniker;
  248.     IRunningObjectTable *pROT;
  249.     if (FAILED(GetRunningObjectTable(0, &pROT))) {
  250.         return E_FAIL;
  251.     }
  252.     WCHAR wsz[128];
  253.     wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph, GetCurrentProcessId());
  254.     HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  255.     if (SUCCEEDED(hr)) {
  256.         hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
  257.         pMoniker->Release();
  258.     }
  259.     pROT->Release();
  260.     return hr;
  261. }
  262. void CFilterGraph::RemoveGraphFromRot(DWORD pdwRegister)
  263. {
  264.     IRunningObjectTable *pROT;
  265.     if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
  266.         pROT->Revoke(pdwRegister);
  267.         pROT->Release();
  268.     }
  269. }
  270. //////////////////////////////////////////////////////////////////////////////