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

📄 rtpreceiver.cpp

📁 symbian平台S60_2nd_FP2_SC rtp实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if( myStack->SelectRTPStack() ==0)
		return NULL;

	// create packet
    RtpPacket* p = new RtpPacket (RECV_BUF);
    assert (p);
	
    // receive packet
    int len = myStack->RTPreceive((char*)p->getHeader(), p->getPacketAlloc());
    p->setTotalUsage (len);
	
    // check packet
    if( !p->isValid() )
    {
        cpLog(LOG_ERR, "****Packet is not valid");
        delete p; p = NULL;
        return NULL;
    }
	
    int dtmf_num = p->getPayloadType();

	//modify for amr transmit,amr payloadtype = 121
	if((dtmf_num >100 && dtmf_num<190) && (dtmf_num != 121))
		p->setPayloadType(rtpPayloadDTMF_RFC2833);
	
	// check if rtp ent
    if (p->getPayloadType() == rtpPayloadDTMF_RFC2833)
    {
		if( recvEvent( p )==true)
		{
			isEvent=true;
			m_event=getDTMFEvent();
			return p; //add by huzx and delete blow
		}
    }
	
    // update receiver info
    // function may return 1, meaning packet
    // out of seq tolr or source not valid
    if (updateSource(p))
    {
        int port=getPort ();
        cpLog(LOG_ERR, "myport is %d,",port);
		cpLog(LOG_ERR, "****Packet is discarded or source not valid");
        delete p; p = NULL;
        return NULL;
    }
	return p;
}


int RtpReceiver::updateSource (RtpPacket* p)
{
    // check if ssrc in probation list
    if (sourceSet && p->getSSRC() == srcProbation && probationSet)
        // old probation packets still in que
        return 1;

    // drop SID packets when SID packets are beginning packets
    if ((p->getPayloadUsage() < ( networkFormat_payloadSize / 3 )) ||
        (p->getPayloadUsage() < 20) )
    {
        cpLog( LOG_DEBUG_STACK, "Dropping SID packet" );
        prevSeqRecv = p->getSequence();
        return 1;
    }

    // new source found or resync old source
    if (!sourceSet || p->getSSRC() != ssrc)
    {
        if (addSource(p))
            return 1;
    }

    // no vaild source yet
    assert (probation >= 0);

    // drop CN packets
    if ((p->getPayloadType() == rtpPayloadCN) ||
        (p->getPayloadType() == 13)) {
        cpLog(LOG_DEBUG_STACK, "drop 1 rtpPayloadCN packet");
        prevSeqRecv = p->getSequence();  // drop comfort noise packet
        return 1;
    }

    if (p->getPayloadType() != networkFormat )
    {
        cpLog(LOG_DEBUG, "Transmitter changing payload parameters(%d/%d) (%d/%d)",
            p->getPayloadType(), networkFormat,
            p->getPayloadUsage(), networkFormat_payloadSize );
        p->printPacket();
        initSource(p);
    }

    // fix rtp time stamp boundry
    if ((( prevPacketRtpTime + network_pktSampleSize ) != p->getRtpTime()) &&
        ((( p->getRtpTime() - prevPacketRtpTime) * 1.0) / network_pktSampleSize < 1.5) &&
        ((( p->getRtpTime() - prevPacketRtpTime) * 1.0) / network_pktSampleSize> 0.5))
    {
        network_pktSampleSize = p->getRtpTime() - prevPacketRtpTime;
        cpLog( LOG_DEBUG_STACK, "Fixing network_pktSampleSize to %d", network_pktSampleSize );
    }

    // check if valid sequence window
    RtpSeqNumber seq = p->getSequence();
    if ( RtpSeqGreater(seq, prevSeqRecv) )  // future packet
    {
        if (seq > prevSeqRecv)
        {
            if ( (seq - prevSeqRecv) > MISORDER )
            {
                // large sequence jump forward, skip over packets less then seq
                cpLog(LOG_DEBUG_STACK, "jump to %d (%d jumps)", seq, seq - prevSeqRecv);
                cpLog(LOG_DEBUG_STACK, "rtpTime %u, prevPacketRtpTime %u", p->getRtpTime(), prevPacketRtpTime);
                prevSeqRecv = seq - 1;
                prevPacketRtpTime = p->getRtpTime() - network_pktSampleSize;
            }
        }
        else if ( (seq + RTP_SEQ_MOD - prevSeqRecv) > MISORDER)
        {
            cpLog(LOG_DEBUG_STACK, "jump cycle to %d (%d jumps)", seq, seq + RTP_SEQ_MOD - prevSeqRecv );
            cpLog(LOG_DEBUG_STACK, "rtpTime %u, prevPacketRtpTime %u", p->getRtpTime(), prevPacketRtpTime);
            prevSeqRecv = seq - 1;
            prevPacketRtpTime = p->getRtpTime() - network_pktSampleSize;
        }
    }
    else if ( RtpSeqGreater(prevSeqRecv, seq) )  // past packet
    {
        // check if the pkt is too late comparing to the pkt already
        // played. Since the prevSeqPlay is irrelavant due to diff
        // api_payload Size, use inPos and playPos to calculate.
        int size = networkFormat_payloadSize;
        int backNoOfSeq = (prevSeqRecv > seq) ?
                          (prevSeqRecv - seq) : (prevSeqRecv + RTP_SEQ_MOD - seq );
        if (inPos > playPos)
        {
            if ((inPos - (backNoOfSeq + 1) * size) < playPos)
            {
                cpLog(LOG_DEBUG_STACK, "too late now: discard seq %d", seq);
                return 1;
            }
        }
        else
        {
            if ((inPos + IN_BUFFER_SIZE - (backNoOfSeq + 1) * size) < playPos)
            {
                cpLog(LOG_DEBUG_STACK, "too late now: discard seq %d", seq);
                return 1;
            }
        }
    }
    else // (seq == prevSeqRecv)  // present packet
    {
        // duplicate with previous packet
        //cpLog(LOG_DEBUG_STACK,"duplicate packet %d", seq);
        //return 1;
    }

    return 0;
}




