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

📄 rtcptransmitter.cpp

📁 symbian平台S60_2nd_FP2_SC rtp实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:


#include <libc\assert.h>
#include <libc\sys\time.h>
#include <libc\string.h>
#include <libc\stdlib.h>
#include <libc\sys\unistd.h>

#include "vtypes.h"

#include "cpLog.h"
#include "rtpTypes.h"
#include "rtpTools.h"
#include "NtpTime.h"
#include "RtpTransmitter.h"
#include "RtcpTransmitter.h"

const int RtcpTransmitter::RTCP_INTERVAL = 5000;


/* ----------------------------------------------------------------- */
/* --- RtcpTransmitter Constructor --------------------------------- */
/* ----------------------------------------------------------------- */

RtcpTransmitter::RtcpTransmitter (CSocketUdp * udp,const char* /*remoteHost*/,
                                  int /*remoteMinPort*/,
                                  int /*remoteMaxPort*/,
                                  RtcpReceiver* receiver)
{
    if (receiver)
    {
		myStack = udp;
        freeStack = false;
    }
    else
    {
		myStack = udp;
        freeStack = true;
    }

	remoteAddr = udp->getDestination();
    constructRtcpTransmitter ();
}

RtcpTransmitter::RtcpTransmitter (CSocketUdp * udp,const char* /*remoteHost*/,
                                  int /*remotePort*/,
                                  RtcpReceiver* receiver)
{
    if (receiver)
    {
        freeStack = false;
    }
    else
    {
        freeStack = true;
    }
	myStack = udp;
	remoteAddr = udp->getDestination();
    constructRtcpTransmitter ();
}


void RtcpTransmitter::constructRtcpTransmitter ()
{
    tran = NULL;
    recv = NULL;
    rtcpRecv = NULL;
    SDESInfo = NULL;

    // prepare for rtcp timing intervals
    nextInterval = getNtpTime();
    updateInterval();
}


RtcpTransmitter::~RtcpTransmitter ()
{
    if (freeStack)
    {
        delete myStack;
        myStack = 0;
    }

    if ((tran) && (SDESInfo))
    {
        delete SDESInfo;
        SDESInfo = NULL;
    }

    tran = NULL;
    recv = NULL;
    rtcpRecv = NULL;
}

void
RtcpTransmitter::setRemoteAddr ( NetworkAddress& theAddr)
{
    remoteAddr = theAddr;
}

/* --- send packet functions --------------------------------------- */

int RtcpTransmitter::transmit (RtcpPacket* p)
{
    myStack->transmitTo ((char*)p->getPacketData(),
                         p->getTotalUsage(),
                         &remoteAddr);
    // exit with sucess
    return 0;
}


void RtcpTransmitter::updateInterval ()
{
    // RTCP_INTERVAL random offset between (.5 to 1.5)
    int delayMs = RTCP_INTERVAL * (500 + rand() / (RAND_MAX / 1000)) / 1000;
    nextInterval = nextInterval + delayMs;
}


int RtcpTransmitter::checkInterval ()
{
    if (getNtpTime() > nextInterval)
    {
        // prepare for next interval
        updateInterval();
        return 1;
    }

    // time not up yet
    return 0;
}




/* --- SR/RR RTCP report packets------------------------------------ */

int RtcpTransmitter::addSR (RtcpPacket* p, int npadSize)
{
    // header
    RtcpHeader* header = reinterpret_cast < RtcpHeader* > (p->freeData());
    int usage = p->allocData (sizeof(RtcpHeader));

    header->version = RTP_VERSION;
    header->padding = (npadSize > 0) ? 1 : 0;
    header->count = 0;
    header->type = (tran) ? rtcpTypeSR : rtcpTypeRR;

    NtpTime nowNtp = getNtpTime();

    // sender information
    if (tran)
    {
        //cpLog (LOG_DEBUG_STACK, "RTCP: Making Sender Info");
        RtcpSender* senderInfo = reinterpret_cast < RtcpSender* > (p->freeData());
        usage += p->allocData (sizeof(RtcpSender));

        int diffNtp = 0;
        if (nowNtp > tran->seedNtpTime)
            diffNtp = nowNtp - tran->seedNtpTime;
        else
            if (tran->seedNtpTime > nowNtp)
                diffNtp = tran->seedNtpTime - nowNtp;

        RtpTime diffRtp = (diffNtp * tran->networkFormat_clockRate) / 1000;
        senderInfo->ssrc = htonl(tran->ssrc);
        senderInfo->ntpTimeSec = htonl(nowNtp.getSeconds());
        senderInfo->ntpTimeFrac = htonl(nowNtp.getFractional());
        senderInfo->rtpTime = htonl(tran->seedRtpTime + diffRtp);
        senderInfo->packetCount = htonl(tran->packetSent);
        senderInfo->octetCount = htonl(tran->payloadSent);
    }
    else
    {
        RtcpChunk* chunk = reinterpret_cast < RtcpChunk* > (p->freeData());
        usage += p->allocData (sizeof(RtpSrc));
        chunk->ssrc = 0 ;  /* if recv only, give src 0 for receiver for now */
    }

    // report blocks
    if ((rtcpRecv) && (rtcpRecv->getTranInfoCount() > 0))
    {
        //cpLog (LOG_DEBUG_STACK, "RTCP: Making Report Block");
        RtpTranInfo* tranInfo = NULL;
        RtpReceiver* recvInfoSpec = NULL;
        RtcpReport* reportBlock = NULL;
        for (int i = 0; i < rtcpRecv->getTranInfoCount(); i++)
        {
            tranInfo = rtcpRecv->getTranInfoList(i);
            recvInfoSpec = tranInfo->recv;

            // only receieved RTCP packets from transmitter
            if (recvInfoSpec == NULL)
                continue;

            // don't report on probation transmitters
            if (recvInfoSpec->probation < 0)
                continue;

            //cpLog (LOG_DEBUG_STACK, "RTCP:  Report block for src %d",
            //       recvInfoSpec->ssrc);
            reportBlock = reinterpret_cast < RtcpReport* > (p->freeData());
            usage += p->allocData (sizeof(RtcpReport));

            reportBlock->ssrc = htonl(recvInfoSpec->ssrc);
            reportBlock->fracLost = calcLostFrac(tranInfo);
            u_int32_t lost = (calcLostCount(tranInfo)) & 0xffffff;
            reportBlock->cumLost[2] = lost & 0xff;
            reportBlock->cumLost[1] = (lost & 0xff00) >> 8;
            reportBlock->cumLost[0] = (lost & 0xff0000) >> 16;
            reportBlock->recvCycles = htons(recvInfoSpec->recvCycles);
            reportBlock->lastSeqRecv = htons(recvInfoSpec->prevSeqRecv);

            // fracational
            // reportBlock->jitter = htonl((u_int32_t)recvInfoSpec->jitter);

            // interger
            //            if (recvInfoSpec->jitter > 0)
            reportBlock->jitter = htonl(recvInfoSpec->jitter >> 4);


            reportBlock->lastSRTimeStamp = htonl(tranInfo->lastSRTimestamp);

            // reportBlock->lastSRDelay in the unit of 1/65536 of sec ??
            // currently it is in ms
            if (tranInfo->lastSRTimestamp == 0)
                reportBlock->lastSRDelay = 0;
            else
            {
                NtpTime thenNtp = tranInfo->recvLastSRTimestamp;
                //                NtpTime thenNtp ((tranInfo->lastSRTimestamp >> 16) |
                //                                 (nowNtp.getSeconds() & 0xffff0000),
                //                                 tranInfo->lastSRTimestamp << 16);
                reportBlock->lastSRDelay = 0;
                if (nowNtp > thenNtp)
                    reportBlock->lastSRDelay = htonl(nowNtp - thenNtp);
                else
                    reportBlock->lastSRDelay = 0;
            }
            // next known transmitter
            header->count++;
        }
    }

    // profile-specific extensions
    // future: not implemented


    // padding
    if (npadSize > 0)
    {
        // future: not implemented
        assert (0);
    }

    // overall packet must ends on 32-bit count
    assert (usage % 4 == 0);

    header->length = htons((usage / 4) - 1);
    //cpLog (LOG_DEBUG_STACK, "RTCP:  SR/RR packet used %d bytes/ %d words",
    //       usage, usage/4);
    return usage;
}



u_int32_t RtcpTransmitter::calcLostFrac (RtpTranInfo* s)
{
    /* from A.3 of RFC 1889 - RTP/RTCP Standards */

    RtpReceiver* r = s->recv;

    u_int32_t expected = ((r->recvCycles + r->prevSeqRecv) - r->seedSeq + 1);
    u_int32_t expected_interval, received_interval, lost_interval;

    expected_interval = expected - s->expectedPrior;
    s->expectedPrior = expected;
    received_interval = r->packetReceived - s->receivedPrior;
    s->receivedPrior = r->packetReceived;
    lost_interval = expected_interval - received_interval;

    u_int32_t fraction;
    if (expected_interval == 0 || lost_interval <= 0) fraction = 0;
    else fraction = (lost_interval << 8) / expected_interval;

    return fraction;
}


u_int32_t RtcpTransmitter::calcLostCount (RtpTranInfo* s)
{
    /* from A.3 of RFC 1889 - RTP/RTCP Standards */

    RtpReceiver* r = s->recv;

    u_int32_t expected = ((r->recvCycles + r->prevSeqRecv) - r->seedSeq + 1);
    return expected - r->packetReceived;
}




/* --- SDES RTCP packet -------------------------------------------- */

int RtcpTransmitter::addSDES (RtcpPacket* p, RtcpSDESType item, int npadSize)
{
    if (!tran) return -1;

    RtcpSDESType list[2];
    list[0] = item;
    list[1] = rtcpSdesEnd;
    return addSDES (p, list, npadSize);
}


int RtcpTransmitter::addSDES (RtcpPacket* p, int npadSize)
{
    if (!tran) return -1;

    RtcpSDESType list[8];
    int i = 0;

    if (strlen(getSdesCname()) > 0) list[i++] = rtcpSdesCname;
    if (strlen(getSdesName()) > 0) list[i++] = rtcpSdesName;

⌨️ 快捷键说明

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