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.

1033 lines
36 KiB

  1. //===========================================================================
  2. //
  3. // MSVidWebDVD.h: Definition of the CMSVidWebDVD class
  4. // Copyright (c) Microsoft Corporation 1999-2000.
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7. #if !defined(AFX_MSVIDWEBDVD_H__6CF9F624_1F3C_44FA_8F00_FCC31B2976D6__INCLUDED_)
  8. #define AFX_MSVIDWEBDVD_H__6CF9F624_1F3C_44FA_8F00_FCC31B2976D6__INCLUDED_
  9. #pragma once
  10. #include <dvdevcod.h>
  11. #include <algorithm>
  12. #include <objectwithsiteimplsec.h>
  13. #include "pbsegimpl.h"
  14. #include "webdvdimpl.h"
  15. #include "seg.h"
  16. #include "resource.h" // main symbols
  17. #include "mslcid.h"
  18. #include "MSVidWebDVDCP.h"
  19. #include "vidrect.h"
  20. #include <strmif.h>
  21. #include <math.h>
  22. #define DVD_ERROR_NoSubpictureStream 99
  23. #define EC_DVD_PLAYING (EC_DVDBASE + 0xFE)
  24. #define EC_DVD_PAUSED (EC_DVDBASE + 0xFF)
  25. #define E_NO_IDVD2_PRESENT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFF0)
  26. #define E_NO_DVD_VOLUME MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFF1)
  27. #define E_REGION_CHANGE_FAIL MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFF2)
  28. #define E_REGION_CHANGE_NOT_COMPLETED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0xFF3)
  29. typedef CComQIPtr<IDvdControl2, &IID_IDvdControl2> PQDVDControl2;
  30. typedef CComQIPtr<IDvdInfo2, &IID_IDvdInfo2> PQDVDInfo2;
  31. typedef CComQIPtr<IMSVidWebDVD, &IID_IMSVidWebDVD> PQWebDVD;
  32. // the following enum and struct are for DVD url parsing.
  33. typedef enum
  34. {
  35. DVD_Playback_Default,
  36. DVD_Playback_Title,
  37. DVD_Playback_Chapter,
  38. DVD_Playback_Chapter_Range,
  39. DVD_Playback_Time,
  40. DVD_Playback_Time_Range
  41. } DVDPlaybackRef;
  42. class DVDUrlInfo{
  43. public:
  44. DVDPlaybackRef enumRef;
  45. CComBSTR bstrPath;
  46. long lTitle;
  47. long lChapter;
  48. long lEndChapter;
  49. ULONG ulTime;
  50. ULONG ulEndTime;
  51. DVDUrlInfo(){
  52. bstrPath;
  53. lTitle = 0;
  54. lChapter = 0;
  55. lEndChapter = 0;
  56. ulTime = 0;
  57. ulEndTime = 0;
  58. }
  59. virtual ~DVDUrlInfo(){
  60. }
  61. };
  62. ////////////////////////////////////////////////////////////////////////////////////
  63. /*************************************************************************/
  64. /* Local Defines to sort of abstract the implementation and make the */
  65. /* changes bit more convinient. */
  66. /*************************************************************************/
  67. #define INITIALIZE_GRAPH_IF_NEEDS_TO_BE \
  68. {}
  69. #define INITIALIZE_GRAPH_IF_NEEDS_TO_BE_AND_PLAY \
  70. {}
  71. #define RETRY_IF_IN_FPDOM(func) \
  72. {func;}
  73. /////////////////////////////////////////////////////////////////////////////
  74. // CMSVidWebDVD
  75. class ATL_NO_VTABLE __declspec(uuid("011B3619-FE63-4814-8A84-15A194CE9CE3")) CMSVidWebDVD :
  76. public CComObjectRootEx<CComSingleThreadModel>,
  77. public IMSVidPBGraphSegmentImpl<CMSVidWebDVD, MSVidSEG_SOURCE, &GUID_NULL>,
  78. public IMSVidGraphSegmentUserInput,
  79. public IObjectWithSiteImplSec<CMSVidWebDVD>,
  80. public CComCoClass<CMSVidWebDVD, &__uuidof(CMSVidWebDVD)>,
  81. public ISupportErrorInfo,
  82. public IMSVidWebDVDImpl<CMSVidWebDVD, &LIBID_MSVidCtlLib, &GUID_NULL, IMSVidWebDVD>,
  83. public CProxy_WebDVDEvent< CMSVidWebDVD >,
  84. public IConnectionPointContainerImpl<CMSVidWebDVD>,
  85. public IObjectSafetyImpl<CMSVidWebDVD, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>,
  86. public IProvideClassInfo2Impl<&CLSID_MSVidWebDVD, &IID_IMSVidWebDVDEvent, &LIBID_MSVidCtlLib>
  87. {
  88. public:
  89. CMSVidWebDVD() :
  90. m_iDVDNav(-1),
  91. m_fUrlInfoSet(false),
  92. m_fResetSpeed(false),
  93. m_fStillOn(false),
  94. m_fFireNoSubpictureStream(false),
  95. m_fStepComplete(false),
  96. m_bEjected(false),
  97. m_DVDFilterState(dvdState_Undefined),
  98. m_lKaraokeAudioPresentationMode(-1),
  99. m_usButton(-1),
  100. m_Rate(1),
  101. m_Mode(TenthsSecondsMode)
  102. {
  103. m_fEnableResetOnStop = false;
  104. }
  105. REGISTER_AUTOMATION_OBJECT(IDS_PROJNAME,
  106. IDS_REG_MSVIDWEBDVD_PROGID,
  107. IDS_REG_MSVIDWEBDVD_DESC,
  108. LIBID_MSVidCtlLib,
  109. __uuidof(CMSVidWebDVD));
  110. DECLARE_PROTECT_FINAL_CONSTRUCT()
  111. BEGIN_COM_MAP(CMSVidWebDVD)
  112. COM_INTERFACE_ENTRY(IDispatch)
  113. COM_INTERFACE_ENTRY(IMSVidWebDVD)
  114. COM_INTERFACE_ENTRY(IObjectWithSite)
  115. COM_INTERFACE_ENTRY(IMSVidGraphSegment)
  116. COM_INTERFACE_ENTRY(IMSVidGraphSegmentUserInput)
  117. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  118. COM_INTERFACE_ENTRY(IMSVidPlayback)
  119. COM_INTERFACE_ENTRY(IMSVidInputDevice)
  120. COM_INTERFACE_ENTRY(IMSVidDevice)
  121. COM_INTERFACE_ENTRY(IProvideClassInfo)
  122. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  123. COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  124. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  125. COM_INTERFACE_ENTRY(IPersist)
  126. COM_INTERFACE_ENTRY(IObjectSafety)
  127. END_COM_MAP()
  128. BEGIN_CONNECTION_POINT_MAP(CMSVidWebDVD)
  129. CONNECTION_POINT_ENTRY(IID_IMSVidWebDVDEvent)
  130. END_CONNECTION_POINT_MAP()
  131. // ISupportsErrorInfo
  132. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  133. // IMSVidWebDVD
  134. public:
  135. int m_iDVDNav;
  136. // QI for IDVDControl2 from DVDNavigator
  137. #if 0
  138. PQDVDControl2 GetDVDControl2() {
  139. if (m_iDVDNav < 0) {
  140. return PQDVDControl2();
  141. }
  142. return PQDVDControl2(m_Filters[m_iDVDNav]);
  143. }
  144. #endif
  145. // QI for IDVDInfo2 from DVDNavigator
  146. PQDVDInfo2 GetDVDInfo2() {
  147. if (m_iDVDNav < 0) {
  148. return PQDVDInfo2();
  149. }
  150. return PQDVDInfo2(m_Filters[m_iDVDNav]);
  151. }
  152. CComBSTR __declspec(property(get=GetName)) m_Name;
  153. CComBSTR GetName(void) {
  154. CString csName = _T("DVD Playback");
  155. return CComBSTR(csName);
  156. }
  157. HRESULT Unload(void) {
  158. m_pDVDControl2.Release();
  159. HRESULT hr = IMSVidGraphSegmentImpl<CMSVidWebDVD, MSVidSEG_SOURCE, &GUID_NULL>::Unload();
  160. return hr;
  161. }
  162. virtual ~CMSVidWebDVD() {
  163. CleanUp();
  164. }
  165. // IMSVidGraphSegment
  166. STDMETHOD(put_Init)(IUnknown *pInit);
  167. STDMETHOD(Build)() {
  168. return NOERROR;
  169. }
  170. STDMETHOD(put_Rate)(double lRate){
  171. HRESULT hr = S_OK;
  172. CComQIPtr<IDvdCmd>IDCmd;
  173. double newRate = lRate;
  174. try{
  175. /*** Checking args and init'ing interfaces ***/
  176. if(!m_pDVDControl2){
  177. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  178. }
  179. // Change rate
  180. if(lRate > 0){
  181. // hr set in Retry macro
  182. long pauseCookie = 0;
  183. HRESULT hres = RunIfPause(&pauseCookie);
  184. if(FAILED(hres)){
  185. return hres;
  186. }
  187. hr = m_pDVDControl2->PlayForwards(lRate, DVD_CMD_FLAG_Flush, reinterpret_cast<IDvdCmd**>(&IDCmd));
  188. if(IDCmd){
  189. IDCmd->WaitForEnd();
  190. }
  191. hres = PauseIfRan(pauseCookie);
  192. if(FAILED(hres)){
  193. return hres;
  194. }
  195. }
  196. else if(lRate < 0){
  197. lRate = -lRate;
  198. // hr set in Retry macro
  199. long pauseCookie = 0;
  200. HRESULT hres = RunIfPause(&pauseCookie);
  201. if(FAILED(hres)){
  202. return hres;
  203. }
  204. hr = m_pDVDControl2->PlayBackwards(lRate, DVD_CMD_FLAG_Flush, reinterpret_cast<IDvdCmd**>(&IDCmd));
  205. if(IDCmd){
  206. IDCmd->WaitForEnd();
  207. }
  208. hres = PauseIfRan(pauseCookie);
  209. if(FAILED(hres)){
  210. return hres;
  211. }
  212. }
  213. else{
  214. hr = E_INVALIDARG;
  215. }
  216. }
  217. catch(HRESULT hrTmp){
  218. // Something went bad, threw a HRESULT
  219. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), hrTmp);
  220. }
  221. catch(...){
  222. // Something went bad, dont know what it threw
  223. hr = E_UNEXPECTED;
  224. }
  225. // Only set rate if it succeeds
  226. if(SUCCEEDED(hr)){
  227. m_Rate = newRate;
  228. }
  229. return hr;
  230. }
  231. STDMETHOD(get_Rate)(double* lRate){
  232. HRESULT hr;
  233. try{
  234. if(!lRate){
  235. return E_POINTER;
  236. }
  237. *lRate = m_Rate;
  238. return S_OK;
  239. }
  240. catch(HRESULT hrTmp){
  241. // Something went bad, threw a HRESULT
  242. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), hrTmp);
  243. }
  244. catch(...){
  245. // Something went bad, dont know what it threw
  246. hr = E_UNEXPECTED;
  247. }
  248. return hr;
  249. }
  250. STDMETHOD(put_EnableResetOnStop)(/*in*/VARIANT_BOOL newVal){
  251. HRESULT hr = S_OK;
  252. try {
  253. bool fEnable = (VARIANT_FALSE == newVal) ? false: true;
  254. bool fEnableOld = m_fEnableResetOnStop;
  255. m_fEnableResetOnStop = fEnable;
  256. if(!m_pDVDControl2){
  257. throw(S_FALSE); // we might not have initialized graph as of yet, but will
  258. // defer this to play state
  259. }/* end of if statement */
  260. hr = m_pDVDControl2->SetOption(DVD_ResetOnStop, fEnable);
  261. if(FAILED(hr)){
  262. m_fEnableResetOnStop = fEnableOld; // restore the old state
  263. }/* end of if statement */
  264. }/* end of try statement */
  265. catch(HRESULT hrTmp){
  266. hr = hrTmp;
  267. }
  268. catch(...){
  269. hr = E_UNEXPECTED;
  270. }/* end of catch statement */
  271. return HandleError(hr);
  272. }/* end of function put_EnableResetOnStop */
  273. //-----------------------------------------------------------------------------------------
  274. // Name: DVD_HMSF_TIMECODE convertDVDSeconds(double)
  275. // Description: Converts a seconds to a dvd timecode
  276. //-----------------------------------------------------------------------------------------
  277. DVD_HMSF_TIMECODE convertDVDSeconds(double Seconds, ULONG ulFlags, LONG mode){
  278. HRESULT hr = S_OK;
  279. DVD_HMSF_TIMECODE dvdTCode = {0,0,0,0};
  280. double fps;
  281. if(ulFlags == DVD_TC_FLAG_25fps){
  282. fps = 25;
  283. }
  284. else if(ulFlags == DVD_TC_FLAG_30fps){
  285. fps = 30;
  286. }
  287. else if(ulFlags == DVD_TC_FLAG_DropFrame){
  288. fps = 29.97;
  289. }
  290. else if(ulFlags == DVD_TC_FLAG_Interpolated){
  291. fps = 30; // is this right???
  292. }
  293. else{
  294. return dvdTCode;
  295. }
  296. if(mode == FrameMode){
  297. Seconds = Seconds / fps;
  298. }
  299. // If it is TenthsSecondsMode need to be converted from 100 nanosecond units
  300. else if(mode == TenthsSecondsMode){
  301. Seconds = Seconds / 100;
  302. }
  303. // If it is some other mode not supported by the vidctl
  304. else{
  305. return dvdTCode;
  306. }
  307. dvdTCode.bHours = (BYTE)(floor(Seconds/3600)); // Number of hours
  308. Seconds = Seconds - 3600 * dvdTCode.bHours;
  309. dvdTCode.bMinutes = (BYTE)(floor(Seconds/60));
  310. Seconds = Seconds - 60 *dvdTCode.bMinutes;
  311. dvdTCode.bSeconds = (BYTE)(floor(Seconds));
  312. Seconds = Seconds - dvdTCode.bSeconds;
  313. dvdTCode.bFrames = (BYTE)(floor(Seconds * fps));
  314. return dvdTCode;
  315. }
  316. //-----------------------------------------------------------------------------------------
  317. // Name: double convertDVDTimeCode(DVD_HMSF_TIMECODE, ULONG)
  318. // Description: Converts a dvd timecode with dvd flags into seconds and returns as a double
  319. //-----------------------------------------------------------------------------------------
  320. double convertDVDTimeCode(DVD_HMSF_TIMECODE dvdTime, ULONG ulFlags, long mode ){
  321. double fps;
  322. if(ulFlags == DVD_TC_FLAG_25fps){
  323. fps = 25;
  324. } else if(ulFlags == DVD_TC_FLAG_30fps){
  325. fps = 30;
  326. } else if(ulFlags == DVD_TC_FLAG_DropFrame){
  327. fps = 29.97;
  328. } else if(ulFlags == DVD_TC_FLAG_Interpolated){
  329. fps = 30; // is this right???
  330. } else{
  331. return 0;
  332. }
  333. double time_temp = static_cast<double>( (3600*dvdTime.bHours) + (60*dvdTime.bMinutes) +
  334. dvdTime.bSeconds + (dvdTime.bFrames/fps) );
  335. if(mode == FrameMode){
  336. time_temp = time_temp * fps;
  337. return time_temp;
  338. } else if(mode == TenthsSecondsMode){
  339. // If it is TenthsSecondsMode need to be converted from 100 nanosecond units
  340. time_temp = time_temp * 100;
  341. return time_temp;
  342. }
  343. // If it is some other mode not supported by the vidctl
  344. return 0;
  345. }
  346. //-----------------------------------------------------------------------------------------
  347. // Name: get_Length(LONGLONG*)
  348. //-----------------------------------------------------------------------------------------
  349. STDMETHOD(get_Length)(/*[out, retval]*/long *lLength){
  350. HRESULT hr = S_OK;
  351. try{
  352. /*** Checking args and init'ing interfaces ***/
  353. if(!lLength){
  354. return E_POINTER;
  355. }
  356. PQDVDInfo2 pqDInfo2 = GetDVDInfo2();
  357. if(!pqDInfo2){
  358. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  359. }
  360. // Get length
  361. DVD_HMSF_TIMECODE TotalTime;
  362. ULONG ulFlags;
  363. double seconds;
  364. hr = pqDInfo2->GetTotalTitleTime(&TotalTime, &ulFlags);
  365. if(FAILED(hr)){
  366. return hr;
  367. }
  368. // Get the length in seconds
  369. seconds = convertDVDTimeCode(TotalTime, ulFlags, m_Mode);
  370. if(seconds == 0){
  371. return E_UNEXPECTED;
  372. }
  373. *lLength = static_cast<long>(seconds);
  374. return S_OK;
  375. }
  376. catch(HRESULT hrTmp){
  377. // Something went bad, threw a HRESULT
  378. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), hrTmp);
  379. }
  380. catch(...){
  381. // Something went bad, dont know what it threw
  382. hr = E_UNEXPECTED;
  383. }
  384. return hr;
  385. }
  386. //-----------------------------------------------------------------------------------------
  387. // Name: get_CurrentPosition(LONGLONG*)
  388. //-----------------------------------------------------------------------------------------
  389. STDMETHOD(get_CurrentPosition)(/*[out,retval]*/long *lPosition) {
  390. HRESULT hr = S_OK;
  391. try{
  392. /*** Checking args and init'ing interfaces ***/
  393. PQDVDInfo2 pqDInfo2 = GetDVDInfo2();
  394. if(!pqDInfo2){
  395. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  396. }
  397. // Get length
  398. DVD_PLAYBACK_LOCATION2 dvdLocation;
  399. double seconds;
  400. hr = pqDInfo2->GetCurrentLocation(&dvdLocation);
  401. if(FAILED(hr)){
  402. return hr;
  403. }
  404. // Get the length in seconds
  405. seconds = convertDVDTimeCode(dvdLocation.TimeCode, dvdLocation.TimeCodeFlags, m_Mode);
  406. if(seconds == 0){
  407. return E_UNEXPECTED;
  408. }
  409. *lPosition = static_cast<long>(seconds);
  410. return S_OK;
  411. }
  412. catch(HRESULT hrTmp){
  413. // Something went bad, threw a HRESULT
  414. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), hrTmp);
  415. }
  416. catch(...){
  417. // Something went bad, dont know what it threw
  418. hr = E_UNEXPECTED;
  419. }
  420. return hr;
  421. }
  422. //-----------------------------------------------------------------------------------------
  423. // Name: put_CurrentPosition(LONGLONG)
  424. //-----------------------------------------------------------------------------------------
  425. STDMETHOD(put_CurrentPosition)(/*[in]*/long lPosition) {
  426. HRESULT hr = S_OK;
  427. CComQIPtr<IDvdCmd>IDCmd;
  428. try{
  429. /*** Checking args and init'ing interfaces ***/
  430. PQDVDInfo2 pqDInfo2 = GetDVDInfo2();
  431. if(!pqDInfo2 || !m_pDVDControl2){
  432. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  433. }
  434. // Get length
  435. DVD_PLAYBACK_LOCATION2 dvdLocation;
  436. hr = pqDInfo2->GetCurrentLocation(&dvdLocation);
  437. if(FAILED(hr)){
  438. return hr;
  439. }
  440. DVD_HMSF_TIMECODE dvdTCode;
  441. // Convert the length in seconds to dvd timecode
  442. dvdTCode = convertDVDSeconds(lPosition, dvdLocation.TimeCodeFlags, m_Mode);
  443. // set the dvd to play at time in the dvd
  444. // hr set in retry macro
  445. long pauseCookie = 0;
  446. HRESULT hres = RunIfPause(&pauseCookie);
  447. if(FAILED(hres)){
  448. return hres;
  449. }
  450. hr = m_pDVDControl2->PlayAtTime(&dvdTCode, dvdLocation.TimeCodeFlags, reinterpret_cast<IDvdCmd**>(&IDCmd));
  451. if(IDCmd){
  452. IDCmd->WaitForEnd();
  453. }
  454. hres = PauseIfRan(pauseCookie);
  455. if(FAILED(hres)){
  456. return hres;
  457. }
  458. return hr;
  459. }
  460. catch(HRESULT hrTmp){
  461. // Something went bad, threw a HRESULT
  462. hr = Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), hrTmp);
  463. }
  464. catch(...){
  465. // Something went bad, dont know what it threw
  466. hr = E_UNEXPECTED;
  467. }
  468. return hr;
  469. }
  470. //-----------------------------------------------------------------------------------------
  471. // Name: put_PositionMode(LONGLONG)
  472. //-----------------------------------------------------------------------------------------
  473. STDMETHOD(put_PositionMode)(/*[in]*/PositionModeList lPositionMode) {
  474. HRESULT hr = S_OK;
  475. try{
  476. if(lPositionMode == FrameMode){
  477. m_Mode = FrameMode;
  478. return S_OK;
  479. }
  480. else if(lPositionMode == TenthsSecondsMode){
  481. m_Mode = TenthsSecondsMode;
  482. return S_OK;
  483. }
  484. // If it is some other mode not supported by the vidctl
  485. else{
  486. return E_UNEXPECTED;
  487. }
  488. }
  489. catch(HRESULT hrTmp){
  490. // Something went bad, threw a HRESULT
  491. return hrTmp;
  492. }
  493. catch(...){
  494. // Something went bad, dont know what it threw
  495. return E_UNEXPECTED;
  496. }
  497. }
  498. //-----------------------------------------------------------------------------------------
  499. // Name: get_PositionMode(LONGLONG*)
  500. //-----------------------------------------------------------------------------------------
  501. STDMETHOD(get_PositionMode)(/*[out,retval]*/PositionModeList* lPositionMode) {
  502. HRESULT hr = S_OK;
  503. try{
  504. // Checking args and interfaces
  505. if(!lPositionMode){
  506. return E_POINTER;
  507. }
  508. *lPositionMode = m_Mode;
  509. return hr;
  510. }
  511. catch(HRESULT hrTmp){
  512. // Something went bad, threw a HRESULT
  513. return hrTmp;
  514. }
  515. catch(...){
  516. // Something went bad, dont know what it threw
  517. return E_UNEXPECTED;
  518. }
  519. }
  520. //-----------------------------------------------------------------------------------------
  521. STDMETHOD(put_Container)(IMSVidGraphSegmentContainer *pCtl)
  522. {
  523. if (!m_fInit) {
  524. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  525. }
  526. try {
  527. if (!pCtl) {
  528. return Unload();
  529. }
  530. if (m_pContainer) {
  531. if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
  532. return Error(IDS_OBJ_ALREADY_INIT, __uuidof(IMSVidWebDVD), CO_E_ALREADYINITIALIZED);
  533. } else {
  534. return NO_ERROR;
  535. }
  536. }
  537. HRESULT hr = NO_ERROR;
  538. DSFilter pfr(CLSID_DVDNavigator);
  539. if (!pfr) {
  540. ASSERT(false);
  541. return Error(IDS_CANT_CREATE_FILTER, __uuidof(IMSVidWebDVD), hr);
  542. }
  543. if (m_pContainer) {
  544. bool rc = m_pGraph.RemoveFilter(*m_Filters.begin());
  545. if (!rc) {
  546. TRACELM(TRACE_ERROR, "IMSVidWebDVD::Load() can't remove filter");
  547. return Error(IDS_CANT_REMOVE_FILTER, __uuidof(IMSVidWebDVD), E_UNEXPECTED);
  548. }
  549. }
  550. m_Filters.clear();
  551. m_Filters.push_back(pfr);
  552. m_iDVDNav = m_Filters.size() - 1;
  553. m_pDVDControl2 = pfr;
  554. // DON'T addref the container. we're guaranteed nested lifetimes
  555. // and an addref creates circular refcounts so we never unload.
  556. m_pContainer.p = pCtl;
  557. m_pGraph = m_pContainer.GetGraph();
  558. USES_CONVERSION;
  559. CString csName(_T("DVD Navigator"));
  560. hr = m_pGraph->AddFilter(m_Filters[m_iDVDNav], T2COLE(csName));
  561. if (FAILED(hr)) {
  562. TRACELSM(TRACE_ERROR, (dbgDump << "IMSVidWebDVD::Load() hr = " << std::hex << hr), "");
  563. return Error(IDS_CANT_ADD_FILTER, __uuidof(IMSVidWebDVD), hr);
  564. }
  565. } catch (ComException &e) {
  566. return e;
  567. } catch(...) {
  568. return E_UNEXPECTED;
  569. }
  570. return NOERROR;
  571. }
  572. // IMSVidGraphSegmentInputs
  573. STDMETHOD(Click)()
  574. {
  575. return E_NOTIMPL;
  576. }
  577. STDMETHOD(DblClick)()
  578. {
  579. return E_NOTIMPL;
  580. }
  581. STDMETHOD(KeyDown)(short* KeyCode, short Shift){
  582. return E_NOTIMPL;
  583. }
  584. STDMETHOD(KeyPress)(short* KeyAscii){
  585. return E_NOTIMPL;
  586. }
  587. STDMETHOD(KeyUp)(short* KeyCode, short Shift){
  588. HRESULT hr;
  589. switch (*KeyCode) {
  590. case VK_UP:
  591. hr = m_pDVDControl2->SelectRelativeButton(DVD_Relative_Upper);
  592. if (FAILED(hr)) {
  593. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::KeyUp() select up failed hr = " << hexdump(hr)), "");
  594. return hr;
  595. } else {
  596. return S_FALSE;
  597. }
  598. break;
  599. case VK_DOWN:
  600. hr = m_pDVDControl2->SelectRelativeButton(DVD_Relative_Lower);
  601. if (FAILED(hr)) {
  602. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::KeyUp() select down failed hr = " << hexdump(hr)), "");
  603. return hr;
  604. } else {
  605. return S_FALSE;
  606. }
  607. break;
  608. case VK_LEFT:
  609. hr = m_pDVDControl2->SelectRelativeButton(DVD_Relative_Left);
  610. if (FAILED(hr)) {
  611. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::KeyUp() select left failed hr = " << hexdump(hr)), "");
  612. return hr;
  613. } else {
  614. return S_FALSE;
  615. }
  616. break;
  617. case VK_RIGHT:
  618. hr = m_pDVDControl2->SelectRelativeButton(DVD_Relative_Right);
  619. if (FAILED(hr)) {
  620. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::KeyUp() select right failed hr = " << hexdump(hr)), "");
  621. return hr;
  622. } else {
  623. return S_FALSE;
  624. }
  625. break;
  626. case VK_SPACE:
  627. case VK_RETURN:
  628. hr = m_pDVDControl2->ActivateButton();
  629. if (FAILED(hr)) {
  630. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::KeyUp() activate failed hr = " << hexdump(hr)), "");
  631. return hr;
  632. } else {
  633. return S_FALSE;
  634. }
  635. break;
  636. }
  637. return E_NOTIMPL;
  638. }
  639. STDMETHOD(MouseDown)(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y){
  640. if ((m_DVDFilterState & dvdState_Running) && m_pDVDControl2) {
  641. if (((m_usButton ^ Button) & MSVIDCTL_LEFT_BUTTON)) {
  642. CPoint pt(x, y);
  643. HRESULT hr = m_pDVDControl2->SelectAtPosition(pt);
  644. if (FAILED(hr)) {
  645. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::MouseDown() select failed hr = " << hexdump(hr)), "");
  646. return hr;
  647. } else {
  648. return S_FALSE;
  649. }
  650. }
  651. m_usButton = Button;
  652. }
  653. return NOERROR;
  654. }
  655. STDMETHOD(MouseMove)(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y){
  656. if ((m_DVDFilterState & dvdState_Running) && m_pDVDControl2) {
  657. if (Button & MSVIDCTL_LEFT_BUTTON) {
  658. CPoint pt(x, y);
  659. HRESULT hr = m_pDVDControl2->SelectAtPosition(pt);
  660. if (FAILED(hr)) {
  661. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::MouseMove() select failed hr = " << hexdump(hr)), "");
  662. return hr;
  663. } else {
  664. return S_FALSE;
  665. }
  666. }
  667. m_usButton = Button;
  668. }
  669. return NOERROR;
  670. }
  671. STDMETHOD(MouseUp)(short Button, short Shift, OLE_XPOS_PIXELS x, OLE_YPOS_PIXELS y){
  672. if ((m_DVDFilterState & dvdState_Running) && m_pDVDControl2) {
  673. if (((m_usButton ^ Button) & MSVIDCTL_LEFT_BUTTON)) {
  674. CPoint pt(x, y);
  675. HRESULT hr = m_pDVDControl2->ActivateAtPosition(pt);
  676. if (FAILED(hr)) {
  677. TRACELSM(TRACE_DETAIL, (dbgDump << "CVidMSWebDVD::MouseUp() activate failed hr = " << hexdump(hr)), "");
  678. return hr;
  679. } else {
  680. return S_FALSE;
  681. }
  682. }
  683. }
  684. return NOERROR;
  685. }
  686. // IMSVidDevice
  687. STDMETHOD(get_Name)(BSTR * Name)
  688. {
  689. if (!m_fInit) {
  690. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidFilePlayback), CO_E_NOTINITIALIZED);
  691. }
  692. if (Name == NULL)
  693. return E_POINTER;
  694. try {
  695. *Name = m_Name.Copy();
  696. } catch(...) {
  697. return E_POINTER;
  698. }
  699. return NOERROR;
  700. }
  701. // IMSVidInputDevice
  702. STDMETHOD(IsViewable)(VARIANT* pv, VARIANT_BOOL *pfViewable)
  703. {
  704. HRESULT hr = View(pv);
  705. if (SUCCEEDED(hr))
  706. {
  707. *pfViewable = VARIANT_TRUE;
  708. }
  709. return hr;
  710. }
  711. STDMETHOD(View)(VARIANT* pv) {
  712. if (!m_fInit) {
  713. return Error(IDS_OBJ_NO_INIT, __uuidof(IMSVidWebDVD), CO_E_NOTINITIALIZED);
  714. }
  715. if (!pv) {
  716. return E_POINTER;
  717. }
  718. if (pv->vt != VT_BSTR) {
  719. return E_INVALIDARG;
  720. }
  721. if (m_pGraph && !m_pGraph.IsStopped()) {
  722. return Error(IDS_INVALID_STATE, __uuidof(IMSVidWebDVD), HRESULT_FROM_WIN32(ERROR_INVALID_STATE));
  723. }
  724. // retrieve the DVD playback info from URL
  725. // save the info
  726. DeleteUrlInfo();
  727. HRESULT hr = ParseDVDPath(pv->bstrVal);
  728. if (SUCCEEDED(hr))
  729. {
  730. m_fUrlInfoSet = true;
  731. }
  732. return hr;
  733. }
  734. STDMETHOD(OnEventNotify)(long lEvent, LONG_PTR lParam1, LONG_PTR lParam2);
  735. STDMETHOD(OnDVDEvent)(long lEvent, LONG_PTR lParam1, LONG_PTR lParam2);
  736. STDMETHOD(PreRun)();
  737. STDMETHOD(PostRun)();
  738. STDMETHOD(PreStop)();
  739. STDMETHOD(PostStop)();
  740. STDMETHOD(PlayTitle)(long lTitle);
  741. STDMETHOD(PlayChapterInTitle)(long lTitle, long lChapter);
  742. STDMETHOD(PlayChapter)(long lChapter);
  743. STDMETHOD(PlayChaptersAutoStop)(long lTitle, long lstrChapter, long lChapterCount);
  744. STDMETHOD(PlayAtTime)(BSTR strTime);
  745. STDMETHOD(PlayAtTimeInTitle)(long lTitle, BSTR strTime);
  746. STDMETHOD(PlayPeriodInTitleAutoStop)(long lTitle, BSTR strStartTime, BSTR strEndTime);
  747. STDMETHOD(ReplayChapter)();
  748. STDMETHOD(PlayPrevChapter)();
  749. STDMETHOD(PlayNextChapter)();
  750. STDMETHOD(StillOff)();
  751. STDMETHOD(get_AudioLanguage)(long lStream, VARIANT_BOOL fFormat, BSTR* strAudioLang);
  752. STDMETHOD(ShowMenu)(DVDMenuIDConstants MenuID);
  753. STDMETHOD(Resume)();
  754. STDMETHOD(ReturnFromSubmenu)();
  755. STDMETHOD(get_ButtonsAvailable)(/*[out, retval]*/ long *pVal);
  756. STDMETHOD(get_CurrentButton)(/*[out, retval]*/ long *pVal);
  757. STDMETHOD(SelectAndActivateButton)(long lButton);
  758. STDMETHOD(ActivateButton)();
  759. STDMETHOD(SelectRightButton)();
  760. STDMETHOD(SelectLeftButton)();
  761. STDMETHOD(SelectLowerButton)();
  762. STDMETHOD(SelectUpperButton)();
  763. STDMETHOD(ActivateAtPosition)(long xPos, long yPos);
  764. STDMETHOD(SelectAtPosition)(long xPos, long yPos);
  765. STDMETHOD(get_ButtonAtPosition)(long xPos, long yPos, /*[out, retval] */ long* plButton);
  766. STDMETHOD(get_NumberOfChapters)(long lTitle, /*[out, retval]*/ long *pVal);
  767. STDMETHOD(get_TotalTitleTime)(/*[out, retval]*/ BSTR *pVal);
  768. STDMETHOD(get_TitlesAvailable)(/*[out, retval]*/ long* pVal);
  769. STDMETHOD(get_VolumesAvailable)(/*[out, retval]*/ long *pVal);
  770. STDMETHOD(get_CurrentVolume)(/*[out, retval]*/ long *pVal);
  771. STDMETHOD(get_CurrentDiscSide)(/*[out, retval]*/ long *pVal);
  772. STDMETHOD(get_CurrentDomain)(/*[out, retval]*/ long *pVal);
  773. STDMETHOD(get_CurrentChapter)(/*[out, retval]*/ long *pVal);
  774. STDMETHOD(get_CurrentTitle)(/*[out, retval]*/ long *pVal);
  775. STDMETHOD(get_CurrentTime)(/*[out, retval]*/ BSTR *pVal);
  776. STDMETHOD(DVDTimeCode2bstr)(/*[in]*/ long timeCode, /*[out, retval]*/ BSTR *pTimeStr);
  777. STDMETHOD(get_DVDDirectory)(/*[out, retval]*/ BSTR *pVal);
  778. STDMETHOD(put_DVDDirectory)(/*[in]*/ BSTR newVal);
  779. STDMETHOD(IsSubpictureStreamEnabled)(/*[in]*/ long lstream, /*[out, retval]*/ VARIANT_BOOL *fEnabled);
  780. STDMETHOD(IsAudioStreamEnabled)(/*[in]*/ long lstream, /*[out, retval]*/ VARIANT_BOOL *fEnabled);
  781. STDMETHOD(get_CurrentSubpictureStream)(/*[out, retval]*/ long *pVal);
  782. STDMETHOD(put_CurrentSubpictureStream)(/*[in]*/ long newVal);
  783. STDMETHOD(get_SubpictureLanguage)(long lStream, /*[out, retval] */ BSTR* strLanguage);
  784. STDMETHOD(get_CurrentAudioStream)(/*[out, retval]*/ long *pVal);
  785. STDMETHOD(put_CurrentAudioStream)(/*[in]*/ long newVal);
  786. STDMETHOD(get_AudioStreamsAvailable)(/*[out, retval]*/ long *pVal);
  787. STDMETHOD(get_AnglesAvailable)(/*[out, retval]*/ long *pVal);
  788. STDMETHOD(get_CurrentAngle)(/*[out, retval]*/ long *pVal);
  789. STDMETHOD(put_CurrentAngle)(/*[in]*/ long newVal);
  790. STDMETHOD(get_SubpictureStreamsAvailable)(/*[out, retval]*/ long *pVal);
  791. STDMETHOD(get_SubpictureOn)(/*[out, retval]*/ VARIANT_BOOL *pVal);
  792. STDMETHOD(put_SubpictureOn)(/*[in]*/ VARIANT_BOOL newVal);
  793. STDMETHOD(get_DVDUniqueID)(/*[out, retval]*/ BSTR *pVal);
  794. STDMETHOD(AcceptParentalLevelChange)(VARIANT_BOOL fAccept, BSTR strUserName, BSTR strPassword);
  795. STDMETHOD(NotifyParentalLevelChange)(/*[in]*/ VARIANT_BOOL newVal);
  796. STDMETHOD(SelectParentalCountry)(long lCountry, BSTR strUserName, BSTR strPassword);
  797. STDMETHOD(SelectParentalLevel)(long lParentalLevel, BSTR strUserName, BSTR strPassword);
  798. STDMETHOD(get_TitleParentalLevels)(long lTitle, /*[out, retval] */ long* plParentalLevels);
  799. STDMETHOD(get_PlayerParentalCountry)(/*[out, retval] */ long* plCountryCode);
  800. STDMETHOD(get_PlayerParentalLevel)(/*[out, retval] */ long* plParentalLevel);
  801. STDMETHOD(Eject)();
  802. STDMETHOD(UOPValid)(long lUOP, VARIANT_BOOL* pfValid);
  803. STDMETHOD(get_SPRM)(long lIndex, /*[out, retval] */ short *psSPRM);
  804. STDMETHOD(get_GPRM)(long lIndex, /*[out, retval] */ short *psSPRM);
  805. STDMETHOD(put_GPRM)(long lIndex, short sValue);
  806. STDMETHOD(get_DVDTextStringType)(long lLangIndex, long lStringIndex, /*[out, retval] */ DVDTextStringType* pType);
  807. STDMETHOD(get_DVDTextString)(long lLangIndex, long lStringIndex, /*[out, retval] */ BSTR* pstrText);
  808. STDMETHOD(get_DVDTextNumberOfStrings)(long lLangIndex, /*[out, retval] */ long* plNumOfStrings);
  809. STDMETHOD(get_DVDTextNumberOfLanguages)(long* /*[out, retval] */ plNumOfLangs);
  810. STDMETHOD(get_DVDTextLanguageLCID)(/*[in]*/ long lLangIndex, /*[out, retval]*/ long* lcid);
  811. STDMETHOD(get_LanguageFromLCID)(/*[in]*/ long lcid, /*[out, retval]*/ BSTR* lang);
  812. STDMETHOD(RegionChange)();
  813. STDMETHOD(get_DVDAdm)(/*[out, retval]*/ IDispatch* *pVal);
  814. STDMETHOD(DeleteBookmark)();
  815. STDMETHOD(RestoreBookmark)();
  816. STDMETHOD(SaveBookmark)();
  817. STDMETHOD(SelectDefaultAudioLanguage)(long lang, long ext);
  818. STDMETHOD(SelectDefaultSubpictureLanguage)(long lang, DVDSPExt ext);
  819. STDMETHOD(get_PreferredSubpictureStream)(/*[out, retval]*/ long *pVal);
  820. STDMETHOD(get_DefaultMenuLanguage)(long* lang);
  821. STDMETHOD(put_DefaultMenuLanguage)(long lang);
  822. STDMETHOD(get_DefaultSubpictureLanguage)(long* lang);
  823. STDMETHOD(get_DefaultAudioLanguage)(long *lang);
  824. STDMETHOD(get_DefaultSubpictureLanguageExt)(DVDSPExt* ext);
  825. STDMETHOD(get_DefaultAudioLanguageExt)(long *ext);
  826. STDMETHOD(get_KaraokeAudioPresentationMode)(/*[out, retval]*/ long *pVal);
  827. STDMETHOD(put_KaraokeAudioPresentationMode)(/*[in]*/ long newVal);
  828. STDMETHOD(get_KaraokeChannelContent)(long lStream, long lChan, /*[out, retval] */ long* lContent);
  829. STDMETHOD(get_KaraokeChannelAssignment)(long lStream, /*[out, retval] */ long *lChannelAssignment);
  830. STDMETHOD(RestorePreferredSettings)();
  831. STDMETHOD(get_ButtonRect)(long lButton, /*[out, retval] */ IMSVidRect** pRect);
  832. STDMETHOD(get_DVDScreenInMouseCoordinates)(/*[out, retval] */ IMSVidRect** ppRect);
  833. STDMETHOD(put_DVDScreenInMouseCoordinates)(IMSVidRect* pRect);
  834. //STDMETHOD(CanStep)(VARIANT_BOOL fBackwards, VARIANT_BOOL *pfCan);
  835. //STDMETHOD(Step)(long lStep);
  836. private:
  837. // Private helper functions
  838. inline HRESULT RunIfPause(long *dwCookie){
  839. if(!dwCookie){
  840. return E_POINTER;
  841. }
  842. *dwCookie = 0;
  843. MSVidCtlStateList _curState = STATE_UNBUILT;
  844. CComQIPtr<IMSVidCtl>_pq_VidCtl(m_pContainer);
  845. if(!_pq_VidCtl){
  846. return E_UNEXPECTED;
  847. }
  848. HRESULT _hr = _pq_VidCtl->get_State(&_curState);
  849. if(_curState == STATE_PAUSE){
  850. *dwCookie = 1;
  851. CComQIPtr<IMSVidAudioRenderer> _pq_AR;
  852. _hr = _pq_VidCtl->get_AudioRendererActive(&_pq_AR);
  853. if(FAILED(_hr)){
  854. return _hr;
  855. }
  856. _hr = _pq_AR->get_Volume(dwCookie);
  857. if(FAILED(_hr)){
  858. return _hr;
  859. }
  860. _hr = _pq_AR->put_Volume(-10000); // -10000 is volume off
  861. if(FAILED(_hr)){
  862. return _hr;
  863. }
  864. if(*dwCookie == 0){
  865. *dwCookie = 2;
  866. }
  867. _hr = _pq_VidCtl->Run();
  868. if(FAILED(_hr)){
  869. return _hr;
  870. }
  871. }
  872. return S_OK;
  873. }
  874. // Input is 0 not in pause state, < 0 volume settting, 1 muted audio, 2 full audio volume
  875. inline HRESULT PauseIfRan(long dwCookie){
  876. if(!dwCookie){
  877. return S_FALSE;
  878. }
  879. MSVidCtlStateList _curState = STATE_UNBUILT;
  880. CComQIPtr<IMSVidCtl>_pq_VidCtl(m_pContainer);
  881. if(!_pq_VidCtl){
  882. return E_UNEXPECTED;
  883. }
  884. HRESULT _hr = _pq_VidCtl->get_State(&_curState);
  885. if(_curState != STATE_PAUSE){
  886. _hr = _pq_VidCtl->Pause();
  887. if(FAILED(_hr)){
  888. return _hr;
  889. }
  890. }
  891. if(dwCookie == 1){
  892. return S_OK;
  893. }
  894. if(dwCookie == 2){
  895. dwCookie = 0;
  896. }
  897. CComQIPtr<IMSVidAudioRenderer> _pq_AR;
  898. _hr = _pq_VidCtl->get_AudioRendererActive(&_pq_AR);
  899. if(FAILED(_hr)){
  900. return _hr;
  901. }
  902. _hr = _pq_AR->put_Volume(dwCookie);
  903. if(FAILED(_hr)){
  904. return _hr;
  905. }
  906. return S_OK;
  907. }
  908. HRESULT PassFP_DOM();
  909. HRESULT HandleError(HRESULT hr);
  910. HRESULT CleanUp();
  911. HRESULT RestoreGraphState();
  912. HRESULT Bstr2DVDTime(DVD_HMSF_TIMECODE *ptrTimeCode, const BSTR *pbstrTime);
  913. HRESULT DVDTime2bstr(const DVD_HMSF_TIMECODE *pTimeCode, BSTR *pbstrTime);
  914. HRESULT TransformToWndwls(POINT& pt);
  915. HRESULT SelectParentalLevel(long lParentalLevel);
  916. HRESULT SelectParentalCountry(long lParentalCountry);
  917. HRESULT AppendString(TCHAR* strDest, INT strID, LONG dwLen);
  918. HRESULT GetDVDDriveLetter(TCHAR* lpDrive);
  919. HRESULT ParseDVDPath(BSTR pPath);
  920. HRESULT SetPlaybackFromUrlInfo();
  921. HRESULT SetDirectoryFromUrlInfo();
  922. void DeleteUrlInfo();
  923. int ParseNumber(LPWSTR& p, int nMaxDigits=0);
  924. // Private data members
  925. bool m_fResetSpeed;
  926. bool m_fStillOn;
  927. bool m_fFireNoSubpictureStream;
  928. bool m_fStepComplete;
  929. bool m_bEjected;
  930. DVDFilterState m_DVDFilterState;
  931. CComPtr<IMSVidWebDVDAdm> m_pDvdAdmin;
  932. MSLangID m_LangID;
  933. long m_lKaraokeAudioPresentationMode;
  934. PQDVDControl2 m_pDVDControl2;
  935. short m_usButton;
  936. DVDUrlInfo m_urlInfo;
  937. bool m_fUrlInfoSet;
  938. long m_Rate;
  939. PositionModeList m_Mode;
  940. };
  941. #endif // !defined(AFX_MSVIDWEBDVD_H__6CF9F624_1F3C_44FA_8F00_FCC31B2976D6__INCLUDED_)