int RtpReceiver::addSource(RtpPacket* p)
{
    // don't allow ssrc changes without removing first
    if (sourceSet)
    {
        if (probation < 4)
        {
            probation ++;

            int port=getPort ();
            cpLog(LOG_ERR, "myport is %d,probation is %d",port,probation);
            cpLog(LOG_ERR, "Rejecting new transmitter %u, keeping %u",p->getSSRC(), ssrc);
            return 1;
        }
        else 
           removeSource(ssrc);
    }

    // check if ssrc in probation list
    if (sourceSet && p->getSSRC() == srcProbation && probationSet)
        return 1;

    sourceSet = true;
    ssrc = p->getSSRC();
    cpLog(LOG_DEBUG_STACK, "Received ssrc = %u", ssrc);
    probation = 0;
    packetReceived = 0;
    payloadReceived = 0;

    // init SDES and RTCP fields
    if (rtcpRecv)
       rtcpRecv->addTranInfo(ssrc, this);

    initSource (p);
    return 0;
}



void RtpReceiver::initSource (RtpPacket* p)
{
    assert (ssrc == p->getSSRC());

    cpLog(LOG_DEBUG_STACK, "InitSource %u with sequence %d and rtp time %u",
          ssrc, p->getSequence(), p->getRtpTime());
    seedSeq = p->getSequence();
    seedNtpTime = getNtpTime();
    seedRtpTime = p->getRtpTime();

    // set receiving codec
    //If codec is G711, paylaod size cannot change, if it does it is
    //an error, just drop the packet
    if((p->getPayloadType() == 0) && 
       (p->getPayloadUsage() != networkFormat_payloadSize))
    {
        cpLog(LOG_ERR, "Incorrect payload size (%d) for payload type (%d), expected (%d) ignoring packet",
                               p->getPayloadUsage(), p->getPayloadType(), networkFormat_payloadSize);
    }
    else if ((p->getPayloadType() != networkFormat) ||
        (p->getPayloadUsage() != networkFormat_payloadSize))
    {
        int networkFormat_org = networkFormat;
        int network_pktSampleSize_org = network_pktSampleSize;
        int networkFormat_payloadSize_org = networkFormat_payloadSize;
        float multiplier = (p->getPayloadUsage() * 1.0) / (networkFormat_payloadSize * 1.0);
        float new_samples = multiplier * (network_pktSampleSize * 1.0);

        setNetworkFormat( p->getPayloadType(),
                          (int) new_samples,
                          0, p);

        if (networkFormat_perSampleSize)
            network_pktSampleSize = network_pktSampleSize / networkFormat_perSampleSize;
        else
            setNetworkFormatCodec ();

        if (networkFormat_org != networkFormat)
            cpLog (LOG_DEBUG, "  networkFormat corrected to %d", networkFormat);        if (network_pktSampleSize_org != network_pktSampleSize)
            cpLog (LOG_DEBUG, "  Number of network_pktSampleSize corrected to %d", network_pktSampleSize);
        if (networkFormat_payloadSize_org != networkFormat_payloadSize)
            cpLog (LOG_DEBUG, "  Number of networkFormat_payloadSize corrected to %d", networkFormat_payloadSize);
    }

    //For dynamic payload type, setApiFormat the same as NetworkFormat
    if ((apiFormat != p->getPayloadType()) &&
        (p->getPayloadType() >= rtpPayloadDynMin) &&
        (p->getPayloadType() <= rtpPayloadDynMax))
    {
        setApiFormat( p->getPayloadType(),
                      network_pktSampleSize,
                      0, p);
    }

    inPos = 0;
    playPos = 0;

    // set timing information
    prevRtpTime = p->getRtpTime() - api_pktSampleSize;
    prevPacketRtpTime = p->getRtpTime() - network_pktSampleSize;
    prevNtpTime = rtp2ntp(p->getRtpTime()) - network_pktSampleSize * 1000 / networkFormat_clockRate;
    prevSeqRecv = p->getSequence() - 1;
    prevSeqPlay = p->getSequence() - 1;
    recvCycles = 0;
    playCycles = 0;

    transit = 0;
    jitter = 0;
    jitterTime = jitterSeed;

    // set up next gotime
    gotime = rtp2ntp (p->getRtpTime()) + jitterTime;
}

void RtpReceiver::removeSource (RtpSrc s, int flag)
{
    if (s != ssrc)
        cpLog(LOG_DEBUG_STACK, "Removing non active source: %u", s);

    // no longer listen to this source
    probationSet = true;
    srcProbation = s;

    // no transmitter
    sourceSet = false;
    ssrc = 0;
    probation = -2;

    // remove from RTCP receiver
    if (rtcpRecv && !flag) rtcpRecv->removeTranInfo (s, 1);

    cpLog (LOG_DEBUG_STACK, "Removing source: %u", s);
}



NtpTime RtpReceiver::rtp2ntp (RtpTime rtpTime)
{
    NtpTime ntptime = seedNtpTime +
                      ((rtpTime - seedRtpTime) * 1000 / apiFormat_clockRate);
    return ntptime;
}

/* --- Session state functions ------------------------------------- */
void RtpReceiver::emptyNetwork ()
{
// 接受数据 ,但是不处理数据。//ZHAOSONG

/*
    // set up network activit
    fd_set netFD;
    FD_ZERO (&netFD);
    FD_SET (myStack->getSocketFD(), &netFD);
    struct timeval timeout;
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;

    // create empty holder packet
    RtpPacket* p = new RtpPacket (RECV_BUF);
    assert (p);

    // receive packets until no more activity
    int len;
    int selret = select (myStack->getSocketFD() + 1,
                         &netFD, NULL, NULL, &timeout);
    while (selret > 0)
    {
        len = myStack->receive (p->getPacketData(), p->getPacketAlloc());
        if (len <= 0) break;
        FD_ZERO (&netFD);
        FD_SET (myStack->getSocketFD(), &netFD);
        selret = select (myStack->getSocketFD() + 1,
                         &netFD, NULL, NULL, &timeout);
    }
    delete p; p = NULL;

    cpLog (LOG_DEBUG_STACK, "RtpReceiver: Done empty network queue");
	*/
}


