📄 srcinfo.cpp
字号:
llActualPacketTime =
pStrInfo->BufferingState().CreateINT64Timestamp(ulPktTime);
/* if this is a stream where we do not have to wait to receive
* a packet >= stream's last expected packet time,
* make the highest timestamp to be the HIGHEST timestamp
* across ALL streams for this source.
*
* This is to fix end tag support on sources with sparse streams
* e.g. audio/video with an event stream where we may not really
* have a packet till way down in the future.
*/
if (pRendInfo->m_pStreamInfo->m_bCanBeStoppedAnyTime &&
!pStreamInfo->m_bSrcInfoStreamDone &&
m_llLatestPacketTime > llLastExpectedPacketTime)
{
/* check if ALL other streams have ended */
if (AllOtherStreamsHaveEnded(pStreamInfo))
{
/*
* The logic above was designed to handle endTime's
* on a/v streams, so that once we received a/v packets
* past the end time (even though more packets are
* still coming in), we can go ahead and end the
* event stream. However, this was causing a bug
* where syncmm event streams were getting terminated
* even though there was a packet waiting for it
* at the transport. This additional test imposes
* that we don't terminate the stream unless we
* have no packets waiting at the transport AND
* the stream has said it's done.
*/
if (pStreamInfo->BufferingState().DoneAtTransport())
{
bEndMe = TRUE;
llActualPacketTime = m_llLatestPacketTime;
}
}
}
}
if (!bPersistent &&
(!pSource->IsLive() || pSource->isRestrictedLiveStream()) &&
!pStreamInfo->m_bSrcInfoStreamDone &&
llActualPacketTime > llLastExpectedPacketTime &&
bEndMe)
{
if (!bAtInterrupt || pRendInfo->m_bInterruptSafe)
{
pStreamInfo->m_bSrcInfoStreamDone = TRUE;
pStreamInfo->ResetPostEndTimeEventList();
if (!pStreamInfo->m_bSrcInfoStreamFillingDone &&
ulNumStreamsToBeFilled > 0)
{
pStreamInfo->m_bSrcInfoStreamFillingDone = TRUE;
ulNumStreamsToBeFilled--;
}
if (pRendInfo->m_ulNumberOfPacketsQueued == 0 &&
pRendInfo->m_pRenderer)
{
m_pPlayer->SendPostSeekIfNecessary(pRendInfo);
pRendInfo->m_pRenderer->OnEndofPackets();
pRendInfo->m_bOnEndOfPacketSent = TRUE;
}
if (!pSource->isRestrictedLiveStream())
{
CheckIfDone();
}
}
else
{
ScheduleProcessCallback();
continue;
}
}
}
if (!bPersistent &&
m_bInitialized &&
m_ulSourceDuration < m_pPlayer->m_ulCurrentPlayTime &&
m_pSource &&
!m_pSource->IsLive() &&
m_pSource->IsActive())
{
/* Remove bandwidth usage for this source */
m_pSource->AdjustClipBandwidthStats(FALSE);
}
else if (m_bInitialized &&
m_pSource &&
m_pPlayer->m_ulCurrentPlayTime > m_pSource->GetDelay() &&
m_pPlayer->m_ulCurrentPlayTime <= m_ulSourceDuration &&
!m_pSource->IsActive())
{
/* Add bandwidth usage for this source */
m_pSource->AdjustClipBandwidthStats(TRUE);
}
return HXR_OK;
}
HX_RESULT
SourceInfo::Register()
{
HX_RESULT theErr = HXR_OK;
if (!m_bIsRegisterSourceDone)
{
m_bIsRegisterSourceDone = TRUE;
if (m_pSource->m_bSureStreamClip)
{
m_pPlayer->SureStreamSourceRegistered(this);
}
m_pSource->CanBeFastStarted();
#if defined(HELIX_FEATURE_ASM)
/* Register Source with ASM Bandwidth Manager */
IHXBandwidthManager* pMgr = 0;
HX_VERIFY(HXR_OK == m_pPlayer->QueryInterface(
IID_IHXBandwidthManager, (void **)&pMgr));
theErr = pMgr->RegisterSource(m_pSource, (IUnknown*) (IHXPlayer*) m_pPlayer);
pMgr->Release();
#endif /* HELIX_FEATURE_ASM */
}
return theErr;
}
HX_RESULT
SourceInfo::UnRegister()
{
HX_RESULT theErr = HXR_OK;
if (m_bIsRegisterSourceDone)
{
m_bIsRegisterSourceDone = FALSE;
if (m_pSource->m_bSureStreamClip)
{
m_pPlayer->SureStreamSourceUnRegistered(this);
}
#if defined(HELIX_FEATURE_ASM)
/* Register Source with ASM Bandwidth Manager */
IHXBandwidthManager* pMgr = 0;
HX_VERIFY(HXR_OK == m_pPlayer->QueryInterface(
IID_IHXBandwidthManager, (void **)&pMgr));
HX_ASSERT(pMgr) ;
if (pMgr)
{
theErr = pMgr->UnRegisterSource(m_pSource);
pMgr->Release();
}
CheckIfDone();
#endif /* HELIX_FEATURE_ASM */
}
return theErr;
}
void
SourceInfo::ChangeAccelerationStatus(BOOL bMayBeAccelerated,
BOOL bUseAccelerationFactor,
UINT32 ulAccelerationFactor)
{
IHXBandwidthManager* pMgr = 0;
HX_VERIFY(HXR_OK == m_pPlayer->QueryInterface(
IID_IHXBandwidthManager, (void **)&pMgr));
if (pMgr)
{
pMgr->ChangeAccelerationStatus(m_pSource, bMayBeAccelerated,
bUseAccelerationFactor, ulAccelerationFactor);
pMgr->Release();
}
}
void SourceInfo::CheckIfDone()
{
BOOL bIsDone = TRUE;
CHXMapLongToObj::Iterator ndxRend;
RendererInfo* pRendInfo = NULL;
STREAM_INFO* pStreamInfo = NULL;
// keep the source active throughout the duration
// of source
if (m_bDone &&
m_bActive &&
m_pPlayer->m_uNumSourcesActive > 0 &&
!KeepSourceActive())
{
m_bActive = FALSE;
m_pPlayer->m_uNumSourcesActive--;
}
if (!m_bDone)
{
ndxRend = m_pRendererMap->Begin();
for (;ndxRend != m_pRendererMap->End(); ++ndxRend)
{
pRendInfo = (RendererInfo*)(*ndxRend);
pStreamInfo = pRendInfo->m_pStreamInfo;
if (!pStreamInfo->m_bSrcInfoStreamDone)
{
bIsDone = FALSE;
break;
}
}
if (bIsDone || m_pSource->IsSourceDone())
{
m_bDone = TRUE;
if (!m_bAllPacketsReceived)
{
m_bAllPacketsReceived = TRUE;
// If we are done receiving all the packets, release bandwidth
UnRegister();
}
if (!m_pSource->IsSourceDone())
{
m_pSource->SetEndOfClip(TRUE);
}
if (m_pPlayer->m_uNumCurrentSourceNotDone > 0)
{
m_pPlayer->m_uNumCurrentSourceNotDone--;
}
}
}
#if defined(HELIX_FEATURE_BASICGROUPMGR)
if (!m_bActive &&
m_bTrackStoppedToBeSent &&
!m_pPlayer->m_pEngine->AtInterruptTime())
{
// send TrackStopped at the end of its active duration
m_bTrackStoppedToBeSent = FALSE;
m_pPlayer->m_pGroupManager->TrackStopped(m_uGroupID, m_uTrackID);
if (m_pPeerSourceInfo)
{
m_pPeerSourceInfo->m_bTrackStoppedToBeSent = FALSE;
}
}
#endif /* HELIX_FEATURE_BASICGROUPMGR */
}
void
SourceInfo::SetupRendererSites(BOOL bIsPersistent)
{
CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
for (; ndxRend != m_pRendererMap->End(); ++ndxRend)
{
RendererInfo* pRendInfo = (RendererInfo*) (*ndxRend);
IHXRenderer* pRenderer = (IHXRenderer*) pRendInfo->m_pRenderer;
HX_DISPLAY_TYPE ulFlags;
IHXBuffer* pInfoBuffer = NULL;
/*
* Find out if the renderer is a display type renderer.
*/
if (HXR_OK == pRenderer->GetDisplayType(ulFlags,pInfoBuffer))
{
HX_RELEASE(pInfoBuffer);
if (HX_DISPLAY_WINDOW == (HX_DISPLAY_WINDOW & ulFlags))
{
STREAM_INFO* pStreamInfo = pRendInfo->m_pStreamInfo;
IHXValues* pProps = pStreamInfo->m_pStreamProps;
/*
* Call the helper function that handles setup of a
* renderer site. This function will do the
* whole process of finding out if a site exists by
* PlayToFrom; if not, it calls the site supplier; then it
* it actually hooks up the SiteUserSupplier with all
* the appropriate sites, etc.
*/
m_pPlayer->SetupRendererSite(pRenderer,pProps,bIsPersistent);
}
}
}
}
HX_RESULT
SourceInfo::InitializeRenderers(BOOL& bSourceInitialized)
{
HX_RESULT theErr = HXR_OK;
HX_RESULT theFinalErr = HXR_OK;
IHXValues* pHeader = NULL;
HXStream* pStream = NULL;
IHXRenderer* pRenderer = NULL;
IHXBuffer* pMimeTypeBuffer = NULL;
IUnknown* pUnkRenderer = NULL;
STREAM_INFO* pStreamInfo = NULL;
BOOL bAddDefaultUpgrade = FALSE;
bSourceInitialized = FALSE;
if (m_pPlayer->m_pEngine->AtInterruptTime()) //for Mac
{
return HXR_OK;
}
if (m_pSource->GetLastError() != HXR_OK)
{
/* Since the source has an error, mark plugin load attempt
* to TRUE so that the player object can request upgrade
* if it needs to
*/
m_bLoadPluginAttempted = TRUE;
return HXR_OK;
}
if (!m_pSource->IsInitialized())
{
// atleast one source is not yet initialized
return HXR_OK;
}
bSourceInitialized = TRUE;
#if defined(HELIX_FEATURE_NESTEDMETA)
IHXPersistentComponent* pPersistentComponent = NULL;
if (HXR_OK == m_pPlayer->m_pPersistentComponentManager->GetPersistentComponent(m_ulPersistentComponentID,
pPersistentComponent))
{
// no need to AddRef() since it's maintained by PersistentManager
m_pRendererAdviseSink = ((HXPersistentComponent*)pPersistentComponent)->m_pRendererAdviseSink;
m_pRendererAdviseSink->AddRef();
}
HX_RELEASE(pPersistentComponent);
#endif /* HELIX_FEATURE_NESTEDMETA */
theErr = SetupStreams();
if (m_bIndefiniteDuration ||
m_pSource->IsLive() ||
m_pPlayer->IsLive())
{
m_pPlayer->m_bIsLive = TRUE;
m_pPlayer->m_pAudioPlayer->SetLive(m_pPlayer->m_bIsLive);
if (m_pSource->isRestrictedLiveStream())
{
m_pPlayer->SetPresentationTime(max(m_pPlayer->m_ulPresentationDuration, GetActiveDuration()));
}
else
{
m_pPlayer->SetPresentationTime(0);
}
}
else
{
m_pPlayer->SetPresentationTime(max(m_pPlayer->m_ulPresentationDuration, GetActiveDuration()));
}
// attemp to load all the plugins
m_bLoadPluginAttempted = TRUE;
UINT16 uNumStreams = m_pSource->GetNumStreams();
CHXMapLongToObj::Iterator ndxRend = m_pRendererMap->Begin();
for (UINT16 i = 0; ndxRend != m_pRendererMap->End(); ++ndxRend, i++)
{
RendererInfo* pRendInfo = (RendererInfo*)(*ndxRend);
pStreamInfo = pRendInfo->m_pStreamInfo;
pHeader = pStreamInfo->m_pHeader;
pStream = pRendInfo->m_pStream;
HX_ASSERT(pHeader);
HX_ASSERT(pStream);
pRenderer = NULL;
pUnkRenderer = NULL;
bAddDefaultUpgrade = FALSE;
HX_RELEASE(pMimeTypeBuffer);
pHeader->GetPropertyCString("MimeType", pMimeTypeBuffer);
HX_ASSERT(pMimeTypeBuffer && pMimeTypeBuffer->GetBuffer());
if (!pMimeTypeBuffer || !pMimeTypeBuffer->GetBuffer())
{
GOTOEXITONERROR(theErr = HXR_NOT_INITIALIZED, exit);
}
/*
* Check for "CanBeStoppedAnyTime" property. For streams with this
* property, we do not have to wait to receive a
* packet with timestamp >= lastPacketTime.
* We can instead use the highest timestamp received across
* ALL the streams in a given source
*/
UINT32 ulCanBeStoppedAnyTime = 0;
if (pHeader->GetPropertyULONG32("CanBeStoppedAnyTime", ulCanBeStoppedAnyTime) == HXR_OK)
{
pStreamInfo->m_bCanBeStoppedAnyTime = (ulCanBeStoppedAnyTime == 1);
}
/* temporary hack till we fix rmff fileformat to correctly set this
* property AND the servers areupdated to have this fixed fileformat.
*/
else if (::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/x-pn-realevent") == 0 ||
::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "syncMM/x-pn-realvideo") == 0)
{
pStreamInfo->m_bCanBeStoppedAnyTime = TRUE;
}
else if (::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/vnd.rn-objectsstream") == 0 ||
::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/x-rn-objects") == 0 ||
::strcasecmp((const char*) pMimeTypeBuffer->GetBuffer(), "application/vnd.rn-objects") == 0)
{
m_pPlayer->m_pEngine->m_lROBActive++;
}
IHXPluginHandler3* pPlugin2Handler3 = NULL;
HX_VERIFY(HXR_OK ==
m_pPlayer->m_pPlugin2Handler->QueryInterface(IID_IHXPluginHandler3, (void**) &pPlugin2Handler3));
if (!(HXR_OK == pPlugin2Handler3->FindGroupOfPluginsUsingStrings(PLUGIN_CLASS, PLUGIN_RENDERER_TYPE,
PLUGIN_RENDERER_MIME, (char*)pMimeTypeBuffer->GetBuffer(), NULL, NULL, pRendInfo->m_pRendererEnumerator) &&
pRendInfo->m_pRendererEnumerator &&
(HXR_OK == pRendInfo->m_pRendererEnumerator->GetNextPlugin(pUnkRenderer, NULL)) &&
pUnkRenderer))
{
#if defined(HELIX_FEATURE_AUTOUPGRADE)
if(m_pPlayer->m_pUpgradeCollection)
m_pPlayer->m_pUpgradeCollection->Add(eUT_Required, pMimeTypeBuffer, 0, 0);
#endif /* HELIX_FEATURE_AUTOUPGRADE */
theErr = HXR_NO_RENDERER;
}
HX_RELEASE(pPlugin2Handler3);
GOTOEXITONERROR(theErr, nextrend);
tryNextRendererForSameMimeType:
HX_ASSERT(pUnkRenderer);
pUnkRenderer->QueryInterface(IID_IHXRenderer, (void**) &pRenderer);
theErr = pStream->SetRenderer(pUnkRenderer);
GOTOEXITONERROR(theErr, nextrend);
HX_RELEASE(pUnkRenderer);
// now get the TAC info for this track/source
UINT32 sourceID;
sourceID = 0;
if (HXR_OK == m_pSource->GetID(sourceID))
{
m_pPlayer->CheckTrackAndSourceOnTrackStarted(m_uGroupID, m_uTrackID, sourceID);
}
if (!pStreamInfo->m_pStreamProps)
{
// Create an IHXValues for storing stream properties related
// to metafile initilization and layout hookup.
pStreamInfo->m_pStreamProps = new CHXHeader();
pStreamInfo->m_pStreamProps->AddRef();
}
IHXBuffer* pStreamPlayTo;
pStreamPlayTo = NULL;
// If the stream doesn't have a playto property, than
// check if the parent source has a playto property
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -