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

📄 rtcpreceiver.cpp

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

#include <libc\assert.h>
#include <libc\sys\time.h>
#include "vtypes.h"
#include <libc\string.h>

#include "cpLog.h"
#include "rtpTypes.h"
#include "rtpTools.h"
#include "NtpTime.h"
#include "RtpReceiver.h"
#include "RtcpReceiver.h"
#include "NtpTime.h"

/* ----------------------------------------------------------------- */
/* --- rtpcReceiver Constructor ------------------------------------ */
/* ----------------------------------------------------------------- */

RtcpReceiver::RtcpReceiver (CSocketUdp * udp,int localMinPort, int localMaxPort)
{
   // myStack = new UdpStack(NULL, localMinPort, localMaxPort);
	myStack = udp;
    freeStack = true;

    constructRtcpReceiver();
}

RtcpReceiver::RtcpReceiver (CSocketUdp * udp,int localPort)
{
  //  myStack = new UdpStack(NULL, localPort) ;
	myStack = udp;
    freeStack = true;

    constructRtcpReceiver();
}

RtcpReceiver::RtcpReceiver (CSocketUdp* udp)
{
    myStack = udp;
    freeStack = false;

    constructRtcpReceiver();
}


void RtcpReceiver::constructRtcpReceiver ()
{

    packetReceived = 0;

    accumOneWayDelay = 0;
    avgOneWayDelay = 0;
    accumRoundTripDelay = 0;
    avgRoundTripDelay = 0;
}


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

    // must remove each transmitter block and each SDES info
//    map < RtpSrc, RtpTranInfo* > ::iterator s = tranInfoList.begin();
//    while (s != tranInfoList.end())
//    {
//        removeTranInfo((s->second)->ssrc);
//        s = tranInfoList.begin();
//    }

	for(TInt i=0; i<tranInfoList.Count(); i ++)
	{
		RtpTranInfo * pTranInfo =  tranInfoList[i]->iTranInfo; 
		if(pTranInfo)
			removeTranInfo(pTranInfo->ssrc);
	}

	tranInfoList.ResetAndDestroy();
	tranInfoList.Close();
    //cpLog(LOG_DEBUG_STACK, "RTCP: Receiver removed");
}



/* --- receive packet functions ------------------------------------ */


RtcpPacket* RtcpReceiver::getPacket ()
{
	// 检查网络活动状态<-1>
/*ZHAOSONG
    // check for network activity
    fd_set netFD;
    FD_ZERO (&netFD);
    FD_SET (myStack->getSocketFD(), &netFD);
    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;
    int selret = select (myStack->getSocketFD() + 1,
                         &netFD, NULL, NULL, &timeout);
    if (selret <= 0)
    {
		if (selret < 0) perror ("rtcpReceiver select");
		else
          return NULL;
    }
    else
    {
        //cpLog(LOG_DEBUG_STACK, "Get RTCP packet");
    }

    // create packet
*/

	if( myStack->SelectRTCPStack() ==0)
		return NULL;

    RtcpPacket* p = new RtcpPacket ();

    int len = myStack->RTCPreceive(p->getPacketData(),
                                    p->getPacketAlloc());
                                    
 
    // ? RtpTime arrival = generateTime ();
    if (len <= 0)
    {
        delete p;
        p = NULL;
        return NULL;
    }
    p->setTotalUsage (len);

    // kudo
    //    p->printPacket();

    // check packet
    if (!isValid(p))
    {
        delete p;
        p = NULL;
        return NULL;
    }
    return p;
}



int RtcpReceiver::isValid (RtcpPacket* p)
{
    char* begin = reinterpret_cast < char* > (p->getPacketData());
    char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
    RtcpHeader* middle = reinterpret_cast < RtcpHeader* > (begin);

    // check if known payload type for first packet
    if (middle->type != rtcpTypeSR && middle->type != rtcpTypeRR)
        return 0;

    // check padbyte
    if (middle->padding)
        return 0;

    // check header lengths
    while (begin < end && (int)middle->version == RTP_VERSION)
    {
        begin += (ntohs(middle->length) + 1) * sizeof(RtpSrc);
        middle = reinterpret_cast < RtcpHeader* > (begin);
    }

    if (begin != end)
        return 0;

    // exit with success
    cpLog(LOG_DEBUG_STACK, "RTCP packet is valid");
    //    cout << "RTCP packet is valid" << endl;
    return 1;
}



