📄 hxsm.cpp
字号:
// satisfactory as a truly long term solution since // bw rate control is regarded by some as critical // for limited resource platforms.#if !defined(HELIX_CONFIG_LOW_HEAP_STREAMING) pThin->SetDeliveryBandwidth(ulActualRate, 0);#endif } else { ulTotalBandwidth += pASMSourceInfo->m_ulLastSetDelivery; } } HX_RELEASE(pThin); } if (bLossBehind) { m_ulNumReportsSinceUpShift = -10; m_ulResistanceBitRate = MAX(15000, ulTotalBandwidth); DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "Resistance Move %d", m_ulResistanceBitRate)); } } } else if (!ulNumSlightlyBehindSources) { INT32 lAccelTestPoint; double dRFactor = 1.05; if ((INT32)m_ulUpShiftBandwidthAvail > lAggregateBandwidthUsage) { lAccelTestPoint = (INT32) ((m_ulUpShiftBandwidthAvail - lAggregateBandwidthUsage) * ((float)m_ulUpShiftTestPointScaleFactor / 10000.0) + lAggregateBandwidthUsage); } else { lAccelTestPoint = lAggregateBandwidthUsage; } UINT32 ulAccelTestPoint = (lAccelTestPoint > 0) ? (UINT32)lAccelTestPoint : 0; BOOL bResistanceLimited = FALSE; BOOL bWentHigherThanResistanceRate = FALSE; if (ulAccelTestPoint > m_ulMaxAccelBitRate) { ulAccelTestPoint = m_ulMaxAccelBitRate; } if (ulAccelTestPoint > m_ulResistanceBitRate) { UINT32 ulActualResistanceBitRate = m_ulResistanceBitRate; if (ulActualResistanceBitRate < ulAggregateUsed) { ulActualResistanceBitRate = (UINT32)(ulAggregateUsed * 1.05); } UINT32 ulOldAccelTestPoint = ulAccelTestPoint; if (ulAccelTestPoint > ulActualResistanceBitRate) { UINT32 bHowManyReports = (ulActualResistanceBitRate < ulTotalMaxSubscribedBw) ? 5 : 10; if (m_ulUpShiftPastResistanceCount > bHowManyReports) { bWentHigherThanResistanceRate = TRUE; if ((m_ulOriginalResistanceBitRate > ulActualResistanceBitRate) && (ulActualResistanceBitRate < ulTotalMaxSubscribedBw)) { dRFactor = (ulActualResistanceBitRate + ((m_ulOriginalResistanceBitRate - ulActualResistanceBitRate) * 0.10)) / (double)ulActualResistanceBitRate; if (dRFactor < 1.01) { dRFactor = 1.01; }#ifdef MOREDEBUG DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "Resistance Accel Factor %0.2f", dRFactor));#endif } else { dRFactor = 1.01; } ulAccelTestPoint = (UINT32)(ulActualResistanceBitRate * dRFactor); } else { ulAccelTestPoint = ulActualResistanceBitRate; } if (ulOldAccelTestPoint < ulAccelTestPoint) { ulAccelTestPoint = ulOldAccelTestPoint; } else { bResistanceLimited = TRUE; } } } if ((m_ulNumReportsSinceUpShift >= 2) && ((INT32)m_ulHighestBandwidthAvail < lAggregateBandwidthUsage)) { m_ulHighestBandwidthAvail = lAggregateBandwidthUsage; m_ulPeakUsedBandwidth = lAggregateBandwidthUsage; m_bInitialHighBwAvail = FALSE; } DEBUG_OUT(m_pEM, DOL_TRANSPORT_EXTENDED, (s, "UP Bw Report: Num=%d, Avail=%d, CurrentBw=%d, TestPoint=%d", m_ulNumReportsSinceUpShift, m_ulUpShiftBandwidthAvail, lAggregateBandwidthUsage, ulAccelTestPoint)); BOOL bDidChange = FALSE; BOOL bBrokeMax = FALSE; if ((m_ulNumReportsSinceUpShift >= 2) && (INT32) (ulAccelTestPoint) > lAggregateBandwidthUsage) { m_ulLastStableBandwidth = lAggregateBandwidthUsage; for (i = m_pASMSourceInfo->Begin(); i != m_pASMSourceInfo->End(); ++i) { pASMSourceInfo = (ASMSourceInfo*)(*i); IHXThinnableSource* pThin = 0; UINT32 ulSourceBandwidth = pASMSourceInfo->m_ulSubscribedBw; UINT32 ulNewValue = (UINT32)( (float)ulSourceBandwidth / (float)ulAggregateUsed * (float)ulAccelTestPoint); if (ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw * 4)) { ulNewValue = (UINT32) (pASMSourceInfo->m_ulMaxSubscribedBw * 4); } /* * Live streams get capped at 107% of Max to prevent * unneeded bandwidht modulation. */ if ((pASMSourceInfo->m_pSource->IsLive()) && (ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw * 1.07))) { ulNewValue = (UINT32) (pASMSourceInfo->m_ulMaxSubscribedBw * 1.07); } if ((ulNewValue > (pASMSourceInfo->m_ulMaxSubscribedBw)) && (ulNewValue > (ulSourceBandwidth * 3)) && (pASMSourceInfo->m_ulLastSetDelivery < pASMSourceInfo->m_ulMaxSubscribedBw)) { /* * If we are already accelerating 3x subscribed bandwidth * and we are about to upshift beyond the max possible * bandwidth, then let's stop and take a breather just * above the max subscription. This prevents us from * buffering huge amounts of the crappy low bw stream. */ UINT32 ulTemp; ulTemp = (UINT32) (pASMSourceInfo->m_ulMaxSubscribedBw * 1.10); ulNewValue = MIN(ulTemp, ulNewValue); } if (pASMSourceInfo->m_ulLastSetDelivery > pASMSourceInfo->m_ulMaxSubscribedBw) { bBrokeMax = TRUE; } if (pASMSourceInfo->m_bMayBeAccelerated && (HXR_OK == pASMSourceInfo->m_pSource-> QueryInterface(IID_IHXThinnableSource, (void **)&pThin))) { double Factor; if (bResistanceLimited) { Factor = 1.005; } else if (pASMSourceInfo->m_pSource->IsLive()) { Factor = 1.01; } else { Factor = 1.05; } if ((ulNewValue > (pASMSourceInfo->m_ulLastSetDelivery * Factor)) && pASMSourceInfo->m_bSourceAccelAllowed) { DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "(%p)Accelerating: NewTransmissionRate=%d", pASMSourceInfo->m_pSource, ulNewValue)); m_ulUpShiftPastResistanceCount = 0; if (ulNewValue > ulSourceBandwidth) { pASMSourceInfo->m_pSource->LeaveBufferedPlay(); } bDidChange = TRUE; /* * WHOA! If this is a timestamp delivered source * i.e. 5.0 thinning, then the imperical Getbandwidth() * will never reach the rate that we set, so we help * it along a bit (just a bit of a nudge, eh?). */ if (pASMSourceInfo->m_bTimeStampDelivery) { pASMSourceInfo->m_ulIncomingBandwidth = ulNewValue; } m_ulNumReportsSinceUpShift = 0; pASMSourceInfo->m_bInvalidUpReport = TRUE; m_bDidOfferUpShiftToRecalc = FALSE; pThin->SetDeliveryBandwidth( (pASMSourceInfo->m_ulLastSetDelivery = ulNewValue), 0); } } HX_RELEASE(pThin); } } if ((bDidChange == TRUE) && (bWentHigherThanResistanceRate)) { m_ulResistanceBitRate = (UINT32)(m_ulResistanceBitRate * dRFactor); DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "Went over ResistanceBitRate %d", m_ulResistanceBitRate)); } if (((bDidChange == FALSE) && (m_ulNumReportsSinceUpShift > NUM_REPORTS_NEEDED_TO_UPSHIFT) || (bBrokeMax == TRUE)) && (m_bDidOfferUpShiftToRecalc == FALSE)) { m_State = HX_NONE; m_bDidOfferUpShiftToRecalc = TRUE; m_ulOfferToRecalc = lAggregateBandwidthUsage;#ifdef MOREDEBUG DEBUG_OUT(m_pEM, DOL_TRANSPORT, (s, "Upshift Offer to Recalc() %d", m_ulOfferToRecalc));#endif Recalc(); return; } }}voidASMStreamInfo::NotifyNewBandwidth(){ m_pNegotiator->SetBandwidthUsage(m_ulLastBandwidth, m_bTimeStampDelivery);}voidASMStreamInfo::NotifyTimeStampDelivery(){ if(m_bTimeStampDelivery) { m_pASMSourceInfo->m_bTimeStampDelivery = TRUE; }}UINT32ASMSourceInfo::GetBandwidth(){ return m_ulIncomingBandwidth;}voidASMStreamInfo::SetLastBandwidth(UINT32 ulOffer){ m_ulLastBandwidth = ulOffer;}voidASMStreamInfo::NotifyLimitBandwidth(UINT32 ulRecv){ if(m_pASMSourceInfo->m_bBehind) { m_pNegotiator->HandleSlowSource(ulRecv); }}ASMSourceInfo::ASMSourceInfo(HXSource* pSource, HXSM* pHXASM) : m_ulLastReportTime(0) , m_ulIncomingBandwidth(0) , m_ulRateBeforeDeAccel(0) , m_lTimeDiffBase(0) , m_ulBytesBehind(0) , m_lLastBehindTime(0) , m_ulLastSetDelivery(0xffffffff) , m_ulSubscribedBw(0) , m_ulMaxSubscribedBw(0) , m_bBehind(FALSE) , m_bLossBehind(FALSE) , m_bSlightlyBehind(FALSE) , m_bTimeStampDelivery(FALSE) , m_bPendingChill(FALSE) , m_bInvalidUpReport(FALSE) , m_bPerfectPlay(FALSE) , m_bIsDone(FALSE) , m_bMayBeAccelerated(TRUE) , m_bTryToUpShift(FALSE) , m_bAdjustBandwidth(FALSE) , m_ulLowestBandwidthBeforeTimeStamp(0) , m_bSourceAccelAllowed(TRUE) , m_bSourceDecelAllowed (TRUE) , m_bSlidingBwWindowReady(FALSE) , m_pMasterRuleBook(0) , m_pStreams(0) , m_TransportType(TNG_UDP) , m_pSource(pSource) , m_pSBI(0) , THRESHOLD(1000) , m_lRefCount(0) , m_ulBwDetectionDataCount(0) , m_ulBwDetectionDataLen(0) , m_ulSlidingWindowLocation(0) , m_pBwDetectionData(NULL) , m_pHXASM(pHXASM){ m_lOuterThreshold = THRESHOLD; IHXValues* pHeader = 0; pSource->AddRef(); if (pSource->m_pFileHeader) { IHXBuffer* pMasterRuleBook = NULL; pSource->m_pFileHeader-> GetPropertyCString("ASMRuleBook", pMasterRuleBook); if (pMasterRuleBook) { m_pMasterRuleBook = new ASMRuleBook ((const char *)pMasterRuleBook->GetBuffer()); } HX_RELEASE(pMasterRuleBook); }}ASMSourceInfo::~ASMSourceInfo(){ HX_VECTOR_DELETE(m_pBwDetectionData); delete[] m_pStreams; delete m_pMasterRuleBook;}BOOLASMSourceInfo::AllocBWDetectionData(UINT32 ulReqSize){ BOOL bOk = TRUE; // Our current array is too small if (ulReqSize > m_ulBwDetectionDataLen) { BwDetectionData* pTemp = new BwDetectionData[ulReqSize]; if (!pTemp) { bOk = FALSE; } else { if (m_pBwDetectionData) { memcpy(pTemp, m_pBwDetectionData, m_ulBwDetectionDataLen * sizeof(BwDetectionData)); /* Flawfinder: ignore */ HX_VECTOR_DELETE(m_pBwDetectionData); } m_pBwDetectionData = pTemp; m_ulBwDetectionDataLen = ulReqSize; } } return bOk;}voidASMSourceInfo::Done(){ HX_RELEASE(m_pSBI); HX_RELEASE(m_pSource); m_bIsDone = TRUE;}STDMETHODIMP_(UINT32)ASMSourceInfo::AddRef(void){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(UINT32)ASMSourceInfo::Release(void){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMPASMSourceInfo::QueryInterface( REFIID interfaceID, void** ppInterfaceObj){ QInterfaceList qiList[] = { { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)this }, { GET_IIDHANDLE(IID_IHXBandwidthManagerInput), (IHXBandwidthManagerInput*)this }, }; return ::QIFind(qiList, QILISTSIZE(qiList), interfaceID, ppInterfaceObj);}STDMETHODIMPASMSourceInfo::ReportDataPacket( UINT32 ulTimeStamp, UINT32 ulArrivedTimeStamp, UINT32 ulSize){ if (m_bIsDone) { return HXR_OK; } UINT32 ulCurrentTime = HX_GET_TICKCOUNT(); if (!m_pHXASM->m_ulNextPacketWindow) { m_pHXASM->m_ulNextPacketWindow = ulCurrentTime; } if (ulSiz
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -