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

📄 rtcp.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 4 页
字号:

    header.ssrc = ssrc;
    
    header.bits = RTCP_HEADER_INIT;
    header.bits = bitfieldSet(header.bits, count, HEADER_RC, HDR_LEN_RC);
    header.bits = bitfieldSet(header.bits, type,  HEADER_PT, HDR_LEN_PT);        
    header.bits = bitfieldSet(header.bits, W32Len(dataLen) - 1, 
                              HEADER_len, HDR_LEN_len);
    
    ConvertFromNetwork(&header, 0, W32Len(SIZEOF_RTCPHEADER));

    return header;
}


static RvUint32 getLost(rtpSource *s)
{
    RvUint32 extended_max;
    RvUint32 expected;
    RvInt32  received_interval;
    RvInt32  expected_interval;
    RvInt32  lost;
    RvInt32  lost_interval;
    RvUint8  fraction;

    extended_max = s->cycles + s->max_seq;
    expected = extended_max - s->base_seq + 1;
    lost = expected - s->received;
    expected_interval = expected - s->expected_prior;
    s->expected_prior = expected;
    received_interval = s->received - s->received_prior;
    s->received_prior = s->received;
    lost_interval = expected_interval - received_interval;
    
    if (expected_interval == 0  ||  lost_interval <= 0) 
        fraction = 0;
    else 
        fraction = (RvUint8)((lost_interval << 8) / expected_interval);

    return (fraction << 24) + lost;
}


static RvUint32 getJitter(rtpSource *s)
{
    return s->jitter >> 4;
}

static RvUint32 getSequence(rtpSource *s)
{
    return s->max_seq + s->cycles;
}

/* 
static RvBool socketCompare(rtcpSession *element1, rtcpSession *element2)
{
    return (element1->socket == element2->socket);
}
  */

/* static RvBool ssrcCompare(rtcpInfo *element1, rtcpInfo *element2)
{
    return (element1->ssrc == element2->ssrc);
} */

static void rtcpReceive_(RvSocketSelect* ss, RvSocketListener* sl, void *data) 
{
    rtcpSession* s = (rtcpSession*)sl->data;
    RvSocketAddr fromAddr;
    RvUint32 buffer[MAXRTCPPACKET/sizeof(RvUint32)+1];
    RV_BUFFER buf;

    if (s == NULL) 
        return;

	rvMutexLock(&s->mutex);

    buf = buffCreate(buffer, MAXRTCPPACKET);

    buf.length = rvSocketRecvFrom(&s->socket, buf.buffer, buf.length, &fromAddr);

    if (rvSocketAddrGetInetPort(&fromAddr) != rvSocketGetPort(&s->socket) || 
	  !isMyIP(&fromAddr))
        rtcpProcessCompoundRTCPPacket((HRTCPSESSION)s, &buf, getNNTPTime());

	rvMutexUnlock(&s->mutex);
}

static void rtcpTimerCallback(RvTimer *timer, void *data)
{
    rtcpSession* s = (rtcpSession*)data;
    RvUint32 buffer[MAXRTCPPACKET/sizeof(RvUint32)+1];
    RV_BUFFER buf;
	RvIpv4Addr ipv4;
	RvSocketAddr toAddr;

	rvMutexLock(&s->mutex);
    buf = buffCreate(buffer,MAXRTCPPACKET);

	rvTimerReset(&s->tElem, RTCP_TIMEOUT);

    rtcpCreateRTCPPacket((HRTCPSESSION)s, &buf);
	rvIpv4AddrConstruct(&ipv4, s->ip);
	rvSocketAddrConstructIpv4(&toAddr, &ipv4, s->port);
	rvSocketSendTo(&s->socket, buf.buffer, buf.length, &toAddr);
	rvMutexUnlock(&s->mutex);
}
                     /* == Internal RTCP Functions == */

RVVXDAPI
RvInt32 VXDCALLCONV rtcpCreateRTCPPacket(
                IN      HRTCPSESSION  hRTCP,  
                IN OUT  RV_BUFFER *      buf) 
{
    rtcpSession *s = (rtcpSession *)hRTCP;
    rtcpHeader head;
    RvUint32 allocated = 0;
    RV_BUFFER bufC;
    rtcpType type = RTCP_SR;

	rvMutexLock(&s->mutex);

    if (buffValid(buf, SIZEOF_RTCPHEADER + SIZEOF_SR))
    {
        RvUint64 myTime = s->myInfo.eSR.tNNTP;
        RvUint8 cc = 0;
		RvListIter(rtcpInfo) iter;
        
        allocated = SIZEOF_RTCPHEADER;
        
        if (s->myInfo.active)
        {
            s->myInfo.active = rvFalse;
            bufC = buffCreate(&(s->myInfo.eSR), SIZEOF_SR);
            buffAddToBuffer(buf, &bufC, allocated);            
            ConvertToNetwork(buf->buffer + allocated, 0, W32Len(bufC.length));
            allocated += SIZEOF_SR;
        }
        else 
        {
            type = RTCP_RR;
        }

		for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
        {
            rtcpInfo *info = rvListIterData(iter);
            if (info->active)
            {
                info->eToRR.bfLost     = getLost    (&(info->src));
                info->eToRR.nJitter    = getJitter  (&(info->src));
                info->eToRR.nExtMaxSeq = getSequence(&(info->src));
                info->eToRR.tDLSR      = 
                    (info->tLSRmyTime) ? 
                    (reduceNNTP(myTime)-info->tLSRmyTime) : 
                    0;
                
                bufC = buffCreate(&(info->eToRR), SIZEOF_RR);

                if (buffAddToBuffer(buf, &bufC, allocated))
                {
                    cc++;
                    if (cc == 32) 
                        break;
                    ConvertToNetwork(buf->buffer + allocated, 0, 
                                      W32Len(bufC.length));
                    allocated += SIZEOF_RR;
                }                         
                info->active = rvFalse;
            }
        }

        head = makeHeader(s->myInfo.ssrc, cc, type, (RvUint16)allocated);
        bufC = buffCreate(&head, SIZEOF_RTCPHEADER);
        buffAddToBuffer(buf, &bufC, 0);

        /* add an CNAME SDES packet to the compound packet */
        if (buffValid(buf, 
            allocated + SIZEOF_RTCPHEADER + SIZEOF_SDES(s->myInfo.eCName)))
        {
            RV_BUFFER sdes_buf;

            /* 'sdes_buf' is inside the compound buffer 'buf' */
            sdes_buf = buffCreate(buf->buffer + allocated, 
                (SIZEOF_RTCPHEADER + SIZEOF_SDES(s->myInfo.eCName)));

            head = makeHeader(s->myInfo.ssrc, 1, RTCP_SDES, 
              (RvUint16)sdes_buf.length);
            
            memcpy(sdes_buf.buffer, (char *)&head, SIZEOF_RTCPHEADER);
            memcpy(sdes_buf.buffer + SIZEOF_RTCPHEADER, &(s->myInfo.eCName),
                   SIZEOF_SDES(s->myInfo.eCName));

            allocated += sdes_buf.length;
        }
        
        if (s->myInfo.collision == 1  &&
            buffValid(buf, allocated + SIZEOF_RTCPHEADER))
        {
            head = makeHeader(s->myInfo.ssrc, 1, RTCP_BYE, 
                              SIZEOF_RTCPHEADER);
            
            bufC = buffCreate(&head, SIZEOF_RTCPHEADER);
            buffAddToBuffer(buf, &bufC, allocated);
            s->myInfo.collision = 2;
            allocated += SIZEOF_RTCPHEADER;
        }
    }

    buf->length = allocated;

	rvMutexUnlock(&s->mutex);
    return 0;
}

RVVXDAPI
RvInt32 VXDCALLCONV rtcpProcessRTCPPacket(
        IN  rtcpSession *  s,
        IN  RvUint8 *         data,
        IN  RvInt32          dataLen,
        IN  rtcpType       type,
        IN  RvInt32          reportCount,
        IN  RvUint64         myTime)
{
	RvListIter(rtcpInfo) iter;
    unsigned scanned = 0;
    rtcpInfo *fInfo = NULL;
	RvUint32 ssrc;

    if (dataLen == 0)
        return 0;

	rvMutexLock(&s->mutex);


    switch(type) 
    {
        case RTCP_SR:	
        case RTCP_RR:   
        {
            ConvertToNetwork(data, 0, 1);
            ssrc = *(RvUint32 *)(data);
            scanned = sizeof(RvUint32);

            if (ssrc == s->myInfo.ssrc) 
            {
                s->myInfo.collision = 1;
				rvMutexUnlock(&s->mutex);
                return ERR_RTCP_SSRCCOLLISION;
            }
                
			for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
			{
				if(rvListIterData(iter)->ssrc == ssrc)
				{
					fInfo = rvListIterData(iter);
					break;
				}
			}
          
            if (fInfo == NULL) /* New source */
            {
                /* Initialize info */
			    rtcpInfo info;
                memset(&info, 0, sizeof(info)); 		
                info.ssrc          = *(RvUint32 *)(data);
                info.eToRR.ssrc    = info.ssrc;
                info.active        = rvFalse;
                info.src.probation = MIN_SEQUENTIAL - 1;
                
				rvListPushFront(rtcpInfo)(&s->hList, &info);
				fInfo = rvListFront(&s->hList);
            }
            break;
        }
            
        default: 
            break;
    }

    /* process the information */
    switch(type)
    {
        case RTCP_SR:
        {
            ConvertToNetwork(data + scanned, 0, W32Len(sizeof(rtcpSR)));

            if (fInfo)
            {
                fInfo->eSR        = *(rtcpSR *)(data + scanned);  
                fInfo->eToRR.tLSR = reduceNNTP(fInfo->eSR.tNNTP);
                fInfo->tLSRmyTime = reduceNNTP(myTime);
            }

            scanned += SIZEOF_SR;
        }

        /* fall into RR */
            
        case RTCP_RR:   
        {
            if (fInfo)
            {
                int i;
                rtcpRR* rr = (rtcpRR*)(data + scanned);

				s->rtt += computeRoundTripTime(rr);
				++s->numOfRRs;

                ConvertToNetwork(data + scanned, 0, 
                                  reportCount * W32Len(sizeof(rtcpRR)));
                
                for (i=0; i < reportCount; i++)
                {
                    if (rr[i].ssrc == s->myInfo.ssrc)
                    {
                        fInfo->eFromRR = rr[i];
                        break;
                    }
                }
            }

            break;
        }
        
        case RTCP_SDES: 
        {
            int i;
            rtcpSDES *sdes;

            for (i = 0; i < reportCount; i++)
            {
                ConvertToNetwork(data + scanned, 0, 1);
                ssrc = *(RvUint32 *)(data + scanned);

                sdes = (rtcpSDES *)(data + scanned + sizeof(ssrc));

				for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
				{
					fInfo = rvListIterData(iter);
					if(fInfo->ssrc == ssrc)
					{
						switch(sdes->type)
						{
							case RTCP_SDES_CNAME:
								memcpy(&(fInfo->eCName), sdes,
									   SIZEOF_SDES(*sdes));
								fInfo->eCName.value[sdes->length] = 0;    
								break;
							/* known SDES types that are not handled:
							case RTCP_SDES_END:
							case RTCP_SDES_NAME:
							case RTCP_SDES_EMAIL:
							case RTCP_SDES_PHONE:
							case RTCP_SDES_LOC:
							case RTCP_SDES_TOOL:
							case RTCP_SDES_NOTE:
							case RTCP_SDES_PRIV:
								break; */
						}
						break;
					}
					scanned += SIZEOF_SDES(*sdes) + sizeof(RvUint32);
				}
			}
            break;
        }
            
        case RTCP_BYE:  
        {
            int i;

            for (i = 0; i < reportCount; i++)
            {
                ConvertToNetwork(data + scanned, 0, 1);
                ssrc = *(RvUint32 *)(data + scanned);
                scanned += sizeof(ssrc);

				for(iter = rvListBegin(&s->hList); iter != rvListEnd(&s->hList); iter = rvListIterNext(iter))
				{
					fInfo = rvListIterData(iter);
					if(fInfo->ssrc == ssrc)
					{
						fInfo->invalid = rvTrue;
						fInfo->ssrc    = 0;
						break;
					}
				}
            }

            break;
        }
            
        case RTCP_APP:  
            break;

⌨️ 快捷键说明

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