int RtcpReceiver::readRTCP (RtcpPacket* p)
{

    char* begin = reinterpret_cast < char* > (p->getPacketData());
    char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
    RtcpHeader* middle = NULL;
    int ret = 0;

    while (begin < end)
    {
        middle = reinterpret_cast < RtcpHeader* > (begin);
        switch (middle->type)
        {
            case (rtcpTypeSR):
            case (rtcpTypeRR):
               readSR (middle);
               break;
            case (rtcpTypeSDES):
               readSDES (middle);
               break;
            case (rtcpTypeBYE):
               if ( readBYE (middle) == 0)
               {
                  ret = 1;
               }
               break;
            case (rtcpTypeAPP):
               readAPP (middle);
            break;
            default:
               cpLog (LOG_ERR, "RTCP: Unknown RTCP type");
            break;
        }
        begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
    }
    return ret;
}



RtcpHeader* RtcpReceiver::findRTCP (RtcpPacket* p, RtcpType type)
{
    char* begin = reinterpret_cast < char* > (p->getPacketData());
    char* end = reinterpret_cast < char* > (begin + p->getTotalUsage());
    RtcpHeader* middle = NULL;

    while (begin < end)
    {
        middle = reinterpret_cast < RtcpHeader* > (begin);
        if (type == static_cast < RtcpType > (middle->type))
            return middle;
        begin += (ntohs(middle->length) + 1) * sizeof(u_int32_t);
    }

    // packet type not found
    cpLog (LOG_ERR, "RTCP: Type found here: %d", (int)type);
    return NULL;
}



/* --- Read SR RTCP packet ----------------------------------------- */

int RtcpReceiver::readSR (RtcpPacket* p)
{
    RtcpHeader* head = findRTCP (p, rtcpTypeSR);
    if (head == NULL) head = findRTCP (p, rtcpTypeRR);
    if (head == NULL) return -1;

    readSR (head);

    // read next RR packet if found
    // future: - ?

    return 0;
}


void RtcpReceiver::readSR (RtcpHeader* head)
{
    char* middle = NULL;

    NtpTime nowNtp = getNtpTime();

    // read SR block
    if (head->type == rtcpTypeSR)
    {
        RtcpSender* senderBlock = reinterpret_cast < RtcpSender* >
                                  ((char*)head + sizeof(RtcpHeader));
        RtpTranInfo* s = findTranInfo(ntohl(senderBlock->ssrc));
        s->lastSRTimestamp = (ntohl(senderBlock->ntpTimeSec) << 16 |
                              ntohl(senderBlock->ntpTimeFrac) >> 16);
        s->recvLastSRTimestamp = nowNtp;

        //printSR (senderBlock);  // - debug

        packetReceived++;

        NtpTime thenNtp ( ntohl(senderBlock->ntpTimeSec),
                          ntohl(senderBlock->ntpTimeFrac) );

        accumOneWayDelay += (nowNtp - thenNtp);

        avgOneWayDelay = accumOneWayDelay / packetReceived;

        middle = (char*)head + sizeof(RtcpHeader) + sizeof(RtcpSender);
    }
    else
    {
        // move over blank SR header
        middle = (char*)head + sizeof(RtcpHeader);

        // move over the ssrc of packet sender
        RtpSrc* sender = reinterpret_cast < RtpSrc* > (middle);
        RtpSrc ssrc;

        ssrc = ntohl(*sender);
        middle += sizeof(RtpSrc);

        packetReceived++;
    }


    // read RR blocks
    RtcpReport* block = reinterpret_cast < RtcpReport* > (middle);
    for (int i = head->count; i > 0; i--)
    {
        //printRR (block);  // - debug

        // - ? what these are if the count is more than 1??
        NtpTime thenNtp (ntohl(block->lastSRTimeStamp) >> 16,
                         ntohl(block->lastSRTimeStamp) << 16 );

        NtpTime nowNtp1 (nowNtp.getSeconds() & 0x0000FFFF, 
                         nowNtp.getFractional() & 0xFFFF0000);
        accumRoundTripDelay += ((nowNtp1 - thenNtp)
                                - ntohl(block->lastSRDelay));

        avgRoundTripDelay = accumRoundTripDelay / packetReceived;

        ++block;
    }

    // handle profile specific extensions
    // - ?
}




void RtcpReceiver::printSR (RtcpSender* /*p*/)
{
//    cerr << "Got SR from " << ntohl(p->ssrc) << endl;

⌨️ 快捷键说明

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