⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtcputil.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    /*
     * Increment item byte count for null termination
     */
    unByteCount++;
    
    // Align on word boundary
    // RTCP pkt length is in 32-bits word!
    unByteCount += (unByteCount % 4) ? 4 - (unByteCount % 4) : 0;

    HX_ASSERT(unByteCount % 4 == 0);
    // I am counting 32-bits word
    pPkt->length = (unByteCount / 4);	    // count of words - 1

    //one more 32-bits for SSRC
    pPkt->length++;
        
    return HXR_OK;
}

HX_RESULT
ReportHandler::MakeBye(RTCPPacket* pPkt)
{
    HX_ASSERT(m_pSenderMe || m_pReceiverMe);
    HX_ASSERT(pPkt);
    
    pPkt->version_flag = 0x02;
    pPkt->padding_flag = 0;    
    pPkt->packet_type = RTCP_BYE;    
    pPkt->length = 1;   // len in 32-bits words minus one
    pPkt->count = 1;
    // use access function
    if (m_pSenderMe)
    {
	pPkt->SetByeSrc(&m_pSenderMe->m_ulSsrc, pPkt->count);        
#ifdef DUMP_REPORTS
	printf("BYE %u:\n", m_pSenderMe->m_ulSsrc);
#endif	
    }
    else
    {
    	pPkt->SetByeSrc(&m_pReceiverMe->m_ulSsrc, pPkt->count);        
#ifdef DUMP_REPORTS
	printf("BYE %u\n", m_pReceiverMe->m_ulSsrc);
#endif	
    }

#ifdef DUMP_REPORTS
    fflush(stdout);
#endif    
    return HXR_OK;
}

/*
*   for now this is the only APP.  
*/
HX_RESULT
ReportHandler::MakeEOSApp(RTCPPacket* pPkt)
{
    HX_ASSERT(m_pSenderMe);
    HX_ASSERT(pPkt);
    
    pPkt->version_flag = 0x02;
    pPkt->padding_flag = 0;    
    pPkt->packet_type = RTCP_APP;
    pPkt->app_ssrc = m_pSenderMe->m_ulSsrc;
    pPkt->count = 1;	
    pPkt->length = 4;   // 2 + the length of APPItem...fortunately, we don't 
			// have to align them
    memcpy(pPkt->app_name, "RNWK", 4); /* Flawfinder: ignore */

    // this is application dependent...
    APPItem item;
    item.app_type = APP_EOS;
    item.seq_no = m_pSenderMe->m_unLastSeqNo;
    item.packet_sent = (UINT8)m_pSenderMe->m_ulNumPktSentSoFar ? 1 : 0;
    item.timestamp = m_pSenderMe->m_ulLastRTPTimestamp;

    pPkt->SetAPPItem(&item, pPkt->count);   

    return HXR_OK;
}

HX_RESULT
ReportHandler::MakeBufInfoApp(RTCPPacket* pPkt, 
			      UINT32 ulLowTS, UINT32 ulHighTS,
			      UINT32 ulBytesBuffered)
{
    HX_RESULT res = HXR_UNEXPECTED;

    if (pPkt)
    {
	pPkt->version_flag = 0x02;
	pPkt->padding_flag = 0;    
	pPkt->packet_type = RTCP_APP;
	pPkt->count = 1;
	pPkt->app_ssrc = m_pReceiverMe->m_ulSsrc;
	memcpy(pPkt->app_name, "HELX", 4);
	pPkt->length = 2;

	APPItem item;
	item.app_type = APP_BUFINFO;
	item.lowest_timestamp = ulLowTS;
	item.highest_timestamp = ulHighTS;
	item.bytes_buffered = ulBytesBuffered;
	item.padding0 = 0;
	pPkt->SetAPPItem(&item, 1);
	pPkt->length += 4;
	res = HXR_OK;
    }

    return res;
}

ReceiverInfo*
ReportHandler::GetOrCreateReceiverInfo(UINT32 ulSsrc)
{
    ReceiverInfo* pReceiver = NULL;
    if (!m_mapReceivers.Lookup(ulSsrc, (void*&)pReceiver))
    {
#ifdef DUMP_MEMBER_COUNT    
	printf("New Receiver (#%u): %u\n", m_mapReceivers.GetCount()+1, ulSsrc);
	fflush(stdout);
#endif	
	// doesn't exist, create one.
	pReceiver = new ReceiverInfo;
	if (!pReceiver)
	{
	    return NULL;
	}
	m_mapReceivers.SetAt(ulSsrc, (void*)pReceiver);
#if _DEBUG
	ReceiverInfo* pTmp = NULL;
	HX_ASSERT(m_mapReceivers.Lookup(ulSsrc, (void*&)pTmp));	
	HX_ASSERT(pTmp);
#endif		
    }

    HX_ASSERT(pReceiver);
    return pReceiver;
}

void
ReportHandler::DeleteReceiverInfo(UINT32 ulSsrc)
{
    /*	since we need to do timeout, we might as well do the right thing for
    *	this as well....mark as delete, and delete after a fixed timeout...so, 
    *	we know we don't receive any late pkt after we delete this entry...    
    */

    ReceiverInfo* pReceiver = NULL;
    if (m_mapReceivers.Lookup(ulSsrc, (void*&)pReceiver))
    {
#ifdef DUMP_MEMBER_COUNT    
	printf("Deleteing Receiver: %u\n", ulSsrc);
	fflush(stdout);
#endif	
	HX_ASSERT(pReceiver);
	m_mapReceivers.RemoveKey(ulSsrc);
	delete pReceiver;
    }    
}

ReceptionInfo*
ReportHandler::GetOrCreateReceptionInfo(UINT32 ulSsrc)
{
    ReceptionInfo* pRInfo = NULL;
    if (!m_mapSenders.Lookup(ulSsrc, (void*&)pRInfo))
    {
#ifdef DUMP_MEMBER_COUNT    
	printf("New Sender (#%u): %u\n", m_mapSenders.GetCount()+1, ulSsrc);
	fflush(stdout);
#endif	
	// doesn't exist, create one.
	pRInfo = new ReceptionInfo();
	if (!pRInfo)
	{
	    return NULL;
	}
//	pRInfo->m_ulProbation = m_ulDefaultProbation;
	
	m_mapSenders.SetAt(ulSsrc, (void*)pRInfo);
#if _DEBUG
	ReceptionInfo* pTmp = NULL;
	HX_ASSERT(m_mapSenders.Lookup(ulSsrc, (void*&)pTmp));	
	HX_ASSERT(pTmp);
#endif		
    }

    HX_ASSERT(pRInfo);
    return pRInfo;
}

void
ReportHandler::DeleteReceptionInfo(UINT32 ulSsrc)
{
    /*	since we need to do timeout, we might as well do the right thing for
    *	this as well....mark as delete, and delete after a fixed timeout...so, 
    *	we know we don't receive any late pkt after we delete this entry...    
    */

    ReceptionInfo* pRInfo= NULL;
    if (m_mapSenders.Lookup(ulSsrc, (void*&)pRInfo))
    {
#ifdef DUMP_MEMBER_COUNT    
	printf("Deleteing Sender: %u\n", ulSsrc);
	fflush(stdout);
#endif	    
	HX_ASSERT(pRInfo);
	m_mapSenders.RemoveKey(ulSsrc);
	delete pRInfo;
    }    
}

/*
*/
double
ReportHandler::GetRTCPInterval()
{
    // include myself
    double interval = 
    rtcp_interval(m_mapReceivers.GetCount() + 1,
		  m_pSenderMe ? m_mapSenders.GetCount()+1 : m_mapSenders.GetCount(),
		  m_ulRSByteRate,
		  m_ulRRByteRate,
		  m_pSenderMe ? m_pSenderMe->m_bWeSent : 0,
		  m_ulAvgRTCPSize,
		  m_bInitialIntervalCalc,
		  m_minRTCPInterval);

    m_bInitialIntervalCalc = FALSE;	
    return interval;
}

void ReportHandler::SetRTCPIntervalParams(UINT32 ulRSBitRate, 
					  UINT32 ulRRBitRate,
					  UINT32 ulMinRTCPIntervalMs)
{
    m_ulRSByteRate = ulRSBitRate >> 3; // bitrate -> byterate
    m_ulRRByteRate = ulRRBitRate >> 3; // bitrate -> byterate
    m_minRTCPInterval = ((double)ulMinRTCPIntervalMs) / 1000.0; // ms -> sec
}

/*
*   ReceptionInfo Func's
*/

void
ReceptionInfo::InitSeqNo(UINT16 unSeqNo)
{
#ifdef _DEBUG
    HX_ASSERT(INIT == m_state);
    m_state = UPDATE;
#endif    
//    m_ulBaseSeqNo = unSeqNo - 1;
    m_ulBaseSeqNo = unSeqNo;
    m_unMaxSeqNo =  unSeqNo;
    m_ulBadSeqNo =  RTP_SEQ_MOD + 1;
    m_ulCycles =    0;
    m_ulNumPktReceived = 0;    
    m_ulExpectedPrior  = 0;
    m_ulReceivedPrior  = 0;        
}

BOOL
ReceptionInfo::UpdateSeqNo(UINT16 unSeqNo)
{   
#ifdef _DEBUG
    HX_ASSERT(UPDATE == m_state);
#endif

    UINT16 unDelta = unSeqNo - m_unMaxSeqNo;

#if 0 /* don't ever throu pkt away! */
    if (m_ulProbation)
    {
	if (unSeqNo == m_unMaxSeqNo + 1)
	{
	    // pkt is in sequence
	    m_ulProbation--;
	    m_unMaxSeqNo = unSeqNo;
	    if (0 == m_ulProbation)
	    {	
		InitSeqNo(unSeqNo);
		m_ulNumPktReceived++;
		return TRUE;
	    }
	}
	else
	{ 
	    // pkt is NOT in sequence
	    m_ulProbation = MIN_SEQUENTIAL - 1;
	    m_unMaxSeqNo = unSeqNo;
	}
	return FALSE;
    }
    else 
#endif    
    if (unDelta < MAX_DROPOUT)
    {
	// in order, with permissible gap
	if (unSeqNo < m_unMaxSeqNo)
	{
	    // seq# wrapped - count another 64k cycle
	    m_ulCycles += RTP_SEQ_MOD;	    
	}
	
	m_unMaxSeqNo = unSeqNo;
    }
    else if (unDelta <= RTP_SEQ_MOD - MAX_MISORDER)
    {
	// seq# made a very large jump
	if (unSeqNo == m_ulBadSeqNo)
	{
	    // two sequential pkts -- assume that the other side
	    // restarted w/o telling us, so just re-sync
	    // (i.e., pretned this was the first pkt)
	    InitSeqNo(unSeqNo);
	}
	else
	{
	    
	    m_ulBadSeqNo = (unSeqNo + 1) & (RTP_SEQ_MOD - 1);
	    // (i.e. m_ulBadSeq = unSeq + 1;)
	    return FALSE;
	}
    }
    else 
    {
	/* duplicate or reordered packet */
    }

    m_ulNumPktReceived++;    

    return TRUE;
}


void
ReceptionInfo::MakeReceptionReport(UINT32 ulSsrc, REF(ReceptionReport) rr, UINT32 ulNow)
{
#ifdef DUMP_REPROTS
    printf("making rr for %u\n", ulSsrc);
    fflush(stdout);
#endif    

    // ssrc of a sender that we are reporting
    rr.ssrc = ulSsrc;
    
    /* extended last seqno received */
    rr.last_seq = m_ulCycles + m_unMaxSeqNo; 

    /* simply #pkt expected - received */
    UINT32 ulExpected = rr.last_seq - m_ulBaseSeqNo + 1;
    rr.lost =  ulExpected - m_ulNumPktReceived; 

    UINT32 ulExpectedInterval = ulExpected - m_ulExpectedPrior;
    UINT32 ulReceivedInterval = m_ulNumPktReceived - m_ulReceivedPrior;
    INT32  lLostInterval = ulExpectedInterval - ulReceivedInterval;

    // save them for the next time
    m_ulExpectedPrior = ulExpected;
    m_ulReceivedPrior = m_ulNumPktReceived;

    /*
     * The resulting fraction is an 8-bit fixed point number with the binary
     * point at the left edge.
     */  
    if (0 == ulExpectedInterval || lLostInterval <= 0)
    {
	rr.fraction = 0;
    }
    else
    {
	rr.fraction = (UINT8)((lLostInterval << 8) / ulExpectedInterval);
    }
    
    rr.jitter = m_ulJitter >> 4;
    rr.lsr = m_ulLSR ? m_ulLSR : 0;
    /* expressed in 1/65536 sec...ahhh...make it 66 */
    rr.dlsr = (m_ulLastSRReceived ? 
		CALCULATE_ELAPSED_TICKS(m_ulLastSRReceived, ulNow) : 
		0 /* SR not yet received */) * 66;
		

#ifdef DUMP_REPROTS
    printf("\tssrc: %u\n", rr.ssrc);
    printf("\tlast_seq: %u\n", rr.last_seq);
    printf("\tlost: %u\n", rr.lost);
    printf("\tfraction: %u\n", rr.fraction);
    printf("\tjitter: %u\n", rr.jitter);
    printf("\tlsr: %u\n", rr.lsr);
    printf("\tdlsr: %u\n", rr.dlsr);
    fflush(stdout);
#endif    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -