📄 hxntsrc.cpp
字号:
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_RESULTHXNetSource::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 // IsTimeStampDeliverycleanup: 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 */}BOOLHXNetSource::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 */}UINT16HXNetSource::GetNumStreams(void){ HX_ASSERT(m_bInitialized); return m_uNumStreams;}HX_RESULTHXNetSource::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_RESULTHXNetSource::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_RESULTHXNetSource::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; 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_RESULTHXNetSource::GetEventFromProtocol(UINT16 usStreamNumber, CHXEvent*& pEvent){ HX_RESULT theErr = HXR_OK; UINT32 ulEventTime = 0; UINT32 ulRemainToBufferInMs = 0; UINT32 ulRemainToBuffer = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -