📄 hxplay.cpp
字号:
HXPlayer::PausePlayer(BOOL bNotifyTLC /* = TRUE*/)
{
HX_RESULT theErr = HXR_OK;
if (m_bIsDone)
{
return HXR_UNEXPECTED;
}
if (m_bPaused)
{
return HXR_OK;
}
m_bPaused = TRUE;
if (m_bIsLive && !(m_bRecordServiceEnabled && m_pRecordService))
{
m_bLiveSeekToBeDone = TRUE;
m_ulLiveSeekTime = m_pAudioPlayer->GetCurrentPlayBackTime();
m_ulTimeOfPause = HX_GET_TICKCOUNT();
}
m_bIsPlaying = FALSE;
m_bTimelineToBeResumed = TRUE;
m_pAudioPlayer->Pause();
CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
{
SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
theErr = pSourceInfo->Pause();
}
/* Send OnPause to advice sink ONLY if it is not an internal Pause */
if (bNotifyTLC && !m_bInternalPauseResume && !m_bInternalReset && m_pAdviseSink)
{
m_pAdviseSink->OnPause(m_ulCurrentPlayTime);
}
return (theErr);
}
/************************************************************************
* Method:
* IHXPlayer::Seek
* Purpose:
* Tell the player to seek in the playback timeline of all its
* sources.
*
*/
STDMETHODIMP HXPlayer::Seek(ULONG32 ulTime)
{
HX_RESULT theErr = HXR_OK;
m_bCoreLocked = TRUE;
m_pCoreMutex->Lock();
theErr = SeekPlayer(ulTime);
m_pCoreMutex->Unlock();
m_bCoreLocked = FALSE;
return theErr;
}
HX_RESULT
HXPlayer::SeekPlayer(ULONG32 ulTime)
{
HX_RESULT theErr = HXR_OK;
if (m_bIsDone)
{
return HXR_UNEXPECTED;
}
// do not allow seeking till we have been initialized
if (!m_bInitialized)
{
return HXR_NOT_INITIALIZED;
}
/* we do allow internal seek (done during resume after live pause)*/
if ((m_bIsLive && !m_bLiveSeekToBeDone && !(m_bRecordServiceEnabled && m_pRecordService)) ||
!AreAllSourcesSeekable())
{
/* Add error code for HXR_OPERATION_NOT_ALLOWED*/
return HXR_FAILED;
}
/* Someone called Seek without calling Pause, So we will have to call
* Pause and Resume internally
*/
if (!m_bPaused)
{
m_bInternalPauseResume = TRUE;
PausePlayer();
}
#if defined(HELIX_FEATURE_NEXTGROUPMGR)
/* Stop prefetching */
if (m_pNextGroupManager->GetNumSources() > 0)
{
m_pNextGroupManager->StopPreFetch();
m_bLastGroup = FALSE;
m_bNextGroupStarted = FALSE;
}
#endif /* HELIX_FEATURE_NEXTGROUPMGR */
m_ulTimeBeforeSeek = m_pAudioPlayer->GetCurrentPlayBackTime();
m_ulTimeAfterSeek = ulTime;
UpdateCurrentPlayTime(ulTime);
m_pAudioPlayer->Seek(ulTime);
CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
for (; !theErr && ndxSource != m_pSourceMap->End(); ++ndxSource)
{
SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
pSourceInfo->Seek(ulTime);
}
if (m_pAdviseSink)
{
m_pAdviseSink->OnPreSeek(m_ulTimeBeforeSeek, m_ulTimeAfterSeek);
}
// change the state of buffering to seek
if (m_bIsLive)
{
m_BufferingReason = BUFFERING_LIVE_PAUSE;
}
else
{
m_BufferingReason = BUFFERING_SEEK;
}
/* Send all pre-seek events to the renderers */
SendPreSeekEvents();
ndxSource = m_pSourceMap->Begin();
for (; !theErr && ndxSource != m_pSourceMap->End();)
{
SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
HXSource * pSource = pSourceInfo->m_pSource;
// since the map index could be screwed up by the removing of
// the current node in AdjustSeekOnRepeatedSource()
++ndxSource;
/* pSource should never be NULL */
HX_ASSERT(pSource);
if (pSourceInfo->m_bSeekPending || !pSourceInfo->IsInitialized())
{
continue;
}
/* This will pump all pre-seek packets to the renderer(s) */
if (pSourceInfo->m_pPeerSourceInfo)
{
theErr = AdjustSeekOnRepeatedSource(pSourceInfo, ulTime);
}
else
{
theErr = pSource->DoSeek(ulTime);
}
}
m_b100BufferingToBeSent = TRUE;
// reset the player state
UpdateSourceActive();
m_bIsDone = FALSE;
if (!theErr)
{
if (m_bInternalPauseResume)
{
theErr = Begin();
m_bInternalPauseResume = FALSE;
}
else
{
/* Start pre-fetch */
theErr = StartDownload();
}
}
return (theErr);
}
/************************************************************************
* Method:
* IHXPlayer::GetSourceCount
* Purpose:
* Returns the current number of source instances supported by
* this player instance.
*/
STDMETHODIMP_(UINT16) HXPlayer::GetSourceCount()
{
/* We may have stopped the sources but not removed from the SourceMap
* since we need to keep the renderers active till the next URL is
* opened. In this case, report the current number of active sources
* as zero.
*/
if (m_bCloseAllRenderersPending)
{
return 0;
}
else
{
return (UINT16)m_pSourceMap->GetCount();
}
}
/************************************************************************
* Method:
* IHXPlayer::GetSource
* Purpose:
* Returns the Nth source instance supported by this player.
*/
STDMETHODIMP HXPlayer::GetSource
(
UINT16 nIndex,
REF(IUnknown*) pUnknown
)
{
pUnknown = NULL;
if (m_bCloseAllRenderersPending || nIndex >= m_pSourceMap->GetCount())
{
return HXR_INVALID_PARAMETER;
}
CHXMapPtrToPtr::Iterator ndxSource = m_pSourceMap->Begin();
for (UINT16 i = 0; i < nIndex; i++)
{
++ndxSource;
}
SourceInfo* pSourceInfo = (SourceInfo*)(*ndxSource);
HX_ASSERT(pSourceInfo);
HXSource* pSource = pSourceInfo->m_pSource;
if(!pSource)
{
pUnknown = NULL;
return HXR_UNEXPECTED;
}
return pSource ? pSource->QueryInterface(IID_IUnknown,(void**)&pUnknown) : HXR_FAIL;
}
/************************************************************************
* Method:
* IHXPlayer::GetClientContext
* Purpose:
* Called by the get the client context for this player. This is
* traditionally to determine called by top level client application.
*/
STDMETHODIMP HXPlayer::GetClientContext
(
REF(IUnknown*) pUnknown
)
{
pUnknown = m_pClient;
if (m_pClient)
{
m_pClient->AddRef();
}
return HXR_OK;
}
/************************************************************************
* Method:
* IHXPlayer::SetClientContext
* Purpose:
* Called by the client to install itself as the provider of client
* services to the core. This is traditionally called by the top
* level client application.
*/
STDMETHODIMP HXPlayer::SetClientContext(IUnknown* pUnknown)
{
if (m_pClient) return HXR_UNEXPECTED;
if (!pUnknown) return HXR_UNEXPECTED;
m_pClient = pUnknown;
m_pClient->AddRef();
/* Override Default objects */
#if defined(HELIX_FEATURE_PREFERENCES)
IHXPreferences* pPreferences = 0;
if (HXR_OK == m_pClient->QueryInterface(IID_IHXPreferences, (void**) &pPreferences) ||
HXR_OK == m_pEngine->QueryInterface(IID_IHXPreferences, (void**) &pPreferences))
{
HX_RELEASE(m_pPreferences);
m_pPreferences = pPreferences;
}
#endif /* HELIX_FEATURE_PREFERENCES */
#if defined(HELIX_FEATURE_HYPER_NAVIGATE)
IHXHyperNavigate* pHyperNavigate = NULL;
IHXHyperNavigateWithContext* pHyperNavigateWithContext = NULL;
m_pClient->QueryInterface(IID_IHXHyperNavigateWithContext,
(void**) &pHyperNavigateWithContext);
m_pClient->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate);
if (pHyperNavigate == NULL)
{
m_pEngine->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate);
}
HX_ASSERT(pHyperNavigate != NULL);
if (pHyperNavigate || pHyperNavigateWithContext)
{
HX_ASSERT(m_pHyperNavigate == NULL);
HX_RELEASE(m_pHyperNavigate);
//
// Create new hypernaviate interface that knows how to interpret commands.
//
PlayerHyperNavigate* pPlayerHyperNavigate = new PlayerHyperNavigate;
// override the default hypernavigate interface with one that can interpret commands.
pPlayerHyperNavigate->AddRef();
pPlayerHyperNavigate->Init((IHXPlayer*)this, pHyperNavigate, pHyperNavigateWithContext);
m_pHyperNavigate = pPlayerHyperNavigate;
// free memory
HX_RELEASE(pHyperNavigate);
HX_RELEASE(pHyperNavigateWithContext);
}
#endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
#if defined(HELIX_FEATURE_VIDEO)
IHXSiteSupplier* pSiteSupplier = 0;
if (HXR_OK == m_pClient->QueryInterface(IID_IHXSiteSupplier, (void**) &pSiteSupplier))
{
HX_RELEASE(m_pSiteSupplier);
m_pSiteSupplier = pSiteSupplier;
}
#endif /* HELIX_FEATURE_VIDEO */
m_pClient->QueryInterface(IID_IHXClientRequestSink, (void**) &m_pClientRequestSink);
/* For load testing, we have ASM Manager on a per player basis */
#if defined(HELIX_FEATURE_ASM)
BOOL bLoadTest = FALSE;
ReadPrefBOOL(m_pPreferences, "LoadTest", bLoadTest);
if (bLoadTest)
{
HX_ASSERT(m_pASM == NULL);
m_pASM = CreateBandwidthManager();
if (m_pASM)
{
m_pASM->AddRef();
HX_RELEASE(m_pBandwidthMgr);
m_pASM->QueryInterface(IID_IHXBandwidthManager,
(void**) &m_pBandwidthMgr);
}
}
#endif /* HELIX_FEATURE_ASM */
return HXR_OK;
}
/************************************************************************
* Method:
* HXPlayer::Init
* Purpose:
* Get the interface to the client engine object of which the player
* is a part of.
*
*/
STDMETHODIMP HXPlayer::Init(IHXClientEngine* pEngine,
UINT32 unRegistryID,
CHXAudioPlayer* pAudioPlayer)
{
HX_RESULT theErr = HXR_OK;
IHXBuffer* pPlayerRegName = NULL;
m_pEngine = (HXClientEngine *) pEngine;
m_pAudioPlayer = pAudioPlayer;
m_pCoreMutex = m_pEngine->GetCoreMutex();
m_pEngine->m_pPlugin2Handler->QueryInterface(IID_IHXPlugin2Handler,
(void**)&m_pPlugin2Handler);
if (m_pEngine)
{
m_pEngine->AddRef();
#if defined(HELIX_FEATURE_SINKCONTROL)
if (m_pAdviseSink)
{
m_pAdviseSink->Init(m_pEngine);
}
if (m_pErrorSinkControl)
{
m_pErrorSinkControl->Init(m_pEngine);
}
#endif /* HELIX_FEATURE_SINKCONTROL */
theErr = m_pEngine->QueryInterface(IID_IHXScheduler,
(void**) &m_pScheduler);
#if defined(HELIX_FEATURE_ASM)
m_pEngine->QueryInterface(IID_IHXBandwidthManager,
(void**) &m_pBandwidthMgr);
#endif /* HELIX_FEATURE_ASM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -