📄 jvoiprtptransmission.cpp
字号:
/* This file is a part of JVOIPLIB, a library designed to facilitate the use of Voice over IP (VoIP). Copyright (C) 2000-2004 Jori Liesenborgs (jori@lumumba.luc.ac.be) This library (JVOIPLIB) is based upon work done for my thesis at the School for Knowledge Technology (Belgium/The Netherlands) This file was developed at the 'Expertise Centre for Digital Media' (EDM) in Diepenbeek, Belgium (http://www.edm.luc.ac.be). The EDM is a research institute of the 'Limburgs Universitair Centrum' (LUC) (http://www.luc.ac.be). The full GNU Library General Public License can be found in the file LICENSE.LGPL which is included in the source code archive. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "jvoipconfig.h"#include "jvoiprtptransmission.h"#include "jvoipcompression.h"#include "jvoiperrors.h"#include "rtpsession.h"#include "rtppacket.h"#include "rtpudpv4transmitter.h"#include "rtpsourcedata.h"#include "rtpipv4address.h"#include "rtpsessionparams.h"#include "voiceblock.h"#include <time.h>#include <string.h>#include <iostream>#ifndef WIN32 #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#else #include <winsock2.h>#endif // WIN32#include "debugnew.h"#define JVOIPRTPTRANS_JVOIPPAYLOADTYPE 101#define JVOIPRTPTRANS_HEADEROVERHEAD (20 /* min IP header */ + 8 /* UDP header */ + 12 /* min RTP header */)#define JVOIPRTPTRANS_JITTERADJUSTINTERVAL 3 // every three seconds#define JVOIPRTPTRANS_MAXPACKDIST 128#define JVOIPRTPTRANS_MAXPACKOUTRANGECOUNT 4#define JVOIPRTPTRANS_MAXTSDIST 4410000L#define JVOIPRTPTRANS_MAXTSOUTRANGECOUNT 4#define JVOIPRTPTRANS_PAYLOADTYPE_PCMU 0#define JVOIPRTPTRANS_PAYLOADTYPE_GSM 3#define JVOIPRTPTRANS_PAYLOADTYPE_LPC 7// Here is the component state info for the RTP transmitterclass JVOIPRTPTransmissionState : public JVOIPComponentState{public: JVOIPRTPTransmissionState(std::list<JVOIPRTPTransmission::ParticipantInfo*> &particip, std::list<JVOIPuint32> &mcast, std::list<JVOIPRTPTransmission::IPPortPair> &destin, std::list<JVOIPRTPTransmission::IPPortPair> &accept, std::list<JVOIPRTPTransmission::IPPortPair> &ignore, JVOIPSessionParams::ReceiveType recvtype, int curparticipid, double bytessent, double bytesreceived) throw (JVOIPException); ~JVOIPRTPTransmissionState(); std::list<JVOIPRTPTransmission::ParticipantInfo*> &Participants() { return participants; } std::list<JVOIPuint32> &MulticastIPs() { return mcastIPs; } std::list<JVOIPRTPTransmission::IPPortPair> &Destinations() { return destinations; } std::list<JVOIPRTPTransmission::IPPortPair> &AcceptList() { return acceptlist; } std::list<JVOIPRTPTransmission::IPPortPair> &IgnoreList() { return ignorelist; } JVOIPSessionParams::ReceiveType ReceiveType() const { return receivetype; } int CurrentID() const { return curid; } double BytesSent() const { return numbytessent; } double BytesReceived() const { return numbytesreceived; }private: std::list<JVOIPRTPTransmission::ParticipantInfo*> participants; std::list<JVOIPuint32> mcastIPs; std::list<JVOIPRTPTransmission::IPPortPair> destinations,acceptlist,ignorelist; JVOIPSessionParams::ReceiveType receivetype; int curid; double numbytessent,numbytesreceived;};JVOIPRTPTransmissionState::JVOIPRTPTransmissionState(std::list<JVOIPRTPTransmission::ParticipantInfo*> &particip, std::list<JVOIPuint32> &mcast, std::list<JVOIPRTPTransmission::IPPortPair> &destin, std::list<JVOIPRTPTransmission::IPPortPair> &accept, std::list<JVOIPRTPTransmission::IPPortPair> &ignore, JVOIPSessionParams::ReceiveType recvtype, int curparticipid, double bytessent, double bytesreceived) throw (JVOIPException){ std::list<JVOIPRTPTransmission::ParticipantInfo*>::const_iterator it1; std::list<JVOIPuint32>::const_iterator it2; std::list<JVOIPRTPTransmission::IPPortPair>::const_iterator it3; for (it1 = particip.begin() ; it1 != particip.end() ; ++it1) { JVOIPRTPTransmission::ParticipantInfo *p; p = new JVOIPRTPTransmission::ParticipantInfo(*(*it1)); if (p == NULL) throw JVOIPException(ERR_JVOIPLIB_GENERAL_OUTOFMEM); participants.push_back(p); } for (it2 = mcast.begin() ; it2 != mcast.end() ; ++it2) mcastIPs.push_back(*it2); for (it3 = destin.begin() ; it3 != destin.end() ; ++it3) destinations.push_back(*it3); for (it3 = accept.begin() ; it3 != accept.end() ; ++it3) acceptlist.push_back(*it3); for (it3 = ignore.begin() ; it3 != ignore.end() ; ++it3) ignorelist.push_back(*it3); receivetype = recvtype; curid = curparticipid; numbytessent = bytessent; numbytesreceived = bytesreceived; }JVOIPRTPTransmissionState::~JVOIPRTPTransmissionState(){ std::list<JVOIPRTPTransmission::ParticipantInfo*>::const_iterator it; for (it = participants.begin() ; it != participants.end() ; ++it) delete (*it); participants.clear();}// the parameter classJVOIPComponentParams *JVOIPRTPTransmissionParams::CreateCopy() const{ return new JVOIPRTPTransmissionParams(portbase,autoadjustbuffering,defaultbuffer,minimbuffer,acceptownpackets,localip);}// // Our own RTPSession instance// class JVOIPRTPTransSession : public RTPSession{public: JVOIPRTPTransSession(JVOIPRTPTransmission *trans) { transmitter = trans; }protected: void OnNewSource(RTPSourceData *srcdat) { transmitter->RTPJoinHandler(srcdat->GetSSRC()); } void OnRemoveSource(RTPSourceData *srcdat) { transmitter->RTPLeaveHandler(srcdat->GetSSRC()); }private: JVOIPRTPTransmission *transmitter;};//// The actual component//JVOIPRTPTransmission::JVOIPRTPTransmission(JVOIPSession *sess) throw (JVOIPException) : JVOIPTransmission(sess){ if (participantmutex.Init() < 0) throw JVOIPException(ERR_JVOIPLIB_GENERAL_CANTINITMUTEX); init = false; portbase = 0; localip = 0; autoadjustbuffering = false; acceptownpackets = false; defaultbuffer = 0;}JVOIPRTPTransmission::~JVOIPRTPTransmission(){ Cleanup();} int JVOIPRTPTransmission::Init(int sampinterval,int inputsamprate,int inputbytespersample,const JVOIPComponentParams *componentparams){ JVOIPRTPTransmissionParams defparams,*usrparams; int status; if (init) return ERR_JVOIPLIB_GENERAL_COMPONENTALREADYINIT; if (!SupportedSampleRate(inputsamprate)) return ERR_JVOIPLIB_RTPTRANS_UNSUPPORTEDSAMPLERATE; samplingrate = inputsamprate; bytespersample = inputbytespersample; interval = ((double)sampinterval)/1000.0; // convert to seconds if (componentparams == NULL) usrparams = &defparams; else if ((usrparams = dynamic_cast<JVOIPRTPTransmissionParams *>(const_cast<JVOIPComponentParams *>(componentparams))) == NULL) usrparams = &defparams; portbase = usrparams->GetPortBase(); localip = usrparams->GetLocalIP(); autoadjustbuffering = usrparams->GetAutoAdjustBuffer(); defaultbuffer = usrparams->GetDefaultBuffering(); minimbuffer = usrparams->GetMinimumBuffering(); acceptownpackets = usrparams->GetAcceptOwnPackets(); receivetype = JVOIPSessionParams::AcceptAll; if ((status = CreateNewRTPSession()) < 0) return status; // obtain the local IP that JRTPLIB uses // rtpsess->GetLocalIP(&localip); curid = 0; numbytessent = 0; numbytesreceived = 0; init = true; return 0;}int JVOIPRTPTransmission::Cleanup(){ if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; rtpsess->BYEDestroy(RTPTime(0.5),0,0); delete rtpsess; init = false; ClearParticipantInfo(); mcastIPs.clear(); destinations.clear(); acceptlist.clear(); ignorelist.clear(); return 0;}void JVOIPRTPTransmission::Reset(){ if (!init) return; std::list<ParticipantInfo*>::const_iterator it; participantmutex.Lock(); for (it = participants.begin() ; it != participants.end() ; ++it) { if (!(*it)->isnewsource) (*it)->ClearAllPublicFields(); } participantmutex.Unlock();}int JVOIPRTPTransmission::StartVoiceSourceIteration(){ if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; rtpsess->BeginDataAccess(); participantmutex.Lock(); return 0;}void JVOIPRTPTransmission::EndVoiceSourceIteration(){ if (!init) return; rtpsess->EndDataAccess(); participantmutex.Unlock();}bool JVOIPRTPTransmission::GotoFirstVoiceSource(){ bool val; RTPSourceData *srcdat; ParticipantInfo *inf; if (!init) return false; val = rtpsess->GotoFirstSourceWithData(); if (!val) return false; do { srcdat = rtpsess->GetCurrentSourceInfo(); inf = GetParticipantInfo(srcdat->GetSSRC()); if (!inf) val = rtpsess->GotoNextSourceWithData(); } while (!inf && val); val = (inf)?true:false; return val;}bool JVOIPRTPTransmission::GotoNextVoiceSource(){ bool val; RTPSourceData *srcdat; ParticipantInfo *inf; if (!init) return false; val = rtpsess->GotoNextSourceWithData(); if (!val) return false; do { srcdat = rtpsess->GetCurrentSourceInfo(); inf = GetParticipantInfo(srcdat->GetSSRC()); if (!inf) val = rtpsess->GotoNextSourceWithData(); } while (!inf && val); val = (inf)?true:false; return val;}VoIPFramework::VOIPuint64 JVOIPRTPTransmission::GetVoiceSourceID(){ RTPSourceData *srcdat; ParticipantInfo *inf; VoIPFramework::VOIPuint64 id = 0; if (!init) return 0; srcdat = rtpsess->GetCurrentSourceInfo(); if (srcdat) { inf = GetParticipantInfo(srcdat->GetSSRC()); if (inf) id = inf->ID(); } return id;}int JVOIPRTPTransmission::Poll(){ if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; // Polling is done in the background return 0;}bool JVOIPRTPTransmission::SourceHasMoreData(){ RTPSourceData *srcdat; ParticipantInfo *inf; bool val = false; if (!init) return 0; srcdat = rtpsess->GetCurrentSourceInfo(); if (srcdat) { inf = GetParticipantInfo(srcdat->GetSSRC()); if (inf) val = srcdat->HasData(); } return val;}int JVOIPRTPTransmission::SetSampleOffset(VoIPFramework::VOIPdouble offset){ std::list<ParticipantInfo*>::const_iterator it1; std::list<PacknumOffsetPair>::iterator it2; if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; cursampleoffset = offset; // check if we can clean some packet number lists participantmutex.Lock(); for (it1 = participants.begin() ; it1 != participants.end() ; ++it1) { if (!(*it1)->isnewsource) { it2 = (*it1)->receivedpacknums.begin(); while (it2 != (*it1)->receivedpacknums.end() && (*it2).offset <= offset) it2 = (*it1)->receivedpacknums.erase(it2); } } participantmutex.Unlock(); return 0;}bool JVOIPRTPTransmission::AddDestination(JVOIPuint32 destip,JVOIPuint16 destportbase){ std::list<IPPortPair>::const_iterator it; bool found,val; if (!init) return false; // search to see if the destination exists for (found = false,it = destinations.begin() ; !found && it != destinations.end() ; ++it) { if ((*it).ip == destip && (*it).port == destportbase) found = true; } if (!found) { RTPIPv4Address dest(destip,destportbase); if (rtpsess->AddDestination(dest) < 0) val = false; else { destinations.push_back(IPPortPair(destip,destportbase)); val = true; } } else val = true; return val;}bool JVOIPRTPTransmission::DeleteDestination(JVOIPuint32 destip,JVOIPuint16 destportbase){ std::list<IPPortPair>::iterator it; bool found,val; if (!init) return false; // search to see if the destination exists for (found = false,it = destinations.begin() ; !found && it != destinations.end() ; ) { if ((*it).ip == destip && (*it).port == destportbase) found = true; else ++it; } if (!found) return false; RTPIPv4Address dest(destip,destportbase); if (rtpsess->DeleteDestination(dest) < 0) val = false; else { val = true; destinations.erase(it); } return val;}void JVOIPRTPTransmission::ClearDestinations(){ if (!init) return; rtpsess->ClearDestinations(); destinations.clear();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -