📄 hxcleng.cpp
字号:
{
int s=0;
//XXXgfw no need for these selects if we aren't doing network i/o.
//Of course, it would be nice for those using this instead of a sleep
//to time their callbacks back into the core, that it works...
//I guess we can just turn this into a sleep for timeval seconds if
//we are not doing any network playback. Of course, if you have a
//threaded core it won't hurt to much either way.
#if defined(HELIX_FEATURE_PLAYBACK_NET)
fd_set real_readfds;
fd_set real_writefds;
fd_set real_exceptfds;
struct timeval tv;
static unix_TCP* un = 0;
if(!un)
{
un = new unix_TCP;
}
if(readfds)
{
real_readfds = *readfds;
}
else
{
FD_ZERO(&real_readfds);
}
if(writefds)
{
real_writefds = *writefds;
}
else
{
FD_ZERO(&real_writefds);
}
if(exceptfds)
{
real_exceptfds = *exceptfds;
}
else
{
FD_ZERO(&real_exceptfds);
}
if(timeout)
{
tv = *timeout;
}
else
{
/* If no timeout was passed in, and no player adds a timeout,
we will not pass a timeout to select()
*/
tv.tv_sec = -1;
tv.tv_usec = -1;
}
/* It is assumed that the networking code does not care about select
timeouts, so it is only asked for socket info.
*/
un->add_select((int*)&n, &real_readfds, &real_writefds, &real_exceptfds);
CHXSimpleList::Iterator lIterator = m_PlayerList.Begin();
LISTPOSITION lPosition = m_PlayerList.GetHeadPosition();
HXPlayer* pPlayer;
while (lPosition != NULL)
{
pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
pPlayer->CollectSelectInfo(&n,
&real_readfds,
&real_writefds,
&real_exceptfds,
&tv);
}
for(lIterator = m_select_callbacks->Begin();
lIterator != m_select_callbacks->End();
++lIterator)
{
CHXSelectCallback* scb = (CHXSelectCallback*)(*lIterator);
if(scb->m_flags & PNAIO_READ)
FD_SET(scb->m_lFileDescriptor, &real_readfds);
if(scb->m_flags & PNAIO_WRITE)
FD_SET(scb->m_lFileDescriptor, &real_writefds);
if(scb->m_flags & PNAIO_EXCEPTION)
FD_SET(scb->m_lFileDescriptor, &real_exceptfds);
if(scb->m_lFileDescriptor > n)
n = scb->m_lFileDescriptor + 1;
}
UINT32 ulEventTime = 0;
if(m_pScheduler)
{
if(m_pScheduler->GetNextEventDueTimeDiff(ulEventTime))
{
if(ulEventTime < ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)))
{
tv.tv_sec = ulEventTime / 1000;
tv.tv_usec = (ulEventTime % 1000) * 1000;
}
}
}
if(timeout || (tv.tv_sec >= 0 && tv.tv_usec >= 0))
s = ::select(n, &real_readfds, &real_writefds, &real_exceptfds, &tv);
else
s = ::select(n, &real_readfds, &real_writefds, &real_exceptfds, 0);
un->process_select(n, &real_readfds, &real_writefds, &real_exceptfds);
lIterator = m_PlayerList.Begin();
lPosition = m_PlayerList.GetHeadPosition();
while (lPosition != NULL)
{
pPlayer = (HXPlayer*) m_PlayerList.GetNext(lPosition);
pPlayer->ProcessSelect(&n,
&real_readfds,
&real_writefds,
&real_exceptfds,
&tv);
}
for(lIterator = m_select_callbacks->Begin();
lIterator != m_select_callbacks->End();
++lIterator)
{
CHXSelectCallback* scb = (CHXSelectCallback*)(*lIterator);
if((scb->m_flags & PNAIO_READ) &&
FD_ISSET(scb->m_lFileDescriptor, &real_readfds))
{
scb->m_pCallback->Func();
}
if((scb->m_flags & PNAIO_WRITE) &&
FD_ISSET(scb->m_lFileDescriptor, &real_writefds))
{
scb->m_pCallback->Func();
}
if((scb->m_flags & PNAIO_EXCEPTION) &&
FD_ISSET(scb->m_lFileDescriptor, &real_exceptfds))
{
scb->m_pCallback->Func();
}
}
ulEventTime = 0;
if(m_pScheduler)
{
if(m_pScheduler->GetNextEventDueTimeDiff(ulEventTime))
{
if(ulEventTime == 0)
{
Timeline::CallAllTimeSyncs();
}
}
}
#else
s = ::select(0, NULL, NULL, NULL, timeout);
#endif //HELIX_FEATURE_PLAYBACK_NET
return s;
}
STDMETHODIMP
HXClientEngine::Add(IHXCallback* pCallback,
INT32 lFileDescriptor,
UINT32 ulFlags)
{
CHXSelectCallback* scb = new CHXSelectCallback(pCallback,
lFileDescriptor,
ulFlags);
m_select_callbacks->AddTail(scb);
return HXR_OK;
}
STDMETHODIMP
HXClientEngine::Remove(INT32 lFileDescriptor,
UINT32 ulFlags)
{
CHXSimpleList::Iterator i;
CHXSelectCallback* scb;
for(i = m_select_callbacks->Begin();
i != m_select_callbacks->End();
++i)
{
scb = (CHXSelectCallback*)(*i);
if(scb->m_lFileDescriptor == lFileDescriptor &&
scb->m_flags == ulFlags)
{
m_select_callbacks->RemoveAt(m_select_callbacks->Find(scb));
delete scb;
return HXR_OK;
}
}
return HXR_FAIL;
}
#endif /* _UNIX */
/*
* IHXMimeTypeMapper methods
*/
STDMETHODIMP HXClientEngine::MapFromExtToMime
(
const char* /*IN*/ pExtension,
REF(const char*) /*OUT*/ pMimeType
)
{
HX_RESULT hr = HXR_OK;
#if defined(HELIX_FEATURE_PLUGINHANDLER2)
if (!m_pPlugin2Handler)
{
hr = HXR_FAIL;
goto cleanup;
}
// try to map from the normal file format plugins
UINT32 unPluginIndex;
IHXValues* pValues;
IHXBuffer* pBuffer;
// Note that the ref count of the buffer is not increased this is bad. But should be OK in
// this case.
if (HXR_OK == m_pPlugin2Handler->FindIndexUsingStrings(PLUGIN_CLASS, PLUGIN_FILEFORMAT_TYPE,
PLUGIN_FILEEXTENSIONS, (char*)pExtension, NULL, NULL, unPluginIndex))
{
m_pPlugin2Handler->GetPluginInfo(unPluginIndex, pValues);
if (HXR_OK == pValues->GetPropertyCString(PLUGIN_FILEMIMETYPES, pBuffer))
{
pMimeType = (const char*)pBuffer->GetBuffer();
pBuffer->Release();
}
pValues->Release();
}
cleanup:
return hr;
#else
return HXR_FAIL;
#endif /* HELIX_FEATURE_PLUGINHANDLER2 */
}
/*
* IHXClientEngineSetup methods
*/
/************************************************************************
* Method:
* IHXClientEngineSetup::Setup
* Purpose:
* Top level clients use this interface to over-ride certain basic
* interfaces are: IHXPreferences, IHXHyperNavigate
*/
STDMETHODIMP HXClientEngine::Setup(IUnknown* pContext)
{
if (!pContext || m_bInitialized)
return HXR_UNEXPECTED;
/* Make sure this is called before any player is created */
HX_ASSERT(GetPlayerCount() == 0);
if (GetPlayerCount() > 0)
{
return HXR_UNEXPECTED;
}
/* Override Default objects */
IHXCommonClassFactory* pFactory = 0;
if (HXR_OK == pContext->QueryInterface(IID_IHXCommonClassFactory, (void**) &pFactory))
{
HX_RELEASE(m_pCommonClassFactoryOverride);
m_pCommonClassFactoryOverride = pFactory;
}
IHXPreferences* pPreferences = 0;
if (HXR_OK == pContext->QueryInterface(IID_IHXPreferences, (void**) &pPreferences))
{
HX_RELEASE(m_pPreferences);
m_pPreferences = pPreferences;
#if defined(HELIX_FEATURE_HYPER_NAVIGATE)
/* Hand over the new preferences to hyper-navigation module */
m_pOrigHyperNavigate->Init((IUnknown*) (IHXClientEngine*)this);
#endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
}
#if defined(HELIX_FEATURE_HYPER_NAVIGATE)
IHXHyperNavigate* pHyperNavigate = 0;
if (HXR_OK == pContext->QueryInterface(IID_IHXHyperNavigate, (void**) &pHyperNavigate))
{
HX_RELEASE(m_pHyperNavigate);
m_pHyperNavigate = pHyperNavigate;
}
#endif /* defined(HELIX_FEATURE_HYPER_NAVIGATE) */
#ifdef _UNIX
IHXAsyncIOSelection* pAsyncIOSelection = 0;
if (HXR_OK == pContext->QueryInterface(IID_IHXAsyncIOSelection, (void**) &pAsyncIOSelection))
{
HX_RELEASE(m_pAsyncIOSelection);
m_pAsyncIOSelection = pAsyncIOSelection;
}
#endif
#if defined(HELIX_FEATURE_PLAYBACK_NET)
IHXNetworkServices* pNetworkServices = NULL;
if (HXR_OK == pContext->QueryInterface(IID_IHXNetworkServices, (void**) &pNetworkServices))
{
HX_RELEASE(m_pNetworkServices);
m_pNetworkServices = pNetworkServices;
}
#endif /* HELIX_FEATURE_PLAYBACK_NET */
#if defined(HELIX_FEATURE_SYSTEMREQUIRED)
IHXSystemRequired* pSystemRequired = NULL;
if (HXR_OK == pContext->QueryInterface(IID_IHXSystemRequired, (void**) &pSystemRequired))
{
HX_RELEASE(m_pSystemRequired);
m_pSystemRequired = pSystemRequired;
}
#endif /* HELIX_FEATURE_SYSTEMREQUIRED */
IHXMultiPlayPauseSupport* pMPPSupport = NULL;
if (HXR_OK == pContext->QueryInterface(IID_IHXMultiPlayPauseSupport, (void**) &pMPPSupport))
{
HX_RELEASE(m_pMultiPlayPauseSupport);
m_pMultiPlayPauseSupport = pMPPSupport;
}
_Initialize();
return HXR_OK;
}
/*
* HXClientEngine methods
*/
void HXClientEngine::Close()
{
/* There should not be any outstanding players */
HX_ASSERT(m_PlayerList.GetCount() == 0);
#if defined(HELIX_FEATURE_PREFERENCES)
// nhart: if prefs have been overridden, we want to release them before we
// unload our plugins and restore the original prefs.
if (m_pPreferences != m_pOrigPreferences)
{
HX_RELEASE(m_pPreferences);
m_pPreferences = m_pOrigPreferences;
HX_ADDREF(m_pPreferences);
}
#endif /* HELIX_FEATURE_PREFERENCES */
#if defined _UNIX && !defined _VXWORKS
HX_RELEASE(m_pSiteEventHandler);
#endif
CHXSimpleList::Iterator ndxPlayer = m_PlayerList.Begin();
for (; ndxPlayer != m_PlayerList.End(); ++ndxPlayer)
{
HXPlayer* pHXPlayer = (HXPlayer*) (*ndxPlayer);
m_pPlayerSinkControl->PlayerClosed(pHXPlayer);
pHXPlayer->ClosePlayer();
pHXPlayer->Release();
}
m_PlayerList.RemoveAll();
if (m_pPlayerSinkControl)
m_pPlayerSinkControl->Terminate();
HX_RELEASE(m_pPlayerSinkControl);
if (m_bIsSchedulerStarted)
{
m_pScheduler->StopScheduler();
#if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
if (m_pOptimizedScheduler)
{
m_pOptimizedScheduler->StopScheduler();
}
#endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULER */
m_bIsSchedulerStarted = FALSE;
}
#if defined(HELIX_FEATURE_AUDIO)
if (m_pAudioSession)
{
m_pAudioSession->Close();
HX_RELEASE(m_pAudioSession);
}
#endif /* HELIX_FEATURE_AUDIO */
#if defined(HELIX_FEATURE_REGISTRY)
if (m_pRegistry)
{
// remove the registry
if (m_unRegistryID)
{
m_pRegistry->DeleteById(m_unRegistryID);
m_unRegistryID = 0;
}
m_pRegistry->Close();
HX_RELEASE(m_pRegistry);
}
#endif /* HELIX_FEATURE_REGISTRY */
#if defined(HELIX_FEATURE_PAC)
if (m_pProxyAutoConfig)
{
m_pProxyAutoConfig->Close();
HX_RELEASE(m_pProxyAutoConfig);
}
#endif /* HELIX_FEATURE_PAC */
#if defined(HELIX_FEATURE_PLAYBACK_NET)
HX_RELEASE(m_pNetworkServices);
if (m_pOrigNetworkServices)
{
m_pOrigNetworkServices->Close();
HX_RELEASE(m_pOrigNetworkServices);
}
#endif /* HELIX_FEATURE_PLAYBACK_NET */
#ifdef _MEDIUM_BLOCK
if (m_pAllocator)
{
m_pAllocator->SetScheduler(NULL);
}
#endif /* _MEDIUM_BLOCK */
HX_RELEASE(m_pScheduler);
#if defined(HELIX_FEATURE_OPTIMIZED_SCHEDULER)
HX_RELEASE(m_pOptimizedScheduler);
#endif /* HELIX_FEATURE_OPTIMIZED_SCHEDULE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -