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

DirextX编程

开发平台:

Visual C++

  1. //
  2. // CDXGraph.cpp
  3. //
  4. #include "stdafx.h"
  5. #include "CDXGraph.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. ////////////////////////////////////////////////////////////////////////////////
  12. CDXGraph::CDXGraph()
  13. {
  14. mGraph        = 0;
  15. mMediaControl = 0;
  16. mEvent        = 0;
  17. mBasicVideo   = 0;
  18. mBasicAudio   = 0;
  19. mVideoWindow  = 0;
  20. mSeeking      = 0;
  21. mObjectTableEntry = 0;
  22. }
  23. CDXGraph::~CDXGraph()
  24. {
  25. Release();
  26. }
  27. bool CDXGraph::Create(void)
  28. {
  29. if (!mGraph)
  30. {
  31. if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
  32. IID_IGraphBuilder, (void **)&mGraph)))
  33. {
  34. AddToObjectTable();
  35. return QueryInterfaces();
  36. }
  37. mGraph = 0;
  38. }
  39. return false;
  40. }
  41. bool CDXGraph::QueryInterfaces(void)
  42. {
  43. if (mGraph)
  44. {
  45. HRESULT hr = NOERROR;
  46. hr |= mGraph->QueryInterface(IID_IMediaControl, (void **)&mMediaControl);
  47. hr |= mGraph->QueryInterface(IID_IMediaEventEx, (void **)&mEvent);
  48. hr |= mGraph->QueryInterface(IID_IBasicVideo, (void **)&mBasicVideo);
  49. hr |= mGraph->QueryInterface(IID_IBasicAudio, (void **)&mBasicAudio);
  50. hr |= mGraph->QueryInterface(IID_IVideoWindow, (void **)&mVideoWindow);
  51. hr |= mGraph->QueryInterface(IID_IMediaSeeking, (void **)&mSeeking);
  52. if (mSeeking)
  53. {
  54. mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
  55. }
  56. return SUCCEEDED(hr);
  57. }
  58. return false;
  59. }
  60. void CDXGraph::Release(void)
  61. {
  62. if (mSeeking)
  63. {
  64. mSeeking->Release();
  65. mSeeking = 0;
  66. }
  67. if (mMediaControl)
  68. {
  69. mMediaControl->Release();
  70. mMediaControl = 0;
  71. }
  72. if (mEvent)
  73. {
  74. mEvent->Release();
  75. mEvent = 0;
  76. }
  77. if (mBasicVideo)
  78. {
  79. mBasicVideo->Release();
  80. mBasicVideo = 0;
  81. }
  82. if (mBasicAudio)
  83. {
  84. mBasicAudio->Release();
  85. mBasicAudio = 0;
  86. }
  87. if (mVideoWindow)
  88. {
  89. mVideoWindow->put_Visible(OAFALSE);
  90. mVideoWindow->put_MessageDrain((OAHWND)NULL);
  91. mVideoWindow->put_Owner(OAHWND(0));
  92. mVideoWindow->Release();
  93. mVideoWindow = 0;
  94. }
  95. RemoveFromObjectTable();
  96. if (mGraph) 
  97. {
  98. mGraph->Release(); 
  99. mGraph = 0;
  100. }
  101. }
  102. bool CDXGraph::Attach(IGraphBuilder * inGraphBuilder)
  103. {
  104. Release();
  105. if (inGraphBuilder)
  106. {
  107. inGraphBuilder->AddRef();
  108. mGraph = inGraphBuilder;
  109. AddToObjectTable();
  110. return QueryInterfaces();
  111. }
  112. return true;
  113. }
  114. IGraphBuilder * CDXGraph::GetGraph(void)
  115. {
  116. return mGraph;
  117. }
  118. // Connect filter from the upstream output pin to the downstream input pin
  119. bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin, 
  120.   const AM_MEDIA_TYPE * inMediaType)
  121. {
  122. if (mGraph && inOutputPin && inInputPin)
  123. {
  124. HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
  125. return SUCCEEDED(hr) ? true : false;
  126. }
  127. return false;
  128. }
  129. void CDXGraph::DisconnectFilters(IPin * inOutputPin)
  130. {
  131. if (mGraph && inOutputPin)
  132. {
  133. HRESULT hr = mGraph->Disconnect(inOutputPin);
  134. }
  135. }
  136. bool CDXGraph::SetDisplayWindow(HWND inWindow)
  137. {
  138. if (mVideoWindow)
  139. {
  140. // long lVisible;
  141. // mVideoWindow->get_Visible(&lVisible);
  142. // Hide the video window first
  143. mVideoWindow->put_Visible(OAFALSE);
  144. mVideoWindow->put_Owner((OAHWND)inWindow);
  145. RECT windowRect;
  146. ::GetClientRect(inWindow, &windowRect);
  147. mVideoWindow->put_Left(0);
  148. mVideoWindow->put_Top(0);
  149. mVideoWindow->put_Width(windowRect.right - windowRect.left);
  150. mVideoWindow->put_Height(windowRect.bottom - windowRect.top);
  151. mVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
  152. mVideoWindow->put_MessageDrain((OAHWND) inWindow);
  153. // Restore the video window
  154. if (inWindow != NULL)
  155. {
  156. // mVideoWindow->put_Visible(lVisible);
  157. mVideoWindow->put_Visible(OATRUE);
  158. }
  159. else
  160. {
  161. mVideoWindow->put_Visible(OAFALSE);
  162. }
  163. return true;
  164. }
  165. return false;
  166. }
  167. bool CDXGraph::SetNotifyWindow(HWND inWindow)
  168. {
  169. if (mEvent)
  170. {
  171. mEvent->SetNotifyWindow((OAHWND)inWindow, WM_GRAPHNOTIFY, 0);
  172. return true;
  173. }
  174. return false;
  175. }
  176. void CDXGraph::HandleEvent(WPARAM inWParam, LPARAM inLParam)
  177. {
  178. if (mEvent)
  179. {
  180. LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0;
  181. while (SUCCEEDED(mEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
  182. {
  183. mEvent->FreeEventParams(eventCode, eventParam1, eventParam2);
  184. switch (eventCode)
  185. {
  186. case EC_COMPLETE:
  187. break;
  188. case EC_USERABORT:
  189. break;
  190. case EC_ERRORABORT:
  191. break;
  192. default:
  193. break;
  194. }
  195. }
  196. }
  197. }
  198. bool CDXGraph::Run(void)
  199. {
  200. if (mGraph && mMediaControl)
  201. {
  202. if (!IsRunning())
  203. {
  204. if (SUCCEEDED(mMediaControl->Run()))
  205. {
  206. return true;
  207. }
  208. }
  209. else
  210. {
  211. return true;
  212. }
  213. }
  214. return false;
  215. }
  216. bool CDXGraph::Stop(void)
  217. {
  218. if (mGraph && mMediaControl)
  219. {
  220. if (!IsStopped())
  221. {
  222. if (SUCCEEDED(mMediaControl->Stop()))
  223. {
  224. return true;
  225. }
  226. }
  227. }
  228. return false;
  229. }
  230. bool CDXGraph::Pause(void)
  231. {
  232. if (mGraph && mMediaControl)
  233. {
  234. if (!IsPaused())
  235. {
  236. if (SUCCEEDED(mMediaControl->Pause()))
  237. {
  238. return true;
  239. }
  240. }
  241. else
  242. {
  243. return true;
  244. }
  245. }
  246. return false;
  247. }
  248. bool CDXGraph::IsRunning(void)
  249. {
  250. if (mGraph && mMediaControl)
  251. {
  252. OAFilterState state = State_Stopped;
  253. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  254. {
  255. return state == State_Running;
  256. }
  257. }
  258. return false;
  259. }
  260. bool CDXGraph::IsStopped(void)
  261. {
  262. if (mGraph && mMediaControl)
  263. {
  264. OAFilterState state = State_Stopped;
  265. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  266. {
  267. return state == State_Stopped;
  268. }
  269. }
  270. return false;
  271. }
  272. bool CDXGraph::IsPaused(void)
  273. {
  274. if (mGraph && mMediaControl)
  275. {
  276. OAFilterState state = State_Stopped;
  277. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  278. {
  279. return state == State_Paused;
  280. }
  281. }
  282. return false;
  283. }
  284. bool CDXGraph::SetFullScreen(BOOL inEnabled)
  285. {
  286. if (mVideoWindow)
  287. {
  288. HRESULT hr = mVideoWindow->put_FullScreenMode(inEnabled ? OATRUE : OAFALSE);
  289. return SUCCEEDED(hr);
  290. }
  291. return false;
  292. }
  293. bool CDXGraph::GetFullScreen(void)
  294. {
  295. if (mVideoWindow)
  296. {
  297. long  fullScreenMode = OAFALSE;
  298. mVideoWindow->get_FullScreenMode(&fullScreenMode);
  299. return (fullScreenMode == OATRUE);
  300. }
  301. return false;
  302. }
  303. bool CDXGraph::SetSyncSource(IBaseFilter * inFilter)
  304. {
  305. if (inFilter)
  306. {
  307. IReferenceClock *pClock = 0;
  308. inFilter->QueryInterface(IID_IReferenceClock, (void**)&pClock);
  309. if (pClock)
  310. {
  311. // Set the graph clock.
  312. IMediaFilter *pMediaFilter = 0;
  313. mGraph->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter);
  314. pMediaFilter->SetSyncSource(pClock);
  315. pClock->Release();
  316. pMediaFilter->Release();
  317. return true;
  318. }
  319. return false;
  320. }
  321. else
  322. {
  323. // Do not use any reference clock
  324. IMediaFilter *pMediaFilter = 0;
  325. mGraph->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter);
  326. pMediaFilter->SetSyncSource(NULL);
  327. pMediaFilter->Release();
  328. return true;
  329. }
  330. }
  331. bool CDXGraph::SetDefaultSyncSource(void)
  332. {
  333. if (mGraph)
  334. {
  335. HRESULT hr = mGraph->SetDefaultSyncSource();
  336. return SUCCEEDED(hr) ?  true : false;
  337. }
  338. return false;
  339. }
  340. // IMediaSeeking features
  341. bool CDXGraph::GetCurrentPosition(double * outPosition)
  342. {
  343. if (mSeeking)
  344. {
  345. __int64 position = 0;
  346. if (SUCCEEDED(mSeeking->GetCurrentPosition(&position)))
  347. {
  348. *outPosition = ((double)position) / 10000000.;
  349. return true;
  350. }
  351. }
  352. return false;
  353. }
  354. bool CDXGraph::SetCurrentPosition(double inPosition)
  355. {
  356. if (mSeeking)
  357. {
  358. __int64 one = 10000000;
  359. __int64 position = (__int64)(one * inPosition);
  360. HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 
  361. 0, AM_SEEKING_NoPositioning);
  362. return SUCCEEDED(hr);
  363. }
  364. return false;
  365. }
  366. bool CDXGraph::GetDuration(double * outDuration)
  367. {
  368. if (mSeeking)
  369. {
  370. __int64 length = 0;
  371. if (SUCCEEDED(mSeeking->GetDuration(&length)))
  372. {
  373. *outDuration = ((double)length) / 10000000.;
  374. return true;
  375. }
  376. }
  377. return false;
  378. }
  379. bool CDXGraph::RenderFile(const char * inFile)
  380. {
  381. if (mGraph)
  382. {
  383. WCHAR    szFilePath[MAX_PATH];
  384. MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
  385. if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL)))
  386. {
  387. return true;
  388. }
  389. }
  390. return false;
  391. }
  392. bool CDXGraph::WaitForCompletion(void)
  393. {
  394. if (mEvent && IsRunning())
  395. {
  396. long  eventCode = 0;
  397. HRESULT hr = mEvent->WaitForCompletion(INFINITE, &eventCode);
  398. return SUCCEEDED(hr);
  399. }
  400. return true;
  401. }
  402. //////////////////////// For GraphEdit Dubug purpose /////////////////////////////
  403. void CDXGraph::AddToObjectTable(void)
  404. {
  405. IMoniker * pMoniker = 0;
  406.     IRunningObjectTable * objectTable = 0;
  407.     if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
  408. {
  409. WCHAR wsz[256];
  410. wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)mGraph, GetCurrentProcessId());
  411. HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  412. if (SUCCEEDED(hr)) 
  413. {
  414. hr = objectTable->Register(0, mGraph, pMoniker, &mObjectTableEntry);
  415. pMoniker->Release();
  416. }
  417. objectTable->Release();
  418. }
  419. }
  420. void CDXGraph::RemoveFromObjectTable(void)
  421. {
  422. IRunningObjectTable * objectTable = 0;
  423.     if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
  424. {
  425.         objectTable->Revoke(mObjectTableEntry);
  426.         objectTable->Release();
  427. mObjectTableEntry = 0;
  428.     }
  429. }