/* --- Private Information for RTCP -------------------------------- */

void RtpReceiver::setRTCPrecv (RtcpReceiver* s)
{
    rtcpRecv = s;
}


void RtpReceiver::setApiFormat (RtpPayloadType newtype, int no_samples, int packetSize,
                                RtpPacket* p, bool print)
{
    apiFormat = newtype;
    api_pktSampleSize = no_samples;
    apiFormat_perSampleSize = 1;

    switch (newtype)
    {
        case rtpPayloadPCMU:
        case rtpPayloadPCMA:
        if (print) cpLog(LOG_DEBUG, "Setting api format to: PCMU %d", no_samples);
        apiFormat_clockRate = 8000;
        break;
        case rtpPayloadL16_mono:
        if (print) cpLog(LOG_DEBUG, "Setting api format to: L16 %d", no_samples);
        apiFormat_clockRate = 44100;
        apiFormat_perSampleSize = 2;
        break;
        case rtpPayloadG729:
        if (print) cpLog(LOG_DEBUG, "Setting api format to: G729 %d", no_samples);
        apiFormat_clockRate = 8000;
        break;
        case rtpPayloadH261:
        apiFormat_clockRate = 90000;        
        break;
        case rtpPayloadH263:
        apiFormat_clockRate = 90000;        
        break;
        case rtpPayloadG723:
        apiFormat_clockRate = 8000;
        break; 	
        default:
        cpLog(LOG_ERR, "apiFormat: codec(%d) at sampleSize(%d) packetSize(%d)",
              (int)newtype, no_samples, packetSize);
        apiFormat_clockRate = 8000;
    }
    if (p)
        apiFormat_payloadSize = p->getPayloadUsage();
    else
        apiFormat_payloadSize = api_pktSampleSize * apiFormat_perSampleSize;

    if( packetSize != 0 )
        apiFormat_payloadSize = packetSize;
}


void RtpReceiver::setNetworkFormat (RtpPayloadType newtype, int no_samples, int packetSize, 
                                    RtpPacket* p, bool print)
{
    networkFormat = newtype;
    network_pktSampleSize = no_samples;
    networkFormat_perSampleSize = 1;

    switch (newtype)
    {
        case rtpPayloadPCMU:
        case rtpPayloadPCMA:
        if (print) cpLog(LOG_DEBUG, "Setting network format to: PCMU %d", no_samples);
        networkFormat_clockRate = 8000;
        break;
        case rtpPayloadL16_mono:
        if (print) cpLog(LOG_DEBUG, "Setting network format to: L16 %d", no_samples);
        networkFormat_clockRate = 44100;
        networkFormat_perSampleSize = 2;
        break;
        case rtpPayloadH261:
        networkFormat_clockRate = 90000;        
        break;
        case rtpPayloadH263:
        networkFormat_clockRate = 90000;        
        break;
        case rtpPayloadG723:
         networkFormat_clockRate = 8000;
        break; 	         	
        default:
        cpLog(LOG_ERR, "networkFormat: codec(%d) at sampleSize(%d) packetSize(%d)",
              (int)newtype, no_samples, packetSize);
        networkFormat_clockRate = 8000;
    }
    if (p)
        networkFormat_payloadSize = p->getPayloadUsage();
    else
        networkFormat_payloadSize = network_pktSampleSize * networkFormat_perSampleSize;

    if( packetSize != 0 )
        networkFormat_payloadSize = packetSize;
}

void RtpReceiver::setCodecString(const char* codecStringInput)
{
    strncpy(codecString, codecStringInput, strlen(codecStringInput) + 1);
    cpLog(LOG_DEBUG, "set CodecString %s", codecString);
}

⌨️ 快捷键说明

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