📄 hxntsrc.cpp
字号:
pEvent->SetTimeStartPos(ulEventTime);
pEvent->SetTimeOffset(m_ulStartTime - m_ulDelay);
}
else
{
if(nResult == HXR_NO_DATA && (m_bSourceEnd || pStreamInfo->m_bSrcStreamDone))
nResult = HXR_AT_END;
if(nResult == HXR_NO_DATA && m_pBufferManager)
{
UINT32 ulRemainToBufferInMs = 0;
UINT32 ulRemainToBuffer = 0;
m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs, ulRemainToBuffer);
if (ulRemainToBufferInMs || ulRemainToBuffer)
{
nResult = HXR_BUFFERING;
}
else if (pStreamInfo->m_unNeeded > 0 &&
pStreamInfo->m_unNeeded != pStreamInfo->m_unAvailable)
{
nResult = HXR_BUFFERING;
m_uLastBuffering = 0;
m_pBufferManager->ReBuffer();
}
}
}
return nResult;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_RECORDCONTROL */
}
HX_RESULT
HXNetSource::GetEventFromProtocol(UINT16 usStreamNumber, CHXEvent*& pEvent)
{
HX_RESULT theErr = HXR_OK;
UINT32 ulEventTime = 0;
UINT32 ulRemainToBufferInMs = 0;
UINT32 ulRemainToBuffer = 0;
IHXPacket* pPacket = NULL;
STREAM_INFO* pStreamInfo = NULL;
CHXEvent* pTempEvent = NULL;
CHXEventList* pEventList = NULL;
CHXSimpleList::Iterator lIter;
pEvent = NULL;
if (!m_bInitialized && m_state == NETSRC_READY)
{
return HXR_NO_DATA;
}
if (m_bPaused && m_bDelayed)
{
if (TryResume() && m_pPlayer)
{
m_pPlayer->RegisterSourcesDone();
DoResume();
}
else
{
return HXR_NO_DATA;
}
}
/* give some time to the net object...*/
theErr = _ProcessIdle();
if (theErr)
{
return theErr;
}
if (!mStreamInfoTable->Lookup((LONG32) usStreamNumber, (void *&) pStreamInfo))
{
HX_ASSERT(FALSE);
return HXR_INVALID_PARAMETER;
}
if (pStreamInfo->m_bReconnectToBeDone)
{
pEventList = &pStreamInfo->m_EventList;
if (pEventList->GetNumEvents() && !m_bPlayFromRecordControl)
{
pEvent = pEventList->RemoveHead();
//{FILE* f1 = ::fopen("c:\\temp\\reconnect.txt", "a+"); ::fprintf(f1, "GetEventFromPreReconnect\t%lu\t%lu\n", usStreamNumber, pEvent->GetPacket()->GetTime());::fclose(f1);}
}
if (m_pProto)
{
while (TRUE)
{
theErr = m_pProto->GetEvent(usStreamNumber, pTempEvent);
if (theErr)
{
// Mask off any non-crucial errors
switch (theErr)
{
case HXR_AT_END:
case HXR_NO_DATA:
case HXR_BUFFERING:
theErr = HXR_OK;
break;
default:
break;
}
// if there is still an error, it needs to be reported
if (theErr)
{
return theErr;
}
break;
}
HX_ASSERT(pTempEvent);
if (!pStreamInfo->m_pPosReconnectEventList)
{
pStreamInfo->m_pPosReconnectEventList = new CHXEventList;
}
//{FILE* f1 = ::fopen("c:\\temp\\reconnect.txt", "a+"); ::fprintf(f1, "AddEventToPosReconnect\t%lu\t%lu\n", usStreamNumber, pTempEvent->GetPacket()->GetTime());::fclose(f1);}
pStreamInfo->m_pPosReconnectEventList->InsertEvent(pTempEvent);
}
ProcessReconnect(pStreamInfo);
}
}
else
{
pEventList = pStreamInfo->m_pPosReconnectEventList;
if (pEventList && pEventList->GetNumEvents())
{
pEvent = pEventList->RemoveHead();
//{FILE* f1 = ::fopen("c:\\temp\\reconnect.txt", "a+"); ::fprintf(f1, "GetEventFromPosReconnect\t%lu\t%lu\n", usStreamNumber, pEvent->GetPacket()->GetTime());::fclose(f1);}
}
if (!pEvent && m_pProto)
{
while (TRUE)
{
theErr = m_pProto->GetEvent(usStreamNumber, pEvent);
if (theErr)
{
// Mask off any non-crucial errors
switch (theErr)
{
case HXR_AT_END:
case HXR_NO_DATA:
case HXR_BUFFERING:
theErr = HXR_OK;
break;
default:
break;
}
// if there is still an error, it needs to be reported
if (theErr)
{
return theErr;
}
break;
}
HX_ASSERT(pEvent);
if (!pStreamInfo->m_ulReconnectOverlappedPackets)
{
break;
}
//{FILE* f1 = ::fopen("c:\\temp\\reconnect.txt", "a+"); ::fprintf(f1, "DeleteEvent(overlapped)\t%lu\t%lu\n", usStreamNumber, pEvent->GetPacket()->GetTime());::fclose(f1);}
HX_DELETE(pEvent);
pStreamInfo->m_ulReconnectOverlappedPackets--;
}
if (pEvent)
{
//{FILE* f1 = ::fopen("c:\\temp\\reconnect.txt", "a+"); ::fprintf(f1, "GetEventFromTransport\t%lu\t%lu\n", usStreamNumber, pEvent->GetPacket()->GetTime());::fclose(f1);}
}
}
if (pEvent)
{
AddToPreReconnectEventList(pStreamInfo, pEvent);
}
}
if (pEvent)
{
pPacket = pEvent->GetPacket();
if (pPacket)
{
if (!m_bPlayFromRecordControl &&
CanSendToDataCallback(pPacket)&& !pEvent->IsPreSeekEvent())
{
/* Update buffering info and stats */
DataCallback(pPacket);
}
if (pPacket->IsLost())
{
UINT32 ulLastPkt =
pStreamInfo->BufferingState().LastPacketTimestamp();
// Use timestamp from the last packet
ulEventTime = AdjustEventTime(pStreamInfo, ulLastPkt);
}
else
{
ulEventTime = AdjustEventTime(pStreamInfo, pPacket->GetTime());
}
pEvent->SetTimeStartPos(ulEventTime);
}
pEvent->SetTimeOffset(m_ulStartTime - m_ulDelay);
}
else if (m_bSourceEnd || pStreamInfo->m_bSrcStreamDone)
{
theErr = HXR_AT_END;
}
else
{
if(m_bPlayFromRecordControl)
{
theErr = HXR_NO_DATA;
}
else
{
m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs, ulRemainToBuffer);
if (ulRemainToBufferInMs || ulRemainToBuffer)
{
theErr = HXR_BUFFERING;
}
else if (pStreamInfo->m_unNeeded > 0 &&
pStreamInfo->m_unNeeded != pStreamInfo->m_unAvailable)
{
theErr = HXR_BUFFERING;
m_uLastBuffering = 0;
m_pBufferManager->ReBuffer();
}
else
{
theErr = HXR_NO_DATA;
}
}
}
if (m_pBufferCtl)
{
if (theErr == HXR_BUFFERING)
{
/* Make sure we have not paused the server when we are in a
* buffering state
*/
m_pBufferCtl->OnBuffering(ulRemainToBufferInMs, ulRemainToBuffer);
}
else if (theErr == HXR_AT_END)
{
m_pBufferCtl->OnClipEnd();
}
}
#ifdef LOSS_HACK
if (m_ulLossHack > 0 && ((UINT32) (rand() % 100) < m_ulLossHack) &&
!theErr && pEvent && !(pEvent->GetPacket())->IsLost())
{
GenerateFakeLostPacket(pEvent);
/* Update the stats */
pStreamInfo->m_ulLost++;
}
#endif /* LOSS_HACK */
return theErr;
}
void
HXNetSource::ReBuffer()
{
UINT32 ulRemainToBufferInMs = 0;
UINT32 ulRemainToBuffer = 0;
m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,
ulRemainToBuffer);
// DEBUG_OUT(m_pPlayer, DOL_GENERIC, (s,
// "Rebuffer %p CurrentTime: %lu RemainMs: %lu RemainBytes: %lu", this,
// HX_GET_TICKCOUNT(), ulRemainToBufferInMs, ulRemainToBuffer));
if (ulRemainToBufferInMs == 0 &&
ulRemainToBuffer == 0)
{
m_uLastBuffering = 0;
m_pBufferManager->ReBuffer();
}
}
HX_RESULT
HXNetSource::UpdateRegistry(UINT32 ulRegistryID)
{
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
HX_RESULT theErr = HXR_OK;
UINT32 ulRepeatedRegistryID = 0;
UINT32 ulRegId = 0;
char szRegName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
IHXBuffer* pParentName = NULL;
IHXBuffer* pRepeatRegName = NULL;
STREAM_INFO* pStreamInfo = NULL;
SOURCE_STATS* pNewStats = NULL;
CHXMapLongToObj::Iterator ndxStream;
m_ulRegistryID = ulRegistryID;
if (!m_pStats)
{
// XXX HP, Hummmmmmmm ....
HX_ASSERT(FALSE);
SetupRegistry();
}
else if (m_ulRegistryID != m_pStats->m_ulRegistryID)
{
#if defined(HELIX_FEATURE_SMIL_REPEAT)
// repeated source
if (!m_pSourceInfo->m_bLeadingSource ||
m_pSourceInfo->m_pRepeatList)
{
if (m_pStatsManager)
{
m_pStatsManager->UpdateRegistry(m_ulRegistryID);
}
else if (m_pRegistry &&
HXR_OK == m_pRegistry->GetPropName(m_pPlayer->m_ulRepeatedRegistryID, pRepeatRegName))
{
SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.%ld%ld%ld",
pRepeatRegName->GetBuffer(),
m_pSourceInfo->m_uGroupID,
m_pSourceInfo->m_uTrackID,
(int)m_pSourceInfo->m_bLeadingSource);
ulRepeatedRegistryID = m_pRegistry->GetId(szRegName);
if (!ulRepeatedRegistryID)
{
ulRepeatedRegistryID = m_pRegistry->AddComp(szRegName);
}
m_pStatsManager = new StatsManager(m_pRegistry, m_ulRegistryID, ulRepeatedRegistryID);
m_pStatsManager->AddRef();
pNewStats = new SOURCE_STATS(m_pRegistry, ulRepeatedRegistryID);
}
else
{
// why stats' creation failed??
HX_ASSERT(FALSE);
}
HX_RELEASE(pRepeatRegName);
}
// normal source
else
#endif /* HELIX_FEATURE_SMIL_REPEAT */
{
pNewStats = new SOURCE_STATS(m_pRegistry, m_ulRegistryID);
}
if (pNewStats && m_pPlayer)
{
*pNewStats = *m_pStats;
ndxStream = mStreamInfoTable->Begin();
for(; ndxStream != mStreamInfoTable->End(); ++ndxStream)
{
pStreamInfo = (STREAM_INFO*) (*ndxStream);
if (m_pRegistry &&
pNewStats &&
HXR_OK == m_pRegistry->GetPropName(pNewStats->m_ulRegistryID, pParentName))
{
SafeSprintf(szRegName, MAX_DISPLAY_NAME, "%s.Stream%ld", pParentName->GetBuffer(),
pStreamInfo->m_uStreamNumber);
ulRegId = m_pRegistry->GetId(szRegName);
if (!ulRegId)
{
ulRegId = m_pRegistry->AddComp(szRegName);
}
if(m_pProto)
m_pProto->UpdateRegistry(pStreamInfo->m_uStreamNumber, ulRegId);
}
HX_RELEASE(pParentName);
}
HX_DELETE(m_pStats);
m_pStats = pNewStats;
}
}
return theErr;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
}
void
HXNetSource::LeavePrefetch(void)
{
#if defined(HELIX_FEATURE_PREFETCH)
m_bPrefetch = FALSE;
if (m_pProto)
{
m_pProto->LeavePrefetch();
}
// send prefetch notification so that SMIL
// renderer can resolve the duration on this prefetch track
if (m_pSourceInfo)
{
m_pPlayer->PrefetchTrackDone(m_pSourceInfo->m_uGroupID,
m_pSourceInfo->m_uTrackID,
HXR_OK);
}
#endif /* HELIX_FEATURE_PREFETCH */
return;
}
void
HXNetSource::EnterFastStart(void)
{
#if defined(HELIX_FEATURE_TURBOPLAY)
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)Enter TurboPlay", this));
m_bFastStart = TRUE;
if (m_pProto)
{
m_pProto->EnterFastStart();
}
#endif /* HELIX_FEATURE_TURBOPLAY */
return;
}
void
HXNetSource::LeaveFastStart(TurboPlayOffReason leftReason)
{
#if defined(HELIX_FEATURE_TURBOPLAY)
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)Leave TurboPlay", this));
m_turboPlayStats.tpOffReason = leftReas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -