📄 jvoiprtptransmission.cpp
字号:
{ JVOIPRTPTransmissionState *s; participantmutex.Lock(); s = new JVOIPRTPTransmissionState(participants,mcastIPs,destinations, acceptlist,ignorelist,receivetype, curid,numbytessent,numbytesreceived); participantmutex.Unlock(); if (s == NULL) return ERR_JVOIPLIB_GENERAL_OUTOFMEM; *compstate = s; } catch(JVOIPException e) { return e.GetErrorNumber(); } return 0;}int JVOIPRTPTransmission::SetComponentState(JVOIPComponentState *compstate){ std::list<ParticipantInfo*>::const_iterator it1; std::list<JVOIPuint32>::const_iterator it2; std::list<IPPortPair>::const_iterator it3; JVOIPRTPTransmissionState *state; if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; if (compstate == NULL) return ERR_JVOIPLIB_GENERAL_ILLEGALSTATEPARAMETER; state = dynamic_cast<JVOIPRTPTransmissionState *>(compstate); if (state == NULL) return ERR_JVOIPLIB_GENERAL_ILLEGALSTATEPARAMETER; ClearParticipantInfo(); mcastIPs.clear(); destinations.clear(); acceptlist.clear(); ignorelist.clear(); rtpsess->LeaveAllMulticastGroups(); rtpsess->ClearDestinations(); rtpsess->ClearAcceptList(); rtpsess->ClearIgnoreList(); switch(state->ReceiveType()) { case JVOIPSessionParams::AcceptSome: rtpsess->SetReceiveMode(RTPTransmitter::AcceptSome); break; case JVOIPSessionParams::IgnoreSome: rtpsess->SetReceiveMode(RTPTransmitter::IgnoreSome); case JVOIPSessionParams::AcceptAll: break; default: rtpsess->SetReceiveMode(RTPTransmitter::AcceptAll); } participantmutex.Lock(); for (it1 = state->Participants().begin() ; it1 != state->Participants().end() ; ++it1) { ParticipantInfo *p; p = new ParticipantInfo(*(*it1)); if (p == NULL) { participantmutex.Unlock(); return ERR_JVOIPLIB_GENERAL_OUTOFMEM; } participants.push_back(p); } participantmutex.Unlock(); for (it2 = state->MulticastIPs().begin() ; it2 != state->MulticastIPs().end() ; ++it2) { RTPIPv4Address mcastgroup(*it2); if (rtpsess->JoinMulticastGroup(mcastgroup) < 0) return ERR_JVOIPLIB_RTPTRANS_CANTREJOINMULTICASTGROUP; mcastIPs.push_back(*it2); } for (it3 = state->Destinations().begin() ; it3 != state->Destinations().end() ; ++it3) { RTPIPv4Address dest((*it3).ip,(*it3).port); if (rtpsess->AddDestination(dest) < 0) return ERR_JVOIPLIB_RTPTRANS_CANTREINSTALLDESTINATIONS; destinations.push_back(*it3); } switch(state->ReceiveType()) { case JVOIPSessionParams::AcceptSome: rtpsess->SetReceiveMode(RTPTransmitter::AcceptSome); break; case JVOIPSessionParams::IgnoreSome: rtpsess->SetReceiveMode(RTPTransmitter::IgnoreSome); break; case JVOIPSessionParams::AcceptAll: default: rtpsess->SetReceiveMode(RTPTransmitter::AcceptAll); } for (it3 = state->AcceptList().begin() ; it3 != state->AcceptList().end() ; ++it3) { if (state->ReceiveType() == JVOIPSessionParams::AcceptSome) { if ((*it3).port == JVOIP_ALLPORTS) { RTPIPv4Address dest((*it3).ip); rtpsess->AddToAcceptList(dest); } else { RTPIPv4Address dest((*it3).ip,(*it3).port); rtpsess->AddToAcceptList(dest); } } acceptlist.push_back(*it3); } for (it3 = state->IgnoreList().begin() ; it3 != state->IgnoreList().end() ; ++it3) { if (state->ReceiveType() == JVOIPSessionParams::IgnoreSome) { if ((*it3).port == JVOIP_ALLPORTS) { RTPIPv4Address dest((*it3).ip); rtpsess->AddToIgnoreList(dest); } else { RTPIPv4Address dest((*it3).ip,(*it3).port); rtpsess->AddToIgnoreList(dest); } } ignorelist.push_back(*it3); } receivetype = state->ReceiveType(); curid = state->CurrentID(); numbytessent = state->BytesSent(); numbytesreceived = state->BytesReceived(); return 0;}std::string JVOIPRTPTransmission::GetComponentName(){ return std::string("JVOIPRTPTransmission");}std::string JVOIPRTPTransmission::GetComponentDescription(){ return std::string("JVOIPLIB Internal RTP transmitter (uses JRTPLIB)");}std::vector<JVOIPCompParamInfo> *JVOIPRTPTransmission::GetComponentParameters() throw (JVOIPException){ std::vector<JVOIPCompParamInfo> *paraminfo; char str[256]; struct in_addr ad; paraminfo = new std::vector<JVOIPCompParamInfo>(5); if (paraminfo == NULL) throw JVOIPException(ERR_JVOIPLIB_GENERAL_OUTOFMEM); // set the local portbase sprintf(str,"%d",portbase); (*paraminfo)[0].SetParameterName(std::string("RTP portbase")); (*paraminfo)[0].SetParameterValue(std::string(str)); // set the local IP address ad.s_addr = htonl(localip); (*paraminfo)[1].SetParameterName(std::string("Local IP")); (*paraminfo)[1].SetParameterValue(std::string(inet_ntoa(ad))); // auto buffering (*paraminfo)[2].SetParameterName(std::string("Auto buffering")); if (autoadjustbuffering) (*paraminfo)[2].SetParameterValue(std::string("Yes")); else (*paraminfo)[2].SetParameterValue(std::string("No")); // default buffering sprintf(str,"%.3f",(float)defaultbuffer); (*paraminfo)[3].SetParameterName(std::string("Default buffering")); (*paraminfo)[3].SetParameterValue(std::string(str)); // accept own packets (*paraminfo)[4].SetParameterName(std::string("Accept own packets")); if (acceptownpackets) (*paraminfo)[4].SetParameterValue(std::string("Yes")); else (*paraminfo)[4].SetParameterValue(std::string("No")); return paraminfo;}int JVOIPRTPTransmission::CreateNewRTPSession(){ int errcode; RTPSessionParams sessparams; RTPUDPv4TransmissionParams transparams; if (sessparams.SetUsePollThread(true) < 0) return ERR_JVOIPLIB_RTPTRANS_CANTINITRTPSESSION; switch(receivetype) { case JVOIPSessionParams::AcceptSome: sessparams.SetReceiveMode(RTPTransmitter::AcceptSome); break; case JVOIPSessionParams::IgnoreSome: sessparams.SetReceiveMode(RTPTransmitter::IgnoreSome); break; case JVOIPSessionParams::AcceptAll: default: sessparams.SetReceiveMode(RTPTransmitter::AcceptAll); } sessparams.SetMaximumPacketSize(JVOIPRTPTRANS_MAXPACKSIZE); sessparams.SetOwnTimestampUnit(1.0/((double)samplingrate)); sessparams.SetAcceptOwnPackets(acceptownpackets); transparams.SetPortbase(portbase); if (localip != 0) { std::list<u_int32_t> iplist; iplist.push_back(localip); transparams.SetLocalIPList(iplist); } rtpsess = new JVOIPRTPTransSession(this); if (rtpsess == NULL) return ERR_JVOIPLIB_GENERAL_OUTOFMEM; if ((errcode = rtpsess->Create(sessparams,&transparams)) < 0) { delete rtpsess; return ERR_JVOIPLIB_RTPTRANS_CANTINITRTPSESSION; } return 0;}bool JVOIPRTPTransmission::SupportedSampleRate(int rate){ if (rate != 4000 && rate != 8000 && rate != 11025 && rate != 22050 && rate != 44100) return false; return true;}void JVOIPRTPTransmission::ClearParticipantInfo(){ std::list<ParticipantInfo*>::const_iterator it; participantmutex.Lock(); for (it = participants.begin() ; it != participants.end() ; ++it) delete (*it); participants.clear(); participantmutex.Unlock();}inline JVOIPRTPTransmission::ParticipantInfo *JVOIPRTPTransmission::GetParticipantInfo(unsigned long ssrc){ std::list<ParticipantInfo*>::const_iterator it; for (it = participants.begin() ; it != participants.end() ; ++it) { if ((*it)->SSRC() == ssrc) return (*it); } return NULL;}void JVOIPRTPTransmission::RTPJoinHandler(unsigned long ssrc){ std::list<ParticipantInfo*>::iterator it; ParticipantInfo *newparticip; bool done; participantmutex.Lock(); it = participants.begin(); done = false; while (!done && it != participants.end()) { if (ssrc <= (*it)->SSRC()) done = true; else ++it; } newparticip = new ParticipantInfo(++curid,ssrc); if (newparticip == NULL) // Out of memory { participantmutex.Unlock(); return; } if (!done) // insert at the back of the array participants.push_back(newparticip); else // insert before position i { if (ssrc != (*it)->SSRC()) participants.insert(it,newparticip); } participantmutex.Unlock();}void JVOIPRTPTransmission::RTPLeaveHandler(unsigned long ssrc){ std::list<ParticipantInfo*>::iterator it; bool done; participantmutex.Lock(); it = participants.begin(); done = false; while (!done && it != participants.end()) { if (ssrc <= (*it)->SSRC()) done = true; else ++it; } if (done) { if (ssrc == (*it)->SSRC()) { delete (*it); participants.erase(it); } } participantmutex.Unlock();}int JVOIPRTPTransmission::SendBlock(VoIPFramework::VoiceBlock *vb){ if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; if ((int)vb->GetSampleRate() != samplingrate || vb->GetBytesPerSample() != bytespersample) return ERR_JVOIPLIB_GENERAL_VOICEBLOCKINFODOESNTMATCHSETTINGS; if (!vb->IsSilence()) { int datalen; unsigned char payloadtype; bool marker; datalen = EncodeData(vb,&payloadtype,&marker); if (datalen < 0) return datalen; // error if (rtpsess->SendPacket(sendbuf,datalen,payloadtype,false,vb->GetNumSamples()) < 0) return ERR_JVOIPLIB_RTPTRANS_CANTSENDPACKET; numbytessent += datalen + JVOIPRTPTRANS_HEADEROVERHEAD; } else { if (rtpsess->IncrementTimestamp(vb->GetNumSamples()) < 0) return ERR_JVOIPLIB_RTPTRANS_CANTINCREMENTTIMESTAMP; } return 0;}int JVOIPRTPTransmission::EncodeData(VoIPFramework::VoiceBlock *vb,unsigned char *payloadtype,bool *marker){ bool specificpayloadtype = false; int len; // Tests for particular payloadtypes len = 0; if (!vb->Has3DInfo()) { if (!vb->IsStereo() && vb->GetSampleRate() == 8000 && vb->GetMajorCompressionID() == JVOIPCOMPRESSIONTYPE_MAJOR_ULAWCOMPRESSION) { *payloadtype = JVOIPRTPTRANS_PAYLOADTYPE_PCMU; specificpayloadtype = true; } else if (!vb->IsStereo() && vb->GetSampleRate() == 8000 && vb->GetMajorCompressionID() == JVOIPCOMPRESSIONTYPE_MAJOR_GSMCOMPRESSION) { *payloadtype = JVOIPRTPTRANS_PAYLOADTYPE_GSM; specificpayloadtype = true; } else if (!vb->IsStereo() && vb->GetSampleRate() == 8000 && vb->GetMajorCompressionID() == JVOIPCOMPRESSIONTYPE_MAJOR_LPCCOMPRESSION) { *payloadtype = JVOIPRTPTRANS_PAYLOADTYPE_LPC; specificpayloadtype = true; } } if (specificpayloadtype) { if ((len = vb->GetNumBytes()) >= JVOIPRTPTRANS_MAXPACKSIZE) return ERR_JVOIPLIB_RTPTRANS_PACKETTOOLARGE; memcpy(sendbuf,vb->GetSamples(false),len); } else { unsigned char infobyte = 0; *payloadtype = JVOIPRTPTRANS_JVOIPPAYLOADTYPE; // encode the sampling rate switch(samplingrate) { case 4000: infobyte = 0; break; case 8000: infobyte = 1; break; case 11025: infobyte = 2; break; case 22050: infobyte = 3; break; case 44100: infobyte = 4; break; default: std::cerr << "JVOIPRTPTransmission::EncodeData: Invalid sampling rate!" << std::endl; } // set 3D info flag if (vb->Has3DInfo()) infobyte |= (1<<4); // set bytes per sample flag if (vb->GetBytesPerSample() != 1) infobyte |= (1<<5); // NOTE: we don't have to say anything about stereo since at this point, we assume // it's mono! sendbuf[len++] = infobyte; // fill in 3D info if (vb->Has3DInfo()) { sendbuf[len++] = vb->GetInfo3DLength(); memcpy(sendbuf+len,vb->GetInfo3D(false),vb->GetInfo3DLength()); len += vb->GetInfo3DLength(); } // set compression info sendbuf[len++] = vb->GetMajorCompressionID(); sendbuf[len++] = vb->GetMinorCompressionID(); if ((len + vb->GetNumBytes()) > JVOIPRTPTRANS_MAXPACKSIZE) return ERR_JVOIPLIB_RTPTRANS_PACKETTOOLARGE; memcpy(sendbuf+len,vb->GetSamples(false),vb->GetNumBytes()); len += vb->GetNumBytes(); } return len;}int JVOIPRTPTransmission::GetSampleBlock(VoIPFramework::VoiceBlock *vb){ RTPPacket *pack; RTPSourceData *srcdat; unsigned long jitter,ssrc; ParticipantInfo *partinf; VoIPFramework::VOIPdouble offset; VoIPFramework::VOIPuint64 packnum; std::list<PacknumOffsetPair>::iterator it; time_t curtime; if (!init) return ERR_JVOIPLIB_GENERAL_COMPONENTNOTINIT; // Get the necessary data from the RTP session pack = rtpsess->GetNextPacket(); srcdat = rtpsess->GetCurrentSourceInfo(); ssrc = srcdat->GetSSRC();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -