2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
28 #include "RealMediaGraph.h"
29 #include "RealMediaWindowlessSite.h"
30 #include "..\..\..\include\RealMedia\rmavsurf.h"
31 #include "..\..\..\include\RealMedia\rmaevent.h"
32 #include "..\..\..\include\RealMedia\rmaprefs.h"
33 #include "..\..\DSUtil\DSUtil.h"
38 CRealMediaPlayer::CRealMediaPlayer(HWND hWndParent
, CRealMediaGraph
* pRMG
)
39 : CUnknown(NAME("CRealMediaPlayer"), NULL
)
41 , m_hWndParent(hWndParent
)
42 , m_fpCreateEngine(NULL
), m_fpCloseEngine(NULL
), m_hRealMediaCore(NULL
)
43 , m_State(State_Stopped
), m_UserState(State_Stopped
), m_nCurrent(0), m_nDuration(0)
45 , m_fVideoSizeChanged(true)
49 CRealMediaPlayer::~CRealMediaPlayer()
54 bool CRealMediaPlayer::Init()
56 CString
prefs(_T("Software\\RealNetworks\\Preferences"));
60 if(ERROR_SUCCESS
!= key
.Open(HKEY_CLASSES_ROOT
, prefs
+ _T("\\DT_Common"), KEY_READ
))
64 ULONG len
= sizeof(buff
);
65 if(ERROR_SUCCESS
!= key
.QueryStringValue(NULL
, buff
, &len
))
70 if(!(m_hRealMediaCore
= LoadLibrary(CString(buff
) + _T("pnen3260.dll"))))
73 m_fpCreateEngine
= (FPRMCREATEENGINE
)GetProcAddress(m_hRealMediaCore
, "CreateEngine");
74 m_fpCloseEngine
= (FPRMCLOSEENGINE
)GetProcAddress(m_hRealMediaCore
, "CloseEngine");
75 m_fpSetDLLAccessPath
= (FPRMSETDLLACCESSPATH
)GetProcAddress(m_hRealMediaCore
, "SetDLLAccessPath");
77 if(!m_fpCreateEngine
|| !m_fpCloseEngine
|| !m_fpSetDLLAccessPath
)
80 if(ERROR_SUCCESS
== key
.Open(HKEY_CLASSES_ROOT
, prefs
, KEY_READ
))
85 for(int i
= 0; ERROR_SUCCESS
== key
.EnumKey(i
, buff
, &len
); i
++, len
= sizeof(buff
))
88 TCHAR buff2
[MAX_PATH
];
89 ULONG len2
= sizeof(buff2
);
90 if(ERROR_SUCCESS
!= key2
.Open(HKEY_CLASSES_ROOT
, prefs
+ _T("\\") + buff
, KEY_READ
)
91 || ERROR_SUCCESS
!= key2
.QueryStringValue(NULL
, buff2
, &len2
))
94 dllpaths
+= CString(buff
) + '=' + buff2
+ '|';
99 if(!dllpaths
.IsEmpty())
101 char* s
= new char[dllpaths
.GetLength()+1];
102 strcpy(s
, CStringA(dllpaths
));
103 for(int i
= 0, j
= strlen(s
); i
< j
; i
++) {if(s
[i
] == '|') s
[i
] = '\0';}
104 m_fpSetDLLAccessPath(s
);
109 if(PNR_OK
!= m_fpCreateEngine(&m_pEngine
))
112 if(PNR_OK
!= m_pEngine
->CreatePlayer(*&m_pPlayer
))
115 if(!(m_pSiteManager
= m_pPlayer
) || !(m_pCommonClassFactory
= m_pPlayer
))
118 m_pAudioPlayer
= m_pPlayer
;
119 m_pAudioPlayer
->AddPostMixHook(static_cast<IRMAAudioHook
*>(this), FALSE
, FALSE
);
120 // m_pVolume = m_pAudioPlayer->GetDeviceVolume();
121 m_pVolume
= m_pAudioPlayer
->GetAudioVolume();
123 // IRMAVolume::SetVolume has a huge latency when used via GetAudioVolume,
124 // but by lowering this audio pushdown thing it can get better
125 CComQIPtr
<IRMAAudioPushdown
, &IID_IRMAAudioPushdown
> pAP
= m_pAudioPlayer
;
126 if(pAP
) pAP
->SetAudioPushdown(300); // 100ms makes the playback sound choppy, 200ms looks ok, but for safety we set this to 300ms... :P
128 CComQIPtr
<IRMAErrorSinkControl
, &IID_IRMAErrorSinkControl
> pErrorSinkControl
= m_pPlayer
;
129 if(pErrorSinkControl
) pErrorSinkControl
->AddErrorSink(static_cast<IRMAErrorSink
*>(this), PNLOG_EMERG
, PNLOG_INFO
);
131 if(PNR_OK
!= m_pPlayer
->AddAdviseSink(static_cast<IRMAClientAdviseSink
*>(this)))
134 if(PNR_OK
!= m_pPlayer
->SetClientContext((IUnknown
*)(INonDelegatingUnknown
*)(this)))
139 if(CComQIPtr<IRMAPreferences, &IID_IRMAPreferences> pPrefs = m_pPlayer)
141 CComPtr<IRMABuffer> pBuffer;
142 HRESULT hr = pPrefs->ReadPref("HTTPProxyHost", *&pBuffer);
145 ULONG32 ulLength = 0;
146 hr = pBuffer->Get(pData, ulLength);
149 hr = m_pCommonClassFactory->CreateInstance(CLSID_IRMABuffer, (void**)&pBuffer);
150 hr = pBuffer->SetSize(strlen("localhost")+1);
151 pData = pBuffer->GetBuffer();
152 strcpy((char*)pData, "localhost");
153 hr = pBuffer->Set(pData, strlen("localhost")+1);
157 hr = pBuffer->Get(pData, ulLength);
159 hr = pPrefs->WritePref("HTTPProxyHost", pBuffer);
167 void CRealMediaPlayer::Deinit()
173 CComQIPtr
<IRMAErrorSinkControl
, &IID_IRMAErrorSinkControl
> pErrorSinkControl
= m_pPlayer
;
174 if(pErrorSinkControl
) pErrorSinkControl
->RemoveErrorSink(static_cast<IRMAErrorSink
*>(this));
176 m_pPlayer
->RemoveAdviseSink(static_cast<IRMAClientAdviseSink
*>(this));
179 m_pAudioPlayer
->RemovePostMixHook(static_cast<IRMAAudioHook
*>(this));
180 m_pAudioPlayer
.Release();
182 m_pEngine
->ClosePlayer(m_pPlayer
);
184 m_pSiteManager
.Release();
185 m_pCommonClassFactory
.Release();
192 m_fpCloseEngine(m_pEngine
);
198 FreeLibrary(m_hRealMediaCore
);
199 m_hRealMediaCore
= NULL
;
203 STDMETHODIMP
CRealMediaPlayer::NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
205 CheckPointer(ppv
, E_POINTER
);
209 QI2(IRMAClientAdviseSink
)
210 QI2(IRMAAuthenticationManager
)
211 QI2(IRMASiteSupplier
)
212 QI2(IRMAPassiveSiteWatcher
)
214 __super::NonDelegatingQueryInterface(riid
, ppv
);
218 STDMETHODIMP
CRealMediaPlayer::ErrorOccurred(const UINT8 unSeverity
, const UINT32 ulRMACode
, const UINT32 ulUserCode
, const char* pUserString
, const char* pMoreInfoURL
)
224 if(CComQIPtr
<IRMAErrorMessages
, &IID_IRMAErrorMessages
> pErrorMessages
= m_pPlayer
)
226 CComPtr
<IRMABuffer
> pBuffer
= pErrorMessages
->GetErrorText(ulRMACode
);
229 char* buff
= (char*)pBuffer
->GetBuffer();
230 int len
= strlen(buff
);
231 if(len
> 0 && (errmsg
= (char*)CoTaskMemAlloc(len
+1)))
232 strcpy(errmsg
, buff
);
236 if(!errmsg
&& (errmsg
= (char*)CoTaskMemAlloc(strlen("RealMedia error")+1)))
237 strcpy(errmsg
, "RealMedia error");
239 m_pRMG
->NotifyEvent(EC_BG_ERROR
, (LONG_PTR
)errmsg
, 0);
245 // IRMAClientAdviseSink
246 STDMETHODIMP
CRealMediaPlayer::OnPosLength(UINT32 ulPosition
, UINT32 ulLength
)
248 m_nCurrent
= (REFERENCE_TIME
)ulPosition
*10000;
249 m_nDuration
= (REFERENCE_TIME
)ulLength
*10000;
252 STDMETHODIMP
CRealMediaPlayer::OnPresentationOpened() {return PNR_OK
;}
253 STDMETHODIMP
CRealMediaPlayer::OnPresentationClosed() {return PNR_OK
;}
254 STDMETHODIMP
CRealMediaPlayer::OnStatisticsChanged()
256 m_pRMG
->NotifyEvent(EC_LENGTH_CHANGED
);
259 STDMETHODIMP
CRealMediaPlayer::OnPreSeek(UINT32 ulOldTime
, UINT32 ulNewTime
)
261 m_nCurrent
= (REFERENCE_TIME
)ulNewTime
*10000;
264 STDMETHODIMP
CRealMediaPlayer::OnPostSeek(UINT32 ulOldTime
, UINT32 ulNewTime
)
266 m_nCurrent
= (REFERENCE_TIME
)ulNewTime
*10000;
269 STDMETHODIMP
CRealMediaPlayer::OnStop()
272 m_State
= State_Stopped
;
273 if(m_UserState
!= State_Stopped
)
274 m_pRMG
->NotifyEvent(EC_COMPLETE
);
277 STDMETHODIMP
CRealMediaPlayer::OnPause(UINT32 ulTime
)
279 m_State
= State_Paused
;
282 STDMETHODIMP
CRealMediaPlayer::OnBegin(UINT32 ulTime
)
284 m_State
= State_Running
;
287 STDMETHODIMP
CRealMediaPlayer::OnBuffering(UINT32 ulFlags
, UINT16 unPercentComplete
)
289 m_unPercentComplete
= unPercentComplete
;
292 STDMETHODIMP
CRealMediaPlayer::OnContacting(const char* pHostName
) {return PNR_OK
;}
294 // IRMAAuthenticationManager
295 STDMETHODIMP
CRealMediaPlayer::HandleAuthenticationRequest(IRMAAuthenticationManagerResponse
* pResponse
)
299 if(dlg
.DoModal() == IDOK
)
301 pResponse
->AuthenticationRequestDone(
302 PNR_OK
, CStringA(dlg
.m_username
), CStringA(dlg
.m_password
));
306 return pResponse
->AuthenticationRequestDone(PNR_NOT_AUTHORIZED
, NULL
, NULL
);
310 STDMETHODIMP
CRealMediaPlayer::SitesNeeded(UINT32 uRequestID
, IRMAValues
* pProps
)
312 if(!pProps
) return PNR_INVALID_PARAMETER
;
314 if(m_pTheSite
|| m_pTheSite2
|| !m_hWndParent
) return PNR_UNEXPECTED
;
318 if(!CreateSite(&m_pTheSite
))
321 ULONG refc
= ((IRMASite
*)m_pTheSite
)->AddRef();
322 refc
= ((IRMASite
*)m_pTheSite
)->Release();
324 if(!(m_pTheSite2
= m_pTheSite
))
325 return E_NOINTERFACE
;
327 CComQIPtr
<IRMAValues
, &IID_IRMAValues
> pSiteProps
= m_pTheSite
;
329 return E_NOINTERFACE
;
333 // no idea what these supposed to do... but they were in the example
334 hr
= pProps
->GetPropertyCString("playto", pValue
);
337 pSiteProps
->SetPropertyCString("channel", pValue
);
342 hr
= pProps
->GetPropertyCString("name", pValue
);
345 pSiteProps
->SetPropertyCString("LayoutGroup", pValue
);
350 m_pTheSite2
->AddPassiveSiteWatcher(static_cast<IRMAPassiveSiteWatcher
*>(this));
352 hr
= m_pSiteManager
->AddSite(m_pTheSite
);
356 m_CreatedSites
[uRequestID
] = m_pTheSite
;
361 STDMETHODIMP
CRealMediaPlayer::SitesNotNeeded(UINT32 uRequestID
)
364 if(!m_CreatedSites
.Lookup(uRequestID
, pSite
))
365 return PNR_INVALID_PARAMETER
;
367 m_CreatedSites
.RemoveKey(uRequestID
);
369 m_pSiteManager
->RemoveSite(pSite
);
371 m_pTheSite2
->RemovePassiveSiteWatcher(static_cast<IRMAPassiveSiteWatcher
*>(this));
373 m_pTheSite
.Release();
374 m_pTheSite2
.Release();
380 STDMETHODIMP
CRealMediaPlayer::BeginChangeLayout() {return E_NOTIMPL
;}
381 STDMETHODIMP
CRealMediaPlayer::DoneChangeLayout()
383 if(m_fVideoSizeChanged
)
385 m_pRMG
->NotifyEvent(EC_VIDEO_SIZE_CHANGED
, MAKELPARAM(m_VideoSize
.cx
, m_VideoSize
.cy
), 0);
386 m_fVideoSizeChanged
= false;
392 // IRMAPassiveSiteWatcher
393 STDMETHODIMP
CRealMediaPlayer::PositionChanged(PNxPoint
* pos
) {return E_NOTIMPL
;}
394 STDMETHODIMP
CRealMediaPlayer::SizeChanged(PNxSize
* size
)
396 if(m_VideoSize
.cx
== 0 || m_VideoSize
.cy
== 0)
398 m_fVideoSizeChanged
= true;
399 m_VideoSize
.cx
= size
->cx
;
400 m_VideoSize
.cy
= size
->cy
;
406 STDMETHODIMP
CRealMediaPlayer::OnBuffer(RMAAudioData
* pAudioInData
, RMAAudioData
* pAudioOutData
) {return E_NOTIMPL
;}
407 STDMETHODIMP
CRealMediaPlayer::OnInit(RMAAudioFormat
* pFormat
)
409 m_pRMG
->NotifyEvent(EC_BG_AUDIO_CHANGED
, pFormat
->uChannels
, 0);
414 // CRealMediaPlayerWindowed
417 CRealMediaPlayerWindowed::CRealMediaPlayerWindowed(HWND hWndParent
, CRealMediaGraph
* pRMG
)
418 : CRealMediaPlayer(hWndParent
, pRMG
)
420 if(!m_wndWindowFrame
.CreateEx(WS_EX_NOPARENTNOTIFY
, NULL
, NULL
, WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|WS_VISIBLE
,
421 CRect(0, 0, 0, 0), CWnd::FromHandle(m_hWndParent
), 0, NULL
))
424 if(!m_wndDestFrame
.Create(NULL
, NULL
, WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
,
425 CRect(0, 0, 0, 0), &m_wndWindowFrame
, 0, NULL
))
429 CRealMediaPlayerWindowed::~CRealMediaPlayerWindowed()
431 m_wndDestFrame
.DestroyWindow();
432 m_wndWindowFrame
.DestroyWindow();
435 void CRealMediaPlayerWindowed::SetWindowRect(CRect r
)
437 if(IsWindow(m_wndWindowFrame
.m_hWnd
))
438 m_wndWindowFrame
.MoveWindow(r
);
441 void CRealMediaPlayerWindowed::SetDestRect(CRect r
)
443 if(IsWindow(m_wndDestFrame
.m_hWnd
))
444 m_wndDestFrame
.MoveWindow(r
);
448 PNxSize s
= {r
.Width(), r
.Height()};
449 m_pTheSite
->SetSize(s
);
453 bool CRealMediaPlayerWindowed::CreateSite(IRMASite
** ppSite
)
458 CComPtr
<IRMASiteWindowed
> pSiteWindowed
;
459 if(PNR_OK
!= m_pCommonClassFactory
->CreateInstance(CLSID_IRMASiteWindowed
, (void**)&pSiteWindowed
))
462 DWORD style
= WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
;
463 if(!AfxGetAppSettings().fIntRealMedia
) style
|= WS_DISABLED
;
464 if(PNR_OK
!= pSiteWindowed
->Create(m_wndDestFrame
.m_hWnd
, style
))
467 return !!(*ppSite
= CComQIPtr
<IRMASite
, &IID_IRMASite
>(pSiteWindowed
).Detach());
470 void CRealMediaPlayerWindowed::DestroySite(IRMASite
* pSite
)
472 if(CComQIPtr
<IRMASiteWindowed
, &IID_IRMASiteWindowed
> pRMASiteWindowed
= pSite
)
473 pRMASiteWindowed
->Destroy();
476 // CRealMediaPlayerWindowless
479 CRealMediaPlayerWindowless::CRealMediaPlayerWindowless(HWND hWndParent
, CRealMediaGraph
* pRMG
)
480 : CRealMediaPlayer(hWndParent
, pRMG
)
482 AppSettings
& s
= AfxGetAppSettings();
484 switch(s
.iRMVideoRendererType
)
488 if(FAILED(CreateAP7(CLSID_RM7AllocatorPresenter
, hWndParent
, &m_pRMAP
)))
492 if(FAILED(CreateAP9(CLSID_RM9AllocatorPresenter
, hWndParent
, &m_pRMAP
)))
498 CRealMediaPlayerWindowless::~CRealMediaPlayerWindowless()
502 STDMETHODIMP
CRealMediaPlayerWindowless::NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
504 CheckPointer(ppv
, E_POINTER
);
507 (m_pRMAP
&& (riid
== __uuidof(ISubPicAllocatorPresenter
) || riid
== IID_IRMAVideoSurface
)) ? m_pRMAP
->QueryInterface(riid
, ppv
) :
508 __super::NonDelegatingQueryInterface(riid
, ppv
);
511 bool CRealMediaPlayerWindowless::CreateSite(IRMASite
** ppSite
)
513 if(!ppSite
|| !m_pRMAP
)
518 CRealMediaWindowlessSite
* pWMWlS
;
520 CComPtr
<IRMASiteWindowless
> pSiteWindowless
;
521 pSiteWindowless
= (IRMASiteWindowless
*)(pWMWlS
= new CRealMediaWindowlessSite(hr
, m_pPlayer
, NULL
, NULL
));
525 pWMWlS
->SetBltService(CComQIPtr
<IRMAVideoSurface
, &IID_IRMAVideoSurface
>(m_pRMAP
));
527 return !!(*ppSite
= CComQIPtr
<IRMASite
, &IID_IRMASite
>(pSiteWindowless
).Detach());
530 void CRealMediaPlayerWindowless::DestroySite(IRMASite
* pSite
)
534 STDMETHODIMP
CRealMediaPlayerWindowless::SizeChanged(PNxSize
* size
)
536 if(CComQIPtr
<IRMAVideoSurface
, &IID_IRMAVideoSurface
> pRMAVS
= m_pRMAP
)
538 RMABitmapInfoHeader BitmapInfo
;
539 memset(&BitmapInfo
, 0, sizeof(BitmapInfo
));
540 BitmapInfo
.biWidth
= size
->cx
;
541 BitmapInfo
.biHeight
= size
->cy
;
542 pRMAVS
->BeginOptimizedBlt(&BitmapInfo
);
545 return __super::SizeChanged(size
);
551 CRealMediaGraph::CRealMediaGraph(HWND hWndParent
, HRESULT
& hr
)
556 m_pRMP
= AfxGetAppSettings().iRMVideoRendererType
== VIDRNDT_RM_DEFAULT
557 ? (CRealMediaPlayer
*)new CRealMediaPlayerWindowed(hWndParent
, this)
558 : (CRealMediaPlayer
*)new CRealMediaPlayerWindowless(hWndParent
, this);
568 delete m_pRMP
, m_pRMP
= NULL
;
576 CRealMediaGraph::~CRealMediaGraph()
586 STDMETHODIMP
CRealMediaGraph::NonDelegatingQueryInterface(REFIID riid
, void** ppv
)
588 CheckPointer(ppv
, E_POINTER
);
591 (m_pRMP
&& (riid
== __uuidof(ISubPicAllocatorPresenter
) || riid
== __uuidof(ISubPicAllocatorPresenter
))) ? m_pRMP
->QueryInterface(riid
, ppv
) :
592 __super::NonDelegatingQueryInterface(riid
, ppv
);
596 STDMETHODIMP
CRealMediaGraph::RenderFile(LPCWSTR lpcwstrFile
, LPCWSTR lpcwstrPlayList
)
600 CHAR buff
[MAX_PATH
] = {0};
601 WideCharToMultiByte(GetACP(), 0, lpcwstrFile
, -1, buff
, MAX_PATH
, 0, 0);
604 if(fn
.Find("://") < 0) fn
= "file://" + fn
;
606 m_pRMP
->m_unPercentComplete
= 100;
610 if(PNR_OK
!= m_pRMP
->m_pPlayer
->OpenURL(fn
))
613 m_pRMP
->m_pPlayer
->Pause()/*Stop()*/; // please, don't start just yet
619 STDMETHODIMP
CRealMediaGraph::Run()
621 if(m_pRMP
->m_pPlayer
->IsDone())
622 RenderFile(m_fn
, NULL
);
624 m_pRMP
->m_UserState
= State_Running
;
625 return (PNR_OK
== m_pRMP
->m_pPlayer
->Begin()) ? S_OK
: E_FAIL
;
627 STDMETHODIMP
CRealMediaGraph::Pause()
629 m_pRMP
->m_UserState
= State_Paused
;
630 return (PNR_OK
== m_pRMP
->m_pPlayer
->Pause()) ? S_OK
: E_FAIL
;
632 STDMETHODIMP
CRealMediaGraph::Stop()
634 m_pRMP
->m_UserState
= State_Stopped
;
635 return (PNR_OK
== m_pRMP
->m_pPlayer
->Stop()) ? S_OK
: E_FAIL
;
637 STDMETHODIMP
CRealMediaGraph::GetState(LONG msTimeout
, OAFilterState
* pfs
)
639 return pfs
? *pfs
= m_pRMP
->m_State
, S_OK
: E_POINTER
;
643 STDMETHODIMP
CRealMediaGraph::GetDuration(LONGLONG
* pDuration
)
645 return pDuration
? *pDuration
= m_pRMP
->m_nDuration
, S_OK
: E_POINTER
;
647 STDMETHODIMP
CRealMediaGraph::GetCurrentPosition(LONGLONG
* pCurrent
)
649 return pCurrent
? *pCurrent
= m_pRMP
->m_nCurrent
, S_OK
: E_POINTER
;
651 STDMETHODIMP
CRealMediaGraph::SetPositions(LONGLONG
* pCurrent
, DWORD dwCurrentFlags
, LONGLONG
* pStop
, DWORD dwStopFlags
)
653 return (dwCurrentFlags
&AM_SEEKING_AbsolutePositioning
)
654 && (PNR_OK
== m_pRMP
->m_pPlayer
->Seek((ULONG
)(*pCurrent
/ 10000))) ? S_OK
: E_FAIL
;
658 STDMETHODIMP
CRealMediaGraph::SetWindowPosition(long Left
, long Top
, long Width
, long Height
)
661 m_pRMP
->SetWindowRect(CRect(CPoint(Left
, Top
), CSize(Width
, Height
)));
667 STDMETHODIMP
CRealMediaGraph::SetDestinationPosition(long Left
, long Top
, long Width
, long Height
)// {return E_NOTIMPL;}
669 m_pRMP
->SetDestRect(CRect(CPoint(Left
, Top
), CSize(Width
, Height
)));
672 STDMETHODIMP
CRealMediaGraph::GetVideoSize(long* pWidth
, long* pHeight
)
674 if(!pWidth
|| !pHeight
) return E_POINTER
;
675 *pWidth
= m_pRMP
->GetVideoSize().cx
;
676 *pHeight
= m_pRMP
->GetVideoSize().cy
;
681 STDMETHODIMP
CRealMediaGraph::put_Volume(long lVolume
)
683 if(!m_pRMP
->m_pVolume
) return E_UNEXPECTED
;
685 UINT16 volume
= (lVolume
== -10000) ? 0 : (int)pow(10.0, ((double)lVolume
)/5000+2);
686 volume
= max(min(volume
, 100), 0);
688 return PNR_OK
== m_pRMP
->m_pVolume
->SetVolume(volume
) ? S_OK
: E_FAIL
;
690 STDMETHODIMP
CRealMediaGraph::get_Volume(long* plVolume
)
692 if(!m_pRMP
->m_pVolume
) return E_UNEXPECTED
;
694 CheckPointer(plVolume
, E_POINTER
);
696 UINT16 volume
= m_pRMP
->m_pVolume
->GetVolume();
697 volume
= (int)((log10(1.0*volume
)-2)*5000);
698 volume
= max(min(volume
, 0), -10000);
706 STDMETHODIMP
CRealMediaGraph::QueryProgress(LONGLONG
* pllTotal
, LONGLONG
* pllCurrent
)
709 *pllCurrent
= m_pRMP
->m_unPercentComplete
> 0 ? m_pRMP
->m_unPercentComplete
: 100; // after seeking it drops to 0 and would show annoying "Buffering... (0%)" messages on the status line
714 STDMETHODIMP_(engine_t
) CRealMediaGraph::GetEngine() {return RealMedia
;}