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

📄 rtptransmitter.cpp

📁 symbian平台S60_2nd_FP2_SC rtp实现
💻 CPP
字号:

#include "vtypes.h"

#include "cpLog.h"
#include "NetworkAddress.h"
#include "NtpTime.h"
#include "rtpTypes.h"
#include "rtpTools.h"
#include "rtpCodec.h"

/* ----------------------------------------------------------------- */
/* --- RtpTransmitter Constructor ---------------------------------- */
/* ----------------------------------------------------------------- */

RtpTransmitter::RtpTransmitter (CSocketUdp* udp,
								const char* /*remoteHost*/,
                                int /*remoteMinPort*/, 
								int /*remoteMaxPort*/,
                                RtpPayloadType newApiFormat,
                                RtpPayloadType newNetworkFormat,
                                RtpReceiver* receiver)
{
    if(  receiver )
    {
        freeStack = false;
    }
    else
    {
        freeStack = true;
    }
	myStack = udp;
	remoteAddr = udp->getDestination();
    constructRtpTransmitter (newApiFormat, newNetworkFormat);
}


RtpTransmitter::RtpTransmitter (CSocketUdp* udp,
								const char* /*remoteHost*/, 
								int /*remotePort*/,
                                RtpPayloadType newApiFormat,
                                RtpPayloadType newNetworkFormat,
                                RtpReceiver* receiver)
{
    if(  receiver )
    {
        freeStack = false;
    }
    else
    {
        freeStack = true;
    }
	myStack = udp;
	remoteAddr = udp->getDestination();
    constructRtpTransmitter (newApiFormat, newNetworkFormat);
}


void RtpTransmitter::constructRtpTransmitter (RtpPayloadType newApiFormat,
        RtpPayloadType newNetworkFormat)
{
    outPos = 0;
    recPos = 0;
    memset (outBuff, 0, OUT_BUFFER_SIZE);

    // set format and baseSampleRate
    setApiFormat(newApiFormat, 160, 0, NULL, false);
    setNetworkFormat(newNetworkFormat, 160, 0, NULL, false);

    // set private variables
    ssrc = generateSRC();
    seedNtpTime = getNtpTime();
    seedRtpTime = generate32();
    prevNtpTime = seedNtpTime;
    prevRtpTime = seedRtpTime;
    prevSequence = generate32();

    // set counters
    packetSent = 0;
    payloadSent = 0;
    codecString[0] = '\0';

    cpLog(LOG_DEBUG_STACK, "Constructed ssrc = %d", ssrc);
}


RtpTransmitter::~RtpTransmitter ()
{
    cpLog(LOG_DEBUG_STACK, "Closed ssrc = %d", ssrc);
}

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

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

RtpPacket* RtpTransmitter::createPacket (int npadSize, int csrc_count)
{
    // create packet
    RtpPacket* packet = new RtpPacket (apiFormat_payloadSize, npadSize, csrc_count);
    assert (packet);

    // load packet
    packet->setSSRC (ssrc);
    packet->setPayloadType (apiFormat);
    return packet;
}

// takes api RTP packet and send to network
// assumes payload size is already set
int RtpTransmitter::transmit(RtpPacket* packet, bool eventFlag )
{
    if( !packet )
    {
        cpLog(LOG_ERR,"Attempting to transmit a NULL rtp packet");
        return -1;
    }

    RtpPacket* p = packet;
	 rtp_htonl(p);

    // finish packet
    if( p->getPayloadUsage() != networkFormat_payloadSize  &&  !eventFlag )
    {
        cpLog(LOG_DEBUG_STACK,"Sending mismatched packetSize(%d) to networkFormatSize(%d)",
              p->getPayloadUsage(), networkFormat_payloadSize);
    }
    if( !p->timestampSet )
        //vv p->setRtpTime( prevRtpTime +20000); //network_pktSampleSize );
		p->setRtpTime( prevRtpTime + network_pktSampleSize );
    if( !p->sequenceSet )
        p->setSequence( prevSequence + 1 );
    if( p->getPayloadUsage() < 0  ||  p->getPayloadUsage() > 1500 )
    {
        cpLog(LOG_DEBUG_STACK,"Invalid data packet size %d", p->getPayloadUsage());
        return -1;
    }

    // for packet reuse
    p->timestampSet = false;
    p->sequenceSet = false;
	
    // transmit packet
    myStack->transmitTo( (char*)p->getHeader(), p->getTotalUsage(), &remoteAddr );

    // update counters
    packetSent++;
    prevSequence = p->getSequence();
    if( !eventFlag ) // eventFlag = false
    {
        payloadSent += p->getPayloadUsage();
        prevNtpTime = getNtpTime();
        prevRtpTime = p->getRtpTime();
    }

    // set up return value
    int result = p->getPayloadUsage();

    // delete newly created packet
    if( ( p != packet )  &&  p )
    {
        delete p; p = NULL;
    }

    // exit with success
    return result;
}


// takes rawdata, buffers it, and send network packets
int RtpTransmitter::transmitRaw (char* data, int len)
{
	assert(data);
    assert(len >= 0);

    int len1;
    
    // write packet to output buffer
    if( (outPos + len) < OUT_BUFFER_SIZE)
    {
        memcpy (outBuff + outPos, data, len);
        outPos += len;
    }
    else
    {
        // circular memory copy
		// 循环使用buffer
        len1 = OUT_BUFFER_SIZE - outPos;
        memcpy (outBuff + outPos, data, len1);
        memcpy (outBuff, data + len1, len - len1);
        outPos = len - len1;
    }


    // check if enough data to send out packet
   
	if(  (outPos == 0) && (recPos == 0) )
    {
        cpLog (LOG_DEBUG_STACK, "Buffer is empty");
        return 0;
    }
   

    // send out packets from buffer
    int result = 0;

    // create packet
    RtpPacket* p = new RtpPacket (networkFormat_payloadSize);
    assert (p);
    p->setSSRC (ssrc);
    p->setPayloadType (networkFormat);

	int packetSize =0;
	if(len<=networkFormat_payloadSize)
	{
		packetSize=len;
        p->setMarkerFlag(1);
	}
	else
		packetSize=networkFormat_payloadSize;

    p->setPayloadUsage (packetSize);
/*
    //fill packets
    while ( ((outPos + OUT_BUFFER_SIZE - recPos) % OUT_BUFFER_SIZE) > packetSize )
    {
		p->setPayloadUsage (packetSize);
		 p->setMarkerFlag(0);
        if(  (recPos + packetSize) < OUT_BUFFER_SIZE)
        {
            memcpy (p->getPayloadLoc(), outBuff + recPos, packetSize);
            recPos += packetSize;
        }
        else
        {
            // circular memory write
            len1 = OUT_BUFFER_SIZE - recPos;
            memcpy (p->getPayloadLoc(), outBuff + recPos, len1);
            memcpy (p->getPayloadLoc() + len1, outBuff, packetSize - len1);
            recPos = packetSize - len1;
        }
        // finish packet
        result += transmit(p);
		
    }
	*/
    //tutu add 
	if( ((outPos + OUT_BUFFER_SIZE - recPos) % OUT_BUFFER_SIZE) !=0)
	{
		packetSize=(outPos + OUT_BUFFER_SIZE - recPos) % OUT_BUFFER_SIZE;
		p->setPayloadUsage (packetSize);
		p->setMarkerFlag(1);
		if(  (recPos + packetSize) < OUT_BUFFER_SIZE)
        {
            memcpy (p->getPayloadLoc(), outBuff + recPos, packetSize);
            recPos += packetSize;
        }
        else
        {
            // circular memory write
			// 循环使用buffer
            len1 = OUT_BUFFER_SIZE - recPos;
            memcpy (p->getPayloadLoc(), outBuff + recPos, len1);
            memcpy (p->getPayloadLoc() + len1, outBuff, packetSize - len1);
            recPos = packetSize - len1;
        }
        // finish packet
        result += transmit(p);
	}

    if( p) delete p;
    p = NULL;

    // exit with success
    return result;
}



void RtpTransmitter::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 rtpPayloadG729:
        if( print) cpLog(LOG_DEBUG, "Setting network format to: G729 %d", no_samples);
        networkFormat_clockRate = 8000;
        break;
		case rtpPayloadH263:
         if( print ) cpLog(LOG_DEBUG, "Setting network format to: H263 %d", no_samples);
        networkFormat_clockRate = 90000;
        break;
		case rtpPayloadH261:
         if( print ) cpLog(LOG_DEBUG, "Setting network format to: H261 %d", no_samples);
        networkFormat_clockRate = 90000;
        break;
        default:
        cpLog(LOG_ERR, "networkFormat: codec(%d) samples(%d) packetSize(%d)",
              (int)networkFormat, 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 RtpTransmitter::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 rtpPayloadH263:
		if( print ) cpLog(LOG_DEBUG, "Setting api format to: H263 %d", no_samples);
        apiFormat_clockRate = 90000;
        break;
	case rtpPayloadH261:
		if( print ) cpLog(LOG_DEBUG, "Setting api format to: H261 %d", no_samples);
        apiFormat_clockRate = 90000;
        break;
    default:
        cpLog(LOG_ERR, "apiFormat: codec(%d) samples(%d) packetSize(%d)",
              (int)apiFormat, 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 RtpTransmitter::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 + -