📄 rtpsession.cpp
字号:
BUILDER_UNLOCK return status;}int RTPSession::SetPreTransmissionDelay(const RTPTime &delay){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetPreTransmissionDelay(delay); BUILDER_UNLOCK return status;}RTPTransmissionInfo *RTPSession::GetTransmissionInfo(){ if (!created) return 0; return rtptrans->GetTransmissionInfo();}int RTPSession::Poll(){ int status; if (!created) return ERR_RTP_SESSION_NOTCREATED; if (usingpollthread) return ERR_RTP_SESSION_USINGPOLLTHREAD; if ((status = rtptrans->Poll()) < 0) return status; return ProcessPolledData();}int RTPSession::WaitForIncomingData(const RTPTime &delay,bool *dataavailable){ if (!created) return ERR_RTP_SESSION_NOTCREATED; if (usingpollthread) return ERR_RTP_SESSION_USINGPOLLTHREAD; return rtptrans->WaitForIncomingData(delay,dataavailable);}int RTPSession::AbortWait(){ if (!created) return ERR_RTP_SESSION_NOTCREATED; if (usingpollthread) return ERR_RTP_SESSION_USINGPOLLTHREAD; return rtptrans->AbortWait();}RTPTime RTPSession::GetRTCPDelay(){ if (!created) return RTPTime(0,0); if (usingpollthread) return RTPTime(0,0); SOURCES_LOCK SCHED_LOCK RTPTime t = rtcpsched.GetTransmissionDelay(); SCHED_UNLOCK SOURCES_UNLOCK return t;}int RTPSession::BeginDataAccess(){ if (!created) return ERR_RTP_SESSION_NOTCREATED; SOURCES_LOCK return 0;}bool RTPSession::GotoFirstSource(){ if (!created) return false; return sources.GotoFirstSource();}bool RTPSession::GotoNextSource(){ if (!created) return false; return sources.GotoNextSource();}bool RTPSession::GotoPreviousSource(){ if (!created) return false; return sources.GotoPreviousSource();}bool RTPSession::GotoFirstSourceWithData(){ if (!created) return false; return sources.GotoFirstSourceWithData();}bool RTPSession::GotoNextSourceWithData(){ if (!created) return false; return sources.GotoNextSourceWithData();}bool RTPSession::GotoPreviousSourceWithData(){ if (!created) return false; return sources.GotoPreviousSourceWithData();}RTPSourceData *RTPSession::GetCurrentSourceInfo(){ if (!created) return 0; return sources.GetCurrentSourceInfo();}RTPSourceData *RTPSession::GetSourceInfo(uint32_t ssrc){ if (!created) return 0; return sources.GetSourceInfo(ssrc);}RTPPacket *RTPSession::GetNextPacket(){ if (!created) return 0; return sources.GetNextPacket();}int RTPSession::EndDataAccess(){ if (!created) return ERR_RTP_SESSION_NOTCREATED; SOURCES_UNLOCK return 0;}int RTPSession::SetReceiveMode(RTPTransmitter::ReceiveMode m){ if (!created) return ERR_RTP_SESSION_NOTCREATED; return rtptrans->SetReceiveMode(m);}int RTPSession::AddToIgnoreList(const RTPAddress &addr){ if (!created) return ERR_RTP_SESSION_NOTCREATED; return rtptrans->AddToIgnoreList(addr);}int RTPSession::DeleteFromIgnoreList(const RTPAddress &addr){ if (!created) return ERR_RTP_SESSION_NOTCREATED; return rtptrans->DeleteFromIgnoreList(addr);}void RTPSession::ClearIgnoreList(){ if (!created) return; rtptrans->ClearIgnoreList();}int RTPSession::AddToAcceptList(const RTPAddress &addr){ if (!created) return ERR_RTP_SESSION_NOTCREATED; return rtptrans->AddToAcceptList(addr);}int RTPSession::DeleteFromAcceptList(const RTPAddress &addr){ if (!created) return ERR_RTP_SESSION_NOTCREATED; return rtptrans->DeleteFromAcceptList(addr);}void RTPSession::ClearAcceptList(){ if (!created) return; rtptrans->ClearAcceptList();}int RTPSession::SetMaximumPacketSize(size_t s){ if (!created) return ERR_RTP_SESSION_NOTCREATED; if (s < RTP_MINPACKETSIZE) return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL; int status; if ((status = rtptrans->SetMaximumPacketSize(s)) < 0) return status; BUILDER_LOCK if ((status = packetbuilder.SetMaximumPacketSize(s)) < 0) { BUILDER_UNLOCK // restore previous max packet size rtptrans->SetMaximumPacketSize(maxpacksize); return status; } if ((status = rtcpbuilder.SetMaximumPacketSize(s)) < 0) { // restore previous max packet size packetbuilder.SetMaximumPacketSize(maxpacksize); BUILDER_UNLOCK rtptrans->SetMaximumPacketSize(maxpacksize); return status; } BUILDER_UNLOCK maxpacksize = s; return 0;}int RTPSession::SetSessionBandwidth(double bw){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; SCHED_LOCK RTCPSchedulerParams p = rtcpsched.GetParameters(); status = p.SetRTCPBandwidth(bw*controlfragment); if (status >= 0) { rtcpsched.SetParameters(p); sessionbandwidth = bw; } SCHED_UNLOCK return status;}int RTPSession::SetTimestampUnit(double u){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetTimestampUnit(u); BUILDER_UNLOCK return status;}void RTPSession::SetNameInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetNameInterval(count); BUILDER_UNLOCK}void RTPSession::SetEMailInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetEMailInterval(count); BUILDER_UNLOCK}void RTPSession::SetLocationInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetLocationInterval(count); BUILDER_UNLOCK}void RTPSession::SetPhoneInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetPhoneInterval(count); BUILDER_UNLOCK}void RTPSession::SetToolInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetToolInterval(count); BUILDER_UNLOCK}void RTPSession::SetNoteInterval(int count){ if (!created) return; BUILDER_LOCK rtcpbuilder.SetNoteInterval(count); BUILDER_UNLOCK}int RTPSession::SetLocalName(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalName(s,len); BUILDER_UNLOCK return status;}int RTPSession::SetLocalEMail(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalEMail(s,len); BUILDER_UNLOCK return status;}int RTPSession::SetLocalLocation(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalLocation(s,len); BUILDER_UNLOCK return status;}int RTPSession::SetLocalPhone(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalPhone(s,len); BUILDER_UNLOCK return status;}int RTPSession::SetLocalTool(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalTool(s,len); BUILDER_UNLOCK return status;}int RTPSession::SetLocalNote(const void *s,size_t len){ if (!created) return ERR_RTP_SESSION_NOTCREATED; int status; BUILDER_LOCK status = rtcpbuilder.SetLocalNote(s,len); BUILDER_UNLOCK return status;}int RTPSession::ProcessPolledData(){ RTPRawPacket *rawpack; int status; SOURCES_LOCK while ((rawpack = rtptrans->GetNextPacket()) != 0) { sources.ClearOwnCollisionFlag(); // since our sources instance also uses the scheduler (analysis of incoming packets) // we'll lock it SCHED_LOCK if ((status = sources.ProcessRawPacket(rawpack,rtptrans,acceptownpackets)) < 0) { SCHED_UNLOCK SOURCES_UNLOCK delete rawpack; return status; } SCHED_UNLOCK if (sources.DetectedOwnCollision()) // collision handling! { bool created; if ((status = collisionlist.UpdateAddress(rawpack->GetSenderAddress(),rawpack->GetReceiveTime(),&created)) < 0) { SOURCES_UNLOCK delete rawpack; return status; } if (created) // first time we've encountered this address, send bye packet and { // change our own SSRC if (rtptrans->GetNumRTPPacketsSent() != 0 || rtptrans->GetNumRTCPPacketsSent() != 0) { // Only send BYE packet if we've actually sent data using this // SSRC RTCPCompoundPacket *rtcpcomppack; BUILDER_LOCK if ((status = rtcpbuilder.BuildBYEPacket(&rtcpcomppack,0,0,useSR_BYEifpossible)) < 0) { BUILDER_UNLOCK SOURCES_UNLOCK delete rawpack; return status; } BUILDER_UNLOCK byepackets.push_back(rtcpcomppack); if (byepackets.size() == 1) // was the first packet, schedule a BYE packet (otherwise there's already one scheduled) { SCHED_LOCK rtcpsched.ScheduleBYEPacket(rtcpcomppack->GetCompoundPacketLength()); SCHED_UNLOCK } } // bye packet is built and scheduled, now change our SSRC // and reset the packet count in the transmitter BUILDER_LOCK uint32_t newssrc = packetbuilder.CreateNewSSRC(sources); BUILDER_UNLOCK rtptrans->ResetPacketCount(); // remove old entry in source table and add new one if ((status = sources.DeleteOwnSSRC()) < 0) { SOURCES_UNLOCK delete rawpack; return status; } if ((status = sources.CreateOwnSSRC(newssrc)) < 0) { SOURCES_UNLOCK delete rawpack; return status; } } } delete rawpack; } SCHED_LOCK RTPTime d = rtcpsched.CalculateDeterministicInterval(false); SCHED_UNLOCK RTPTime t = RTPTime::CurrentTime(); double Td = d.GetDouble(); RTPTime sendertimeout = RTPTime(Td*sendermultiplier); RTPTime generaltimeout = RTPTime(Td*membermultiplier); RTPTime byetimeout = RTPTime(Td*byemultiplier); RTPTime colltimeout = RTPTime(Td*collisionmultiplier); RTPTime notetimeout = RTPTime(Td*notemultiplier); sources.MultipleTimeouts(t,sendertimeout,byetimeout,generaltimeout,notetimeout); collisionlist.Timeout(t,colltimeout); // We'll check if it's time for RTCP stuff SCHED_LOCK bool istime = rtcpsched.IsTime(); SCHED_UNLOCK if (istime) { RTCPCompoundPacket *pack; // we'll check if there's a bye packet to send, or just a normal packet if (byepackets.empty()) { BUILDER_LOCK if ((status = rtcpbuilder.BuildNextPacket(&pack)) < 0) { BUILDER_UNLOCK SOURCES_UNLOCK return status; } BUILDER_UNLOCK if ((status = rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength())) < 0) { SOURCES_UNLOCK delete pack; return status; } } else { pack = *(byepackets.begin()); byepackets.pop_front(); if ((status = rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength())) < 0) { SOURCES_UNLOCK delete pack; return status; } if (!byepackets.empty()) // more bye packets to send, schedule them { SCHED_LOCK rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength()); SCHED_UNLOCK } } SCHED_LOCK rtcpsched.AnalyseOutgoing(*pack); SCHED_UNLOCK delete pack; } SOURCES_UNLOCK return 0;}int RTPSession::CreateCNAME(uint8_t *buffer,size_t *bufferlength,bool resolve){#ifndef WIN32 bool gotlogin = true;#ifdef RTP_SUPPORT_GETLOGINR buffer[0] = 0; if (getlogin_r((char *)buffer,*bufferlength) != 0) gotlogin = false; else { if (buffer[0] == 0) gotlogin = false; } if (!gotlogin) // try regular getlogin { char *loginname = getlogin(); if (loginname == 0) gotlogin = false; else strncpy((char *)buffer,loginname,*bufferlength); }#else char *loginname = getlogin(); if (loginname == 0) gotlogin = false; else strncpy((char *)buffer,loginname,*bufferlength);#endif // RTP_SUPPORT_GETLOGINR if (!gotlogin) { char *logname = getenv("LOGNAME"); if (logname == 0) return ERR_RTP_SESSION_CANTGETLOGINNAME; strncpy((char *)buffer,logname,*bufferlength); }#else // Win32 version#ifndef _WIN32_WCE DWORD len = *bufferlength; if (!gethostname((LPTSTR)buffer,sizeof(buffer)));//&len)) strcpy((char *)buffer,"unknown");#else strcpy((char *)buffer,"unknown");#endif // _WIN32_WCE #endif // WIN32 buffer[*bufferlength-1] = 0; size_t offset = strlen((const char *)buffer); if (offset < (*bufferlength-1)) buffer[offset] = (uint8_t)'@'; offset++; size_t buflen2 = *bufferlength-offset; int status; if (resolve) { if ((status = rtptrans->GetLocalHostName(buffer+offset,&buflen2)) < 0) return status; *bufferlength = buflen2+offset; } else { char hostname[1024]; strcpy(hostname,"localhost"); // just in case gethostname fails gethostname(hostname,1024); strncpy((char *)(buffer+offset),hostname,buflen2); *bufferlength = offset+strlen(hostname); } if (*bufferlength > RTCP_SDES_MAXITEMLENGTH) *bufferlength = RTCP_SDES_MAXITEMLENGTH; return 0;}#ifdef RTPDEBUGvoid RTPSession::DumpSources(){ BeginDataAccess(); std::cout << "----------------------------------------------------------------" << std::endl; sources.Dump(); EndDataAccess();}void RTPSession::DumpTransmitter(){ if (created) rtptrans->Dump();}#endif // RTPDEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -