📄 hxntsrc.cpp
字号:
(HX_STATUS_READY == uStatusCode))
{
m_pBufferCtl->OnBufferingDone();
}
}
m_uLastStatusCode = uStatusCode;
if (m_bFastStart && !m_turboPlayStats.bBufferDone && HX_STATUS_READY == uStatusCode)
{
m_turboPlayStats.bBufferDone = TRUE;
m_turboPlayStats.ulBufferedTime = CALCULATE_ELAPSED_TICKS(m_ulStartDataWait, HX_GET_TICKCOUNT());
}
return rc;
}
BOOL
HXNetSource::CanBeFastStarted(void)
{
// In low heap mode we always want TurboPlay off.
#if defined(HELIX_FEATURE_TURBOPLAY)
HXStream* pStream = NULL;
CHXSimpleList::Iterator i;
m_bFastStart = TRUE;
if (FALSE == m_pPlayer->CanBeFastStarted(m_pSourceInfo))
{
m_turboPlayStats.tpOffReason = m_pPlayer->m_turboPlayOffReason;
m_bFastStart = FALSE;
goto cleanup;
}
// no faststart on non-RTSP protocol
if (!m_bRTSPProtocol)
{
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s,"(%p)Not RTSP - TurboPlay Off", this));
m_turboPlayStats.tpOffReason = TP_OFF_BY_NONRTSP;
m_bFastStart = FALSE;
goto cleanup;
}
// faststart can be disabled by the server
if (TURBO_PLAY_OFF == m_serverTurboPlay)
{
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s,"(%p)Disabled By Server - TurboPlay Off", this));
m_turboPlayStats.tpOffReason = TP_OFF_BY_SERVER;
m_bFastStart = FALSE;
goto cleanup;
}
// no faststart on live source served from >= 9.0 server which get
// rid of the ring buffer by default
if (mLiveStream && HX_GET_MAJOR_VERSION(m_ulServerVersion) >= 9 &&
(TURBO_PLAY_ON != m_serverTurboPlay))
{
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s,"(%p)Live From Server(>=9) - TurboPlay Off", this));
m_turboPlayStats.tpOffReason = TP_OFF_BY_LIVE;
m_bFastStart = FALSE;
goto cleanup;
}
// no faststart on ROB presentation
if (m_pPlayer->m_pEngine->m_lROBActive > 0)
{
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s,"(%p)ROB Presentation - TurboPlay Off", this));
m_turboPlayStats.tpOffReason = TP_OFF_BY_ROB;
m_bFastStart = FALSE;
goto cleanup;
}
if (m_bFastStart)
{
if (!m_bRARVSourceVerified)
{
m_bRARVSourceVerified = TRUE;
m_bRARVSource = IsRARVSource();
}
EnterFastStart();
}
cleanup:
return m_bFastStart;
#else
return FALSE;
#endif /* HELIX_FEATURE_TURBOPLAY */
}
HX_RESULT
HXNetSource::IsFaststartPushdownFullfilled(REF(UINT16) uStatusCode,
REF(UINT16) ulPercentDone)
{
#if defined(HELIX_FEATURE_TURBOPLAY)
HX_RESULT rc = HXR_OK;
UINT32 ulWaitTime = 0;
UINT32 ulPlayerTime = 0;
UINT32 ulDiff = 0;
UINT32 ulPushdownMS = 0;
UINT32 ulNumFrames =0;
CHXAudioStream* pCHXAudioStream = NULL;
CHXAudioSession* pAudioSession = NULL;
HXStream* pStream = NULL;
HXAudioData audioData;
IUnknown* pUnknown = NULL;
IHXMediaPushdown* pMediaPushdown = NULL;
UINT32 ulAudioPushDownThreshold;
UINT32 ulVideoPushDownThreshold;
CHXSimpleList::Iterator i;
uStatusCode = HX_STATUS_READY;
ulPercentDone = 100;
if (PUSHDOWN_ALL_DONE == m_pushDownStatus)
{
return rc;
}
if (!m_pPlayer)
{
return HXR_FAILED;
}
// compute our thresholds
// I know peice wise defined functions are LAME!!
// hello patel, this type of code is for you!
if (m_maxPossibleAccelRatio > 3.9)
{
ulAudioPushDownThreshold = m_ulTurboPushDown / 2;
ulVideoPushDownThreshold = 4;
}
else if (m_maxPossibleAccelRatio > 2.5)
{
ulAudioPushDownThreshold = (ULONG32) (m_ulTurboPushDown / 1.7);
ulVideoPushDownThreshold = 8;
}
else
{
ulAudioPushDownThreshold = (ULONG32) (m_ulTurboPushDown / 1.6);
ulVideoPushDownThreshold = 12;
}
if (!(PUSHDOWN_AUDIO_DONE & m_pushDownStatus))
{
#if defined(HELIX_FEATURE_AUDIO)
if (!m_pAudioStreamList)
{
CollectAudioStreams(m_pAudioStreamList);
}
if (m_pAudioStreamList && m_pAudioStreamList->GetCount())
{
memset(&audioData, 0, sizeof(HXAudioData));
ulPlayerTime = m_pPlayer->GetCurrentPlayTime();
if (mLiveStream)
{
ulPlayerTime += m_ulFirstPacketTime;
}
for(i = m_pAudioStreamList->Begin(); i != m_pAudioStreamList->End(); ++i)
{
pCHXAudioStream = (CHXAudioStream*)*i;
pCHXAudioStream->Write(&audioData);
// check audio push down
if (!m_bPushDownSet)
{
m_bPushDownSet = TRUE;
if (pCHXAudioStream && pCHXAudioStream->m_Owner)
{
pAudioSession = pCHXAudioStream->m_Owner->GetOwner();
}
if (pAudioSession && m_ulTurboPushDown < 2000)
{
pAudioSession->SetAudioPushdown(m_ulTurboPushDown);
}
}
// For live, ulPlayerTime could be > audioData.ulAudioTime if
// the renderer hasn't send 1st audio packet to the audio stream
if (audioData.ulAudioTime >= ulPlayerTime)
{
ulDiff = audioData.ulAudioTime - ulPlayerTime;
}
if (ulDiff >= ulAudioPushDownThreshold)
{
m_pushDownStatus = (PushDownStatus)(m_pushDownStatus | PUSHDOWN_AUDIO_DONE);
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)AudioPushDown Satisfied %lu %lu", this, ulDiff, ulAudioPushDownThreshold));
break;
}
}
}
// no audio stream
else
#endif /* HELIX_FEATURE_AUDIO */
{
m_pushDownStatus = (PushDownStatus)(m_pushDownStatus | PUSHDOWN_AUDIO_DONE);
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)AudioPushDown Satisfied(no audio)", this));
}
}
if (!(PUSHDOWN_VIDEO_DONE & m_pushDownStatus))
{
// check video push down
for (i = m_HXStreamList.Begin(); i != m_HXStreamList.End(); ++i)
{
pStream = (HXStream*) (*i);
// there should be 1 renderer per stream
if (HXR_OK == pStream->GetRenderer(0, pUnknown))
{
if (HXR_OK == pUnknown->QueryInterface(IID_IHXMediaPushdown, (void**)&pMediaPushdown))
{
if (pStream->m_bPostSeekToBeSent)
{
goto cleanup;
}
pMediaPushdown->GetCurrentPushdown(ulPushdownMS, ulNumFrames);
// check to see if we are using G2 video
if (pMediaPushdown->IsG2Video())
{
if (ulNumFrames < 9 && ulNumFrames < ulVideoPushDownThreshold)
{
goto cleanup;
}
}
else
{
if (ulNumFrames < ulVideoPushDownThreshold)
{
goto cleanup;
}
}
}
HX_RELEASE(pMediaPushdown);
}
HX_RELEASE(pUnknown);
}
m_pushDownStatus = (PushDownStatus)(m_pushDownStatus | PUSHDOWN_VIDEO_DONE);
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)VideoPushDown Satisfied %lu %lu", this, ulNumFrames, ulVideoPushDownThreshold));
}
// Milko wants to make it such that TimeStampDelivered
// IsTimeStampDelivery
cleanup:
HX_RELEASE(pMediaPushdown);
HX_RELEASE(pUnknown);
if (PUSHDOWN_ALL_DONE == m_pushDownStatus)
{
if (m_bInitialBuffering)
{
InitialBufferingDone();
}
m_uLastBuffering = 100;
m_ulTurboStartActiveTime = HX_GET_TICKCOUNT();
DEBUG_OUT(m_pPlayer, DOL_TRANSPORT, (s, "(%p)TURBO Started", this));
}
else
{
uStatusCode = HX_STATUS_BUFFERING;
ulPercentDone = 0;
// we switch to the normal status calculation if
// we detect the TurboPlay takes unreasonable amount of time to start(>8s)
ulWaitTime = CALCULATE_ELAPSED_TICKS(m_ulStartDataWait, HX_GET_TICKCOUNT());
if (ulWaitTime >= 8000)
{
rc = HXR_FAILED;
}
}
return rc;
#else
return HXR_NOTIMPL;
#endif /* HELIX_FEATURE_TURBOPLAY */
}
BOOL
HXNetSource::IsRARVSource(void)
{
#if defined(HELIX_FEATURE_TURBOPLAY)
BOOL bResult = TRUE;
IHXBuffer* pMimeType = NULL;
STREAM_INFO* pStreamInfo = NULL;
CHXMapLongToObj::Iterator lStreamIterator = mStreamInfoTable->Begin();
for (; lStreamIterator != mStreamInfoTable->End(); ++lStreamIterator)
{
pStreamInfo = (STREAM_INFO*) (*lStreamIterator);
if (pStreamInfo->m_pHeader &&
HXR_OK == pStreamInfo->m_pHeader->GetPropertyCString("MimeType", pMimeType))
{
const char* pszMimeType = (const char*)pMimeType->GetBuffer();
// all "-encrypted" mimetypes should have been stripped in FixUpMime()
if (strcmp(pszMimeType, REALMEDIA_MIME_TYPE) != 0 &&
strcmp(pszMimeType, REALAUDIO_MIME_TYPE) != 0 &&
strcmp(pszMimeType, REALVIDEO_MIME_TYPE) != 0 &&
strcmp(pszMimeType, REALAUDIO_MULTIRATE_MIME_TYPE) != 0 &&
strcmp(pszMimeType, REALAUDIO_MULTIRATE_LIVE_MIME_TYPE) != 0 &&
strcmp(pszMimeType, REALVIDEO_MULTIRATE_MIME_TYPE) != 0)
{
bResult = FALSE;
break;
}
}
HX_RELEASE(pMimeType);
}
HX_RELEASE(pMimeType);
return bResult;
#else
return FALSE;
#endif /* HELIX_FEATURE_TURBOPLAY */
}
UINT16
HXNetSource::GetNumStreams(void)
{
HX_ASSERT(m_bInitialized);
return m_uNumStreams;
}
HX_RESULT
HXNetSource::GetStreamInfo(ULONG32 ulStreamNumber,
STREAM_INFO*& theStreamInfo)
{
HX_RESULT theErr = HXR_OK;
STREAM_INFO* pStreamInfo = NULL;
STREAM_STATS* pStreamStats = NULL;
if (!mStreamInfoTable->Lookup((LONG32)ulStreamNumber, (void *&)pStreamInfo))
{
theErr = HXR_INVALID_PARAMETER;
}
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
if (m_pProto && HXR_OK == m_pProto->GetStreamStatistics(ulStreamNumber, &pStreamStats))
{
pStreamInfo->m_pStats = pStreamStats;
if (!pStreamInfo->m_pStats)
{
return HXR_UNEXPECTED;
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */
theStreamInfo = pStreamInfo;
return theErr;
}
HX_RESULT
HXNetSource::GetEvent(UINT16 usStreamNumber, CHXEvent*& pEvent)
{
HX_TRACE("HXNetSource::GetEvent");
if (!m_bPlayFromRecordControl)
{
HX_RESULT nResult = GetEventFromProtocol(usStreamNumber, pEvent);
#if defined(HELIX_FEATURE_RECORDCONTROL)
// Case of record-only RecordControl (no playback support).
if (pEvent && m_pRecordControl)
{
m_pRecordControl->OnPacket(pEvent->GetPacket(), pEvent->GetTimeOffset());
}
#endif /* HELIX_FEATURE_RECORDCONTROL */
return nResult;
}
pEvent = NULL;
HX_RESULT nResult = HXR_OK;
STREAM_INFO* pStreamInfo = NULL;
if (!mStreamInfoTable->Lookup((LONG32) usStreamNumber, (void *&) pStreamInfo))
{
HX_ASSERT(FALSE);
return HXR_INVALID_PARAMETER;
}
if (pStreamInfo->m_bReconnectToBeDone)
{
CHXEventList* pEventList = &pStreamInfo->m_EventList;
if (pEventList->GetNumEvents())
pEvent = pEventList->RemoveHead();
return pEvent ? HXR_OK : HXR_NO_DATA;
}
return GetEventFromRecordControl(usStreamNumber, pEvent);
}
HX_RESULT
HXNetSource::GetEventFromRecordControl(UINT16 usStreamNumber, CHXEvent*& pEvent)
{
#if defined(HELIX_FEATURE_RECORDCONTROL)
if(!m_bPlayFromRecordControl)
return HXR_UNEXPECTED;
HX_ASSERT(m_pRecordControl);
pEvent = NULL;
IHXPacket* pPacket = NULL;
HX_RESULT nResult = m_pRecordControl->GetPacket(usStreamNumber, pPacket);
STREAM_INFO* pStreamInfo = NULL;
mStreamInfoTable->Lookup((LONG32) usStreamNumber, (void *&) pStreamInfo);
if(nResult == HXR_OK)
{
UINT32 ulEventTime = 0;
if (pStreamInfo)
{
if (!CanSendToDataCallback(pPacket))
{
UINT32 ulLastPkt =
pStreamInfo->BufferingState().LastPacketTimestamp();
// Use timestamp from the last packet
ulEventTime = AdjustEventTime(pStreamInfo, ulLastPkt);
}
else
{
ulEventTime = AdjustEventTime(pStreamInfo, pPacket->GetTime());
/* Update buffering info and stats */
DataCallback(pPacket);
}
}
pEvent = new CHXEvent(pPacket, 0);
HX_RELEASE(pPacket);
if(!pEvent)
return HXR_FAILED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -