📄 hxplay.cpp
字号:
m_pEngine->QueryInterface(IID_IHXClientViewSource,
(void**)&m_pClientViewSource);
m_pEngine->QueryInterface(IID_IHXClientViewRights,
(void**)&m_pClientViewRights);
m_pEngine->QueryInterface(IID_IHXPreferredTransportManager,
(void**)&m_pPreferredTransportManager);
m_pEngine->QueryInterface(IID_IHXNetInterfaces,
(void**)&m_pNetInterfaces);
#if defined(HELIX_FEATURE_REGISTRY)
// create registry entries
if (HXR_OK != m_pEngine->QueryInterface(IID_IHXRegistry, (void**)&m_pRegistry))
{
m_pRegistry = NULL;
}
else
#endif /* HELIX_FEATURE_REGISTRY */
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
char szRegName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
m_pStats = new PLAYER_STATS(m_pRegistry, unRegistryID);
m_pRegistry->AddInt("Statistics.StreamSwitchOccured", 0);
if (m_pRegistry &&
HXR_OK == m_pRegistry->GetPropName(unRegistryID, pPlayerRegName))
{
SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.Repeat", pPlayerRegName->GetBuffer());
m_ulRepeatedRegistryID = m_pRegistry->AddComp(szRegName);
SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.NextGroup", pPlayerRegName->GetBuffer());
m_ulNextGroupRegistryID = m_pRegistry->AddComp(szRegName);
}
HX_RELEASE(pPlayerRegName);
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
#if defined(HELIX_FEATURE_REGISTRY) && defined(HELIX_FEATURE_MASTERTAC)
// create master TAC object
UINT32 playerID = 0;
GetID(playerID);
m_pMasterTAC->SetRegistry(m_pRegistry,playerID);
#endif /* HELIX_FEATURE_REGISTRY && HELIX_FEATURE_MASTERTAC*/
}
m_pCookies = m_pEngine->GetCookies();
}
else
{
theErr = HXR_INVALID_PARAMETER;
}
if (m_pAudioPlayer && theErr == HXR_OK)
{
m_pAudioPlayer->AddRef();
theErr = m_pAudioPlayer->Init((IUnknown*) (IHXPlayer*)this);
}
#if defined(HELIX_FEATURE_NEXTGROUPMGR)
if (m_pNextGroupManager)
{
m_pNextGroupManager->Init();
}
#endif /* HELIX_FEATURE_NEXTGROUPMGR */
return theErr;
}
/************************************************************************
* Method:
* IHXPlayer::IsDone
* Purpose:
* Ask the player if it is done with the current presentation
*
*/
STDMETHODIMP_ (BOOL) HXPlayer::IsDone(void)
{
return m_bIsPresentationDone;
}
/************************************************************************
* Method:
* IHXPlayer::IsLive
* Purpose:
* Ask the player whether it contains the live source
*
*/
STDMETHODIMP_ (BOOL) HXPlayer::IsLive(void)
{
return m_bIsLive;
}
/************************************************************************
* Method:
* IHXPlayer::GetCurrentPlayTime
* Purpose:
* Get the current time on the Player timeline
*
*/
STDMETHODIMP_ (ULONG32) HXPlayer::GetCurrentPlayTime(void)
{
HX_RESULT theErr = HXR_OK;
m_bCoreLocked = TRUE;
m_pCoreMutex->Lock();
theErr = m_pAudioPlayer->GetCurrentPlayBackTime();
m_pCoreMutex->Unlock();
m_bCoreLocked = FALSE;
return theErr;
}
/************************************************************************
* Method:
* IHXPlayer::AddAdviseSink
* Purpose:
* Call this method to add a client advise sink.
*
*/
STDMETHODIMP HXPlayer::AddAdviseSink (IHXClientAdviseSink* pAdviseSink)
{
#if defined(HELIX_FEATURE_SINKCONTROL)
if (m_pAdviseSink)
{
return m_pAdviseSink->AddAdviseSink(pAdviseSink);
}
else
#endif /* HELIX_FEATURE_SINKCONTROL */
{
return HXR_NOTIMPL;
}
}
/************************************************************************
* Method:
* IHXPlayer::RemoveAdviseSink
* Purpose:
* Call this method to remove a client advise sink.
*/
STDMETHODIMP HXPlayer::RemoveAdviseSink(IHXClientAdviseSink* pAdviseSink)
{
HX_RESULT theErr = HXR_OK;
m_bCoreLocked = TRUE;
m_pCoreMutex->Lock();
#if defined(HELIX_FEATURE_SINKCONTROL)
if (m_pAdviseSink)
{
theErr = m_pAdviseSink->RemoveAdviseSink(pAdviseSink);
}
#endif /* HELIX_FEATURE_SINKCONTROL */
m_pCoreMutex->Unlock();
m_bCoreLocked = FALSE;
return theErr;
}
ULONG32 HXPlayer::GetInst(void)
{
#if defined(_WIN32)
return (ULONG32)GetModuleHandle(NULL);
#elif defined(_WIN16)
return (ULONG32)g_hInstance;
#else
return 0;
#endif
}
HX_RESULT
HXPlayer::SetStatsGranularity
(
ULONG32 ulGranularity
)
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
m_ulStatsGranularity = ulGranularity;
if (m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS == m_ulStatsGranularity)
{
m_pUpdateStatsCallback->m_bIsCallbackPending = FALSE;
m_pScheduler->Remove(m_pUpdateStatsCallback->m_PendingHandle);
m_pUpdateStatsCallback->m_PendingHandle = 0;
}
else if (!m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS != m_ulStatsGranularity)
{
UpdateStatistics();
}
return HXR_OK;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
STDMETHODIMP
HXPlayer::ClosePresentation()
{
m_bCoreLocked = TRUE;
m_pCoreMutex->Lock();
// This stops the player if it is playing and cleans up the layout.
StopPlayer(END_STOP);
CloseAllRenderers(0);
#if defined(HELIX_FEATURE_VIDEO)
if (m_pSiteSupplier && !m_bBeginChangeLayoutTobeCalled)
{
m_bBeginChangeLayoutTobeCalled = TRUE;
m_pSiteSupplier->DoneChangeLayout();
}
#endif /* HELIX_FEATURE_VIDEO */
m_pCoreMutex->Unlock();
m_bCoreLocked = FALSE;
return HXR_OK;
}
STDMETHODIMP
HXPlayer::SetMinimumPreroll(UINT32 ulMinPreroll)
{
HX_RESULT hr = HXR_OK;
m_ulMinimumTotalPreroll = ulMinPreroll;
return hr;
}
STDMETHODIMP
HXPlayer::GetMinimumPreroll(REF(UINT32) ulMinPreroll)
{
HX_RESULT hr = HXR_OK;
ulMinPreroll = m_ulMinimumTotalPreroll;
return hr;
}
HX_RESULT
HXPlayer::UpdateStatistics(void)
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
BOOL bUpdate = FALSE;
ULONG32 ulPlayerTotal = 0;
ULONG32 ulPlayerReceived = 0;
ULONG32 ulPlayerNormal = 0;
ULONG32 ulPlayerRecovered = 0;
ULONG32 ulPlayerDuplicate = 0;
ULONG32 ulPlayerOutOfOrder = 0;
ULONG32 ulPlayerLost = 0;
ULONG32 ulPlayerLate = 0;
UINT32 ulPlayerTotal30 = 0;
UINT32 ulPlayerLost30 = 0;
ULONG32 ulPlayerResendRequested = 0;
ULONG32 ulPlayerResendReceived = 0;
ULONG32 ulPlayerBandwidth = 0;
ULONG32 ulPlayerCurBandwidth = 0;
ULONG32 ulPlayerAvgBandwidth = 0;
INT32 lAvgLatency = 0;
INT32 lHighLatency = 0;
INT32 lLowLatency = 0xFFFF;
ULONG32 ulStreamNumber = 0;
SourceInfo* pSourceInfo = NULL;
RendererInfo* pRenderInfo = NULL;
IHXStatistics* pStatistics = NULL;
UINT16 uBufferingMode = 0;
CHXMapPtrToPtr::Iterator ndxSource;
CHXMapLongToObj::Iterator ndxRend;
if (!m_bInitialized || m_bPaused)
{
goto exit;
}
// update statistics
ndxSource = m_pSourceMap->Begin();
for (; ndxSource != m_pSourceMap->End(); ++ndxSource)
{
pSourceInfo = (SourceInfo*) (*ndxSource);
// notify the renderer to update its statistics
ndxRend = pSourceInfo->m_pRendererMap->Begin();
for (; ndxRend != pSourceInfo->m_pRendererMap->End(); ++ndxRend)
{
pRenderInfo = (RendererInfo*)(*ndxRend);
if (pRenderInfo->m_pRenderer &&
HXR_OK == pRenderInfo->m_pRenderer->
QueryInterface(IID_IHXStatistics,
(void**)&pStatistics))
{
pStatistics->UpdateStatistics();
pStatistics->Release();
pStatistics = NULL;
}
}
// update each source
if (pSourceInfo->m_pSource &&
HXR_OK == pSourceInfo->m_pSource->UpdateStatistics())
{
ulPlayerTotal += pSourceInfo->m_pSource->m_pStats->m_pTotal->GetInt();
ulPlayerReceived += pSourceInfo->m_pSource->m_pStats->m_pReceived->GetInt();
ulPlayerNormal += pSourceInfo->m_pSource->m_pStats->m_pNormal->GetInt();
ulPlayerRecovered += pSourceInfo->m_pSource->m_pStats->m_pRecovered->GetInt();
ulPlayerDuplicate += pSourceInfo->m_pSource->m_pStats->m_pDuplicate->GetInt();
ulPlayerOutOfOrder += pSourceInfo->m_pSource->m_pStats->m_pOutOfOrder->GetInt();
ulPlayerLost += pSourceInfo->m_pSource->m_pStats->m_pLost->GetInt();
ulPlayerLate += pSourceInfo->m_pSource->m_pStats->m_pLate->GetInt();
ulPlayerResendRequested += pSourceInfo->m_pSource->m_pStats->m_pResendRequested->GetInt();
ulPlayerResendReceived += pSourceInfo->m_pSource->m_pStats->m_pResendReceived->GetInt();
ulPlayerTotal30 += pSourceInfo->m_pSource->m_pStats->m_pTotal30->GetInt();
ulPlayerLost30 += pSourceInfo->m_pSource->m_pStats->m_pLost30->GetInt();
ulPlayerBandwidth += pSourceInfo->m_pSource->m_pStats->m_pClipBandwidth->GetInt();
ulPlayerCurBandwidth += pSourceInfo->m_pSource->m_pStats->m_pCurBandwidth->GetInt();
ulPlayerAvgBandwidth += pSourceInfo->m_pSource->m_pStats->m_pAvgBandwidth->GetInt();
lAvgLatency += pSourceInfo->m_pSource->m_pStats->m_pAvgLatency->GetInt();
if (lHighLatency < pSourceInfo->m_pSource->m_pStats->m_pHighLatency->GetInt())
{
lHighLatency = pSourceInfo->m_pSource->m_pStats->m_pHighLatency->GetInt();
}
if (lLowLatency > pSourceInfo->m_pSource->m_pStats->m_pLowLatency->GetInt())
{
lLowLatency = pSourceInfo->m_pSource->m_pStats->m_pLowLatency->GetInt();
}
if (uBufferingMode < (UINT16) pSourceInfo->m_pSource->m_pStats->m_pBufferingMode->GetInt())
{
uBufferingMode = (UINT16) pSourceInfo->m_pSource->m_pStats->m_pBufferingMode->GetInt();
}
if (pSourceInfo->m_pSource->m_pStatsManager)
{
pSourceInfo->m_pSource->m_pStatsManager->Copy();
}
}
}
bUpdate = SetIntIfNecessary(m_pStats->m_pTotal, (INT32)ulPlayerTotal);
bUpdate |= SetIntIfNecessary(m_pStats->m_pReceived, (INT32)ulPlayerReceived);
bUpdate |= SetIntIfNecessary(m_pStats->m_pNormal, (INT32)ulPlayerNormal);
bUpdate |= SetIntIfNecessary(m_pStats->m_pRecovered, (INT32)ulPlayerRecovered);
bUpdate |= SetIntIfNecessary(m_pStats->m_pDuplicate, (INT32)ulPlayerDuplicate);
bUpdate |= SetIntIfNecessary(m_pStats->m_pOutOfOrder, (INT32)ulPlayerOutOfOrder);
bUpdate |= SetIntIfNecessary(m_pStats->m_pLost, (INT32)ulPlayerLost);
bUpdate |= SetIntIfNecessary(m_pStats->m_pLate, (INT32)ulPlayerLate);
bUpdate |= SetIntIfNecessary(m_pStats->m_pTotal30, (INT32)ulPlayerTotal30);
bUpdate |= SetIntIfNecessary(m_pStats->m_pLost30, (INT32)ulPlayerLost30);
bUpdate |= SetIntIfNecessary(m_pStats->m_pResendRequested, (INT32)ulPlayerResendRequested);
bUpdate |= SetIntIfNecessary(m_pStats->m_pResendReceived, (INT32)ulPlayerResendReceived);
bUpdate |= SetIntIfNecessary(m_pStats->m_pClipBandwidth, (INT32)ulPlayerBandwidth);
bUpdate |= SetIntIfNecessary(m_pStats->m_pCurBandwidth, (INT32)ulPlayerCurBandwidth);
bUpdate |= SetIntIfNecessary(m_pStats->m_pAvgBandwidth, (INT32)ulPlayerAvgBandwidth);
bUpdate |= SetIntIfNecessary(m_pStats->m_pAvgLatency, (INT32)lAvgLatency);
bUpdate |= SetIntIfNecessary(m_pStats->m_pHighLatency, (INT32)lHighLatency);
bUpdate |= SetIntIfNecessary(m_pStats->m_pLowLatency, (INT32)lLowLatency);
bUpdate |= SetIntIfNecessary(m_pStats->m_pBufferingMode, (INT32)uBufferingMode);
if (bUpdate || m_bForceStatsUpdate)
{
if (m_pAdviseSink)
{
m_pAdviseSink->OnStatisticsChanged();
}
m_bForceStatsUpdate = FALSE;
}
exit:
if (!m_pUpdateStatsCallback->m_bIsCallbackPending && ALLFS != m_ulStatsGranularity)
{
m_pUpdateStatsCallback->m_bIsCallbackPending = TRUE;
m_pUpdateStatsCallback->m_PendingHandle = m_pScheduler->RelativeEnter(m_pUpdateStatsCallback,
m_ulStatsGranularity);
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
return HXR_OK;
}
HX_RESULT
HXPlayer::SetupAudioPlayer()
{
HX_RESULT theErr = HXR_OK;
HX_ASSERT(m_bInitialized);
#if defined(THREADS_SUPPORTED) && !defined(_MAC_UNIX)
if (m_bUseCoreThread && !m_pEngine->AtInterruptTime())
{
HX_ASSERT(m_pSetupCallback->GetPendingCallback() == 0);
if (!m_pSetupCallback->GetPendingCallback())
{
m_pSetupCallback->CallbackScheduled(
m_pScheduler->RelativeEnter(m_pSetupCallback, 0));
}
return HXR_OK;
}
#endif /*_WIN32*/
m_bSetupToBeDone = FALSE;
PrepareAudioPlayer();
#if defined(THREADS_SUPPORTED) && !defined(_MAC_UNIX)
if (m_bUseCoreThread && m_pEngine->AtInterruptTime())
{
m_pAudioPlayer->UseCoreThread();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -