DSScreenCastGraph.cxx 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. #if !defined(_WIN32_WCE)
  2. /* Copyright (C) 2014 Mamadou DIOP
  3. *
  4. * This file is part of Open Source Doubango Framework.
  5. *
  6. * DOUBANGO is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * DOUBANGO is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with DOUBANGO.
  18. */
  19. #include <streams.h>
  20. #include "internals/DSScreenCastGraph.h"
  21. #include "internals/DSPushSource.h"
  22. #include "internals/DSUtils.h"
  23. #include "internals/DSCaptureUtils.h"
  24. #include "tsk_debug.h"
  25. #include <iostream>
  26. using namespace std;
  27. DSScreenCastGraph::DSScreenCastGraph(ISampleGrabberCB* callback, HRESULT *hr)
  28. : DSBaseCaptureGraph(callback, hr)
  29. {
  30. this->grabberCallback = callback;
  31. this->captureFormat = NULL;
  32. this->captureGraphBuilder = NULL;
  33. this->graphBuilder = NULL;
  34. this->sourceFilter = NULL;
  35. this->sampleGrabberFilter = NULL;
  36. this->nullRendererFilter = NULL;
  37. this->grabberController = NULL;
  38. this->mediaController = NULL;
  39. this->mediaEventController = NULL;
  40. this->running = FALSE;
  41. this->paused = FALSE;
  42. *hr = this->createCaptureGraph();
  43. }
  44. DSScreenCastGraph::~DSScreenCastGraph()
  45. {
  46. SAFE_RELEASE(this->mediaEventController);
  47. SAFE_RELEASE(this->mediaController);
  48. SAFE_RELEASE(this->grabberController);
  49. SAFE_RELEASE(this->nullRendererFilter);
  50. SAFE_RELEASE(this->sampleGrabberFilter);
  51. SAFE_RELEASE(this->graphBuilder);
  52. SAFE_RELEASE(this->captureGraphBuilder);
  53. SAFE_RELEASE(this->sourceFilter);
  54. }
  55. HRESULT DSScreenCastGraph::setParameters(DSCaptureFormat *format, int framerate)
  56. {
  57. return S_OK;
  58. }
  59. #ifdef _WIN32_WCE
  60. # include <tinydshow/wce/DSInxbNullFilter.h>
  61. #endif
  62. HRESULT DSScreenCastGraph::connect()
  63. {
  64. HRESULT hr;
  65. if (!this->sourceFilter) {
  66. TSK_DEBUG_ERROR("Invalid source filter");
  67. return E_FAIL;
  68. }
  69. #if 0
  70. if (!this->captureFormat) {
  71. TSK_DEBUG_ERROR("Invalid capture format");
  72. return E_FAIL;
  73. }
  74. #endif
  75. hr = ConnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter);
  76. if(FAILED(hr)) {
  77. TSK_DEBUG_ERROR("ConnectFilters failed");
  78. return hr;
  79. }
  80. hr = ConnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter);
  81. if(FAILED(hr)) {
  82. TSK_DEBUG_ERROR("ConnectFilters failed");
  83. return hr;
  84. }
  85. return hr;
  86. }
  87. HRESULT DSScreenCastGraph::disconnect()
  88. {
  89. HRESULT hr;
  90. if (!this->sourceFilter) {
  91. return E_FAIL;
  92. }
  93. #if 0
  94. if (!this->captureFormat) {
  95. return E_FAIL;
  96. }
  97. #endif
  98. hr = DisconnectFilters(this->graphBuilder, this->sourceFilter, this->sampleGrabberFilter);
  99. hr = DisconnectFilters(this->graphBuilder, this->sampleGrabberFilter, this->nullRendererFilter);
  100. return hr;
  101. }
  102. HRESULT DSScreenCastGraph::start()
  103. {
  104. HRESULT hr;
  105. if (isRunning() && !isPaused()) {
  106. return S_OK;
  107. }
  108. hr = this->mediaController->Run();
  109. if (!SUCCEEDED(hr)) {
  110. TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Run() has failed with %ld", hr);
  111. return hr;
  112. }
  113. this->running = true;
  114. return hr;
  115. }
  116. HRESULT DSScreenCastGraph::pause()
  117. {
  118. HRESULT hr = S_OK;
  119. if (isRunning()) {
  120. hr = this->mediaController->Pause();
  121. if (SUCCEEDED(hr)) {
  122. this->paused = TRUE;
  123. }
  124. }
  125. return hr;
  126. }
  127. HRESULT DSScreenCastGraph::stop()
  128. {
  129. if (!this->running) {
  130. return S_OK;
  131. }
  132. HRESULT hr;
  133. hr = this->mediaController->Stop();
  134. if (FAILED(hr)) {
  135. TSK_DEBUG_ERROR("DSScreenCastGraph::mediaController->Stop() has failed with %ld", hr);
  136. }
  137. this->running = false;
  138. this->paused = false;
  139. return hr;
  140. }
  141. bool DSScreenCastGraph::isRunning()
  142. {
  143. return this->running;
  144. }
  145. bool DSScreenCastGraph::isPaused()
  146. {
  147. return this->paused;
  148. }
  149. HRESULT DSScreenCastGraph::getConnectedMediaType(AM_MEDIA_TYPE *mediaType)
  150. {
  151. return this->grabberController->GetConnectedMediaType(mediaType);
  152. }
  153. HRESULT DSScreenCastGraph::createCaptureGraph()
  154. {
  155. HRESULT hr;
  156. // Create capture graph builder
  157. hr = COCREATE(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2, this->captureGraphBuilder);
  158. if(FAILED(hr)) {
  159. return hr;
  160. }
  161. // Create the graph builder
  162. hr = COCREATE(CLSID_FilterGraph, IID_IGraphBuilder, this->graphBuilder);
  163. if(FAILED(hr)) {
  164. return hr;
  165. }
  166. // Initialize the Capture Graph Builder.
  167. hr = this->captureGraphBuilder->SetFiltergraph(this->graphBuilder);
  168. if(FAILED(hr)) {
  169. return hr;
  170. }
  171. // Create source filter
  172. LPUNKNOWN pUnk = NULL;
  173. this->sourceFilter = (CPushSourceDesktop*)CPushSourceDesktop::CreateInstance(pUnk, &hr);
  174. if(FAILED(hr)) {
  175. return hr;
  176. }
  177. this->sourceFilter->AddRef();
  178. // Create the sample grabber filter
  179. hr = COCREATE(CLSID_SampleGrabber, IID_IBaseFilter, this->sampleGrabberFilter);
  180. if(FAILED(hr)) {
  181. return hr;
  182. }
  183. // Create the NULL renderer
  184. hr = COCREATE(CLSID_NullRenderer, IID_IBaseFilter, this->nullRendererFilter);
  185. if(FAILED(hr)) {
  186. return hr;
  187. }
  188. // Add source filter to the graph
  189. hr = this->graphBuilder->AddFilter(this->sourceFilter, FILTER_SCREENCAST);
  190. if(FAILED(hr)) {
  191. return hr;
  192. }
  193. // Add sample grabber to the graph
  194. hr = this->graphBuilder->AddFilter(this->sampleGrabberFilter, FITLER_SAMPLE_GRABBER);
  195. if(FAILED(hr)) {
  196. return hr;
  197. }
  198. // Add null renderer to the graph
  199. hr = this->graphBuilder->AddFilter(this->nullRendererFilter, FILTER_NULL_RENDERER);
  200. if(FAILED(hr)) {
  201. return hr;
  202. }
  203. // Find media control
  204. hr = QUERY(this->graphBuilder, IID_IMediaControl, this->mediaController);
  205. if(FAILED(hr)) {
  206. return hr;
  207. }
  208. // Create the sample grabber controller
  209. hr = QUERY(this->sampleGrabberFilter, IID_ISampleGrabber, this->grabberController);
  210. if(FAILED(hr)) {
  211. return hr;
  212. }
  213. // Set the sample grabber media type (RGB24)
  214. // TODO : CHECK
  215. AM_MEDIA_TYPE mt;
  216. ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
  217. mt.majortype = MEDIATYPE_Video;
  218. mt.subtype = MEDIASUBTYPE_RGB24;
  219. mt.formattype = FORMAT_VideoInfo;
  220. hr = this->grabberController->SetMediaType(&mt);
  221. if(FAILED(hr)) {
  222. return hr;
  223. }
  224. // Set sample grabber media type
  225. this->grabberController->SetOneShot(FALSE);
  226. this->grabberController->SetBufferSamples(FALSE);
  227. hr = this->grabberController->SetCallback(this->grabberCallback, 1);
  228. if(FAILED(hr)) {
  229. return hr;
  230. }
  231. return hr;
  232. }
  233. #endif /* _WIN32_WCE */