📄 sinkctl.cpp
字号:
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnPostSeek
* Purpose:
* Called by client engine to inform the client that a seek has
* just occured. The render is informed the last time for the
* stream's time line before the seek, as well as the first new
* time for the stream's time line after the seek.
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnPostSeek( ULONG32 ulOldTime,
ULONG32 ulNewTime)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnPostSeek(ulOldTime,
ulNewTime);
}
else
{
AddToPendingList(pPlayerAdviseSink, ONPOSTSEEK,
ulOldTime, ulNewTime);
}
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnStop
* Purpose:
* Called by client engine to inform the client that a stop has
* just occured.
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnStop(void)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnStop();
}
else
{
AddToPendingList(pPlayerAdviseSink, ONSTOP);
}
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnPause
* Purpose:
* Called by client engine to inform the client that a pause has
* just occured. The render is informed the last time for the
* stream's time line before the pause.
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnPause(ULONG32 ulTime)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnPause(ulTime);
}
else
{
AddToPendingList(pPlayerAdviseSink, ONPAUSE, ulTime);
}
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnBegin
* Purpose:
* Called by client engine to inform the client that a begin or
* resume has just occured. The render is informed the first time
* for the stream's time line after the resume.
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnBegin(ULONG32 ulTime)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnBegin(ulTime);
}
else
{
AddToPendingList(pPlayerAdviseSink, ONBEGIN, ulTime);
}
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnBuffering
* Purpose:
* Called by client engine to inform the client that buffering
* of data is occuring. The render is informed of the reason for
* the buffering (start-up of stream, seek has occured, network
* congestion, etc.), as well as percentage complete of the
* buffering process.
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnBuffering(ULONG32 ulFlags,
UINT16 unPercentComplete)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnBuffering(ulFlags,
unPercentComplete);
}
else
{
AddToPendingList(pPlayerAdviseSink, ONBUFFERING,
ulFlags, (UINT32) unPercentComplete);
}
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXClientAdviseSink::OnContacting
* Purpose:
* Called by client engine to inform the client is contacting
* hosts(s).
*
*/
STDMETHODIMP CHXAdviseSinkControl::OnContacting(const char* pHostName)
{
CHXSimpleList::Iterator lSinkerator = m_pSinkList.Begin();
for (; lSinkerator != m_pSinkList.End(); ++lSinkerator)
{
PlayerAdviseSink* pPlayerAdviseSink =
(PlayerAdviseSink*) (*lSinkerator);
if (!m_pInterruptState->AtInterruptTime() ||
pPlayerAdviseSink->m_bInterruptSafe)
{
ProcessPendingRequests(pPlayerAdviseSink);
pPlayerAdviseSink->m_pAdviseSink->OnContacting(pHostName);
}
else
{
AddToPendingList(pPlayerAdviseSink, ONCONTACTING,
0, 0, (char*) pHostName);
}
}
return HXR_OK;
}
void CHXAdviseSinkControl::AdviseSinkCallback(void* pParam)
{
CHXAdviseSinkControl* pObj = (CHXAdviseSinkControl*)pParam;
if (pObj)
{
pObj->ProcessAllRequests();
}
}
/************************************************************************
/* CHXErrorSinkControl */
CHXErrorSinkControl::CHXErrorSinkControl() :
m_lRefCount (0)
,m_pPendingErrorList(NULL)
,m_pInterruptState(NULL)
,m_pScheduler(NULL)
,m_pErrorCallback(NULL)
{
m_pErrorCallback = new CHXGenericCallback((void*)this, (fGenericCBFunc)ErrorCallback);
m_pErrorCallback->AddRef();
}
CHXErrorSinkControl::~CHXErrorSinkControl()
{
Close();
}
STDMETHODIMP
CHXErrorSinkControl::AddErrorSink (
IHXErrorSink* pErrorSink,
const UINT8 unLowSeverity,
const UINT8 unHighSeverity)
{
if (pErrorSink)
{
PlayerErrorSink* pPlayerErrorSink = new PlayerErrorSink(pErrorSink, unLowSeverity, unHighSeverity);
m_pSinkList.AddTail(pPlayerErrorSink);
pErrorSink->AddRef();
}
return HXR_OK;
}
STDMETHODIMP
CHXErrorSinkControl::RemoveErrorSink(IHXErrorSink* pErrorSink)
{
PlayerErrorSink* pPlayerErrorSink;
CHXSimpleList::Iterator lIterator = m_pSinkList.Begin();
for (; lIterator != m_pSinkList.End(); ++lIterator)
{
pPlayerErrorSink = (PlayerErrorSink *) (*lIterator);
if (pPlayerErrorSink->m_pErrorSink == pErrorSink)
{
HX_RELEASE (pErrorSink);
LISTPOSITION pos = m_pSinkList.Find(pPlayerErrorSink);
m_pSinkList.RemoveAt(pos);
delete pPlayerErrorSink;
return HXR_OK;
}
}
return HXR_FAIL;
}
STDMETHODIMP
CHXErrorSinkControl::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IHXErrorSinkControl), (IHXErrorSinkControl*)this },
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXErrorSinkControl*)this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
STDMETHODIMP_ (ULONG32)
CHXErrorSinkControl::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHODIMP_ (ULONG32)
CHXErrorSinkControl::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
void
CHXErrorSinkControl::GetSeverityRange(IHXErrorSink* pErrorSink,
UINT8& unLowSeverity,
UINT8& unHighSeverity)
{
PlayerErrorSink* pPlayerErrorSink;
CHXSimpleList::Iterator lIterator = m_pSinkList.Begin();
for (; lIterator != m_pSinkList.End(); ++lIterator)
{
pPlayerErrorSink = (PlayerErrorSink *) (*lIterator);
if (pPlayerErrorSink->m_pErrorSink == pErrorSink)
{
unLowSeverity = pPlayerErrorSink->m_unLowSeverity;
unHighSeverity = pPlayerErrorSink->m_unHighSeverity;
break;
}
}
}
void
CHXErrorSinkControl::Init(IHXClientEngine* pEngine)
{
pEngine->QueryInterface(IID_IHXInterruptState,
(void**) &m_pInterruptState);
pEngine->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
}
void
CHXErrorSinkControl::Close()
{
PlayerErrorSink* pPlayerErrorSink;
CHXSimpleList::Iterator lIterator = m_pSinkList.Begin();
for (; lIterator != m_pSinkList.End(); ++lIterator)
{
pPlayerErrorSink = (PlayerErrorSink *) (*lIterator);
HX_RELEASE (pPlayerErrorSink->m_pErrorSink);
delete pPlayerErrorSink;
}
m_pSinkList.RemoveAll();
while (m_pPendingErrorList && m_pPendingErrorList->GetCount() > 0)
{
ErrorReport* pErrorReport =
(ErrorReport*) m_pPendingErrorList->RemoveHead();
delete pErrorReport;
}
if (m_pErrorCallback)
{
m_pScheduler->Remove(m_pErrorCallback->GetPendingCallback());
m_pErrorCallback->CallbackCanceled();
HX_RELEASE(m_pErrorCallback);
}
HX_DELETE(m_pPendingErrorList);
HX_RELEASE(m_pInterruptState);
HX_RELEASE(m_pScheduler);
}
HX_RESULT
CHXErrorSinkControl::ErrorOccurred( const UINT8 unSeverity,
const ULONG32 ulHXCode,
const ULONG32 ulUserCode,
const char* pUserString,
const char* pMoreInfoURL)
{
if (m_pInterruptState->AtInterruptTime())
{
if (!m_pPendingErrorList)
{
m_pPendingErrorList = new CHXSimpleList;
}
ErrorReport* pErrorReport = new ErrorReport;
pErrorReport->m_unSeverity = unSeverity;
pErrorReport->m_ulHXCode = ulHXCode;
pErrorReport->m_ulUserCode = ulUserCode;
if (pUserString && *pUserString)
{
pErrorReport->m_pUserString = new char[strlen(pUserString) + 1];
::strcpy(pErrorReport->m_pUserString, pUserString); /* Flawfinder: ignore */
}
if (pMoreInfoURL && *pMoreInfoURL)
{
pErrorReport->m_pMoreInfoURL = new char[strlen(pMoreInfoURL) + 1];
::strcpy(pErrorReport->m_pMoreInfoURL, pMoreInfoURL); /* Flawfinder: ignore */
}
m_pPendingErrorList->AddTail((void*) pErrorReport);
if (!m_pErrorCallback->GetPendingCallback())
{
m_pErrorCallback->CallbackScheduled(
m_pScheduler->RelativeEnter(m_pErrorCallback, 0));
}
return HXR_OK;
}
ReportPendingErrors();
CallReport(unSeverity,
ulHXCode,
ulUserCode,
pUserString,
pMoreInfoURL);
return HXR_OK;
}
void
CHXErrorSinkControl::ReportPendingErrors()
{
if (m_pErrorCallback)
{
m_pScheduler->Remove(m_pErrorCallback->GetPendingCallback());
m_pErrorCallback->CallbackCanceled();
}
while (m_pPendingErrorList && m_pPendingErrorList->GetCount() > 0)
{
ErrorReport* pErrorReport =
(ErrorReport*) m_pPendingErrorList->RemoveHead();
CallReport(pErrorReport->m_unSeverity,
pErrorReport->m_ulHXCode,
pErrorReport->m_ulUserCode,
pErrorReport->m_pUserString,
pErrorReport->m_pMoreInfoURL);
delete pErrorReport;
}
}
HX_RESULT
CHXErrorSinkControl::CallReport
(
const UINT8 unSeverity,
HX_RESULT ulHXCode,
const ULONG32 ulUserCode,
const char* pUserString,
const char* pMoreInfoURL
)
{
CHXSimpleList::Iterator ndxSink;
for (ndxSink = m_pSinkList.Begin();
ndxSink != m_pSinkList.End(); ++ndxSink)
{
PlayerErrorSink* pPlayerErrorSink =
(PlayerErrorSink*) (*ndxSink);
// error-reporting based on its severity
if (unSeverity >= pPlayerErrorSink->m_unLowSeverity &&
unSeverity <= pPlayerErrorSink->m_unHighSeverity)
// unSeverity <= pPlayerErrorSink->m_unHighSeverity && !m_pAltURLs->GetCount())
{
pPlayerErrorSink->m_pErrorSink->ErrorOccurred(unSeverity, ulHXCode,
ulUserCode, pUserString, pMoreInfoURL);
}
}
return HXR_OK;
}
void CHXErrorSinkControl::ErrorCallback(void* pParam)
{
CHXErrorSinkControl* pObj = (CHXErrorSinkControl*)pParam;
if (pObj)
{
pObj->ReportPendingErrors();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -