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

📄 ppffsrc.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }    pCompoundEnd = pCompound + ulCompoundLen;        UINT8 uchVersion;    UINT16 unLength;    UINT8 uchType;    BYTE* uchOff;    do     {    	uchOff = pCompound;	uchVersion	= (*uchOff++ & 0xc0) >> 6;	uchType		= *uchOff++;	unLength	= *uchOff++ << 8;	unLength	|= *uchOff++;	// If it's our own RR, just ignore!	if (RTCP_RR == uchType) 	{	    UINT32 ulRrSsrc;	    ulRrSsrc  = ((UINT32)*uchOff++)<<24; 	    ulRrSsrc |= ((UINT32)*uchOff++)<<16;	    ulRrSsrc |= ((UINT32)*uchOff++)<<8; 	    ulRrSsrc |= ((UINT32)*uchOff++);	    if (ulRrSsrc == m_ulThisSrcID)	    {                // this is our own RR		goto done;	    }	}	pCompound = (pCompound + ((unLength + 1) * 4));    } while (pCompound < pCompoundEnd && uchVersion == 2);    if (pCompound!= pCompoundEnd)    {	HX_ASSERT(uchVersion == 2);	HX_ASSERT(pCompound > pCompoundEnd);	HX_ASSERT(pCompound < pCompoundEnd);	HX_ASSERT(FALSE && "invalid RTCP length");	/* something is worng */	goto done;    }    /*    * This may be a compound RTCP packet so keep unpacking until we    * have unpacked everything.    */     while (pNext && pNext < (pFirst + pBuf->GetSize()))    {	RTCPPacket	pkt;		pNext = pkt.unpack(pNext, (pFirst + pBuf->GetSize()) - pNext);		// erase:  Look in rmartsp rtpwrap.h unpack	// sometimes sdes_data is NULL for some reason.	if (NULL == pNext)	{	    HX_ASSERT(FALSE && "sdes_data empty");	    continue;	}	switch (pkt.packet_type)	{	case RTCP_SR:	    {		// get the right source from ssrc		if (!GetStreamBySSRC(pkt.sr_ssrc, pStrm))		{		    /*		     *	Unless we receive at least one RTP pkt (which can 		     *	be used to make sure payload type is the same), don't		     *	take any SR		     */		    goto done;	     	}		HX_ASSERT(pStrm);		pStrm->m_bHeardSinceLastTime = TRUE;		pStrm->m_ulNumRRIntervals    = 0;		if (!pStrm->m_bMadeCut)		{		    goto done;		}				if (!pStrm->IsRMStream())		{		    pStrm->m_Syncer.HandleRTCPSync(NTPTime(pkt.ntp_sec, pkt.ntp_frac),						   pkt.rtp_ts);		}#ifdef _SYNC_TRACE		if (m_sfile)		{		    fprintf(m_sfile, "syncing ssrc(%u): TS(%u) -> %u\n",			pkt.sr_ssrc, 			pStrm->m_Syncer.GetSyncOffsetRTP(), 			pStrm->m_Syncer.GetSyncOffsetHX());		    fflush(m_sfile);		}#endif	// _SYNC_TRACE				// it's better come from sender of RTP pkt		if (pStrm->m_ulSSRC != pkt.sr_ssrc)		{		    HX_ASSERT(FALSE && "wrong ssrc in SR");		    goto done;		}		/*************		*** need to be tested later		**************/		// save SR ts		// the middle 32 bits out of 64 in the NTP timestamp		pStrm->m_ulLSR = pkt.ntp_sec  << 16;		pStrm->m_ulLSR |= pkt.ntp_frac;		// save current time for later use 		pStrm->m_ulLastSRArrivalTime = HX_GET_TICKCOUNT();	    }	    break;	    	case RTCP_BYE:	    {		// In this RTCP, there should be nothing after Bye	    // 	    	UINT32* pByeSsrc;	    	// remove all the source in this bye	    	for (UINT32 i = 0; i < pkt.count; i++)	    	{	    	    pByeSsrc = pkt.bye_src + i;#ifdef XXXGo_DEBUG		    if (m_pFFLog)		    {			fprintf(m_pFFLog, "BYE!!!\n");		    }#endif		    		    // we don't want to end this stream right away as it still		    // has some packets in the buffer that needs to be played    		    if (!MarkAsEnd(*pByeSsrc))	    	    {	    		if (!RemoveSource(*pByeSsrc))	    		{	    		    // this is BYE from non-sender  	    	    	    RemoveMember(*pByeSsrc);			  	    	    	}  	    	    }	    	}	    		    	theErr = HXR_OK;	   			if (m_pByePkt && m_pRTCPInterval)		{		    // RTCP_BYE is pending.		    m_pRTCPInterval->SetCurNumMembers(m_pRTCPInterval->GetCurNumMembers()+1);		}		goto done;	    }	    break;	    	case RTCP_SDES:	    {	    	if (!pStrm)	    	{		    HX_ASSERT(pMember);		    if (!pMember)		    {		    	goto done;		    }	    	}	    	else	    	{	    	    pMember = pStrm;	    	}		/*******************	    	* get at leat CNAME	    	********************/	    	// look for list of sdes item with source id	    	CHXSimpleList* pSdesList;	    	SDESItem* pSdes;		if (pkt.m_mapSDESSources.Lookup(pMember->m_ulSSRC, (void*&)pSdesList))		{		    // set up variables to iterate over list		    int nNumElements = pSdesList->GetCount();		    LISTPOSITION lpPosition = pSdesList->GetHeadPosition();		    // Go through all list elements deleting the data at each node.		    for (int i=0; i < nNumElements; i++)		    {			pSdes = (SDESItem*) pSdesList->GetNext(lpPosition);			// set up			CHXString** ppStr = NULL;			if (SDES_CNAME == pSdes->sdes_type)	    		    ppStr = &pMember->m_pCName;			else if (SDES_NAME == pSdes->sdes_type)			    ppStr = &pMember->m_pName;			else if (SDES_EMAIL == pSdes->sdes_type)			    ppStr = &pMember->m_pEmail;			else if (SDES_PHONE == pSdes->sdes_type)			    ppStr = &pMember->m_pPhone;			else if (SDES_LOC == pSdes->sdes_type)		 	    ppStr = &pMember->m_pLoc;			else if (SDES_TOOL == pSdes->sdes_type)			    ppStr = &pMember->m_pTool;			else if (SDES_NOTE == pSdes->sdes_type)			    ppStr = &pMember->m_pNote;			else if (SDES_PRIV== pSdes->sdes_type)			    ppStr = &pMember->m_pPriv;			else			    HX_ASSERT(FALSE && "wrong sdes_type");			if (!*ppStr)			{			    *ppStr = new CHXString(pSdes->data);			}			else if (**ppStr != (const char*)pSdes->data)			{			    // since we keyed off from ssrc, ssrc might 			    // have been changed (restart/collision)			    // XXXGH need to update maps			    /*			    char sz[100];			    memset(sz, 0, 100);			    wsprintf( sz, "what we had = %s\n"	  		                  "new one     = %s ", 	    				   (*ppStr)->GetBuffer(10),	    				   pSdes->data);			    ::MessageBox( NULL, sz, "SDES not the same", MB_OK );			    HX_ASSERT(FALSE && "sdes not the same");			    */			}			ppStr = NULL;			/*			* XXXGH			* somehow, we have to store ssrc that comes with 			* SDES, so we can correctly map it			*/		    }  		}	    }	    break;	    	case RTCP_RR:	    {		if (pkt.rr_ssrc == m_ulThisSrcID)		{		    // just ignore our own RR.		    goto done;		}		else		{ 		    if (!GetStreamBySSRC(pkt.rr_ssrc, pStrm))		    {		    	// this is not a sender			if (!GetMember(pkt.rr_ssrc, pMember))			{			    AddNewMember(pkt.rr_ssrc, pMember);			}#ifdef XXXGo_DEBUG			if (m_pFFLog)			{			    fprintf(m_pFFLog, "put %d %d\n", 			    pMember->m_binInfo.lBin,			    pMember->m_binInfo.pos);			    fflush(m_pFFLog);			}#endif						m_MemberTimeoutBins.PutInNewestBin(pMember, pMember->m_binInfo);         	    }		}	    }	    break;	    	case RTCP_APP:	    {		//::MessageBox( NULL, NULL, "RTCP_APP", MB_OK );	    }	    break;	    	default:	    break;	}    } // end while        done:    HX_RELEASE(pBuf);    if (m_pRTCPSock)    {	m_pRTCPSock->Read(1024);      }    return theErr;}/**   */HX_RESULTCPurePlaySource::UpdateStatistics(IHXRegistry* pReg, ULONG32 ulTimeNow){    /*    * If we have had the registry ID of the place to put    * our bandwidth info set then use it and set the proper    * bandwidth for this stream    */    CStream* pStream = NULL;    CHXMapLongToObj::Iterator i;    // if GetStreamByStrmId() doesn't find the Stream, it will return NULL    for (i = m_SsrcToStream.Begin();	 i != m_SsrcToStream.End();	 ++i)    {	pStream = (CStream*) (*i);	HX_ASSERT(pStream);	// for each stream, update the stats	if (pStream && 	    (pStream->m_bMadeCut) && 	    (pStream->m_ulClipBandwidthID != 0))	{	    pStream->UpdateStatistics(pReg, ulTimeNow);	}	    	    }    return HXR_OK;}HX_RESULTCPurePlaySource::MakeRR(REF(RTCPPacket) pktRR){/*    if (GetNumSrc() == 0)    {	// it dones't make sense to even try to send RR when there is no sender	return HXR_FAIL;    }*/        /*    * this is a good chance to look at any inactive source and get rid of it    * from the map    */    CHXMapLongToObj::Iterator i;    UINT32 ulSrcCount = 0;//    UINT32 ulNumInactive = 0;    CStream* pStrm = NULL;        for (i  = m_SsrcToStream.Begin(); i != m_SsrcToStream.End(); ++i)    {	pStrm = (CStream*)(*i);    	if (pStrm->m_bHeardSinceLastTime)    	{    	    ulSrcCount++;    	}    	else     	{    	    if (pStrm->m_bMadeCut)    	    {    		// 2 RTCP interval is too small.  Once we remove this source,    		// it will call StreamDone on this stream.  so, a little     		// congestion end up with end of feed.    	    	if (++pStrm->m_ulNumRRIntervals >= 5)    	    	{#ifdef XXXGo_DEBUG	if (m_pFFLog)	{	    fprintf(m_pLogFile, "SenderTimeout! Stream# %u\n", pStrm->m_unStreamNum);	    fflush(m_pLogFile);	}#endif		                	    	    	    	    RemoveSource(pStrm->m_ulSSRC);//		    ulNumInactive++;		}	    }    	    else    	    {    		// rest of sources can come and go.  Much important to get the     		// number of sources right!    		if (++pStrm->m_ulNumRRIntervals >= 2)    		{    		    RemoveSource(pStrm->m_ulSSRC);    		}    	    }    	}    }#if 0    // if we haven't heard from any of sources for 5 RR intervals,    // assume end    if ((GetNumSrc() != 0) && (GetNumSrc() == ulNumInactive))    {    	for (i  = m_StrmIdToStrm.Begin(); i != m_StrmIdToStrm.End(); ++i)    	{    	    RemoveSource(((CStream*)(*i))->m_ulSSRC);	}	return HXR_FAIL;    }#endif        pktRR.version_flag = 0x02;	   // protocol version    pktRR.padding_flag = 0;	   // no padding    pktRR.packet_type = RTCP_RR;   // this is RR    pktRR.rr_ssrc = m_ulThisSrcID; // receiver generating this report    // If there is no data transmission or reception to report, just add empty     // RR pkt with count = 0    if (0 == ulSrcCount)    {    	pktRR.count = 0;    	pktRR.length = 1;    }    else    {    	pktRR.count = (UINT8)ulSrcCount;    	// 6 bytes / report    	pktRR.length = 1 + 6 * (UINT16)ulSrcCount;            ReceptionReport* pRr = new ReceptionReport[ulSrcCount];        if (!pRr)        {            return HXR_FAIL;        }        UINT32 ulCount = 0;        for (i  = m_SsrcToStream.Begin();             i != m_SsrcToStream.End() && ulCount < ulSrcCount;     	     ++i)        {            if (((CStream*)(*i))->m_bHeardSinceLastTime)  	    {    	    	((CStream*)(*i))->GetReceptionReport(pRr[ulCount]);    	    	((CStream*)(*i))->m_bHeardSinceLastTime = FALSE;    	    	ulCount++;    	    }        }        HX_ASSERT(ulCount == ulSrcCount);        // XXXGo ReceptionReport::static_size() returns 24 because lost is in fact     	// 24 bits.  However, since it is represented as UINT32, I really want 25.    	// so, calling sizeof() for now.//    	pktRR.SetReceiverReport(pRr, sizeof(ReceptionReport) * ulSrcCount);    	pktRR.SetReceiverReport(pRr, ulSrcCount);    	// since SetReceiverReport is making a copy, delete what we have    	HX_VECTOR_DELETE(pRr);    }     return HXR_OK;}/**  Schdule a callback with a relative time*/voidCPurePlaySource::Schedule(UINT32 ulNextTime, int lEvent){    if (!m_pScheduler)    {	return;    }        if (m_hStatusCallbackID != 0)    {#ifdef XXXGo_DEBUG	if (m_pLogFile)	{	    fprintf(m_pLogFile, "Re - ");	    fflush(m_pLogFile);	}	    #endif    	m_pScheduler->Remove(m_hStatusCallbackID);	m_hStatusCallbackID = 0;    }    HX_ASSERT(0 == m_hStatusCallbackID);        CRTCPSendStatusCallback* pSSCB = new CRTCPSendStatusCallback(this, lEvent);    if (!pSSCB)    {	return;    }#ifdef XXXGo_DEBUG	if (m_pLogFile)	{	    fprintf(m_pLogFile, "Schduling (%u)\n", ulNextTime);	    fflush(m_pLogFile);	}	    #endif        pSSCB->AddRef();    m_hStatusCallbackID = m_pScheduler->RelativeEnter(pSSCB, ulNextTime);    pSSCB->Release();}voidCPurePlaySource::OnExpire(INT32 lEvent){#ifdef XXXGo_DEBUG	if (m_pLogFile)	{	    fprintf(m_pLogFile, "\tOnExpire\n");	    fflush(m_pLogFile);	}	    #endif    // Remove any member that timeout.    CleanupMemberTable();    /*     *	This func is responsible for deciding whether to send an RTCP report or      *	BYE packet now, or to reschedule transmission.     *  It is also responsible for updating the pmembers, initial, tp, and      *	avg_rtcp_size state var's.  This func should be called upon expiration      *	of the event timer.     */    UINT32 ulInterval = 0;	/* Interval *///    double  tn;	/* Next transmit time */    BOOL    bSendIt = FALSE;	/* flag for sending pkt */    UINT32 ulCurTime = GetCurrentSchedulerTimeInMsec(m_pScheduler);    //    HXTimeval lTime = m_pScheduler->GetCurrentSchedulerTime();    // in msec.//    UINT32 ulCurTime = lTime.tv_sec * 1000 + lTime.tv_usec / 1000;       UINT32 ulLastTime = m_pRTCPInterval->GetLastRTCPTime();    // ulNumMembers + ulNumSenders = Total num members    UINT32 ulNumMembers = m_SsrcToMember.GetCount();    UINT32 ulNumSenders = GetTrueNumSrc();        /*      *	To compensate for OPTION B converging to a value below the intended      *	average.     */    double const COMPENSATION = 2.71828 - 1.5;    /*

⌨️ 快捷键说明

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