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

📄 rtcp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:

    return res;
}


/*=========================================================================**
**  == rtcpGetSSRC() ==                                                    **
**                                                                         **
**  Returns the synchronization source value for an RTCP session.          **
**                                                                         **
**  PARAMETERS:                                                            **
**      hRTCP      The handle of the RTCP session.                         **
**                                                                         **
**  RETURNS:                                                               **
**      The synchronization source value for the specified RTCP session.   **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpGetSSRC(
                IN  HRTCPSESSION  hRTCP)
{
    rtcpSession *s = (rtcpSession *)hRTCP;

    return s->myInfo.ssrc;
}


/*=========================================================================**
**  == rtcpSetSSRC() ==                                                    **
**                                                                         **
**  Changes the synchronization source value for an RTCP session.          **
**                                                                         **
**  PARAMETERS:                                                            **
**      hRTCP      The handle of the RTCP session.                         **
**                                                                         **
**      ssrc       A synchronization srouce value for the RTCP session.    **
**                                                                         **
**  RETURNS:                                                               **
**      If the enumeration process was stopped by the enumerator, the      **
**      function returns RV_FALSE, otherwise RV_TRUE.                      **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpSetSSRC(
                IN  HRTCPSESSION  hRTCP,
                IN  RvUint32      ssrc)
{
    rtcpSession *s = (rtcpSession *)hRTCP;

    s->myInfo.ssrc      = ssrc;
    s->myInfo.collision = 0;

    return RV_OK;
}

                 /* == ENDS: Accessory RTCP Functions == */



                     /* == Internal RTCP Functions == */


RVAPI
RvInt32 RVCALLCONV rtcpGetEnumFirst(
                IN  HRTCPSESSION  hRTCP,
                IN  RvInt32 *     ssrc)
{
    return rtcpGetEnumNext(hRTCP, -1, ssrc);
}

RVAPI
RvInt32 RVCALLCONV rtcpGetEnumNext(
                IN  HRTCPSESSION  hRTCP,
                IN  RvInt32       prev,
                IN  RvInt32 *     ssrc)
{
    rtcpSession *s = (rtcpSession *)hRTCP;
    rtcpInfo* info;
    RvInt32 index, doAgain = 1;

    if (prev < 0)
        index = 0;
    else
        index = prev+1;

    while ((doAgain == 1)&&(index < s->sessionMembers))
    {
        info = &s->participantsArray[index];
        if (!info->invalid)
        {
            doAgain = 0;
            *ssrc = info->ssrc;
        }
        else
        {
            index++;
        }
    }
    if (index < s->sessionMembers)
        return index;
    else
        return -1;
}

/* todo: check reference guide about this function */
RVAPI
RvInt32 RVCALLCONV rtcpCreateRTCPPacket(
                IN      HRTCPSESSION  hRTCP,
                IN OUT  RvRtpBuffer*  buf)
{
    rtcpSession *s = (rtcpSession *)hRTCP;
    rtcpHeader head;
    RvUint32 allocated = 0;
    RvRtpBuffer bufC;
    rtcpType type = RTCP_SR;
    int            index;

    if (buffValid(buf, SIZEOF_RTCPHEADER + SIZEOF_SR))
    {
        RvUint64 myTime = s->myInfo.eSR.tNNTP;
        RvUint8 cc = 0;
        rtcpInfo *info;

        allocated = SIZEOF_RTCPHEADER;

        if (s->myInfo.active)
        {
            s->myInfo.active = RV_FALSE;
            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;
        }


        index = 0;

        while( index < s->sessionMembers)
        {
            info = &s->participantsArray[index];
            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 = RV_FALSE;
            }

           index++;
        }

        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)))
        {
            RvRtpBuffer 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),
                   (RvSize_t)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;

    return RV_OK;
}


/* todo: check reference guide about this function */
RVAPI
RvInt32 RVCALLCONV rtcpProcessCompoundRTCPPacket(
        IN      HRTCPSESSION  hRTCP,
        IN OUT  RvRtpBuffer*  buf,
        IN      RvUint64      myTime)
{
    rtcpSession *s = (rtcpSession *)hRTCP;
    rtcpHeader *head;
    RvUint8 *currPtr = buf->buffer, *dataPtr, *compoundEnd;
    int hdr_count, hdr_len;
    rtcpType hdr_type;

    compoundEnd = buf->buffer + buf->length;

    while (currPtr < compoundEnd)
    {
        if ((compoundEnd + 1 - currPtr) < 1)
        {
            return ERR_RTCP_ILLEGALPACKET;
        }

        head = (rtcpHeader*)(currPtr);
        ConvertFromNetwork(currPtr, 0, 1);

        hdr_count = bitfieldGet(head->bits, HEADER_RC, HDR_LEN_RC);
        hdr_type  = (rtcpType)bitfieldGet(head->bits, HEADER_PT, HDR_LEN_PT);
        hdr_len   = sizeof(RvUint32) *
                    (bitfieldGet(head->bits, HEADER_len, HDR_LEN_len));

        if ((compoundEnd - currPtr) < hdr_len)
        {
            return ERR_RTCP_ILLEGALPACKET;
        }

        dataPtr = (RvUint8 *)head + sizeof(RvUint32);

        rtcpProcessRTCPPacket(s, dataPtr, hdr_len, hdr_type, hdr_count,
                              myTime);

        currPtr += hdr_len + sizeof(RvUint32);
    }

    return RV_OK;
}



RVAPI
RvInt32 RVCALLCONV rtcpProcessRTCPPacket(
        IN  rtcpSession *  s,
        IN  RvUint8 *         data,
        IN  RvInt32        dataLen,
        IN  rtcpType       type,
        IN  RvInt32        reportCount,
        IN  RvUint64       myTime)
{
    unsigned scanned = 0;
    rtcpInfo info, *fInfo=NULL;

    if (dataLen == 0)
        return RV_OK;

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

            if (info.ssrc == s->myInfo.ssrc)
            {
                s->myInfo.collision = 1;

                return ERR_RTCP_SSRCCOLLISION;
            }

            fInfo = findSSrc(s,info.ssrc);

            if (!fInfo) /* New source */
            {
                /* insert the new source */
                RvLockGet(&s->lock);
                fInfo = insertNewSSRC(s, *(RvUint32 *)data);
                RvLockRelease(&s->lock);
            }
            break;
        }

        default:
            break;
    }

    /* process the information */
    switch(type)
    {
        case RTCP_SR:
        {
            ConvertFromNetwork(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);

                ConvertFromNetwork(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++)
            {
                ConvertFromNetwork(data + scanned, 0, 1);
                info.ssrc = *(RvUint32 *)(data + scanned);

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

                fInfo = findSSrc(s,info.ssrc);

⌨️ 快捷键说明

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