Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
10 KiB

  1. //==========================================================================;
  2. //
  3. // Copyright (c) Microsoft Corporation 1999-2000.
  4. //
  5. //--------------------------------------------------------------------------;
  6. //
  7. // MSVidFilePlayback.cpp : Implementation of CMSVidFilePlayback
  8. //
  9. #include "stdafx.h"
  10. #ifndef TUNING_MODEL_ONLY
  11. #include "atltmp.h"
  12. #include "MSVidCtl.h"
  13. #include "MSVidFilePlayback.h"
  14. #include <nserror.h>
  15. #include <wmsdkidl.h>
  16. #define FILE_BEGINNING 0
  17. #define LOCAL_OATRUE -1
  18. DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MSVidFilePlaybackDevice, CMSVidFilePlayback)
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CMSVidFilePlayback
  21. STDMETHODIMP CMSVidFilePlayback::PostRun(){
  22. if(m_fGraphInit){
  23. InitGraph();
  24. m_fGraphInit = false;
  25. }
  26. return IMSVidPBGraphSegmentImpl<CMSVidFilePlayback, MSVidSEG_SOURCE, &GUID_NULL>::PostRun();
  27. }
  28. STDMETHODIMP CMSVidFilePlayback::put_Rate(double lRate){
  29. HRESULT hr = S_OK;
  30. try{
  31. /*** Checking args and init'ing interfaces ***/
  32. if (!m_pGraph) {
  33. // graph not valid
  34. return Error(IDS_INVALID_STATE, __uuidof(IMSVidFilePlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  35. }
  36. // Attempt to set the rate using IMediaSeeking
  37. DSFilter Reader = m_Filters[m_iReader];
  38. PQMediaSeeking PQIMSeeking;
  39. if(Reader){
  40. for(DSFilter::iterator iPin = Reader.begin(); iPin != Reader.end(); ++iPin){
  41. PQIMSeeking = (*iPin);
  42. if(PQIMSeeking){
  43. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::put_Rate found Pin"), "");
  44. break;
  45. }
  46. }
  47. }
  48. if(!PQIMSeeking){
  49. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::put_Rate using graph"), "");
  50. PQIMSeeking = m_pGraph;
  51. }
  52. if(PQIMSeeking){
  53. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::put_Rate using Imediaseeking"), "");
  54. return PQIMSeeking->SetRate(lRate);
  55. }
  56. // If IMediaSeeking FAILS try IMediaPostion
  57. PQMediaPosition PQIMPos(m_pGraph);
  58. if(PQIMPos){
  59. // Change rate
  60. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::put_Rate using Imediaposition"), "");
  61. return PQIMPos->put_Rate((double)lRate);
  62. }
  63. // Could Not QI Either one set the error
  64. return Error(IDS_E_CANTQI , __uuidof(IMSVidFilePlayback), E_NOINTERFACE);
  65. }
  66. catch(HRESULT hrTmp){
  67. // Something went bad, threw a HRESULT
  68. return Error(IDS_INVALID_STATE , __uuidof(IMSVidFilePlayback), hrTmp);
  69. }
  70. catch(...){
  71. // Something went bad, dont know what it threw
  72. return E_UNEXPECTED;
  73. }
  74. }
  75. STDMETHODIMP CMSVidFilePlayback::get_Rate(double *lRate){
  76. HRESULT hr = S_OK;
  77. try{
  78. /*** Checking args and init'ing interfaces ***/
  79. if (!m_pGraph) {
  80. // graph not valid
  81. return Error(IDS_INVALID_STATE, __uuidof(IMSVidFilePlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  82. }
  83. // Attempt to set the rate using IMediaSeeking
  84. DSFilter Reader = m_Filters[m_iReader];
  85. PQMediaSeeking PQIMSeeking;
  86. if(Reader){
  87. for(DSFilter::iterator iPin = Reader.begin(); iPin != Reader.end(); ++iPin){
  88. PQIMSeeking = (*iPin);
  89. if(PQIMSeeking){
  90. break;
  91. }
  92. }
  93. }
  94. if(!PQIMSeeking){
  95. PQIMSeeking = m_pGraph;
  96. }
  97. if(PQIMSeeking){
  98. return PQIMSeeking->GetRate(lRate);
  99. }
  100. // If IMediaSeeking FAILS try IMediaPostion
  101. PQMediaPosition PQIMPos(m_pGraph);
  102. if(PQIMPos){
  103. // Change rate
  104. return PQIMPos->get_Rate(lRate);
  105. }
  106. // Could Not QI Either one set the error
  107. return Error(IDS_E_CANTQI , __uuidof(IMSVidFilePlayback), E_NOINTERFACE);
  108. }
  109. catch(HRESULT hrTmp){
  110. // Something went bad, threw a HRESULT
  111. return Error(IDS_INVALID_STATE , __uuidof(IMSVidFilePlayback), hrTmp);
  112. }
  113. catch(...){
  114. // Something went bad, dont know what it threw
  115. return E_UNEXPECTED;
  116. }
  117. }
  118. STDMETHODIMP CMSVidFilePlayback::PreStop(){
  119. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::PreStop()"), "");
  120. double curRate = 0;
  121. HRESULT hr = get_Rate(&curRate);
  122. if(SUCCEEDED(hr) && curRate != 1){
  123. hr = IMSVidFilePlaybackImpl<CMSVidFilePlayback, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidFilePlayback>::put_Rate(1);
  124. if(FAILED(hr)){
  125. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::PreStop() base put_Rate 1 failed"), "");
  126. }
  127. hr = put_Rate(1);
  128. if(FAILED(hr)){
  129. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::PreStop() put_Rate 1 failed"), "");
  130. }
  131. }
  132. else{
  133. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::PreStop() get_Rate failed"), "");
  134. }
  135. return NOERROR;
  136. }
  137. STDMETHODIMP CMSVidFilePlayback::PostStop(){
  138. HRESULT hr = S_OK;
  139. TRACELSM(TRACE_DETAIL, (dbgDump << "MSVidFilePlayback::PostStop()"), "");
  140. try {
  141. #if 0
  142. // If the graph is not is stopped state
  143. // we make sure it is
  144. if (!m_pGraph.IsStopped()) {
  145. HRESULT hr = PQVidCtl(m_pContainer)->Stop();
  146. }
  147. #endif
  148. // If m_fEnableResetOnStop is true then we need to reset
  149. // the postion back to the beggining
  150. // else do nothing
  151. // If it fails file cannot be reset to beginning
  152. if(m_fEnableResetOnStop){
  153. put_CurrentPosition(0);
  154. }
  155. }
  156. catch(HRESULT hrTmp){
  157. hr = hrTmp;
  158. }
  159. catch(...){
  160. hr = E_UNEXPECTED;
  161. }
  162. return hr;
  163. }
  164. STDMETHODIMP CMSVidFilePlayback::InterfaceSupportsErrorInfo(REFIID riid)
  165. {
  166. static const IID* arr[] =
  167. {
  168. &IID_IMSVidFilePlayback
  169. };
  170. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  171. {
  172. if (InlineIsEqualGUID(*arr[i],riid))
  173. return S_OK;
  174. }
  175. return S_FALSE;
  176. }
  177. STDMETHODIMP CMSVidFilePlayback::put_Container(IMSVidGraphSegmentContainer *pCtl)
  178. {
  179. try {
  180. if (!m_fInit) {
  181. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidFilePlayback), CO_E_NOTINITIALIZED);
  182. }
  183. if (!pCtl) {
  184. return Unload();
  185. }
  186. if (m_pContainer) {
  187. if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
  188. return Error(IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidFilePlayback), CO_E_ALREADYINITIALIZED);
  189. } else {
  190. return NO_ERROR;
  191. }
  192. }
  193. // DON'T addref the container. we're guaranteed nested lifetimes
  194. // and an addref creates circular refcounts so we never unload.
  195. m_pContainer.p = pCtl;
  196. m_pGraph = m_pContainer.GetGraph();
  197. return NOERROR;
  198. } catch (ComException &e) {
  199. return e;
  200. } catch (...) {
  201. return E_UNEXPECTED;
  202. }
  203. }
  204. STDMETHODIMP CMSVidFilePlayback::Build() {
  205. if (!m_FileName) {
  206. return Error(IDS_INVALID_STATE, __uuidof(IMSVidFilePlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  207. }
  208. if(m_Filters.size() > 0){
  209. return NOERROR;
  210. }
  211. USES_CONVERSION;
  212. CString csName(_T("File Playback"));
  213. DSFilter pfr;
  214. HRESULT hr = pfr.CoCreateInstance(CLSID_WMAsfReader,0, CLSCTX_INPROC_SERVER);
  215. if(SUCCEEDED(hr)){
  216. CComQIPtr<IFileSourceFilter> pqFS(pfr);
  217. if(!!pqFS){
  218. // set the target ASF filename
  219. hr = pqFS->Load(m_FileName, NULL);
  220. if(FAILED(hr)){
  221. if(hr == (HRESULT)NS_E_LICENSE_REQUIRED){
  222. CComQIPtr<IWMDRMReader> pq_DRMReader(pqFS);
  223. if(pq_DRMReader){
  224. hr = pq_DRMReader->AcquireLicense(1); // 1 == attempt silently
  225. if(SUCCEEDED(hr)){
  226. hr = pqFS->Load(m_FileName, NULL);
  227. }
  228. else{
  229. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() Could not acquire license"), "");
  230. }
  231. }
  232. else{
  233. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() Could not qi for IWMDRMReader "), "");
  234. }
  235. }
  236. }
  237. if(SUCCEEDED(hr)){
  238. // add the ASF writer filter to the graph
  239. hr = m_pGraph->AddFilter(pfr, csName);
  240. if(SUCCEEDED(hr)){
  241. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() added WMV filter to graph hr = " << std::hex << hr), "");
  242. }
  243. else{
  244. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() could not add filter to graph hr = " << std::hex << hr), "");
  245. }
  246. }
  247. else{
  248. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() Could not set file name, hr = " << std::hex << hr), "");
  249. }
  250. }
  251. else{
  252. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() Could not get IFileSourceFilter interface, hr = " << std::hex << hr), "");
  253. }
  254. }
  255. else{
  256. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() CreateFilter AsfReader failed, hr = " << std::hex << hr), "");
  257. }
  258. if (FAILED(hr)) {
  259. hr = m_pGraph->AddSourceFilter(m_FileName, csName, &pfr);
  260. if(FAILED(hr)){
  261. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidFilePlayback::Build() Add Source Filter Failed, hr = " << std::hex << hr), "");
  262. return Error(IDS_CANT_PLAY_FILE, __uuidof(IMSVidFilePlayback), hr);
  263. }
  264. }
  265. m_Filters.clear();
  266. m_Filters.push_back(pfr);
  267. m_iReader = m_Filters.size() - 1;
  268. return NOERROR;
  269. }
  270. STDMETHODIMP CMSVidFilePlayback::OnEventNotify(long lEvent, LONG_PTR lParam1, LONG_PTR lParam2) {
  271. return IMSVidPBGraphSegmentImpl<CMSVidFilePlayback, MSVidSEG_SOURCE, &GUID_NULL>::OnEventNotify(lEvent, lParam1, lParam2);
  272. }
  273. #endif //TUNING_MODEL_ONLY
  274. // end of file - MSVidFilePlayback.cpp