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

DirextX编程

开发平台:

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. void CDXGraph::Release(void)
  62. {
  63. if (mSeeking)
  64. {
  65. mSeeking->Release();
  66. mSeeking = NULL;
  67. }
  68. if (mMediaControl)
  69. {
  70. mMediaControl->Release();
  71. mMediaControl = NULL;
  72. }
  73. if (mEvent)
  74. {
  75. mEvent->Release();
  76. mEvent = NULL;
  77. }
  78. if (mBasicVideo)
  79. {
  80. mBasicVideo->Release();
  81. mBasicVideo = NULL;
  82. }
  83. if (mBasicAudio)
  84. {
  85. mBasicAudio->Release();
  86. mBasicAudio = NULL;
  87. }
  88. if (mVideoWindow)
  89. {
  90. mVideoWindow->put_Visible(OAFALSE);
  91. mVideoWindow->put_MessageDrain((OAHWND)NULL);
  92. mVideoWindow->put_Owner(OAHWND(0));
  93. mVideoWindow->Release();
  94. mVideoWindow = NULL;
  95. }
  96. RemoveFromObjectTable();
  97. if (mGraph) 
  98. {
  99. mGraph->Release(); 
  100. mGraph = NULL;
  101. }
  102. }
  103. bool CDXGraph::Attach(IGraphBuilder * inGraphBuilder)
  104. {
  105. Release();
  106. if (inGraphBuilder)
  107. {
  108. inGraphBuilder->AddRef();
  109. mGraph = inGraphBuilder;
  110. AddToObjectTable();
  111. return QueryInterfaces();
  112. }
  113. return true;
  114. }
  115. IGraphBuilder * CDXGraph::GetGraph(void)
  116. {
  117. return mGraph;
  118. }
  119. IMediaEventEx * CDXGraph::GetEventHandle(void)
  120. {
  121. return mEvent;
  122. }
  123. // Connect filter from the upstream output pin to the downstream input pin
  124. bool CDXGraph::ConnectFilters(IPin * inOutputPin, IPin * inInputPin, 
  125.   const AM_MEDIA_TYPE * inMediaType)
  126. {
  127. if (mGraph && inOutputPin && inInputPin)
  128. {
  129. HRESULT hr = mGraph->ConnectDirect(inOutputPin, inInputPin, inMediaType);
  130. return SUCCEEDED(hr) ? true : false;
  131. }
  132. return false;
  133. }
  134. void CDXGraph::DisconnectFilters(IPin * inOutputPin)
  135. {
  136. if (mGraph && inOutputPin)
  137. {
  138. HRESULT hr = mGraph->Disconnect(inOutputPin);
  139. }
  140. }
  141. bool CDXGraph::SetDisplayWindow(HWND inWindow)
  142. {
  143. if (mVideoWindow)
  144. {
  145. // long lVisible;
  146. // mVideoWindow->get_Visible(&lVisible);
  147. // Hide the video window first
  148. mVideoWindow->put_Visible(OAFALSE);
  149. mVideoWindow->put_Owner((OAHWND)inWindow);
  150. RECT windowRect;
  151. ::GetClientRect(inWindow, &windowRect);
  152. mVideoWindow->put_Left(0);
  153. mVideoWindow->put_Top(0);
  154. mVideoWindow->put_Width(windowRect.right - windowRect.left);
  155. mVideoWindow->put_Height(windowRect.bottom - windowRect.top);
  156. mVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
  157. mVideoWindow->put_MessageDrain((OAHWND) inWindow);
  158. // Restore the video window
  159. if (inWindow != NULL)
  160. {
  161. // mVideoWindow->put_Visible(lVisible);
  162. mVideoWindow->put_Visible(OATRUE);
  163. }
  164. else
  165. {
  166. mVideoWindow->put_Visible(OAFALSE);
  167. }
  168. return true;
  169. }
  170. return false;
  171. }
  172. bool CDXGraph::ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight)
  173. {
  174. if (mVideoWindow)
  175. {
  176. long lVisible = OATRUE;
  177. mVideoWindow->get_Visible(&lVisible);
  178. // Hide the video window first
  179. mVideoWindow->put_Visible(OAFALSE);
  180. mVideoWindow->put_Left(inLeft);
  181. mVideoWindow->put_Top(inTop);
  182. mVideoWindow->put_Width(inWidth);
  183. mVideoWindow->put_Height(inHeight);
  184. // Restore the video window
  185. mVideoWindow->put_Visible(lVisible);
  186. return true;
  187. }
  188. return false;
  189. }
  190. bool CDXGraph::SetNotifyWindow(HWND inWindow)
  191. {
  192. if (mEvent)
  193. {
  194. mEvent->SetNotifyWindow((OAHWND)inWindow, WM_GRAPHNOTIFY, 0);
  195. return true;
  196. }
  197. return false;
  198. }
  199. void CDXGraph::HandleEvent(WPARAM inWParam, LPARAM inLParam)
  200. {
  201. if (mEvent)
  202. {
  203. LONG eventCode = 0, eventParam1 = 0, eventParam2 = 0;
  204. while (SUCCEEDED(mEvent->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
  205. {
  206. mEvent->FreeEventParams(eventCode, eventParam1, eventParam2);
  207. switch (eventCode)
  208. {
  209. case EC_COMPLETE:
  210. break;
  211. case EC_USERABORT:
  212. case EC_ERRORABORT:
  213. break;
  214. default:
  215. break;
  216. }
  217. }
  218. }
  219. }
  220. bool CDXGraph::Run(void)
  221. {
  222. if (mGraph && mMediaControl)
  223. {
  224. if (!IsRunning())
  225. {
  226. if (SUCCEEDED(mMediaControl->Run()))
  227. {
  228. return true;
  229. }
  230. }
  231. else
  232. {
  233. return true;
  234. }
  235. }
  236. return false;
  237. }
  238. bool CDXGraph::Stop(void)
  239. {
  240. if (mGraph && mMediaControl)
  241. {
  242. if (!IsStopped())
  243. {
  244. if (SUCCEEDED(mMediaControl->Stop()))
  245. {
  246. return true;
  247. }
  248. }
  249. else
  250. {
  251. return true;
  252. }
  253. }
  254. return false;
  255. }
  256. bool CDXGraph::Pause(void)
  257. {
  258. if (mGraph && mMediaControl)
  259. {
  260. if (!IsPaused())
  261. {
  262. if (SUCCEEDED(mMediaControl->Pause()))
  263. {
  264. return true;
  265. }
  266. }
  267. else
  268. {
  269. return true;
  270. }
  271. }
  272. return false;
  273. }
  274. bool CDXGraph::IsRunning(void)
  275. {
  276. if (mGraph && mMediaControl)
  277. {
  278. OAFilterState state = State_Stopped;
  279. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  280. {
  281. return state == State_Running;
  282. }
  283. }
  284. return false;
  285. }
  286. bool CDXGraph::IsStopped(void)
  287. {
  288. if (mGraph && mMediaControl)
  289. {
  290. OAFilterState state = State_Stopped;
  291. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  292. {
  293. return state == State_Stopped;
  294. }
  295. }
  296. return false;
  297. }
  298. bool CDXGraph::IsPaused(void)
  299. {
  300. if (mGraph && mMediaControl)
  301. {
  302. OAFilterState state = State_Stopped;
  303. if (SUCCEEDED(mMediaControl->GetState(10, &state)))
  304. {
  305. return state == State_Paused;
  306. }
  307. }
  308. return false;
  309. }
  310. bool CDXGraph::SetFullScreen(BOOL inEnabled)
  311. {
  312. if (mVideoWindow)
  313. {
  314. HRESULT hr = mVideoWindow->put_FullScreenMode(inEnabled ? OATRUE : OAFALSE);
  315. return SUCCEEDED(hr);
  316. }
  317. return false;
  318. }
  319. bool CDXGraph::GetFullScreen(void)
  320. {
  321. if (mVideoWindow)
  322. {
  323. long  fullScreenMode = OAFALSE;
  324. mVideoWindow->get_FullScreenMode(&fullScreenMode);
  325. return (fullScreenMode == OATRUE);
  326. }
  327. return false;
  328. }
  329. // IMediaSeeking features
  330. bool CDXGraph::GetCurrentPosition(double * outPosition)
  331. {
  332. if (mSeeking)
  333. {
  334. __int64 position = 0;
  335. if (SUCCEEDED(mSeeking->GetCurrentPosition(&position)))
  336. {
  337. *outPosition = ((double)position) / 10000000.;
  338. return true;
  339. }
  340. }
  341. return false;
  342. }
  343. bool CDXGraph::GetStopPosition(double * outPosition)
  344. {
  345. if (mSeeking)
  346. {
  347. __int64 position = 0;
  348. if (SUCCEEDED(mSeeking->GetStopPosition(&position)))
  349. {
  350. *outPosition = ((double)position) / 10000000.;
  351. return true;
  352. }
  353. }
  354. return false;
  355. }
  356. bool CDXGraph::SetCurrentPosition(double inPosition)
  357. {
  358. if (mSeeking)
  359. {
  360. __int64 one = 10000000;
  361. __int64 position = (__int64)(one * inPosition);
  362. HRESULT hr = mSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 
  363. 0, AM_SEEKING_NoPositioning);
  364. return SUCCEEDED(hr);
  365. }
  366. return false;
  367. }
  368. bool CDXGraph::SetStartStopPosition(double inStart, double inStop)
  369. {
  370. if (mSeeking)
  371. {
  372. __int64 one = 10000000;
  373. __int64 startPos = (__int64)(one * inStart);
  374. __int64 stopPos  = (__int64)(one * inStop);
  375. HRESULT hr = mSeeking->SetPositions(&startPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame, 
  376. &stopPos, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame);
  377. return SUCCEEDED(hr);
  378. }
  379. return false;
  380. }
  381. bool CDXGraph::GetDuration(double * outDuration)
  382. {
  383. if (mSeeking)
  384. {
  385. __int64 length = 0;
  386. if (SUCCEEDED(mSeeking->GetDuration(&length)))
  387. {
  388. *outDuration = ((double)length) / 10000000.;
  389. return true;
  390. }
  391. }
  392. return false;
  393. }
  394. bool CDXGraph::SetPlaybackRate(double inRate)
  395. {
  396. if (mSeeking)
  397. {
  398. if (SUCCEEDED(mSeeking->SetRate(inRate)))
  399. {
  400. return true;
  401. }
  402. }
  403. return false;
  404. }
  405. // Attention: range from -10000 to 0, and 0 is FULL_VOLUME.
  406. bool CDXGraph::SetAudioVolume(long inVolume)
  407. {
  408. if (mBasicAudio)
  409. {
  410. HRESULT hr = mBasicAudio->put_Volume(inVolume);
  411. return SUCCEEDED(hr);
  412. }
  413. return false;
  414. }
  415. long CDXGraph::GetAudioVolume(void)
  416. {
  417. long volume = 0;
  418. if (mBasicAudio)
  419. {
  420. mBasicAudio->get_Volume(&volume);
  421. }
  422. return volume;
  423. }
  424. // Attention: range from -10000(left) to 10000(right), and 0 is both.
  425. bool CDXGraph::SetAudioBalance(long inBalance)
  426. {
  427. if (mBasicAudio)
  428. {
  429. HRESULT hr = mBasicAudio->put_Balance(inBalance);
  430. return SUCCEEDED(hr);
  431. }
  432. return false;
  433. }
  434. long CDXGraph::GetAudioBalance(void)
  435. {
  436. long balance = 0;
  437. if (mBasicAudio)
  438. {
  439. mBasicAudio->get_Balance(&balance);
  440. }
  441. return balance;
  442. }
  443. bool CDXGraph::RenderFile(const char * inFile)
  444. {
  445. if (mGraph)
  446. {
  447. WCHAR    szFilePath[MAX_PATH];
  448. MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);
  449. if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL)))
  450. {
  451. return true;
  452. }
  453. }
  454. return false;
  455. }
  456. bool CDXGraph::SnapshotBitmap(const char * outFile)
  457. {
  458. if (mBasicVideo)
  459. {
  460. long bitmapSize = 0;
  461. if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, 0)))
  462. {
  463. bool pass = false;
  464. unsigned char * buffer = new unsigned char[bitmapSize];
  465. if (SUCCEEDED(mBasicVideo->GetCurrentImage(&bitmapSize, (long *)buffer)))
  466. {
  467. BITMAPFILEHEADER hdr;
  468. LPBITMAPINFOHEADER lpbi;
  469. lpbi = (LPBITMAPINFOHEADER)buffer;
  470. int nColors = 1 << lpbi->biBitCount;
  471. if (nColors > 256)
  472. nColors = 0;
  473. hdr.bfType = ((WORD) ('M' << 8) | 'B'); //always is "BM"
  474. hdr.bfSize = bitmapSize + sizeof( hdr );
  475. hdr.bfReserved1  = 0;
  476. hdr.bfReserved2  = 0;
  477. hdr.bfOffBits = (DWORD) (sizeof(BITMAPFILEHEADER) + lpbi->biSize +
  478. nColors * sizeof(RGBQUAD));
  479. CFile bitmapFile(outFile, CFile::modeReadWrite | CFile::modeCreate | CFile::typeBinary);
  480. bitmapFile.Write(&hdr, sizeof(BITMAPFILEHEADER));
  481. bitmapFile.Write(buffer, bitmapSize);
  482. bitmapFile.Close();
  483. pass = true;
  484. }
  485. delete [] buffer;
  486. return pass;
  487. }
  488. }
  489. return false;
  490. }
  491. //////////////////////// For GraphEdit Dubug purpose /////////////////////////////
  492. void CDXGraph::AddToObjectTable(void)
  493. {
  494. IMoniker * pMoniker = 0;
  495.     IRunningObjectTable * objectTable = 0;
  496.     if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
  497. {
  498. WCHAR wsz[256];
  499. wsprintfW(wsz, L"FilterGraph %08p pid %08x", (DWORD_PTR)mGraph, GetCurrentProcessId());
  500. HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
  501. if (SUCCEEDED(hr)) 
  502. {
  503. hr = objectTable->Register(0, mGraph, pMoniker, &mObjectTableEntry);
  504. pMoniker->Release();
  505. }
  506. objectTable->Release();
  507. }
  508. }
  509. void CDXGraph::RemoveFromObjectTable(void)
  510. {
  511. IRunningObjectTable * objectTable = 0;
  512.     if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
  513. {
  514.         objectTable->Revoke(mObjectTableEntry);
  515.         objectTable->Release();
  516. mObjectTableEntry = 0;
  517.     }
  518. }