wmvgraph.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. #ifndef _XBOX
  2. #ifndef _DEBUG
  3. #pragma comment(lib, "xrender\\videocodec\\strmbase.lib")
  4. #else
  5. #pragma comment(lib, "xrender\\videocodec\\strmbased.lib")
  6. #endif
  7. #pragma comment(lib, "winmm.lib")
  8. #include "wmvinterfaces.h"
  9. __forceinline void * _cdecl operator new(size_t size)
  10. {
  11. return IWMVMemoryManager::CoreAlloc(size);
  12. }
  13. __forceinline void _cdecl operator delete(void * ptr)
  14. {
  15. IWMVMemoryManager::CoreFree(ptr);
  16. }
  17. #include "wmvgraph.h"
  18. #include "DShowTextures.h"
  19. IWMVGraph* IWMVGraph::CreateWMVGraphInstance()
  20. {
  21. return new WMVGraph();
  22. }
  23. WMVGraph::WMVGraph()
  24. {
  25. m_pGB = NULL;
  26. m_pMC = NULL;
  27. m_pMP = NULL;
  28. m_pME = NULL;
  29. m_pFileSource = NULL;
  30. m_pRenderer = NULL;
  31. m_maxTime = 0;
  32. m_bSoundOff = false;
  33. }
  34. WMVGraph::~WMVGraph()
  35. {
  36. CloseFile();
  37. }
  38. bool WMVGraph::OpenFile(const char* pcVideoFile)
  39. {
  40. HRESULT hr = S_OK;
  41. // Create the filter graph
  42. hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&m_pGB);
  43. if (FAILED(hr))
  44. {
  45. Msg("Could not create GraphBuilder! hr=0x%x", hr);
  46. return false;
  47. }
  48. // Create the Texture Renderer object
  49. m_pRenderer = new CTextureRenderer(NULL, &hr);
  50. if (FAILED(hr) || !m_pRenderer)
  51. {
  52. if( m_pRenderer )
  53. {
  54. delete m_pRenderer;
  55. m_pRenderer = NULL;
  56. }
  57. Msg("Could not create texture renderer object! hr=0x%x", hr);
  58. return false;
  59. }
  60. // Get a pointer to the IBaseFilter on the TextureRenderer, add it to graph
  61. if (FAILED(hr = m_pGB->AddFilter(m_pRenderer, L"TEXTURERENDERER")))
  62. {
  63. Msg("Could not add renderer filter to graph! hr=0x%x", hr);
  64. return false;
  65. }
  66. // Source Filter
  67. WCHAR wFileName[MAX_PATH];
  68. UINT strSize = strlen(pcVideoFile);
  69. for( UINT d=0,s=0; d<MAX_PATH-1 && s<strSize; s++,d++ )
  70. wFileName[d] = pcVideoFile[s];
  71. wFileName[d] = 0;
  72. IBaseFilter* pFSrc = NULL;
  73. hr = AddFilterByCLSID(m_pGB, CLSID_WMAsfReader, wFileName, &pFSrc);
  74. if (FAILED(hr)) {
  75. Msg("Unable to add [WM ASF Reader]! hr=0x%x, %s", hr, pcVideoFile);
  76. return false;
  77. }
  78. bool bSuccess = true;
  79. // Get the Inteface to IFileSource so we can load the file
  80. m_pFileSource = NULL;
  81. hr = pFSrc->QueryInterface(IID_IFileSourceFilter, (void **)&m_pFileSource);
  82. if (!FAILED(hr) && (m_pFileSource != NULL))
  83. {
  84. hr = m_pFileSource->Load(wFileName, NULL);
  85. if (FAILED(hr)) {
  86. Msg("Unable to load file %s! hr=0x%x", pcVideoFile, hr);
  87. bSuccess = false;
  88. }
  89. }
  90. // Video source Filter Output Pin
  91. IPin* pFSrcPinOut = NULL;
  92. // Audio source Filter Output Pin
  93. IPin* pFSrcPinOut0 = NULL;
  94. // Find the source's Raw Video #1 output pin and the video renderer's input pin
  95. if (bSuccess && FAILED(hr = pFSrc->FindPin(L"Raw Video 0", &pFSrcPinOut))) {
  96. if (FAILED(hr = pFSrc->FindPin(L"Raw Video 1", &pFSrcPinOut))) {
  97. Msg("ConnectWMVFile() unable to find Raw Video Pin #1! hr=0x%x", hr);
  98. bSuccess = false;
  99. }
  100. }
  101. // Find the source's Raw Audio #0 output pin and the audio renderer's input pin
  102. if( !m_bSoundOff )
  103. {
  104. if (bSuccess && FAILED(hr = pFSrc->FindPin(L"Raw Audio 0", &pFSrcPinOut0))) {
  105. if (FAILED(hr = pFSrc->FindPin(L"Raw Audio 1", &pFSrcPinOut0))) {
  106. pFSrcPinOut0 = NULL;
  107. hr = S_OK;
  108. }
  109. }
  110. }
  111. if (bSuccess && pFSrcPinOut0 && FAILED(hr = m_pGB->Render(pFSrcPinOut0)))
  112. {
  113. Msg("Could not render source output pin (audio)! hr=0x%x", hr);
  114. }
  115. if (bSuccess && FAILED(hr = m_pGB->Render(pFSrcPinOut)))
  116. {
  117. Msg("Could not render source output pin (video)! hr=0x%x", hr);
  118. bSuccess = false;
  119. }
  120. // Get the graph's media control, event & position interfaces
  121. if( bSuccess )
  122. {
  123. m_pGB->QueryInterface(&m_pMC);
  124. m_pGB->QueryInterface(&m_pMP);
  125. m_pGB->QueryInterface(&m_pME);
  126. //IID_IBasicAudio
  127. IBasicAudio* pBasicAudio = NULL;
  128. m_pGB->QueryInterface(&pBasicAudio);
  129. if( pBasicAudio )
  130. {
  131. long nVol = 0;// min = -10000; max = 0
  132. nVol = (long)(IWMVMemoryManager::GetVolume() * 10000) - 10000;
  133. if( nVol>0 ) nVol = 0;
  134. else if( nVol<-10000 ) nVol = -10000;
  135. pBasicAudio->put_Volume(nVol);
  136. pBasicAudio->Release();
  137. }
  138. if( m_pMP )
  139. m_pMP->get_Duration(&m_maxTime);
  140. m_curTime = 0;
  141. }
  142. if( pFSrcPinOut0 )
  143. pFSrcPinOut0->Release();
  144. if( pFSrcPinOut )
  145. pFSrcPinOut->Release();
  146. if( pFSrc )
  147. pFSrc->Release();
  148. return bSuccess;
  149. }
  150. HRESULT WMVGraph::AddFilterByCLSID( IGraphBuilder *pGB, // Pointer to the Filter Graph Manager.
  151. const GUID& clsid, // CLSID of the filter to create.
  152. LPCWSTR wszName, // A name for the filter.
  153. IBaseFilter **ppFilter) // Receives a pointer to the filter.
  154. {
  155. if (!pGB || ! ppFilter) return E_POINTER;
  156. *ppFilter = 0;
  157. IBaseFilter *pFilter = 0;
  158. HRESULT hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,
  159. IID_IBaseFilter, reinterpret_cast<void**>(&pFilter));
  160. if (SUCCEEDED(hr))
  161. {
  162. hr = pGB->AddFilter(pFilter, wszName);
  163. if (SUCCEEDED(hr))
  164. *ppFilter = pFilter;
  165. else
  166. pFilter->Release();
  167. }
  168. return hr;
  169. }
  170. void WMVGraph::CloseFile()
  171. {
  172. Stop();
  173. CleanupDShow();
  174. }
  175. void WMVGraph::Play()
  176. {
  177. // Start the graph running;
  178. if( m_pMC )
  179. m_pMC->Run();
  180. }
  181. void WMVGraph::Stop()
  182. {
  183. if( m_pMC )
  184. m_pMC->Stop();
  185. }
  186. void WMVGraph::Restart()
  187. {
  188. m_curTime = 0;
  189. m_pMP->put_CurrentPosition(m_curTime);
  190. }
  191. void WMVGraph::Pause(bool bPause)
  192. {
  193. if( m_pMC )
  194. if( bPause )
  195. m_pMC->Pause();
  196. else
  197. m_pMC->Run();
  198. }
  199. bool WMVGraph::IsFinish()
  200. {
  201. if( !m_pMP ) return true;
  202. REFTIME curTime;
  203. m_pMP->get_CurrentPosition(&curTime);
  204. if( curTime < m_maxTime )
  205. {
  206. if( curTime > (m_maxTime - 0.02) &&
  207. curTime == m_curTime )
  208. return true;
  209. m_curTime = curTime;
  210. return false;
  211. }
  212. return true;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // CleanupDShow
  216. //-----------------------------------------------------------------------------
  217. void WMVGraph::CleanupDShow()
  218. {
  219. // Shut down the graph
  220. if (m_pMC!=NULL)
  221. {
  222. m_pMC->Stop();
  223. m_pMC->Release();
  224. m_pMC = NULL;
  225. }
  226. if (m_pME!=NULL)
  227. {
  228. m_pME->Release();
  229. m_pME = NULL;
  230. }
  231. if (m_pMP!=NULL)
  232. {
  233. m_pMP->Release();
  234. m_pMP = NULL;
  235. }
  236. if (m_pFileSource!=NULL)
  237. {
  238. m_pFileSource->Release();
  239. m_pFileSource = NULL;
  240. }
  241. if (m_pGB!=NULL)
  242. {
  243. m_pGB->Release();
  244. m_pGB = NULL;
  245. }
  246. /*if (m_pRenderer!=NULL)
  247. {
  248. m_pRenderer->Release();
  249. m_pRenderer = NULL;
  250. }*/
  251. }
  252. void WMVGraph::Msg(const char *szFormat, ...)
  253. {
  254. char cTmpBuffer[2048];
  255. va_list args;
  256. va_start(args, szFormat);
  257. _vsnprintf_s(cTmpBuffer, sizeof(cTmpBuffer), szFormat, args);
  258. va_end(args);
  259. IWMVMemoryManager::LogTrace(cTmpBuffer);
  260. }
  261. #endif