CDXGraph.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

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