📄 rtptransmitter.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 + -