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.

1220 lines
42 KiB

  1. //==========================================================================;
  2. //
  3. // Copyright (c) Microsoft Corporation 1999-2000.
  4. //
  5. //--------------------------------------------------------------------------;
  6. //
  7. // MSVidStreamBufferSource.cpp : Implementation of CMSVidStreamBufferSource
  8. //
  9. #include "stdafx.h"
  10. #ifndef TUNING_MODEL_ONLY
  11. #include "atltmp.h"
  12. #include <encdec.h>
  13. #include "MSVidCtl.h"
  14. #include "MSVidsbeSource.h"
  15. #include "encdec.h"
  16. #if 0 // code for testing wm content
  17. #include <wmsdkidl.h>
  18. #endif
  19. #include "msvidsbesink.h" // to get pabCert2
  20. #define FILE_BEGINNING 0
  21. #define LOCAL_OATRUE -1
  22. DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MSVidStreamBufferSource, CMSVidStreamBufferSource)
  23. enum{
  24. CLOSE_TO_LIVE = 50,
  25. };
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CMSVidStreamBufferSource
  28. STDMETHODIMP CMSVidStreamBufferSource::get_SBESource(/*[out, retval]*/ IUnknown **sbeFilter){
  29. if(!sbeFilter){
  30. return E_POINTER;
  31. }
  32. if(!m_spFileSource){
  33. USES_CONVERSION;
  34. CString csName(_T("SBE Playback"));
  35. QIFileSource qiFSource;
  36. HRESULT hr = qiFSource.CoCreateInstance(CLSID_StreamBufferSource, NULL, CLSCTX_INPROC_SERVER);
  37. if (FAILED(hr)){
  38. _ASSERT(false);
  39. return E_UNEXPECTED;
  40. }
  41. if(!qiFSource){
  42. _ASSERT(false);
  43. return E_UNEXPECTED;
  44. }
  45. m_spFileSource = qiFSource;
  46. }
  47. CComPtr<IUnknown> pUnk(m_spFileSource);
  48. if(!pUnk){
  49. return E_UNEXPECTED;
  50. }
  51. *sbeFilter = pUnk.Detach();
  52. return NOERROR;
  53. }
  54. STDMETHODIMP CMSVidStreamBufferSource::CurrentRatings(/*[out, retval]*/ EnTvRat_System *pEnSystem, /*[out, retval]*/ EnTvRat_GenericLevel *pEnRating,
  55. /*[out, retval]*/ LONG *plbfEnAttr){
  56. if(!pEnSystem || !pEnRating || !plbfEnAttr){
  57. return E_POINTER;
  58. }
  59. DSFilterList::iterator i;
  60. EnTvRat_System system = static_cast<EnTvRat_System>(-1);
  61. EnTvRat_GenericLevel level = static_cast<EnTvRat_GenericLevel>(-1);
  62. LONG attr = static_cast<LONG>(-1);
  63. if(m_decFilters.empty()){
  64. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  65. }
  66. for(i = m_decFilters.begin(); i != m_decFilters.end(); ++i){
  67. EnTvRat_System temp_system = static_cast<EnTvRat_System>(-1);
  68. EnTvRat_GenericLevel temp_level = static_cast<EnTvRat_GenericLevel>(-1);
  69. LONG temp_attri = static_cast<LONG>(-1);
  70. CComQIPtr<IDTFilter> qiDT(*i);
  71. if(!qiDT){
  72. continue;
  73. }
  74. HRESULT hr = qiDT->GetCurrRating(&temp_system, &temp_level, &temp_attri);
  75. if(FAILED(hr)){
  76. continue;
  77. }
  78. if(temp_system != system ||
  79. temp_level != level ||
  80. temp_attri != attr){
  81. system = temp_system;
  82. level = temp_level;
  83. attr = temp_attri;
  84. }
  85. }
  86. if(static_cast<long>(system) < 0 || static_cast<long>(level) < 0 || static_cast<long>(attr) < 0){
  87. return E_FAIL;
  88. }
  89. *pEnSystem = system;
  90. *pEnRating = level;
  91. *plbfEnAttr = attr;
  92. return S_OK;
  93. }
  94. // ------------------
  95. STDMETHODIMP CMSVidStreamBufferSource::MaxRatingsLevel(/*[in]*/ EnTvRat_System enSystem, /*[in]*/ EnTvRat_GenericLevel enRating,
  96. /*[in]*/ LONG plbfEnAttr){
  97. DSFilterList::iterator i;
  98. if(m_decFilters.empty()){
  99. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  100. }
  101. for(i = m_decFilters.begin(); i != m_decFilters.end(); ++i){
  102. CComQIPtr<IDTFilter> qiDT(*i);
  103. if(!qiDT){
  104. continue;
  105. }
  106. HRESULT hr = qiDT->put_BlockedRatingAttributes(enSystem, enRating, plbfEnAttr);
  107. if(FAILED(hr)){
  108. return hr;
  109. }
  110. }
  111. return S_OK;
  112. }
  113. STDMETHODIMP CMSVidStreamBufferSource::put_BlockUnrated(/*[in]*/ VARIANT_BOOL bBlock){
  114. DSFilterList::iterator i;
  115. bool block = (bBlock == VARIANT_TRUE) ? true : false;
  116. if(m_decFilters.empty()){
  117. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  118. }
  119. for(i = m_decFilters.begin(); i != m_decFilters.end(); ++i){
  120. CComQIPtr<IDTFilter> qiDT(*i);
  121. if(!qiDT){
  122. continue;
  123. }
  124. HRESULT hr = qiDT->put_BlockUnRated(block);
  125. if(FAILED(hr)){
  126. return hr;
  127. }
  128. }
  129. return S_OK;
  130. }
  131. STDMETHODIMP CMSVidStreamBufferSource::put_UnratedDelay(/*[in]*/ long dwDelay){
  132. DSFilterList::iterator i;
  133. if(m_decFilters.empty()){
  134. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  135. }
  136. for(i = m_decFilters.begin(); i != m_decFilters.end(); ++i){
  137. CComQIPtr<IDTFilter> qiDT(*i);
  138. if(!qiDT){
  139. continue;
  140. }
  141. HRESULT hr = qiDT->put_BlockUnRatedDelay(dwDelay);
  142. if(FAILED(hr)){
  143. return hr;
  144. }
  145. }
  146. return S_OK;
  147. }
  148. STDMETHODIMP CMSVidStreamBufferSource::Unload(void) {
  149. BroadcastUnadvise();
  150. m_decFilters.clear();
  151. HRESULT hr = IMSVidGraphSegmentImpl<CMSVidStreamBufferSource, MSVidSEG_SOURCE, &GUID_NULL>::Unload();
  152. m_iReader = -1;
  153. m_spFileSource = reinterpret_cast<IFileSourceFilter*>(NULL);
  154. return hr;
  155. }
  156. STDMETHODIMP CMSVidStreamBufferSource::put_Init(IUnknown *pInit){
  157. HRESULT hr = IMSVidGraphSegmentImpl<CMSVidStreamBufferSource, MSVidSEG_SOURCE, &GUID_NULL>::put_Init(pInit);
  158. if (FAILED(hr)) {
  159. return hr;
  160. }
  161. if (pInit) {
  162. m_fInit = false;
  163. return E_NOTIMPL;
  164. }
  165. return NOERROR;
  166. }
  167. STDMETHODIMP CMSVidStreamBufferSource::get_Name(BSTR * Name){
  168. if (!m_fInit) {
  169. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidStreamBufferSource), CO_E_NOTINITIALIZED);
  170. }
  171. if (Name == NULL)
  172. return E_POINTER;
  173. try {
  174. *Name = m_Name.Copy();
  175. } catch(...) {
  176. return E_POINTER;
  177. }
  178. return NOERROR;
  179. }
  180. // IMSVidInputDevice
  181. STDMETHODIMP CMSVidStreamBufferSource::IsViewable(VARIANT* pv, VARIANT_BOOL *pfViewable)
  182. {
  183. if (!m_fInit) {
  184. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidStreamBufferSource), CO_E_NOTINITIALIZED);
  185. }
  186. if (!pv) {
  187. return E_POINTER;
  188. }
  189. return E_NOTIMPL;
  190. }
  191. STDMETHODIMP CMSVidStreamBufferSource::View(VARIANT* pv) {
  192. if (!m_fInit) {
  193. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidStreamBufferSource), CO_E_NOTINITIALIZED);
  194. }
  195. if (!pv) {
  196. return E_POINTER;
  197. }
  198. if (!_wcsnicmp(pv->bstrVal, L"DVD:", 4)) {
  199. return E_FAIL;
  200. }
  201. return put_FileName(pv->bstrVal);
  202. }
  203. STDMETHODIMP CMSVidStreamBufferSource::InterfaceSupportsErrorInfo(REFIID riid)
  204. {
  205. static const IID* arr[] =
  206. {
  207. &IID_IMSVidStreamBufferSource
  208. };
  209. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  210. {
  211. if (InlineIsEqualGUID(*arr[i],riid))
  212. return S_OK;
  213. }
  214. return S_FALSE;
  215. }
  216. STDMETHODIMP CMSVidStreamBufferSource::put_Container(IMSVidGraphSegmentContainer *pCtl){
  217. try {
  218. HRESULT hr = S_OK;
  219. if (!m_fInit) {
  220. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidStreamBufferSource), CO_E_NOTINITIALIZED);
  221. }
  222. if (!pCtl) {
  223. #ifdef BUILD_WITH_DRM
  224. CComQIPtr<IServiceProvider> spServiceProvider(m_pGraph);
  225. if (spServiceProvider != NULL) {
  226. CComPtr<IDRMSecureChannel> spSecureService;
  227. hr = spServiceProvider->QueryService(SID_DRMSecureServiceChannel,
  228. IID_IDRMSecureChannel,
  229. reinterpret_cast<LPVOID*>(&spSecureService));
  230. if(S_OK == hr){
  231. // Found existing Secure Server
  232. CComQIPtr<IRegisterServiceProvider> spRegServiceProvider(m_pGraph);
  233. if(spRegServiceProvider == NULL){
  234. // no service provider interface on the graph - fatal!
  235. hr = E_NOINTERFACE;
  236. }
  237. if(SUCCEEDED(hr)){
  238. hr = spRegServiceProvider->RegisterService(SID_DRMSecureServiceChannel, NULL);
  239. }
  240. }
  241. _ASSERT(SUCCEEDED(hr));
  242. }
  243. #endif
  244. return Unload();
  245. }
  246. if (m_pContainer) {
  247. if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
  248. return Error(IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidStreamBufferSource), CO_E_ALREADYINITIALIZED);
  249. } else {
  250. return NO_ERROR;
  251. }
  252. }
  253. // DON'T addref the container. we're guaranteed nested lifetimes
  254. // and an addref creates circular refcounts so we never unload.
  255. m_pContainer.p = pCtl;
  256. m_pGraph = m_pContainer.GetGraph();
  257. hr = BroadcastAdvise();
  258. if (FAILED(hr)) {
  259. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::put_Container() can't advise for broadcast events");
  260. return E_UNEXPECTED;
  261. }
  262. #if 0 // code for testing wm content
  263. CComPtr<IUnknown> pUnkCert;
  264. hr = WMCreateCertificate(&pUnkCert);
  265. if (FAILED(hr)){
  266. _ASSERT(false);
  267. }
  268. CComQIPtr<IMSVidCtl>tempCtl(pCtl);
  269. if(tempCtl){
  270. hr = tempCtl->put_ServiceProvider(pUnkCert);
  271. if (FAILED(hr)){
  272. _ASSERT(false);
  273. }
  274. }
  275. #endif
  276. #ifdef BUILD_WITH_DRM
  277. #ifdef USE_TEST_DRM_CERT
  278. {
  279. DWORD dwDisableDRMCheck = 0;
  280. CRegKey c;
  281. CString keyname(_T("SOFTWARE\\Debug\\MSVidCtl"));
  282. DWORD rc = c.Open(HKEY_LOCAL_MACHINE, keyname, KEY_READ);
  283. if (rc == ERROR_SUCCESS) {
  284. rc = c.QueryValue(dwDisableDRMCheck, _T("DisableDRMCheck"));
  285. if (rc != ERROR_SUCCESS) {
  286. dwDisableDRMCheck = 0;
  287. }
  288. }
  289. if(dwDisableDRMCheck == 1){
  290. return S_OK;
  291. }
  292. }
  293. #endif
  294. CComQIPtr<IServiceProvider> spServiceProvider(m_pGraph);
  295. if (spServiceProvider == NULL) {
  296. return E_NOINTERFACE;
  297. }
  298. CComPtr<IDRMSecureChannel> spSecureService;
  299. hr = spServiceProvider->QueryService(SID_DRMSecureServiceChannel,
  300. IID_IDRMSecureChannel,
  301. reinterpret_cast<LPVOID*>(&spSecureService));
  302. if(S_OK == hr){
  303. // Found existing Secure Server
  304. return S_OK;
  305. }
  306. else{
  307. // if it's not there or failed for ANY reason
  308. // lets create it and register it
  309. CComQIPtr<IRegisterServiceProvider> spRegServiceProvider(m_pGraph);
  310. if(spRegServiceProvider == NULL){
  311. // no service provider interface on the graph - fatal!
  312. hr = E_NOINTERFACE;
  313. }
  314. else{
  315. // Create the Client
  316. CComPtr<IDRMSecureChannel> spSecureServiceServer;
  317. hr = DRMCreateSecureChannel( &spSecureServiceServer);
  318. if(spSecureServiceServer == NULL){
  319. hr = E_OUTOFMEMORY;
  320. }
  321. if(FAILED(hr)){
  322. return hr;
  323. }
  324. // Init keys
  325. hr = spSecureServiceServer->DRMSC_SetCertificate((BYTE *)pabCert2, cBytesCert2);
  326. if(FAILED(hr)){
  327. return hr;
  328. }
  329. hr = spSecureServiceServer->DRMSC_SetPrivateKeyBlob((BYTE *)pabPVK2, cBytesPVK2);
  330. if(FAILED(hr)){
  331. return hr;
  332. }
  333. hr = spSecureServiceServer->DRMSC_AddVerificationPubKey((BYTE *)abEncDecCertRoot, sizeof(abEncDecCertRoot) );
  334. if(FAILED(hr)){
  335. return hr;
  336. }
  337. // Register It
  338. // note RegisterService does not addref pUnkSeekProvider
  339. hr = spRegServiceProvider->RegisterService(SID_DRMSecureServiceChannel, spSecureServiceServer);
  340. }
  341. }
  342. #endif // BUILD_WITH_DRM
  343. return NOERROR;
  344. } catch (ComException &e) {
  345. return e;
  346. } catch (...) {
  347. return E_UNEXPECTED;
  348. }
  349. }
  350. //-----------------------------------------------------------------------------------------
  351. // Name: get_CanStep(VARIANT_BOOL, VARIANT_BOOL*)
  352. //-----------------------------------------------------------------------------------------
  353. STDMETHODIMP CMSVidStreamBufferSource::get_CanStep(VARIANT_BOOL fBackwards, VARIANT_BOOL *pfCan){
  354. // NOTE: NO ONE supports backwords stepping (why not? who knows)
  355. // so just like everyone else we dont either
  356. try{
  357. // Checking args and interfaces
  358. if(!pfCan){
  359. // Passed a NULL Pointer
  360. return E_POINTER;
  361. }
  362. if (!m_pGraph) {
  363. // graph not valid
  364. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  365. }
  366. //Get a VideoFrameStep Interface
  367. PQVideoFrameStep pVFS(m_pGraph);
  368. if(!pVFS){
  369. // Could Not QI
  370. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  371. }
  372. if(fBackwards == VARIANT_TRUE){
  373. *pfCan = VARIANT_TRUE;
  374. return S_OK;
  375. }
  376. else{
  377. if(pVFS->CanStep(FALSE, NULL)==S_OK){
  378. // It is all Good, Can Step Forward
  379. *pfCan = VARIANT_TRUE;
  380. return S_OK;
  381. }
  382. else{
  383. // Can't Step
  384. *pfCan = VARIANT_FALSE;
  385. return S_OK;
  386. }
  387. }
  388. }
  389. catch(HRESULT hrTmp){
  390. // Something went bad, threw a HRESULT
  391. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  392. }
  393. catch(...){
  394. // Something went bad, dont know what it threw
  395. return E_UNEXPECTED;
  396. }
  397. }
  398. //-----------------------------------------------------------------------------------------
  399. // Name: Step(long)
  400. //-----------------------------------------------------------------------------------------
  401. STDMETHODIMP CMSVidStreamBufferSource::Step(long lStep){
  402. try{
  403. // Checking args and interfaces
  404. long tempStep = lStep;
  405. if (!m_pGraph || !m_pContainer) {
  406. // graph not valid
  407. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  408. }
  409. PQVideoFrameStep pVFS(m_pGraph);
  410. if(!pVFS){
  411. // Could Not QI
  412. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  413. }
  414. if(lStep < 0){
  415. PQMediaControl pmc(m_pGraph);
  416. if (!pmc) {
  417. return Error(IDS_NO_MEDIA_CONTROL, __uuidof(IMSVidPlayback), E_UNEXPECTED);
  418. }
  419. HRESULT hr = pmc->Pause();
  420. if (FAILED(hr)) {
  421. TRACELSM(TRACE_ERROR, (dbgDump << "CVidCtl::Pause() hr = " << std::hex << hr), "");
  422. return Error(IDS_CANT_PAUSE_GRAPH, __uuidof(IMSVidPlayback), hr);
  423. }
  424. long cur = 0;
  425. long stepVal = (/*half a second in 100ths of a second*/ 50 * lStep);
  426. PositionModeList curMode;
  427. hr = get_PositionMode(&curMode);
  428. if(FAILED(hr)){
  429. return hr;
  430. }
  431. if(curMode == FrameMode){
  432. stepVal = (stepVal/100) * 30; // hard coded to 30 fps for now
  433. }
  434. hr = get_CurrentPosition(&cur);
  435. if(FAILED(hr)){
  436. return hr;
  437. }
  438. if(cur == 0){
  439. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  440. }
  441. cur = cur + stepVal; // stepVal is negative, duh
  442. hr = put_CurrentPosition(cur);
  443. if(FAILED(hr)){
  444. return hr;
  445. }
  446. // Set tempStep and then step to refresh the current frame
  447. tempStep = 1;
  448. }
  449. // Make it step
  450. return pVFS->Step(tempStep, NULL);
  451. }
  452. catch(HRESULT hrTmp){
  453. // Something went bad, threw a HRESULT
  454. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  455. }
  456. catch(...){
  457. // Something went bad, dont know what it threw
  458. return E_UNEXPECTED;
  459. }
  460. }
  461. //-----------------------------------------------------------------------------------------
  462. // Name: get_Start(long)
  463. //-----------------------------------------------------------------------------------------
  464. STDMETHODIMP CMSVidStreamBufferSource::get_Start(/*[out, retval]*/long *lStart){
  465. HRESULT hr = S_OK;
  466. LONGLONG tempfirst, templatest;
  467. PositionModeList curMode;
  468. try{
  469. // Checking args and init'ing interfaces
  470. if (!lStart){
  471. return E_POINTER;
  472. }
  473. if (!m_pGraph) {
  474. // graph not valid
  475. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  476. }
  477. // See if object supports ISBEMediaSeeking
  478. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  479. if(!( !PQIMSeeking)){ // not not'ing smart pointer, they assert if p == 0
  480. // Find out what postion mode is being used
  481. hr = get_PositionMode(&curMode);
  482. if(FAILED(hr)){
  483. return hr;
  484. }
  485. hr = PQIMSeeking->GetAvailable(&tempfirst, &templatest);
  486. if(FAILED(hr)){
  487. return hr;
  488. }
  489. // If it is FrameMode no conversion needed
  490. if(tempfirst == 0){
  491. *lStart = 0;
  492. hr = S_OK;
  493. return hr;
  494. }
  495. if(curMode == FrameMode){
  496. *lStart = static_cast<long>(tempfirst);
  497. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_Start() return=" << (unsigned long)(*lStart) << " longlong=" << (double)(tempfirst)), "");
  498. hr = S_OK;
  499. return hr;
  500. }
  501. // If it is TenthsSecondsMode need to be converted from 100 nanosecond units
  502. if(curMode == TenthsSecondsMode){
  503. *lStart = static_cast<long>(tempfirst / nano_to_hundredths);
  504. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_Start() return=" << (unsigned long)(*lStart) << " longlong=" << (double)(tempfirst)), "");
  505. hr = S_OK;
  506. return hr;
  507. }
  508. // If it is some other mode not supported by the vidctl
  509. else{
  510. return E_UNEXPECTED;
  511. }
  512. }
  513. // Could Not QI IMedia Seeking or Position
  514. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  515. }
  516. catch(HRESULT hrTmp){
  517. // Something went bad, threw a HRESULT
  518. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  519. }
  520. catch(...){
  521. // Something went bad, dont know what it threw
  522. return E_UNEXPECTED;
  523. }
  524. }
  525. STDMETHODIMP CMSVidStreamBufferSource::get_RecordingAttribute(/*[out, retval]*/ IUnknown **pRecordingAttribute){
  526. if(!pRecordingAttribute){
  527. return E_POINTER;
  528. }
  529. CComPtr<IUnknown> pRecUnk(m_spFileSource);
  530. if(!pRecUnk){
  531. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  532. }
  533. *pRecordingAttribute = pRecUnk.Detach();
  534. return S_OK;
  535. }
  536. //-----------------------------------------------------------------------------------------
  537. // Name: get_Length(long)
  538. //-----------------------------------------------------------------------------------------
  539. STDMETHODIMP CMSVidStreamBufferSource::get_Length(/*[out, retval]*/long *lLength){
  540. HRESULT hr = S_OK;
  541. LONGLONG tempfirst, templatest;
  542. PositionModeList curMode;
  543. try{
  544. // Checking args and init'ing interfaces
  545. if (!lLength){
  546. return E_POINTER;
  547. }
  548. if (!m_pGraph) {
  549. // graph not valid
  550. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  551. }
  552. // See if object supports ISBEMediaSeeking
  553. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  554. if(!( !PQIMSeeking)){ // not not'ing smart pointer, they assert if p == 0
  555. // Find out what postion mode is being used
  556. hr = get_PositionMode(&curMode);
  557. if(FAILED(hr)){
  558. return hr;
  559. }
  560. hr = PQIMSeeking->GetAvailable(&tempfirst, &templatest);
  561. if(FAILED(hr)){
  562. return hr;
  563. }
  564. // If it is FrameMode no conversion needed
  565. if(curMode == FrameMode){
  566. *lLength = static_cast<long>(templatest);
  567. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_Length() return=" << (unsigned long)(*lLength) << " longlong=" << (double)(templatest)), "");
  568. hr = S_OK;
  569. return hr;
  570. }
  571. // If it is TenthsSecondsMode need to be converted from 100 nanosecond units
  572. else if(curMode == TenthsSecondsMode){
  573. *lLength = static_cast<long>(templatest / nano_to_hundredths);
  574. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_Length() return=" << (unsigned long)(*lLength) << " longlong=" << (double)(templatest)), "");
  575. hr = S_OK;
  576. return hr;
  577. }
  578. // If it is some other mode not supported by the vidctl
  579. else{
  580. return E_UNEXPECTED;
  581. }
  582. }
  583. // Could Not QI IMedia Seeking
  584. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  585. }
  586. catch(HRESULT hrTmp){
  587. // Something went bad, threw a HRESULT
  588. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  589. }
  590. catch(...){
  591. // Something went bad, dont know what it threw
  592. return E_UNEXPECTED;
  593. }
  594. }
  595. //-----------------------------------------------------------------------------------------
  596. // Name: get_CurrentPosition(LONGLONG*)
  597. //-----------------------------------------------------------------------------------------
  598. STDMETHODIMP CMSVidStreamBufferSource::get_CurrentPosition(/*[out,retval]*/long *lPosition) {
  599. HRESULT hr = S_OK;
  600. LONGLONG tempval;
  601. PositionModeList curMode;
  602. try{
  603. // Checking args and init'ing interfaces
  604. if (!lPosition){
  605. return E_POINTER;
  606. }
  607. if (!m_spFileSource) {
  608. // graph not valid
  609. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  610. }
  611. // See if object supports ISBEMediaSeeking
  612. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  613. if(!( !PQIMSeeking)){// not not'ing smart pointer, they assert if p == 0
  614. // Find out what postion mode is being used
  615. hr = get_PositionMode(&curMode);
  616. if(FAILED(hr)){
  617. return hr;
  618. }
  619. hr = PQIMSeeking->GetCurrentPosition(&tempval);
  620. if(FAILED(hr)){
  621. return hr;
  622. }
  623. // If it is FrameMode no conversion needed
  624. if(curMode == FrameMode){
  625. *lPosition = static_cast<long>(tempval);
  626. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_CurrentPosition() return=" << (unsigned long)(*lPosition) << " longlong=" << (double)(tempval)), "");
  627. hr = S_OK;
  628. return hr;
  629. }
  630. // If it is TenthsSecondsMode need to be converted from 100 nanosecond units
  631. else if(curMode == TenthsSecondsMode){
  632. *lPosition = static_cast<long>(tempval / nano_to_hundredths);
  633. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::get_CurrentPosition() return=" << (unsigned long)(*lPosition) << " longlong=" << (double)(tempval)), "");
  634. hr = S_OK;
  635. return hr;
  636. }
  637. // If it is some other mode not supported by the vidctl
  638. else{
  639. return E_UNEXPECTED;
  640. }
  641. }
  642. // Could Not QI IMedia Seeking
  643. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  644. }
  645. catch(HRESULT hrTmp){
  646. // Something went bad, threw a HRESULT
  647. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  648. }
  649. catch(...){
  650. // Something went bad, dont know what it threw
  651. return E_UNEXPECTED;
  652. }
  653. }
  654. //-----------------------------------------------------------------------------------------
  655. // Name: put_CurrentPosition(LONGLONG)
  656. //-----------------------------------------------------------------------------------------
  657. STDMETHODIMP CMSVidStreamBufferSource::put_CurrentPosition(/*[in]*/long lPosition) {
  658. HRESULT hr = S_OK;
  659. LONGLONG tempval;
  660. PositionModeList curMode;
  661. try{
  662. // Checking args and interfaces
  663. if (!m_spFileSource) {
  664. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  665. }
  666. // Check for a ISBEMediaSeeking Interface
  667. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  668. if(!( !PQIMSeeking)){ // not not'ing smart pointer, they assert if p == 0
  669. // Get the position Mode
  670. hr = get_PositionMode(&curMode);
  671. if(FAILED(hr)){
  672. return hr;
  673. }
  674. tempval = lPosition;
  675. // If it is in TenthsSecondsMode convert input into 100 nanosecond units
  676. if(curMode == TenthsSecondsMode){
  677. tempval = (tempval) * nano_to_hundredths;
  678. }
  679. // If it is in some other mode
  680. else if(curMode != FrameMode){
  681. return E_UNEXPECTED;
  682. }
  683. // Set the new Position
  684. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::put_CurrentPosition() set to: input=" << (unsigned long)(lPosition) << " longlong=" << (double)(tempval)), "");
  685. hr = PQIMSeeking->SetPositions(&tempval, AM_SEEKING_AbsolutePositioning, NULL, 0);
  686. TRACELSM(TRACE_ERROR, (dbgDump << "StreamBufferSource::put_CurrentPosition() actually set to:" << (double)(tempval)), "");
  687. return hr;
  688. }
  689. // Could Not QI Media Position
  690. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  691. }
  692. catch(HRESULT hrTmp){
  693. // Something went bad, threw a HRESULT
  694. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  695. }
  696. catch(...){
  697. // Something went bad, dont know what it threw
  698. return E_UNEXPECTED;
  699. }
  700. }
  701. //-----------------------------------------------------------------------------------------
  702. // Name: put_PositionMode(LONGLONG)
  703. //-----------------------------------------------------------------------------------------
  704. STDMETHODIMP CMSVidStreamBufferSource::put_PositionMode(/*[in]*/PositionModeList lPositionMode) {
  705. HRESULT hr = S_OK;
  706. double testval;
  707. get_Rate(&testval);
  708. try{
  709. // Checking args and interfaces
  710. if (!m_spFileSource) {
  711. // graph not valid
  712. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  713. }
  714. // only valid values
  715. if(lPositionMode != FrameMode && lPositionMode != TenthsSecondsMode){
  716. return E_INVALIDARG;
  717. }
  718. // Try for a ISBEMediaSeeking
  719. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  720. if(!( !PQIMSeeking)){// not not'ing smart pointer, they assert if p == 0
  721. // Set the new mode
  722. if(lPositionMode == FrameMode){
  723. hr = PQIMSeeking->SetTimeFormat( &( static_cast<GUID>(TIME_FORMAT_FRAME) ) );
  724. return hr;
  725. }
  726. if(lPositionMode == TenthsSecondsMode){
  727. hr = PQIMSeeking->SetTimeFormat(&(static_cast<GUID>(TIME_FORMAT_MEDIA_TIME)));
  728. return hr;
  729. }
  730. }
  731. // Could Not QI
  732. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  733. }
  734. catch(HRESULT hrTmp){
  735. // Something went bad, threw a HRESULT
  736. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  737. }
  738. catch(...){
  739. // Something went bad, dont know what it threw
  740. return E_UNEXPECTED;
  741. }
  742. }
  743. //-----------------------------------------------------------------------------------------
  744. // Name: get_PositionMode(LONGLONG*)
  745. //-----------------------------------------------------------------------------------------
  746. STDMETHODIMP CMSVidStreamBufferSource::get_PositionMode(/*[out,retval]*/PositionModeList* lPositionMode) {
  747. HRESULT hr = S_OK;
  748. double testval;
  749. get_Rate(&testval);
  750. try{
  751. // Checking args and interfaces
  752. if(!lPositionMode){
  753. return E_POINTER;
  754. }
  755. if (!m_spFileSource) {
  756. // graph not valid
  757. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  758. }
  759. // Get an ISBEMediaSeeking Interface
  760. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  761. if(!( !PQIMSeeking)){// not not'ing smart pointer, they assert if p == 0
  762. // Get the mode
  763. GUID cur_mode;
  764. hr = PQIMSeeking->GetTimeFormat(&cur_mode);
  765. if(FAILED(hr)){
  766. return hr;
  767. }
  768. // Check to see which mode it is in
  769. if(cur_mode == static_cast<GUID>(TIME_FORMAT_FRAME)){
  770. *lPositionMode = FrameMode;
  771. return S_OK;
  772. }
  773. if(cur_mode == static_cast<GUID>(TIME_FORMAT_MEDIA_TIME)){
  774. *lPositionMode = TenthsSecondsMode;
  775. return S_OK;
  776. }
  777. // Not in a vidctl supported mode
  778. else{
  779. return E_FAIL;
  780. }
  781. }
  782. // Could Not QI
  783. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  784. }
  785. catch(HRESULT hrTmp){
  786. // Something went bad, threw a HRESULT
  787. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  788. }
  789. catch(...){
  790. // Something went bad, dont know what it threw
  791. return E_UNEXPECTED;
  792. }
  793. }
  794. //-----------------------------------------------------------------------------------------
  795. // Name: put_Rate(double)
  796. //-----------------------------------------------------------------------------------------
  797. STDMETHODIMP CMSVidStreamBufferSource::put_Rate(double lRate){
  798. HRESULT hr = S_OK;
  799. try{
  800. /*** Checking args and init'ing interfaces ***/
  801. if (!m_spFileSource) {
  802. // graph not valid
  803. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  804. }
  805. // Attempt to set the rate using ISBEMediaSeeking
  806. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  807. if(!( !PQIMSeeking)){// not not'ing smart pointer, they assert if p == 0
  808. return PQIMSeeking->SetRate(lRate);
  809. }
  810. // Could Not QI set the error
  811. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  812. }
  813. catch(HRESULT hrTmp){
  814. // Something went bad, threw a HRESULT
  815. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  816. }
  817. catch(...){
  818. // Something went bad, dont know what it threw
  819. return E_UNEXPECTED;
  820. }
  821. }
  822. //-----------------------------------------------------------------------------------------
  823. // Name: get_Rate(double*)
  824. //-----------------------------------------------------------------------------------------
  825. STDMETHODIMP CMSVidStreamBufferSource::get_Rate(double *plRate){
  826. HRESULT hr = S_OK;
  827. try{
  828. /*** Checking args and init'ing interfaces ***/
  829. if (!plRate){
  830. return E_POINTER;
  831. }
  832. if (!m_spFileSource) {
  833. // graph not valid
  834. return Error(IDS_INVALID_STATE, __uuidof(IMSVidPlayback), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  835. }
  836. PQISBEMSeeking PQIMSeeking(m_spFileSource);
  837. if(!( !PQIMSeeking)){// not not'ing smart pointer, they assert if p == 0
  838. return PQIMSeeking->GetRate(plRate);
  839. }
  840. // Could Not QI
  841. return Error(IDS_E_CANTQI , __uuidof(IMSVidPlayback), E_NOINTERFACE);
  842. }
  843. catch(HRESULT hrTmp){
  844. // Something went bad, threw a HRESULT
  845. return Error(IDS_INVALID_STATE , __uuidof(IMSVidPlayback), hrTmp);
  846. }
  847. catch(...){
  848. // Something went bad, dont know what it threw
  849. return E_UNEXPECTED;
  850. }
  851. }
  852. STDMETHODIMP CMSVidStreamBufferSource::PostStop(){
  853. HRESULT hr = S_OK;
  854. try {
  855. #if 0
  856. // If the graph is not is stopped state
  857. // we make sure it is
  858. if (!m_pGraph.IsStopped()) {
  859. HRESULT hr = PQVidCtl(m_pContainer)->Stop();
  860. }
  861. #endif
  862. // If m_fEnableResetOnStop is true then we need to reset
  863. // the postion back to the beggining
  864. // else do nothing
  865. if(m_fEnableResetOnStop){
  866. return put_CurrentPosition(0);
  867. }
  868. }
  869. catch(HRESULT hrTmp){
  870. hr = hrTmp;
  871. }
  872. catch(...){
  873. hr = E_UNEXPECTED;
  874. }
  875. return hr;
  876. }
  877. STDMETHODIMP CMSVidStreamBufferSource::Decompose() {
  878. return put_Container(NULL);
  879. }
  880. STDMETHODIMP CMSVidStreamBufferSource::Build() {
  881. if (!m_FileName) {
  882. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  883. }
  884. QIFileSource qiFSource;
  885. HRESULT hr = S_OK;
  886. DSFilter pfr;
  887. if(!m_spFileSource){
  888. USES_CONVERSION;
  889. hr = qiFSource.CoCreateInstance(CLSID_StreamBufferSource, NULL, CLSCTX_INPROC_SERVER);
  890. if (FAILED(hr)){
  891. _ASSERT(false);
  892. return E_UNEXPECTED;
  893. }
  894. if(!qiFSource){
  895. _ASSERT(false);
  896. return E_UNEXPECTED;
  897. }
  898. m_spFileSource = qiFSource;
  899. hr = m_spFileSource->QueryInterface(&pfr);
  900. if (FAILED(hr) || !pfr) {
  901. _ASSERT(false);
  902. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidStreamBufferSource::Build() Could not create StreamBufferSource hr = " << std::hex << hr), "");
  903. return Error(IDS_CANT_PLAY_FILE, __uuidof(IMSVidStreamBufferSource), hr);
  904. }
  905. }
  906. else{
  907. qiFSource = m_spFileSource;
  908. if(!qiFSource){
  909. _ASSERT(false);
  910. return E_UNEXPECTED;
  911. }
  912. hr = m_spFileSource->QueryInterface(&pfr);
  913. if (FAILED(hr) || !pfr) {
  914. _ASSERT(false);
  915. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidStreamBufferSource::Build() Could not create StreamBufferSource hr = " << std::hex << hr), "");
  916. return Error(IDS_CANT_PLAY_FILE, __uuidof(IMSVidStreamBufferSource), hr);
  917. }
  918. }
  919. CString csName(_T("SBE Playback"));
  920. m_Filters.clear();
  921. hr = m_pGraph.AddFilter(pfr, csName);
  922. if(FAILED(hr)){
  923. _ASSERT(false);
  924. return E_UNEXPECTED;
  925. }
  926. hr = qiFSource->Load(m_FileName, NULL);
  927. if (FAILED(hr)) {
  928. bool rc = m_pGraph.RemoveFilter(pfr);
  929. if (!rc) {
  930. return E_UNEXPECTED;
  931. }
  932. TRACELSM(TRACE_ERROR, (dbgDump << "MSVidStreamBufferSource::Build() Could not create StreamBufferSource hr = " << std::hex << hr), "");
  933. return Error(IDS_CANT_PLAY_FILE, __uuidof(IMSVidStreamBufferSource), hr);
  934. }
  935. m_Filters.push_back(pfr);
  936. m_iReader = m_Filters.size() - 1;
  937. #if ENCRYPT_NEEDED
  938. DSFilterList intermediates;
  939. for(DSFilter::iterator i = pfr.begin(); i != pfr.end(); ++i){
  940. if((*i).GetDirection() == DOWNSTREAM && !(*i).IsConnected()){
  941. // Create and add a decoder Tagger Filter
  942. CComPtr<IUnknown> spEncTagD(CLSID_DTFilter, NULL, CLSCTX_INPROC_SERVER);
  943. if (!spEncTagD) {
  944. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSink::Build() can't load Tagger filter");
  945. return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IStreamBufferSink), E_UNEXPECTED);
  946. }
  947. DSFilter vrD(spEncTagD);
  948. if (!vrD) {
  949. ASSERT(false);
  950. return ImplReportError(__uuidof(IMSVidStreamBufferSink), IDS_CANT_CREATE_FILTER, __uuidof(IStreamBufferSink), E_UNEXPECTED);
  951. }
  952. m_Filters.push_back(vrD);
  953. m_decFilters.push_back(vrD);
  954. csName = _T("Decoder/Tagger Filter");
  955. m_pGraph.AddFilter(vrD, csName);
  956. // Connect pin to the Tagger
  957. hr = (*i).IntelligentConnect(vrD, intermediates);
  958. if(FAILED(hr)){
  959. TRACELM(TRACE_DETAIL, "CAnaSinComp::Compose() if you see this line more than once something must have gone wrong");
  960. }
  961. }
  962. }
  963. ASSERT(intermediates.begin() == intermediates.end());
  964. m_Filters.insert(m_Filters.end(), intermediates.begin(), intermediates.end());
  965. #endif
  966. return NOERROR;
  967. }
  968. STDMETHODIMP CMSVidStreamBufferSource::PreRun(){
  969. #if 0
  970. if(m_iReader == -1 || m_Filters.empty()){
  971. return Error(IDS_INVALID_STATE, __uuidof(IMSVidStreamBufferSource), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  972. }
  973. CComQIPtr<IReferenceClock> pq_IRClock(m_Filters[m_iReader]);
  974. if(!pq_IRClock){
  975. return S_FALSE;
  976. }
  977. CComQIPtr<IMediaFilter> pq_MFGph(m_pGraph);
  978. if(!pq_MFGph){
  979. return E_NOINTERFACE;
  980. }
  981. HRESULT hr = pq_MFGph->SetSyncSource(pq_IRClock);
  982. if(FAILED(hr)){
  983. ASSERT(false);
  984. }
  985. return hr;
  986. #endif
  987. return E_NOTIMPL;
  988. }
  989. STDMETHODIMP CMSVidStreamBufferSource::OnEventNotify(long lEvent, LONG_PTR lParam1, LONG_PTR lParam2) {
  990. if (lEvent == EC_COMPLETE) {
  991. double curRate = 0;
  992. HRESULT hr = S_OK;
  993. hr = get_Rate(&curRate);
  994. if(SUCCEEDED(hr)){
  995. if(curRate < 0){
  996. hr = put_Rate(1);
  997. if(FAILED(hr)){
  998. _ASSERT(false);
  999. }
  1000. // We need to transition to pause then back to play to flush all of the buffers
  1001. // It appears to be a decoder issue, mostly
  1002. PQVidCtl sp_VidCtl(m_pContainer);
  1003. if(sp_VidCtl){
  1004. hr = sp_VidCtl->Pause();
  1005. if(FAILED(hr)){
  1006. _ASSERT(false); // Failed to pause this is really bad
  1007. }
  1008. hr = sp_VidCtl->Run();
  1009. if(FAILED(hr)){
  1010. _ASSERT(false); // Failed to run this is really bad
  1011. }
  1012. }
  1013. else{
  1014. _ASSERT(false); // We got events with no vidctl hosting us, really weird
  1015. }
  1016. CComQIPtr<IMSVidPlayback> ppb(this);
  1017. Fire_EndOfMedia(ppb);
  1018. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify Tossed EndOfMedia at start of sbe stream");
  1019. return NOERROR;
  1020. }
  1021. }
  1022. }
  1023. if(lEvent == STREAMBUFFER_EC_RATE_CHANGED){
  1024. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify STREAMBUFFER_EC_RATE_CHANGED");
  1025. HRESULT hr = S_OK;
  1026. #if 0 // code to try to make up for the lack of a rate change event on the vidctl
  1027. MSVidCtlStateList curState = STATE_UNBUILT;
  1028. hr = PQVidCtl(m_pContainer)->get_State(&curState);
  1029. if(SUCCEEDED(hr) && curState == STATE_PLAY){
  1030. CComQIPtr<IMSVidDevice> pd(this);
  1031. if (!pd) {
  1032. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify Could not qi SBE Source Segment for IMSVidDevice");
  1033. }
  1034. else{
  1035. Fire_StateChange(pd, STATE_PLAY, STATE_PLAY);
  1036. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify Tossed StateChange STATE_PLAY STATE_PLAY for rate change");
  1037. }
  1038. }
  1039. #endif
  1040. long len;
  1041. long curPos;
  1042. curPos = len = 0;
  1043. hr = get_Length(&len);
  1044. if(SUCCEEDED(hr)){
  1045. hr = get_CurrentPosition(&curPos);
  1046. if(SUCCEEDED(hr)){
  1047. if(len <= (curPos + CLOSE_TO_LIVE)){ // if current position is with in CLOSE_TO_LIVE of the len the we just bounced off of the end of the stream
  1048. CComQIPtr<IMSVidPlayback> ppb(this);
  1049. if (!ppb) {
  1050. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify Could not qi SBE Source Segment for IMSVidPlayback");
  1051. }
  1052. else{
  1053. Fire_EndOfMedia(ppb);
  1054. TRACELM(TRACE_ERROR, "CMSVidStreamBufferSource::OnEventNotify Tossed EndOfMedia at end of sbe stream");
  1055. return NOERROR;
  1056. }
  1057. }
  1058. }
  1059. }
  1060. }
  1061. if(lEvent == STREAMBUFFER_EC_TIMEHOLE){
  1062. Fire_TimeHole(lParam1, lParam2);
  1063. return NOERROR;
  1064. }
  1065. if(lEvent == STREAMBUFFER_EC_STALE_DATA_READ){
  1066. Fire_StaleDataRead();
  1067. return NOERROR;
  1068. }
  1069. if(lEvent == STREAMBUFFER_EC_STALE_FILE_DELETED){
  1070. Fire_StaleFilesDeleted();
  1071. return NOERROR;
  1072. }
  1073. if(lEvent == STREAMBUFFER_EC_CONTENT_BECOMING_STALE){
  1074. Fire_ContentBecomingStale();
  1075. return NOERROR;
  1076. }
  1077. return IMSVidPBGraphSegmentImpl<CMSVidStreamBufferSource, MSVidSEG_SOURCE, &GUID_NULL>::OnEventNotify(lEvent, lParam1, lParam2);
  1078. }
  1079. HRESULT CMSVidStreamBufferSource::Fire(GUID gEventID) {
  1080. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidStreamBufferSource::Fire() guid = " << GUID2(gEventID)), "");
  1081. if (gEventID == EVENTID_ETDTFilterLicenseFailure) {
  1082. Fire_CertificateFailure();
  1083. } else if (gEventID == EVENTID_ETDTFilterLicenseOK) {
  1084. Fire_CertificateSuccess();
  1085. } else if (gEventID == EVENTID_DTFilterRatingsBlock) {
  1086. Fire_RatingsBlocked();
  1087. } else if (gEventID == EVENTID_DTFilterRatingsUnblock) {
  1088. Fire_RatingsUnblocked();
  1089. } else if (gEventID == EVENTID_DTFilterRatingChange) {
  1090. Fire_RatingsChanged();
  1091. }
  1092. return NOERROR;
  1093. }
  1094. #endif