00001
00002
00003
00004
00005
00006 #include <streams.h>
00007 #include <limits.h>
00008 #include "seekpt.h"
00009
00010 #pragma warning(disable:4237)
00011
00012 CBaseDispatch::~CBaseDispatch()
00013 {
00014 if (m_pti) {
00015 m_pti->Release();
00016 }
00017 }
00018
00019 STDMETHODIMP
00020 CBaseDispatch::GetTypeInfoCount(UINT * pctinfo)
00021 {
00022 CheckPointer(pctinfo,E_POINTER);
00023 ValidateReadWritePtr(pctinfo,sizeof(UINT *));
00024 *pctinfo = 1;
00025 return S_OK;
00026 }
00027
00028 typedef HRESULT (STDAPICALLTYPE *LPLOADTYPELIB)(
00029 const OLECHAR FAR *szFile,
00030 ITypeLib FAR* FAR* pptlib);
00031
00032 typedef HRESULT (STDAPICALLTYPE *LPLOADREGTYPELIB)(REFGUID rguid,
00033 WORD wVerMajor,
00034 WORD wVerMinor,
00035 LCID lcid,
00036 ITypeLib FAR* FAR* pptlib);
00037
00038 STDMETHODIMP
00039 CBaseDispatch::GetTypeInfo(
00040 REFIID riid,
00041 UINT itinfo,
00042 LCID lcid,
00043 ITypeInfo ** pptinfo)
00044 {
00045 CheckPointer(pptinfo,E_POINTER);
00046 ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *));
00047 HRESULT hr;
00048
00049 *pptinfo = NULL;
00050
00051 if (0 != itinfo) {
00052 return TYPE_E_ELEMENTNOTFOUND;
00053 }
00054
00055 if (NULL == pptinfo) {
00056 return E_POINTER;
00057 }
00058
00059 if (NULL == m_pti) {
00060
00061 LPLOADTYPELIB lpfnLoadTypeLib;
00062 LPLOADREGTYPELIB lpfnLoadRegTypeLib;
00063 ITypeLib *ptlib;
00064 HINSTANCE hInst;
00065
00066 static const char szTypeLib[] = "LoadTypeLib";
00067 static const char szRegTypeLib[] = "LoadRegTypeLib";
00068 static const WCHAR szControl[] = L"control.tlb";
00069
00070 hInst = LoadOLEAut32();
00071 if (hInst == NULL) {
00072 DWORD dwError = GetLastError();
00073 return AmHresultFromWin32(dwError);
00074 }
00075 lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst,
00076 szRegTypeLib);
00077 if (lpfnLoadRegTypeLib == NULL) {
00078 DWORD dwError = GetLastError();
00079 return AmHresultFromWin32(dwError);
00080 }
00081
00082 hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0,
00083 lcid, &ptlib);
00084
00085 if (FAILED(hr)) {
00086
00087 lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib);
00088 if (lpfnLoadTypeLib == NULL) {
00089 DWORD dwError = GetLastError();
00090 return AmHresultFromWin32(dwError);
00091 }
00092
00093 hr = (*lpfnLoadTypeLib)(szControl, &ptlib);
00094 if (FAILED(hr)) {
00095 return hr;
00096 }
00097 }
00098
00099 hr = ptlib->GetTypeInfoOfGuid(
00100 riid,
00101 &m_pti);
00102
00103 ptlib->Release();
00104
00105 if (FAILED(hr)) {
00106 return hr;
00107 }
00108 }
00109
00110 *pptinfo = m_pti;
00111 m_pti->AddRef();
00112 return S_OK;
00113 }
00114
00115 STDMETHODIMP
00116 CBaseDispatch::GetIDsOfNames(
00117 REFIID riid,
00118 OLECHAR ** rgszNames,
00119 UINT cNames,
00120 LCID lcid,
00121 DISPID * rgdispid)
00122 {
00123
00124 ITypeInfo * pti;
00125 HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti);
00126
00127 if (SUCCEEDED(hr)) {
00128 hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid);
00129
00130 pti->Release();
00131 }
00132 return hr;
00133 }
00134
00135 CMediaControl::CMediaControl(const TCHAR * name,LPUNKNOWN pUnk) :
00136 CUnknown(name, pUnk)
00137 {
00138 }
00139
00140 STDMETHODIMP
00141 CMediaControl::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00142 {
00143 ValidateReadWritePtr(ppv,sizeof(PVOID));
00144 if (riid == IID_IMediaControl) {
00145 return GetInterface( (IMediaControl *) this, ppv);
00146 } else {
00147 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
00148 }
00149 }
00150
00151 STDMETHODIMP
00152 CMediaControl::GetTypeInfoCount(UINT * pctinfo)
00153 {
00154 return m_basedisp.GetTypeInfoCount(pctinfo);
00155 }
00156
00157 STDMETHODIMP
00158 CMediaControl::GetTypeInfo(
00159 UINT itinfo,
00160 LCID lcid,
00161 ITypeInfo ** pptinfo)
00162 {
00163 return m_basedisp.GetTypeInfo(
00164 IID_IMediaControl,
00165 itinfo,
00166 lcid,
00167 pptinfo);
00168 }
00169
00170 STDMETHODIMP
00171 CMediaControl::GetIDsOfNames(
00172 REFIID riid,
00173 OLECHAR ** rgszNames,
00174 UINT cNames,
00175 LCID lcid,
00176 DISPID * rgdispid)
00177 {
00178 return m_basedisp.GetIDsOfNames(
00179 IID_IMediaControl,
00180 rgszNames,
00181 cNames,
00182 lcid,
00183 rgdispid);
00184 }
00185
00186 STDMETHODIMP
00187 CMediaControl::Invoke(
00188 DISPID dispidMember,
00189 REFIID riid,
00190 LCID lcid,
00191 WORD wFlags,
00192 DISPPARAMS * pdispparams,
00193 VARIANT * pvarResult,
00194 EXCEPINFO * pexcepinfo,
00195 UINT * puArgErr)
00196 {
00197
00198 if (IID_NULL != riid) {
00199 return DISP_E_UNKNOWNINTERFACE;
00200 }
00201
00202 ITypeInfo * pti;
00203 HRESULT hr = GetTypeInfo(0, lcid, &pti);
00204
00205 if (FAILED(hr)) {
00206 return hr;
00207 }
00208
00209 hr = pti->Invoke(
00210 (IMediaControl *)this,
00211 dispidMember,
00212 wFlags,
00213 pdispparams,
00214 pvarResult,
00215 pexcepinfo,
00216 puArgErr);
00217
00218 pti->Release();
00219 return hr;
00220 }
00221
00222 CMediaEvent::CMediaEvent(const TCHAR * name,LPUNKNOWN pUnk) :
00223 CUnknown(name, pUnk)
00224 {
00225 }
00226
00227 STDMETHODIMP
00228 CMediaEvent::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00229 {
00230 ValidateReadWritePtr(ppv,sizeof(PVOID));
00231 if (riid == IID_IMediaEvent || riid == IID_IMediaEventEx) {
00232 return GetInterface( (IMediaEventEx *) this, ppv);
00233 } else {
00234 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
00235 }
00236 }
00237
00238 STDMETHODIMP
00239 CMediaEvent::GetTypeInfoCount(UINT * pctinfo)
00240 {
00241 return m_basedisp.GetTypeInfoCount(pctinfo);
00242 }
00243
00244 STDMETHODIMP
00245 CMediaEvent::GetTypeInfo(
00246 UINT itinfo,
00247 LCID lcid,
00248 ITypeInfo ** pptinfo)
00249 {
00250 return m_basedisp.GetTypeInfo(
00251 IID_IMediaEvent,
00252 itinfo,
00253 lcid,
00254 pptinfo);
00255 }
00256
00257 STDMETHODIMP
00258 CMediaEvent::GetIDsOfNames(
00259 REFIID riid,
00260 OLECHAR ** rgszNames,
00261 UINT cNames,
00262 LCID lcid,
00263 DISPID * rgdispid)
00264 {
00265 return m_basedisp.GetIDsOfNames(
00266 IID_IMediaEvent,
00267 rgszNames,
00268 cNames,
00269 lcid,
00270 rgdispid);
00271 }
00272
00273 STDMETHODIMP
00274 CMediaEvent::Invoke(
00275 DISPID dispidMember,
00276 REFIID riid,
00277 LCID lcid,
00278 WORD wFlags,
00279 DISPPARAMS * pdispparams,
00280 VARIANT * pvarResult,
00281 EXCEPINFO * pexcepinfo,
00282 UINT * puArgErr)
00283 {
00284
00285 if (IID_NULL != riid) {
00286 return DISP_E_UNKNOWNINTERFACE;
00287 }
00288
00289 ITypeInfo * pti;
00290 HRESULT hr = GetTypeInfo(0, lcid, &pti);
00291
00292 if (FAILED(hr)) {
00293 return hr;
00294 }
00295
00296 hr = pti->Invoke(
00297 (IMediaEvent *)this,
00298 dispidMember,
00299 wFlags,
00300 pdispparams,
00301 pvarResult,
00302 pexcepinfo,
00303 puArgErr);
00304
00305 pti->Release();
00306 return hr;
00307 }
00308
00309 CMediaPosition::CMediaPosition(const TCHAR * name,LPUNKNOWN pUnk) :
00310 CUnknown(name, pUnk)
00311 {
00312 }
00313
00314 CMediaPosition::CMediaPosition(const TCHAR * name,
00315 LPUNKNOWN pUnk,
00316 HRESULT * phr) :
00317 CUnknown(name, pUnk)
00318 {
00319 UNREFERENCED_PARAMETER(phr);
00320 }
00321
00322 STDMETHODIMP
00323 CMediaPosition::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00324 {
00325 ValidateReadWritePtr(ppv,sizeof(PVOID));
00326 if (riid == IID_IMediaPosition) {
00327 return GetInterface( (IMediaPosition *) this, ppv);
00328 } else {
00329 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
00330 }
00331 }
00332
00333 STDMETHODIMP
00334 CMediaPosition::GetTypeInfoCount(UINT * pctinfo)
00335 {
00336 return m_basedisp.GetTypeInfoCount(pctinfo);
00337 }
00338
00339 STDMETHODIMP
00340 CMediaPosition::GetTypeInfo(
00341 UINT itinfo,
00342 LCID lcid,
00343 ITypeInfo ** pptinfo)
00344 {
00345 return m_basedisp.GetTypeInfo(
00346 IID_IMediaPosition,
00347 itinfo,
00348 lcid,
00349 pptinfo);
00350 }
00351
00352 STDMETHODIMP
00353 CMediaPosition::GetIDsOfNames(
00354 REFIID riid,
00355 OLECHAR ** rgszNames,
00356 UINT cNames,
00357 LCID lcid,
00358 DISPID * rgdispid)
00359 {
00360 return m_basedisp.GetIDsOfNames(
00361 IID_IMediaPosition,
00362 rgszNames,
00363 cNames,
00364 lcid,
00365 rgdispid);
00366 }
00367
00368 STDMETHODIMP
00369 CMediaPosition::Invoke(
00370 DISPID dispidMember,
00371 REFIID riid,
00372 LCID lcid,
00373 WORD wFlags,
00374 DISPPARAMS * pdispparams,
00375 VARIANT * pvarResult,
00376 EXCEPINFO * pexcepinfo,
00377 UINT * puArgErr)
00378 {
00379
00380 if (IID_NULL != riid) {
00381 return DISP_E_UNKNOWNINTERFACE;
00382 }
00383
00384 ITypeInfo * pti;
00385 HRESULT hr = GetTypeInfo(0, lcid, &pti);
00386
00387 if (FAILED(hr)) {
00388 return hr;
00389 }
00390
00391 hr = pti->Invoke(
00392 (IMediaPosition *)this,
00393 dispidMember,
00394 wFlags,
00395 pdispparams,
00396 pvarResult,
00397 pexcepinfo,
00398 puArgErr);
00399
00400 pti->Release();
00401 return hr;
00402 }
00403
00404 CPosPassThru::CPosPassThru(const TCHAR *pName,
00405 LPUNKNOWN pUnk,
00406 HRESULT *phr,
00407 IPin *pPin) :
00408 CMediaPosition(pName,pUnk),
00409 m_pPin(pPin)
00410 {
00411 if (pPin == NULL) {
00412 *phr = E_POINTER;
00413 return;
00414 }
00415 }
00416
00417 STDMETHODIMP
00418 CPosPassThru::NonDelegatingQueryInterface(REFIID riid,void **ppv)
00419 {
00420 CheckPointer(ppv,E_POINTER);
00421 *ppv = NULL;
00422
00423 if (riid == IID_IMediaSeeking) {
00424 return GetInterface( static_cast<IMediaSeeking *>(this), ppv);
00425 }
00426 return CMediaPosition::NonDelegatingQueryInterface(riid,ppv);
00427 }
00428
00429 HRESULT
00430 CPosPassThru::GetPeer(IMediaPosition ** ppMP)
00431 {
00432 *ppMP = NULL;
00433
00434 IPin *pConnected;
00435 HRESULT hr = m_pPin->ConnectedTo(&pConnected);
00436 if (FAILED(hr)) {
00437 return E_NOTIMPL;
00438 }
00439 IMediaPosition * pMP;
00440 hr = pConnected->QueryInterface(IID_IMediaPosition, (void **) &pMP);
00441 pConnected->Release();
00442 if (FAILED(hr)) {
00443 return E_NOTIMPL;
00444 }
00445
00446 *ppMP = pMP;
00447 return S_OK;
00448 }
00449
00450 HRESULT
00451 CPosPassThru::GetPeerSeeking(IMediaSeeking ** ppMS)
00452 {
00453 *ppMS = NULL;
00454
00455 IPin *pConnected;
00456 HRESULT hr = m_pPin->ConnectedTo(&pConnected);
00457 if (FAILED(hr)) {
00458 return E_NOTIMPL;
00459 }
00460 IMediaSeeking * pMS;
00461 hr = pConnected->QueryInterface(IID_IMediaSeeking, (void **) &pMS);
00462 pConnected->Release();
00463 if (FAILED(hr)) {
00464 return E_NOTIMPL;
00465 }
00466
00467 *ppMS = pMS;
00468 return S_OK;
00469 }
00470
00471 STDMETHODIMP
00472 CPosPassThru::GetCapabilities(DWORD * pCaps)
00473 {
00474 IMediaSeeking* pMS;
00475 HRESULT hr = GetPeerSeeking(&pMS);
00476 if (FAILED(hr)) {
00477 return hr;
00478 }
00479
00480 hr = pMS->GetCapabilities(pCaps);
00481 pMS->Release();
00482 return hr;
00483 }
00484
00485 STDMETHODIMP
00486 CPosPassThru::CheckCapabilities(DWORD * pCaps)
00487 {
00488 IMediaSeeking* pMS;
00489 HRESULT hr = GetPeerSeeking(&pMS);
00490 if (FAILED(hr)) {
00491 return hr;
00492 }
00493
00494 hr = pMS->CheckCapabilities(pCaps);
00495 pMS->Release();
00496 return hr;
00497 }
00498
00499 STDMETHODIMP
00500 CPosPassThru::IsFormatSupported(const GUID * pFormat)
00501 {
00502 IMediaSeeking* pMS;
00503 HRESULT hr = GetPeerSeeking(&pMS);
00504 if (FAILED(hr)) {
00505 return hr;
00506 }
00507
00508 hr = pMS->IsFormatSupported(pFormat);
00509 pMS->Release();
00510 return hr;
00511 }
00512
00513 STDMETHODIMP
00514 CPosPassThru::QueryPreferredFormat(GUID *pFormat)
00515 {
00516 IMediaSeeking* pMS;
00517 HRESULT hr = GetPeerSeeking(&pMS);
00518 if (FAILED(hr)) {
00519 return hr;
00520 }
00521
00522 hr = pMS->QueryPreferredFormat(pFormat);
00523 pMS->Release();
00524 return hr;
00525 }
00526
00527 STDMETHODIMP
00528 CPosPassThru::SetTimeFormat(const GUID * pFormat)
00529 {
00530 IMediaSeeking* pMS;
00531 HRESULT hr = GetPeerSeeking(&pMS);
00532 if (FAILED(hr)) {
00533 return hr;
00534 }
00535
00536 hr = pMS->SetTimeFormat(pFormat);
00537 pMS->Release();
00538 return hr;
00539 }
00540
00541 STDMETHODIMP
00542 CPosPassThru::GetTimeFormat(GUID *pFormat)
00543 {
00544 IMediaSeeking* pMS;
00545 HRESULT hr = GetPeerSeeking(&pMS);
00546 if (FAILED(hr)) {
00547 return hr;
00548 }
00549
00550 hr = pMS->GetTimeFormat(pFormat);
00551 pMS->Release();
00552 return hr;
00553 }
00554
00555 STDMETHODIMP
00556 CPosPassThru::IsUsingTimeFormat(const GUID * pFormat)
00557 {
00558 IMediaSeeking* pMS;
00559 HRESULT hr = GetPeerSeeking(&pMS);
00560 if (FAILED(hr)) {
00561 return hr;
00562 }
00563
00564 hr = pMS->IsUsingTimeFormat(pFormat);
00565 pMS->Release();
00566 return hr;
00567 }
00568
00569 STDMETHODIMP
00570 CPosPassThru::ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat,
00571 LONGLONG Source, const GUID * pSourceFormat )
00572 {
00573 IMediaSeeking* pMS;
00574 HRESULT hr = GetPeerSeeking(&pMS);
00575 if (FAILED(hr)) {
00576 return hr;
00577 }
00578
00579 hr = pMS->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat );
00580 pMS->Release();
00581 return hr;
00582 }
00583
00584 STDMETHODIMP
00585 CPosPassThru::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
00586 , LONGLONG * pStop, DWORD StopFlags )
00587 {
00588 IMediaSeeking* pMS;
00589 HRESULT hr = GetPeerSeeking(&pMS);
00590 if (FAILED(hr)) {
00591 return hr;
00592 }
00593
00594 hr = pMS->SetPositions(pCurrent, CurrentFlags, pStop, StopFlags );
00595 pMS->Release();
00596 return hr;
00597 }
00598
00599 STDMETHODIMP
00600 CPosPassThru::GetPositions(LONGLONG *pCurrent, LONGLONG * pStop)
00601 {
00602 IMediaSeeking* pMS;
00603 HRESULT hr = GetPeerSeeking(&pMS);
00604 if (FAILED(hr)) {
00605 return hr;
00606 }
00607
00608 hr = pMS->GetPositions(pCurrent,pStop);
00609 pMS->Release();
00610 return hr;
00611 }
00612
00613 HRESULT
00614 CPosPassThru::GetSeekingLongLong
00615 ( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * )
00616 , LONGLONG * pll
00617 )
00618 {
00619 IMediaSeeking* pMS;
00620 HRESULT hr = GetPeerSeeking(&pMS);
00621 if (SUCCEEDED(hr))
00622 {
00623 hr = (pMS->*pMethod)(pll);
00624 pMS->Release();
00625 }
00626 return hr;
00627 }
00628
00629 STDMETHODIMP
00630 CPosPassThru::GetCurrentPosition(LONGLONG *pCurrent)
00631 {
00632
00633 HRESULT hr = GetMediaTime(pCurrent,NULL);
00634 if (SUCCEEDED(hr)) hr = NOERROR;
00635 else hr = GetSeekingLongLong( &IMediaSeeking::GetCurrentPosition, pCurrent );
00636 return hr;
00637 }
00638
00639 STDMETHODIMP
00640 CPosPassThru::GetStopPosition(LONGLONG *pStop)
00641 {
00642 return GetSeekingLongLong( &IMediaSeeking::GetStopPosition, pStop );;
00643 }
00644
00645 STDMETHODIMP
00646 CPosPassThru::GetDuration(LONGLONG *pDuration)
00647 {
00648 return GetSeekingLongLong( &IMediaSeeking::GetDuration, pDuration );;
00649 }
00650
00651 STDMETHODIMP
00652 CPosPassThru::GetPreroll(LONGLONG *pllPreroll)
00653 {
00654 return GetSeekingLongLong( &IMediaSeeking::GetPreroll, pllPreroll );;
00655 }
00656
00657 STDMETHODIMP
00658 CPosPassThru::GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest )
00659 {
00660 IMediaSeeking* pMS;
00661 HRESULT hr = GetPeerSeeking(&pMS);
00662 if (FAILED(hr)) {
00663 return hr;
00664 }
00665
00666 hr = pMS->GetAvailable( pEarliest, pLatest );
00667 pMS->Release();
00668 return hr;
00669 }
00670
00671 STDMETHODIMP
00672 CPosPassThru::GetRate(double * pdRate)
00673 {
00674 IMediaSeeking* pMS;
00675 HRESULT hr = GetPeerSeeking(&pMS);
00676 if (FAILED(hr)) {
00677 return hr;
00678 }
00679 hr = pMS->GetRate(pdRate);
00680 pMS->Release();
00681 return hr;
00682 }
00683
00684 STDMETHODIMP
00685 CPosPassThru::SetRate(double dRate)
00686 {
00687 if (0.0 == dRate) {
00688 return E_INVALIDARG;
00689 }
00690
00691 IMediaSeeking* pMS;
00692 HRESULT hr = GetPeerSeeking(&pMS);
00693 if (FAILED(hr)) {
00694 return hr;
00695 }
00696 hr = pMS->SetRate(dRate);
00697 pMS->Release();
00698 return hr;
00699 }
00700
00701 STDMETHODIMP
00702 CPosPassThru::get_Duration(REFTIME * plength)
00703 {
00704 IMediaPosition* pMP;
00705 HRESULT hr = GetPeer(&pMP);
00706 if (FAILED(hr)) {
00707 return hr;
00708 }
00709
00710 hr = pMP->get_Duration(plength);
00711 pMP->Release();
00712 return hr;
00713 }
00714
00715 STDMETHODIMP
00716 CPosPassThru::get_CurrentPosition(REFTIME * pllTime)
00717 {
00718 IMediaPosition* pMP;
00719 HRESULT hr = GetPeer(&pMP);
00720 if (FAILED(hr)) {
00721 return hr;
00722 }
00723 hr = pMP->get_CurrentPosition(pllTime);
00724 pMP->Release();
00725 return hr;
00726 }
00727
00728 STDMETHODIMP
00729 CPosPassThru::put_CurrentPosition(REFTIME llTime)
00730 {
00731 IMediaPosition* pMP;
00732 HRESULT hr = GetPeer(&pMP);
00733 if (FAILED(hr)) {
00734 return hr;
00735 }
00736 hr = pMP->put_CurrentPosition(llTime);
00737 pMP->Release();
00738 return hr;
00739 }
00740
00741 STDMETHODIMP
00742 CPosPassThru::get_StopTime(REFTIME * pllTime)
00743 {
00744 IMediaPosition* pMP;
00745 HRESULT hr = GetPeer(&pMP);
00746 if (FAILED(hr)) {
00747 return hr;
00748 }
00749 hr = pMP->get_StopTime(pllTime);
00750 pMP->Release();
00751 return hr;
00752 }
00753
00754 STDMETHODIMP
00755 CPosPassThru::put_StopTime(REFTIME llTime)
00756 {
00757 IMediaPosition* pMP;
00758 HRESULT hr = GetPeer(&pMP);
00759 if (FAILED(hr)) {
00760 return hr;
00761 }
00762 hr = pMP->put_StopTime(llTime);
00763 pMP->Release();
00764 return hr;
00765 }
00766
00767 STDMETHODIMP
00768 CPosPassThru::get_PrerollTime(REFTIME * pllTime)
00769 {
00770 IMediaPosition* pMP;
00771 HRESULT hr = GetPeer(&pMP);
00772 if (FAILED(hr)) {
00773 return hr;
00774 }
00775 hr = pMP->get_PrerollTime(pllTime);
00776 pMP->Release();
00777 return hr;
00778 }
00779
00780 STDMETHODIMP
00781 CPosPassThru::put_PrerollTime(REFTIME llTime)
00782 {
00783 IMediaPosition* pMP;
00784 HRESULT hr = GetPeer(&pMP);
00785 if (FAILED(hr)) {
00786 return hr;
00787 }
00788 hr = pMP->put_PrerollTime(llTime);
00789 pMP->Release();
00790 return hr;
00791 }
00792
00793 STDMETHODIMP
00794 CPosPassThru::get_Rate(double * pdRate)
00795 {
00796 IMediaPosition* pMP;
00797 HRESULT hr = GetPeer(&pMP);
00798 if (FAILED(hr)) {
00799 return hr;
00800 }
00801 hr = pMP->get_Rate(pdRate);
00802 pMP->Release();
00803 return hr;
00804 }
00805
00806 STDMETHODIMP
00807 CPosPassThru::put_Rate(double dRate)
00808 {
00809 if (0.0 == dRate) {
00810 return E_INVALIDARG;
00811 }
00812
00813 IMediaPosition* pMP;
00814 HRESULT hr = GetPeer(&pMP);
00815 if (FAILED(hr)) {
00816 return hr;
00817 }
00818 hr = pMP->put_Rate(dRate);
00819 pMP->Release();
00820 return hr;
00821 }
00822
00823 STDMETHODIMP
00824 CPosPassThru::CanSeekForward(LONG *pCanSeekForward)
00825 {
00826 IMediaPosition* pMP;
00827 HRESULT hr = GetPeer(&pMP);
00828 if (FAILED(hr)) {
00829 return hr;
00830 }
00831 hr = pMP->CanSeekForward(pCanSeekForward);
00832 pMP->Release();
00833 return hr;
00834 }
00835
00836 STDMETHODIMP
00837 CPosPassThru::CanSeekBackward(LONG *pCanSeekBackward)
00838 {
00839 IMediaPosition* pMP;
00840 HRESULT hr = GetPeer(&pMP);
00841 if (FAILED(hr)) {
00842 return hr;
00843 }
00844 hr = pMP->CanSeekBackward(pCanSeekBackward);
00845 pMP->Release();
00846 return hr;
00847 }
00848
00849 CRendererPosPassThru::CRendererPosPassThru(const TCHAR *pName,
00850 LPUNKNOWN pUnk,
00851 HRESULT *phr,
00852 IPin *pPin) :
00853 CPosPassThru(pName,pUnk,phr,pPin),
00854 m_StartMedia(0),
00855 m_EndMedia(0),
00856 m_bReset(TRUE)
00857 {
00858 }
00859
00860 HRESULT
00861 CRendererPosPassThru::RegisterMediaTime(IMediaSample *pMediaSample)
00862 {
00863 ASSERT(pMediaSample);
00864 LONGLONG StartMedia;
00865 LONGLONG EndMedia;
00866
00867 CAutoLock cAutoLock(&m_PositionLock);
00868
00869
00870
00871 HRESULT hr = pMediaSample->GetTime(&StartMedia,&EndMedia);
00872 if (FAILED(hr))
00873 {
00874 ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET);
00875 return hr;
00876 }
00877
00878 m_StartMedia = StartMedia;
00879 m_EndMedia = EndMedia;
00880 m_bReset = FALSE;
00881 return NOERROR;
00882 }
00883
00884 HRESULT
00885 CRendererPosPassThru::RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime)
00886 {
00887 CAutoLock cAutoLock(&m_PositionLock);
00888 m_StartMedia = StartTime;
00889 m_EndMedia = EndTime;
00890 m_bReset = FALSE;
00891 return NOERROR;
00892 }
00893
00894 HRESULT
00895 CRendererPosPassThru::GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime)
00896 {
00897 ASSERT(pStartTime);
00898
00899 CAutoLock cAutoLock(&m_PositionLock);
00900 if (m_bReset == TRUE) {
00901 return E_FAIL;
00902 }
00903
00904
00905
00906 HRESULT hr = ConvertTimeFormat( pStartTime, 0, m_StartMedia, &TIME_FORMAT_MEDIA_TIME );
00907 if (pEndTime && SUCCEEDED(hr)) {
00908 hr = ConvertTimeFormat( pEndTime, 0, m_EndMedia, &TIME_FORMAT_MEDIA_TIME );
00909 }
00910 return hr;
00911 }
00912
00913 HRESULT
00914 CRendererPosPassThru::ResetMediaTime()
00915 {
00916 CAutoLock cAutoLock(&m_PositionLock);
00917 m_StartMedia = 0;
00918 m_EndMedia = 0;
00919 m_bReset = TRUE;
00920 return NOERROR;
00921 }
00922
00923 HRESULT
00924 CRendererPosPassThru::EOS()
00925 {
00926 HRESULT hr;
00927
00928 if ( m_bReset == TRUE ) hr = E_FAIL;
00929 else
00930 {
00931 LONGLONG llStop;
00932 if SUCCEEDED(hr=GetStopPosition(&llStop))
00933 {
00934 CAutoLock cAutoLock(&m_PositionLock);
00935 m_StartMedia =
00936 m_EndMedia = llStop;
00937 }
00938 }
00939 return hr;
00940 }
00941
00942 CSourceSeeking::CSourceSeeking(
00943 const TCHAR * pName,
00944 LPUNKNOWN pUnk,
00945 HRESULT* phr,
00946 CCritSec * pLock) :
00947 CUnknown(pName, pUnk),
00948 m_pLock(pLock),
00949 m_rtStart((long)0)
00950 {
00951 m_rtStop = _I64_MAX / 2;
00952 m_rtDuration = m_rtStop;
00953 m_dRateSeeking = 1.0;
00954
00955 m_dwSeekingCaps = AM_SEEKING_CanSeekForwards
00956 | AM_SEEKING_CanSeekBackwards
00957 | AM_SEEKING_CanSeekAbsolute
00958 | AM_SEEKING_CanGetStopPos
00959 | AM_SEEKING_CanGetDuration;
00960 }
00961
00962 HRESULT CSourceSeeking::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00963 {
00964 if(riid == IID_IMediaSeeking) {
00965 CheckPointer(ppv, E_POINTER);
00966 return GetInterface(static_cast<IMediaSeeking *>(this), ppv);
00967 }
00968 else {
00969 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
00970 }
00971 }
00972
00973 HRESULT CSourceSeeking::IsFormatSupported(const GUID * pFormat)
00974 {
00975 CheckPointer(pFormat, E_POINTER);
00976
00977 return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
00978 }
00979
00980 HRESULT CSourceSeeking::QueryPreferredFormat(GUID *pFormat)
00981 {
00982 CheckPointer(pFormat, E_POINTER);
00983 *pFormat = TIME_FORMAT_MEDIA_TIME;
00984 return S_OK;
00985 }
00986
00987 HRESULT CSourceSeeking::SetTimeFormat(const GUID * pFormat)
00988 {
00989 CheckPointer(pFormat, E_POINTER);
00990
00991
00992 return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : E_INVALIDARG;
00993 }
00994
00995 HRESULT CSourceSeeking::IsUsingTimeFormat(const GUID * pFormat)
00996 {
00997 CheckPointer(pFormat, E_POINTER);
00998 return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
00999 }
01000
01001 HRESULT CSourceSeeking::GetTimeFormat(GUID *pFormat)
01002 {
01003 CheckPointer(pFormat, E_POINTER);
01004 *pFormat = TIME_FORMAT_MEDIA_TIME;
01005 return S_OK;
01006 }
01007
01008 HRESULT CSourceSeeking::GetDuration(LONGLONG *pDuration)
01009 {
01010 CheckPointer(pDuration, E_POINTER);
01011 CAutoLock lock(m_pLock);
01012 *pDuration = m_rtDuration;
01013 return S_OK;
01014 }
01015
01016 HRESULT CSourceSeeking::GetStopPosition(LONGLONG *pStop)
01017 {
01018 CheckPointer(pStop, E_POINTER);
01019 CAutoLock lock(m_pLock);
01020 *pStop = m_rtStop;
01021 return S_OK;
01022 }
01023
01024 HRESULT CSourceSeeking::GetCurrentPosition(LONGLONG *pCurrent)
01025 {
01026
01027
01028 return E_NOTIMPL;
01029 }
01030
01031 HRESULT CSourceSeeking::GetCapabilities( DWORD * pCapabilities )
01032 {
01033 CheckPointer(pCapabilities, E_POINTER);
01034 *pCapabilities = m_dwSeekingCaps;
01035 return S_OK;
01036 }
01037
01038 HRESULT CSourceSeeking::CheckCapabilities( DWORD * pCapabilities )
01039 {
01040 CheckPointer(pCapabilities, E_POINTER);
01041
01042
01043 return (~m_dwSeekingCaps & *pCapabilities) ? S_FALSE : S_OK;
01044 }
01045
01046 HRESULT CSourceSeeking::ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat,
01047 LONGLONG Source, const GUID * pSourceFormat )
01048 {
01049 CheckPointer(pTarget, E_POINTER);
01050
01051
01052
01053
01054 if(pTargetFormat == 0 || *pTargetFormat == TIME_FORMAT_MEDIA_TIME)
01055 {
01056 if(pSourceFormat == 0 || *pSourceFormat == TIME_FORMAT_MEDIA_TIME)
01057 {
01058 *pTarget = Source;
01059 return S_OK;
01060 }
01061 }
01062
01063 return E_INVALIDARG;
01064 }
01065
01066 HRESULT CSourceSeeking::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
01067 , LONGLONG * pStop, DWORD StopFlags )
01068 {
01069 DWORD StopPosBits = StopFlags & AM_SEEKING_PositioningBitsMask;
01070 DWORD StartPosBits = CurrentFlags & AM_SEEKING_PositioningBitsMask;
01071
01072 if(StopFlags) {
01073 CheckPointer(pStop, E_POINTER);
01074
01075
01076 if(StopPosBits != StopFlags) {
01077 return E_INVALIDARG;
01078 }
01079 }
01080
01081 if(CurrentFlags) {
01082 CheckPointer(pCurrent, E_POINTER);
01083 if(StartPosBits != AM_SEEKING_AbsolutePositioning &&
01084 StartPosBits != AM_SEEKING_RelativePositioning) {
01085 return E_INVALIDARG;
01086 }
01087 }
01088
01089
01090 {
01091 CAutoLock lock(m_pLock);
01092
01093
01094 if(StartPosBits == AM_SEEKING_AbsolutePositioning)
01095 {
01096 m_rtStart = *pCurrent;
01097 }
01098 else if(StartPosBits == AM_SEEKING_RelativePositioning)
01099 {
01100 m_rtStart += *pCurrent;
01101 }
01102
01103
01104 if(StopPosBits == AM_SEEKING_AbsolutePositioning)
01105 {
01106 m_rtStop = *pStop;
01107 }
01108 else if(StopPosBits == AM_SEEKING_IncrementalPositioning)
01109 {
01110 m_rtStop = m_rtStart + *pStop;
01111 }
01112 else if(StopPosBits == AM_SEEKING_RelativePositioning)
01113 {
01114 m_rtStop = m_rtStop + *pStop;
01115 }
01116 }
01117
01118 HRESULT hr = S_OK;
01119 if(SUCCEEDED(hr) && StopPosBits) {
01120 hr = ChangeStop();
01121 }
01122 if(StartPosBits) {
01123 hr = ChangeStart();
01124 }
01125
01126 return hr;
01127 }
01128
01129 HRESULT CSourceSeeking::GetPositions( LONGLONG * pCurrent, LONGLONG * pStop )
01130 {
01131 if(pCurrent) {
01132 *pCurrent = m_rtStart;
01133 }
01134 if(pStop) {
01135 *pStop = m_rtStop;
01136 }
01137
01138 return S_OK;;
01139 }
01140
01141 HRESULT CSourceSeeking::GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest )
01142 {
01143 if(pEarliest) {
01144 *pEarliest = 0;
01145 }
01146 if(pLatest) {
01147 CAutoLock lock(m_pLock);
01148 *pLatest = m_rtDuration;
01149 }
01150 return S_OK;
01151 }
01152
01153 HRESULT CSourceSeeking::SetRate( double dRate)
01154 {
01155 {
01156 CAutoLock lock(m_pLock);
01157 m_dRateSeeking = dRate;
01158 }
01159 return ChangeRate();
01160 }
01161
01162 HRESULT CSourceSeeking::GetRate( double * pdRate)
01163 {
01164 CheckPointer(pdRate, E_POINTER);
01165 CAutoLock lock(m_pLock);
01166 *pdRate = m_dRateSeeking;
01167 return S_OK;
01168 }
01169
01170 HRESULT CSourceSeeking::GetPreroll(LONGLONG *pPreroll)
01171 {
01172 CheckPointer(pPreroll, E_POINTER);
01173 *pPreroll = 0;
01174 return S_OK;
01175 }
01176
01177 CSourcePosition::CSourcePosition(const TCHAR * pName,
01178 LPUNKNOWN pUnk,
01179 HRESULT* phr,
01180 CCritSec * pLock) :
01181 CMediaPosition(pName, pUnk),
01182 m_pLock(pLock),
01183 m_Start(CRefTime((LONGLONG)0))
01184 {
01185 m_Stop = _I64_MAX;
01186 m_Rate = 1.0;
01187 }
01188
01189 STDMETHODIMP
01190 CSourcePosition::get_Duration(REFTIME * plength)
01191 {
01192 CheckPointer(plength,E_POINTER);
01193 ValidateReadWritePtr(plength,sizeof(REFTIME));
01194 CAutoLock lock(m_pLock);
01195
01196 *plength = m_Duration;
01197 return S_OK;
01198 }
01199
01200 STDMETHODIMP
01201 CSourcePosition::put_CurrentPosition(REFTIME llTime)
01202 {
01203 m_pLock->Lock();
01204 m_Start = llTime;
01205 m_pLock->Unlock();
01206
01207 return ChangeStart();
01208 }
01209
01210 STDMETHODIMP
01211 CSourcePosition::get_StopTime(REFTIME * pllTime)
01212 {
01213 CheckPointer(pllTime,E_POINTER);
01214 ValidateReadWritePtr(pllTime,sizeof(REFTIME));
01215 CAutoLock lock(m_pLock);
01216
01217 *pllTime = m_Stop;
01218 return S_OK;
01219 }
01220
01221 STDMETHODIMP
01222 CSourcePosition::put_StopTime(REFTIME llTime)
01223 {
01224 m_pLock->Lock();
01225 m_Stop = llTime;
01226 m_pLock->Unlock();
01227
01228 return ChangeStop();
01229 }
01230
01231 STDMETHODIMP
01232 CSourcePosition::get_PrerollTime(REFTIME * pllTime)
01233 {
01234 CheckPointer(pllTime,E_POINTER);
01235 ValidateReadWritePtr(pllTime,sizeof(REFTIME));
01236 return E_NOTIMPL;
01237 }
01238
01239 STDMETHODIMP
01240 CSourcePosition::put_PrerollTime(REFTIME llTime)
01241 {
01242 return E_NOTIMPL;
01243 }
01244
01245 STDMETHODIMP
01246 CSourcePosition::get_Rate(double * pdRate)
01247 {
01248 CheckPointer(pdRate,E_POINTER);
01249 ValidateReadWritePtr(pdRate,sizeof(double));
01250 CAutoLock lock(m_pLock);
01251
01252 *pdRate = m_Rate;
01253 return S_OK;
01254 }
01255
01256 STDMETHODIMP
01257 CSourcePosition::put_Rate(double dRate)
01258 {
01259 m_pLock->Lock();
01260 m_Rate = dRate;
01261 m_pLock->Unlock();
01262
01263 return ChangeRate();
01264 }
01265
01266 STDMETHODIMP
01267 CSourcePosition::CanSeekForward(LONG *pCanSeekForward)
01268 {
01269 CheckPointer(pCanSeekForward,E_POINTER);
01270 *pCanSeekForward = OATRUE;
01271 return S_OK;
01272 }
01273
01274 STDMETHODIMP
01275 CSourcePosition::CanSeekBackward(LONG *pCanSeekBackward)
01276 {
01277 CheckPointer(pCanSeekBackward,E_POINTER);
01278 *pCanSeekBackward = OATRUE;
01279 return S_OK;
01280 }
01281
01282 CBasicAudio::CBasicAudio(const TCHAR * pName,LPUNKNOWN punk) :
01283 CUnknown(pName, punk)
01284 {
01285 }
01286
01287 STDMETHODIMP
01288 CBasicAudio::NonDelegatingQueryInterface(REFIID riid, void **ppv)
01289 {
01290 ValidateReadWritePtr(ppv,sizeof(PVOID));
01291 if (riid == IID_IBasicAudio) {
01292 return GetInterface( (IBasicAudio *) this, ppv);
01293 } else {
01294 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
01295 }
01296 }
01297
01298 STDMETHODIMP
01299 CBasicAudio::GetTypeInfoCount(UINT * pctinfo)
01300 {
01301 return m_basedisp.GetTypeInfoCount(pctinfo);
01302 }
01303
01304 STDMETHODIMP
01305 CBasicAudio::GetTypeInfo(
01306 UINT itinfo,
01307 LCID lcid,
01308 ITypeInfo ** pptinfo)
01309 {
01310 return m_basedisp.GetTypeInfo(
01311 IID_IBasicAudio,
01312 itinfo,
01313 lcid,
01314 pptinfo);
01315 }
01316
01317 STDMETHODIMP
01318 CBasicAudio::GetIDsOfNames(
01319 REFIID riid,
01320 OLECHAR ** rgszNames,
01321 UINT cNames,
01322 LCID lcid,
01323 DISPID * rgdispid)
01324 {
01325 return m_basedisp.GetIDsOfNames(
01326 IID_IBasicAudio,
01327 rgszNames,
01328 cNames,
01329 lcid,
01330 rgdispid);
01331 }
01332
01333 STDMETHODIMP
01334 CBasicAudio::Invoke(
01335 DISPID dispidMember,
01336 REFIID riid,
01337 LCID lcid,
01338 WORD wFlags,
01339 DISPPARAMS * pdispparams,
01340 VARIANT * pvarResult,
01341 EXCEPINFO * pexcepinfo,
01342 UINT * puArgErr)
01343 {
01344
01345 if (IID_NULL != riid) {
01346 return DISP_E_UNKNOWNINTERFACE;
01347 }
01348
01349 ITypeInfo * pti;
01350 HRESULT hr = GetTypeInfo(0, lcid, &pti);
01351
01352 if (FAILED(hr)) {
01353 return hr;
01354 }
01355
01356 hr = pti->Invoke(
01357 (IBasicAudio *)this,
01358 dispidMember,
01359 wFlags,
01360 pdispparams,
01361 pvarResult,
01362 pexcepinfo,
01363 puArgErr);
01364
01365 pti->Release();
01366 return hr;
01367 }
01368
01369 CBaseVideoWindow::CBaseVideoWindow(const TCHAR * pName,LPUNKNOWN punk) :
01370 CUnknown(pName, punk)
01371 {
01372 }
01373
01374 STDMETHODIMP
01375 CBaseVideoWindow::NonDelegatingQueryInterface(REFIID riid, void **ppv)
01376 {
01377 ValidateReadWritePtr(ppv,sizeof(PVOID));
01378 if (riid == IID_IVideoWindow) {
01379 return GetInterface( (IVideoWindow *) this, ppv);
01380 } else {
01381 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
01382 }
01383 }
01384
01385 STDMETHODIMP
01386 CBaseVideoWindow::GetTypeInfoCount(UINT * pctinfo)
01387 {
01388 return m_basedisp.GetTypeInfoCount(pctinfo);
01389 }
01390
01391 STDMETHODIMP
01392 CBaseVideoWindow::GetTypeInfo(
01393 UINT itinfo,
01394 LCID lcid,
01395 ITypeInfo ** pptinfo)
01396 {
01397 return m_basedisp.GetTypeInfo(
01398 IID_IVideoWindow,
01399 itinfo,
01400 lcid,
01401 pptinfo);
01402 }
01403
01404 STDMETHODIMP
01405 CBaseVideoWindow::GetIDsOfNames(
01406 REFIID riid,
01407 OLECHAR ** rgszNames,
01408 UINT cNames,
01409 LCID lcid,
01410 DISPID * rgdispid)
01411 {
01412 return m_basedisp.GetIDsOfNames(
01413 IID_IVideoWindow,
01414 rgszNames,
01415 cNames,
01416 lcid,
01417 rgdispid);
01418 }
01419
01420 STDMETHODIMP
01421 CBaseVideoWindow::Invoke(
01422 DISPID dispidMember,
01423 REFIID riid,
01424 LCID lcid,
01425 WORD wFlags,
01426 DISPPARAMS * pdispparams,
01427 VARIANT * pvarResult,
01428 EXCEPINFO * pexcepinfo,
01429 UINT * puArgErr)
01430 {
01431
01432 if (IID_NULL != riid) {
01433 return DISP_E_UNKNOWNINTERFACE;
01434 }
01435
01436 ITypeInfo * pti;
01437 HRESULT hr = GetTypeInfo(0, lcid, &pti);
01438
01439 if (FAILED(hr)) {
01440 return hr;
01441 }
01442
01443 hr = pti->Invoke(
01444 (IVideoWindow *)this,
01445 dispidMember,
01446 wFlags,
01447 pdispparams,
01448 pvarResult,
01449 pexcepinfo,
01450 puArgErr);
01451
01452 pti->Release();
01453 return hr;
01454 }
01455
01456 CBaseBasicVideo::CBaseBasicVideo(const TCHAR * pName,LPUNKNOWN punk) :
01457 CUnknown(pName, punk)
01458 {
01459 }
01460
01461 STDMETHODIMP
01462 CBaseBasicVideo::NonDelegatingQueryInterface(REFIID riid, void **ppv)
01463 {
01464 ValidateReadWritePtr(ppv,sizeof(PVOID));
01465 if (riid == IID_IBasicVideo || riid == IID_IBasicVideo2) {
01466 return GetInterface( static_cast<IBasicVideo2 *>(this), ppv);
01467 } else {
01468 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
01469 }
01470 }
01471
01472 STDMETHODIMP
01473 CBaseBasicVideo::GetTypeInfoCount(UINT * pctinfo)
01474 {
01475 return m_basedisp.GetTypeInfoCount(pctinfo);
01476 }
01477
01478 STDMETHODIMP
01479 CBaseBasicVideo::GetTypeInfo(
01480 UINT itinfo,
01481 LCID lcid,
01482 ITypeInfo ** pptinfo)
01483 {
01484 return m_basedisp.GetTypeInfo(
01485 IID_IBasicVideo,
01486 itinfo,
01487 lcid,
01488 pptinfo);
01489 }
01490
01491 STDMETHODIMP
01492 CBaseBasicVideo::GetIDsOfNames(
01493 REFIID riid,
01494 OLECHAR ** rgszNames,
01495 UINT cNames,
01496 LCID lcid,
01497 DISPID * rgdispid)
01498 {
01499 return m_basedisp.GetIDsOfNames(
01500 IID_IBasicVideo,
01501 rgszNames,
01502 cNames,
01503 lcid,
01504 rgdispid);
01505 }
01506
01507 STDMETHODIMP
01508 CBaseBasicVideo::Invoke(
01509 DISPID dispidMember,
01510 REFIID riid,
01511 LCID lcid,
01512 WORD wFlags,
01513 DISPPARAMS * pdispparams,
01514 VARIANT * pvarResult,
01515 EXCEPINFO * pexcepinfo,
01516 UINT * puArgErr)
01517 {
01518
01519 if (IID_NULL != riid) {
01520 return DISP_E_UNKNOWNINTERFACE;
01521 }
01522
01523 ITypeInfo * pti;
01524 HRESULT hr = GetTypeInfo(0, lcid, &pti);
01525
01526 if (FAILED(hr)) {
01527 return hr;
01528 }
01529
01530 hr = pti->Invoke(
01531 (IBasicVideo *)this,
01532 dispidMember,
01533 wFlags,
01534 pdispparams,
01535 pvarResult,
01536 pexcepinfo,
01537 puArgErr);
01538
01539 pti->Release();
01540 return hr;
01541 }
01542
01543 CDispParams::CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr)
01544 {
01545 cNamedArgs = 0;
01546 rgdispidNamedArgs = NULL;
01547 cArgs = nArgs;
01548
01549 if (cArgs) {
01550 rgvarg = new VARIANT[cArgs];
01551 if (NULL == rgvarg) {
01552 cArgs = 0;
01553 if (phr) {
01554 *phr = E_OUTOFMEMORY;
01555 }
01556 return;
01557 }
01558
01559 for (UINT i = 0; i < cArgs; i++) {
01560
01561 VARIANT * pDest = &rgvarg[i];
01562 VARIANT * pSrc = &pArgs[i];
01563
01564 pDest->vt = pSrc->vt;
01565 switch(pDest->vt) {
01566
01567 case VT_I4:
01568 pDest->lVal = pSrc->lVal;
01569 break;
01570
01571 case VT_UI1:
01572 pDest->bVal = pSrc->bVal;
01573 break;
01574
01575 case VT_I2:
01576 pDest->iVal = pSrc->iVal;
01577 break;
01578
01579 case VT_R4:
01580 pDest->fltVal = pSrc->fltVal;
01581 break;
01582
01583 case VT_R8:
01584 pDest->dblVal = pSrc->dblVal;
01585 break;
01586
01587 case VT_BOOL:
01588 pDest->boolVal = pSrc->boolVal;
01589 break;
01590
01591 case VT_ERROR:
01592 pDest->scode = pSrc->scode;
01593 break;
01594
01595 case VT_CY:
01596 pDest->cyVal = pSrc->cyVal;
01597 break;
01598
01599 case VT_DATE:
01600 pDest->date = pSrc->date;
01601 break;
01602
01603 case VT_BSTR:
01604 if (pSrc->bstrVal == NULL) {
01605 pDest->bstrVal = NULL;
01606 } else {
01607
01608
01609
01610
01611 WORD len = * (WORD*) (pSrc->bstrVal - (sizeof(WORD) / sizeof(OLECHAR)));
01612 OLECHAR* pch = new OLECHAR[len + (sizeof(WORD)/sizeof(OLECHAR))];
01613 if (pch) {
01614 WORD *pui = (WORD*)pch;
01615 *pui = len;
01616 pDest->bstrVal = pch + (sizeof(WORD)/sizeof(OLECHAR));
01617 CopyMemory(pDest->bstrVal, pSrc->bstrVal, len*sizeof(OLECHAR));
01618 } else {
01619 cArgs = i;
01620 if (phr) {
01621 *phr = E_OUTOFMEMORY;
01622 }
01623 }
01624 }
01625 pDest->bstrVal = pSrc->bstrVal;
01626 break;
01627
01628 case VT_UNKNOWN:
01629 pDest->punkVal = pSrc->punkVal;
01630 pDest->punkVal->AddRef();
01631 break;
01632
01633 case VT_DISPATCH:
01634 pDest->pdispVal = pSrc->pdispVal;
01635 pDest->pdispVal->AddRef();
01636 break;
01637
01638 default:
01639
01640 ASSERT(0);
01641 break;
01642 }
01643 }
01644
01645 } else {
01646 rgvarg = NULL;
01647 }
01648
01649 }
01650
01651 CDispParams::~CDispParams()
01652 {
01653 for (UINT i = 0; i < cArgs; i++) {
01654 switch(rgvarg[i].vt) {
01655 case VT_BSTR:
01656 if (rgvarg[i].bstrVal != NULL) {
01657 OLECHAR * pch = rgvarg[i].bstrVal - (sizeof(WORD)/sizeof(OLECHAR));
01658 delete pch;
01659 }
01660 break;
01661
01662 case VT_UNKNOWN:
01663 rgvarg[i].punkVal->Release();
01664 break;
01665
01666 case VT_DISPATCH:
01667 rgvarg[i].pdispVal->Release();
01668 break;
01669 }
01670 }
01671 delete[] rgvarg;
01672 }
01673
01674 CDeferredCommand::CDeferredCommand(
01675 CCmdQueue * pQ,
01676 LPUNKNOWN pUnk,
01677 HRESULT * phr,
01678 LPUNKNOWN pUnkExecutor,
01679 REFTIME time,
01680 GUID* iid,
01681 long dispidMethod,
01682 short wFlags,
01683 long nArgs,
01684 VARIANT* pDispParams,
01685 VARIANT* pvarResult,
01686 short* puArgErr,
01687 BOOL bStream
01688 ) :
01689 CUnknown(NAME("DeferredCommand"), pUnk),
01690 m_pQueue(pQ),
01691 m_pUnk(pUnkExecutor),
01692 m_iid(iid),
01693 m_dispidMethod(dispidMethod),
01694 m_wFlags(wFlags),
01695 m_DispParams(nArgs, pDispParams, phr),
01696 m_pvarResult(pvarResult),
01697 m_bStream(bStream),
01698 m_hrResult(E_ABORT)
01699
01700 {
01701
01702 COARefTime convertor(time);
01703 m_time = convertor;
01704
01705
01706
01707
01708
01709 IUnknown * pInterface;
01710 HRESULT hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface);
01711 if (FAILED(hr)) {
01712 *phr = hr;
01713 return;
01714 }
01715 pInterface->Release();
01716
01717
01718 ITypeInfo *pti;
01719 hr = m_Dispatch.GetTypeInfo(*iid, 0, 0, &pti);
01720 if (FAILED(hr)) {
01721 *phr = hr;
01722 return;
01723 }
01724
01725 pti->Release();
01726
01727
01728 if (wFlags == DISPATCH_PROPERTYPUT) {
01729 m_DispParams.cNamedArgs = 1;
01730 m_DispId = DISPID_PROPERTYPUT;
01731 m_DispParams.rgdispidNamedArgs = &m_DispId;
01732 }
01733
01734
01735 hr = pQ->Insert(this);
01736 if (FAILED(hr)) {
01737 *phr = hr;
01738 }
01739 }
01740
01741 #if 0
01742 CDeferredCommand::~CDeferredCommand()
01743 {
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 }
01759 #endif
01760
01761 STDMETHODIMP
01762 CDeferredCommand::NonDelegatingQueryInterface(REFIID riid, void **ppv)
01763 {
01764 ValidateReadWritePtr(ppv,sizeof(PVOID));
01765 if (riid == IID_IDeferredCommand) {
01766 return GetInterface( (IDeferredCommand *) this, ppv);
01767 } else {
01768 return CUnknown::NonDelegatingQueryInterface(riid, ppv);
01769 }
01770 }
01771
01772 STDMETHODIMP
01773 CDeferredCommand::Cancel()
01774 {
01775 if (m_pQueue == NULL) {
01776 return VFW_E_ALREADY_CANCELLED;
01777 }
01778
01779 HRESULT hr = m_pQueue->Remove(this);
01780 if (FAILED(hr)) {
01781 return hr;
01782 }
01783
01784 m_pQueue = NULL;
01785 return S_OK;
01786 }
01787
01788 STDMETHODIMP
01789 CDeferredCommand::Confidence(LONG* pConfidence)
01790 {
01791 return E_NOTIMPL;
01792 }
01793
01794 STDMETHODIMP
01795 CDeferredCommand::GetHResult(HRESULT * phrResult)
01796 {
01797 CheckPointer(phrResult,E_POINTER);
01798 ValidateReadWritePtr(phrResult,sizeof(HRESULT));
01799
01800 if (m_pQueue != NULL) {
01801 return E_ABORT;
01802 }
01803 *phrResult = m_hrResult;
01804 return S_OK;
01805 }
01806
01807 STDMETHODIMP
01808 CDeferredCommand::Postpone(REFTIME newtime)
01809 {
01810
01811
01812
01813 COARefTime convertor(newtime);
01814
01815
01816 if (m_pQueue->CheckTime(convertor, IsStreamTime())) {
01817 return VFW_E_TIME_ALREADY_PASSED;
01818 }
01819
01820
01821 HRESULT hr = m_pQueue->Remove(this);
01822 if (FAILED(hr)) {
01823 return hr;
01824 }
01825
01826
01827 m_time = convertor;
01828
01829
01830 hr = m_pQueue->Insert(this);
01831
01832 return hr;
01833 }
01834
01835 HRESULT
01836 CDeferredCommand::Invoke()
01837 {
01838
01839 if (m_pQueue == NULL) {
01840 return VFW_E_ALREADY_CANCELLED;
01841 }
01842
01843
01844 ITypeInfo* pti;
01845 HRESULT hr = m_Dispatch.GetTypeInfo(GetIID(), 0, 0, &pti);
01846 if (FAILED(hr)) {
01847 return hr;
01848 }
01849
01850
01851
01852 IUnknown* pInterface;
01853
01854 hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface);
01855 if (FAILED(hr)) {
01856 pti->Release();
01857 return hr;
01858 }
01859
01860 EXCEPINFO expinfo;
01861 UINT uArgErr;
01862 m_hrResult = pti->Invoke(
01863 pInterface,
01864 GetMethod(),
01865 GetFlags(),
01866 GetParams(),
01867 GetResult(),
01868 &expinfo,
01869 &uArgErr);
01870
01871
01872 pInterface->Release();
01873 pti->Release();
01874
01875
01876
01877 hr = m_pQueue->Remove(this);
01878 m_pQueue = NULL;
01879 return hr;
01880 }
01881
01882 CCmdQueue::CCmdQueue() :
01883 m_listPresentation(NAME("Presentation time command list")),
01884 m_listStream(NAME("Stream time command list")),
01885 m_evDue(TRUE),
01886 m_dwAdvise(0),
01887 m_pClock(NULL),
01888 m_bRunning(FALSE)
01889 {
01890 }
01891
01892 CCmdQueue::~CCmdQueue()
01893 {
01894
01895
01896
01897
01898 POSITION pos = m_listPresentation.GetHeadPosition();
01899
01900 while(pos) {
01901 CDeferredCommand* pCmd = m_listPresentation.GetNext(pos);
01902 pCmd->Release();
01903 }
01904 m_listPresentation.RemoveAll();
01905
01906 pos = m_listStream.GetHeadPosition();
01907
01908 while(pos) {
01909 CDeferredCommand* pCmd = m_listStream.GetNext(pos);
01910 pCmd->Release();
01911 }
01912 m_listStream.RemoveAll();
01913
01914 if (m_pClock) {
01915 if (m_dwAdvise) {
01916 m_pClock->Unadvise(m_dwAdvise);
01917 m_dwAdvise = 0;
01918 }
01919 m_pClock->Release();
01920 }
01921 }
01922
01923 HRESULT
01924 CCmdQueue::New(
01925 CDeferredCommand **ppCmd,
01926 LPUNKNOWN pUnk,
01927 REFTIME time,
01928 GUID* iid,
01929 long dispidMethod,
01930 short wFlags,
01931 long cArgs,
01932 VARIANT* pDispParams,
01933 VARIANT* pvarResult,
01934 short* puArgErr,
01935 BOOL bStream
01936 )
01937 {
01938 CAutoLock lock(&m_Lock);
01939
01940 HRESULT hr = S_OK;
01941 *ppCmd = NULL;
01942
01943 CDeferredCommand* pCmd;
01944 pCmd = new CDeferredCommand(
01945 this,
01946 NULL,
01947 &hr,
01948 pUnk,
01949 time,
01950 iid,
01951 dispidMethod,
01952 wFlags,
01953 cArgs,
01954 pDispParams,
01955 pvarResult,
01956 puArgErr,
01957 bStream);
01958
01959 if (pCmd == NULL) {
01960 hr = E_OUTOFMEMORY;
01961 } else {
01962 *ppCmd = pCmd;
01963 }
01964 return hr;
01965 }
01966
01967 HRESULT
01968 CCmdQueue::Insert(CDeferredCommand* pCmd)
01969 {
01970 CAutoLock lock(&m_Lock);
01971
01972
01973 pCmd->AddRef();
01974
01975 CGenericList<CDeferredCommand> * pList;
01976 if (pCmd->IsStreamTime()) {
01977 pList = &m_listStream;
01978 } else {
01979 pList = &m_listPresentation;
01980 }
01981 POSITION pos = pList->GetHeadPosition();
01982
01983
01984 while (pos &&
01985 (pList->Get(pos)->GetTime() <= pCmd->GetTime())) {
01986
01987 pList->GetNext(pos);
01988 }
01989
01990
01991 if (!pos) {
01992 pList->AddTail(pCmd);
01993 } else {
01994 pList->AddBefore(pos, pCmd);
01995 }
01996
01997 SetTimeAdvise();
01998 return S_OK;
01999 }
02000
02001 HRESULT
02002 CCmdQueue::Remove(CDeferredCommand* pCmd)
02003 {
02004 CAutoLock lock(&m_Lock);
02005 HRESULT hr = S_OK;
02006
02007 CGenericList<CDeferredCommand> * pList;
02008 if (pCmd->IsStreamTime()) {
02009 pList = &m_listStream;
02010 } else {
02011 pList = &m_listPresentation;
02012 }
02013 POSITION pos = pList->GetHeadPosition();
02014
02015
02016 while (pos && (pList->Get(pos) != pCmd)) {
02017 pList->GetNext(pos);
02018 }
02019
02020
02021 if (!pos) {
02022 hr = VFW_E_NOT_FOUND;
02023 } else {
02024
02025
02026 pList->Remove(pos);
02027
02028
02029 pCmd->Release();
02030
02031
02032 SetTimeAdvise();
02033 }
02034 return hr;
02035 }
02036
02037 HRESULT
02038 CCmdQueue::SetSyncSource(IReferenceClock* pClock)
02039 {
02040 CAutoLock lock(&m_Lock);
02041
02042
02043 if (pClock) {
02044 pClock->AddRef();
02045 }
02046
02047
02048 if (m_pClock) {
02049 if (m_dwAdvise) {
02050 m_pClock->Unadvise(m_dwAdvise);
02051 m_dwAdvise = 0;
02052 }
02053 m_pClock->Release();
02054 }
02055 m_pClock = pClock;
02056
02057
02058 SetTimeAdvise();
02059 return S_OK;
02060 }
02061
02062 void
02063 CCmdQueue::SetTimeAdvise(void)
02064 {
02065
02066 if (!m_pClock) {
02067 return;
02068 }
02069
02070
02071 m_evDue.Reset();
02072
02073
02074 CRefTime current;
02075
02076
02077 if (m_listPresentation.GetCount() > 0) {
02078
02079 POSITION pos = m_listPresentation.GetHeadPosition();
02080 current = m_listPresentation.Get(pos)->GetTime();
02081 }
02082
02083
02084 if (m_bRunning) {
02085
02086 CRefTime t;
02087
02088 if (m_listStream.GetCount() > 0) {
02089
02090 POSITION pos = m_listStream.GetHeadPosition();
02091 t = m_listStream.Get(pos)->GetTime();
02092
02093
02094 t += m_StreamTimeOffset;
02095
02096
02097 if ((current == TimeZero) || (t < current)) {
02098 current = t;
02099 }
02100 }
02101 }
02102
02103
02104 if ((current > TimeZero) && (current != m_tCurrentAdvise)) {
02105 if (m_dwAdvise) {
02106 m_pClock->Unadvise(m_dwAdvise);
02107
02108 m_evDue.Reset();
02109 }
02110
02111
02112
02113
02114 HRESULT hr = m_pClock->AdviseTime(
02115 (REFERENCE_TIME)current,
02116 TimeZero,
02117 (HEVENT) HANDLE(m_evDue),
02118 &m_dwAdvise);
02119
02120 ASSERT(SUCCEEDED(hr));
02121 m_tCurrentAdvise = current;
02122 }
02123 }
02124
02125 HRESULT
02126 CCmdQueue::Run(REFERENCE_TIME tStreamTimeOffset)
02127 {
02128 CAutoLock lock(&m_Lock);
02129
02130 m_StreamTimeOffset = tStreamTimeOffset;
02131 m_bRunning = TRUE;
02132
02133
02134 SetTimeAdvise();
02135 return S_OK;
02136 }
02137
02138 HRESULT
02139 CCmdQueue::EndRun()
02140 {
02141 CAutoLock lock(&m_Lock);
02142
02143 m_bRunning = FALSE;
02144
02145
02146 SetTimeAdvise();
02147 return S_OK;
02148 }
02149
02150 HRESULT
02151 CCmdQueue::GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout)
02152 {
02153
02154 for (;;) {
02155
02156 {
02157 CAutoLock lock(&m_Lock);
02158
02159
02160 CDeferredCommand * pCmd = NULL;
02161
02162
02163
02164
02165 if (m_listPresentation.GetCount() > 0) {
02166 POSITION pos = m_listPresentation.GetHeadPosition();
02167 pCmd = m_listPresentation.Get(pos);
02168 }
02169
02170 if (m_bRunning && (m_listStream.GetCount() > 0)) {
02171 POSITION pos = m_listStream.GetHeadPosition();
02172 CDeferredCommand* pStrm = m_listStream.Get(pos);
02173
02174 CRefTime t = pStrm->GetTime() + m_StreamTimeOffset;
02175 if (!pCmd || (t < pCmd->GetTime())) {
02176 pCmd = pStrm;
02177 }
02178 }
02179
02180
02181 if (pCmd) {
02182 if (CheckTime(pCmd->GetTime(), pCmd->IsStreamTime())) {
02183
02184
02185 pCmd->AddRef();
02186 *ppCmd = pCmd;
02187 return S_OK;
02188 }
02189 }
02190 }
02191
02192
02193 if (WaitForSingleObject(m_evDue, msTimeout) != WAIT_OBJECT_0) {
02194 return E_ABORT;
02195 }
02196 }
02197 }
02198
02199 HRESULT
02200 CCmdQueue::GetCommandDueFor(REFERENCE_TIME rtStream, CDeferredCommand**ppCmd)
02201 {
02202 CAutoLock lock(&m_Lock);
02203
02204 CRefTime tStream(rtStream);
02205
02206
02207 CDeferredCommand* pStream = NULL;
02208 if (m_listStream.GetCount() > 0) {
02209 POSITION pos = m_listStream.GetHeadPosition();
02210 pStream = m_listStream.Get(pos);
02211 }
02212 CDeferredCommand* pPresent = NULL;
02213 if (m_listPresentation.GetCount() > 0) {
02214 POSITION pos = m_listPresentation.GetHeadPosition();
02215 pPresent = m_listPresentation.Get(pos);
02216 }
02217
02218
02219 if (pPresent && CheckTime(pPresent->GetTime(), FALSE)) {
02220 pPresent->AddRef();
02221 *ppCmd = pPresent;
02222 return S_OK;
02223 }
02224
02225
02226 if (pStream && (pStream->GetTime() <= tStream)) {
02227 pPresent->AddRef();
02228 *ppCmd = pStream;
02229 return S_OK;
02230 }
02231
02232
02233
02234
02235 if (m_bRunning && pPresent) {
02236
02237
02238 tStream += m_StreamTimeOffset;
02239
02240
02241 if (pPresent->GetTime() <= tStream) {
02242 *ppCmd = pPresent;
02243 return S_OK;
02244 }
02245 }
02246
02247
02248 return VFW_E_NOT_FOUND;
02249 }
02250