RTPTime RTCPScheduler::CalculateBYETransmissionInterval() { if (!byescheduled) return RTPTime(0,0); if (sendbyenow) return RTPTime(0,0); double C,n; C = ((double)avgbyepacketsize)/((1.0-schedparams.GetSenderBandwidthFraction())*schedparams.GetRTCPBandwidth()); n = (double)byemembers; RTPTime Tmin = schedparams.GetMinimumTransmissionInterval(); double tmin = Tmin.GetDouble(); if (schedparams.GetUseHalfAtStartup()) tmin /= 2.0; double ntimesC = n*C; double Td = (tmin>ntimesC)?tmin:ntimesC; double mul = rtprand.GetRandomDouble()+0.5; // gives random value between 0.5 and 1.5 double T = (Td*mul)/1.21828; // see RFC 3550 p 30 return RTPTime(T); }
RTPSessionParams::RTPSessionParams() : mininterval(0,0) { #ifdef RTP_SUPPORT_THREAD usepollthread = true; #else usepollthread = false; #endif // RTP_SUPPORT_THREAD maxpacksize = RTP_DEFAULTPACKETSIZE; receivemode = RTPTransmitter::AcceptAll; acceptown = false; owntsunit = -1; // The user will have to set it to the correct value himself resolvehostname = false; #ifdef RTP_SUPPORT_PROBATION probationtype = RTPSources::ProbationStore; #endif // RTP_SUPPORT_PROBATION mininterval = RTPTime(RTCP_DEFAULTMININTERVAL); sessionbandwidth = RTP_DEFAULTSESSIONBANDWIDTH; controlfrac = RTCP_DEFAULTBANDWIDTHFRACTION; senderfrac = RTCP_DEFAULTSENDERFRACTION; usehalfatstartup = RTCP_DEFAULTHALFATSTARTUP; immediatebye = RTCP_DEFAULTIMMEDIATEBYE; SR_BYE = RTCP_DEFAULTSRBYE; sendermultiplier = RTP_SENDERTIMEOUTMULTIPLIER; generaltimeoutmultiplier = RTP_MEMBERTIMEOUTMULTIPLIER; byetimeoutmultiplier = RTP_BYETIMEOUTMULTIPLIER; collisionmultiplier = RTP_COLLISIONTIMEOUTMULTIPLIER; notemultiplier = RTP_NOTETTIMEOUTMULTIPLIER; }
void RTPPollThread::Stop() { if (!IsRunning()) return; stopmutex.Lock(); stop = true; stopmutex.Unlock(); if (transmitter) transmitter->AbortWait(); RTPTime thetime = RTPTime::CurrentTime(); bool done = false; while (JThread::IsRunning() && !done) { // wait max 5 sec RTPTime curtime = RTPTime::CurrentTime(); if ((curtime.GetDouble()-thetime.GetDouble()) > 5.0) done = true; RTPTime::Wait(RTPTime(0,10000)); } if (JThread::IsRunning()) { #ifndef _WIN32_WCE std::cerr << "RTPPollThread: Warning! Having to kill thread!" << std::endl; #endif // _WIN32_WCE JThread::Kill(); } stop = false; transmitter = 0; }
void RTPHandler::send(unsigned char* pckt, unsigned int n) { //TODO: Fragmentation; int e = sess.SendPacket((void *)pckt,n,0,false,CLK_RATE); if(error(e)) return; sess.BeginDataAccess(); // check incoming packets if (sess.GotoFirstSourceWithData()) { while(sess.GotoNextSourceWithData()) { RTPPacket *pack; while ((pack = sess.GetNextPacket()) != NULL) { cout <<"Got packet !" << endl; sess.DeletePacket(pack); } } } sess.EndDataAccess(); RTPTime::Wait(RTPTime(0,FPS)); }
int main(void) { int status,i; RTPSession s; RTPSessionParams sessparams; RTPUDPv4TransmissionParams transparams; char blaai[100]; transparams.SetPortbase(10000); sessparams.SetOwnTimestampUnit(1.0/8000.0); sessparams.SetUsePollThread(true); sessparams.SetMaximumPacketSize(10000); status = s.Create(sessparams,&transparams); s.SetLocalName((const uint8_t *)"Jori Liesenborgs",16); s.SetLocalEMail((const uint8_t *)"*****@*****.**",20); s.SetLocalNote((const uint8_t *)"Blaai",5); s.SetNameInterval(3); s.SetEMailInterval(5); s.SetNoteInterval(2); status = s.AddDestination(RTPIPv4Address(ntohl(inet_addr("192.168.2.115")),5000)); //status = s.AddDestination(RTPIPv4Address(ntohl(inet_addr("127.0.0.1")),7000)); int snd = open("/dev/dsp",O_RDWR); int val; val = 0; status = ioctl(snd,SNDCTL_DSP_STEREO,&val); val = 8; status = ioctl(snd,SNDCTL_DSP_SAMPLESIZE,&val); val = 8000; status = ioctl(snd,SNDCTL_DSP_SPEED,&val); val = 7 | (128<<16); ioctl(snd,SNDCTL_DSP_SETFRAGMENT,&val); i = 0; while (i++ < 40000) { if (i == 1000) { //std::cout <<"Disabling note" << std::endl; s.SetNoteInterval(0); } uint8_t data[PACKSIZE]; RTPTime t1 = RTPTime::CurrentTime(); status = read(snd,data,PACKSIZE); RTPTime t2 = RTPTime::CurrentTime(); t2 -= t1; printf("%d.%06d\n",t2.GetSeconds(),t2.GetMicroSeconds()); status = s.SendPacket(data,PACKSIZE,1,false,PACKSIZE); } close(snd); printf("Destroying...\n"); s.BYEDestroy(RTPTime(10,0),(const uint8_t *)"Leaving session",16); return 0; }
void RTCPScheduler::PerformReverseReconsideration() { if (firstcall) return; double diff1,diff2; int members = sources.GetActiveMemberCount(); RTPTime tc = RTPTime::CurrentTime(); RTPTime tn_min_tc = nextrtcptime; if (tn_min_tc > tc) tn_min_tc -= tc; else tn_min_tc = RTPTime(0,0); // std::cout << "+tn_min_tc0 " << nextrtcptime.GetDouble()-tc.GetDouble() << std::endl; // std::cout << "-tn_min_tc0 " << -nextrtcptime.GetDouble()+tc.GetDouble() << std::endl; // std::cout << "tn_min_tc " << tn_min_tc.GetDouble() << std::endl; RTPTime tc_min_tp = tc; if (tc_min_tp > prevrtcptime) tc_min_tp -= prevrtcptime; else tc_min_tp = 0; if (pmembers == 0) // avoid division by zero pmembers++; diff1 = (((double)members)/((double)pmembers))*tn_min_tc.GetDouble(); diff2 = (((double)members)/((double)pmembers))*tc_min_tp.GetDouble(); nextrtcptime = tc; prevrtcptime = tc; nextrtcptime += RTPTime(diff1); prevrtcptime -= RTPTime(diff2); pmembers = members; }
RTPTime RTCPScheduler::CalculateDeterministicInterval(bool sender /* = false */) { int numsenders = sources.GetSenderCount(); int numtotal = sources.GetActiveMemberCount(); // std::cout << "CalculateDeterministicInterval" << std::endl; // std::cout << " numsenders: " << numsenders << std::endl; // std::cout << " numtotal: " << numtotal << std::endl; // Try to avoid division by zero: if (numtotal == 0) numtotal++; double sfraction = ((double)numsenders)/((double)numtotal); double C,n; if (sfraction <= schedparams.GetSenderBandwidthFraction()) { if (sender) { C = ((double)avgrtcppacksize)/(schedparams.GetSenderBandwidthFraction()*schedparams.GetRTCPBandwidth()); n = (double)numsenders; } else { C = ((double)avgrtcppacksize)/((1.0-schedparams.GetSenderBandwidthFraction())*schedparams.GetRTCPBandwidth()); n = (double)(numtotal-numsenders); } } else { C = ((double)avgrtcppacksize)/schedparams.GetRTCPBandwidth(); n = (double)numtotal; } RTPTime Tmin = schedparams.GetMinimumTransmissionInterval(); double tmin = Tmin.GetDouble(); if (!hassentrtcp && schedparams.GetUseHalfAtStartup()) tmin /= 2.0; double ntimesC = n*C; double Td = (tmin>ntimesC)?tmin:ntimesC; // TODO: for debugging // std::cout << " Td: " << Td << std::endl; return RTPTime(Td); }
bool whu_RtpRPicSAg::RecvPic(IplImage* RecvImg) { bool done = false; int status; char RecvBuf[1204]; RTPTime delay(0.020); RTPTime starttime = RTPTime::CurrentTime(); int lengh ,i; uchar* ptr; session.BeginDataAccess(); if (session.GotoFirstSource()) { int line=0; do { RTPPacket *packet; while ((packet = session.GetNextPacket()) != 0) { timestamp1 = packet->GetTimestamp(); lengh=packet->GetPayloadLength(); RawData = packet->GetPayloadData(); memcpy(RecvBuf,RawData,1204); memcpy(&line,RecvBuf,4); if (line>=0&&line<RecvImg->height) { ptr=(uchar*)(RecvImg->imageData+line*RecvImg->widthStep); memcpy(ptr,RecvBuf+4,1200); } else{ printf("loss packet\n"); } session.DeletePacket(packet); } } while (session.GotoNextSource()); } session.EndDataAccess(); RTPTime::Wait(delay); RTPTime t = RTPTime::CurrentTime(); t -= starttime; if (t > RTPTime(60.0)) done = true; return true; }
RTPTime RTCPScheduler::CalculateTransmissionInterval(bool sender) { RTPTime Td = CalculateDeterministicInterval(sender); double td,mul,T; // std::cout << "CalculateTransmissionInterval" << std::endl; td = Td.GetDouble(); mul = rtprand.GetRandomDouble()+0.5; // gives random value between 0.5 and 1.5 T = (td*mul)/1.21828; // see RFC 3550 p 30 // std::cout << " Td: " << td << std::endl; // std::cout << " mul: " << mul << std::endl; // std::cout << " T: " << T << std::endl; return RTPTime(T); }
RTPTime RTCPScheduler::GetTransmissionDelay() { if (firstcall) { firstcall = false; prevrtcptime = RTPTime::CurrentTime(); pmembers = sources.GetActiveMemberCount(); CalculateNextRTCPTime(); } RTPTime curtime = RTPTime::CurrentTime(); if (curtime > nextrtcptime) // packet should be sent return RTPTime(0,0); RTPTime diff = nextrtcptime; diff -= curtime; return diff; }
//反初始化 void CRTPRecv::UnInitialize() { if (m_InitializeFlag==false) { return; } m_InitializeFlag = false; /*//结束线程 m_CheckThreadStatus=FALSE; WaitForSingleObject(m_CheckThreadHandle,INFINITE); CloseHandle(m_CheckThreadHandle); m_CheckThreadHandle=NULL;*/ //关闭RTP BYEDestroy(RTPTime(RTP_BYE_DELAY_TIME,0), 0, 0); m_pContext = NULL; m_pCallBack = NULL; m_pRTPRecvStatusUserData=NULL; m_pRTPRecvStatusUserData=NULL; LOG_DEBUG("RTP Uninitialize"); }
void RTPSession::BYEDestroy(const RTPTime &maxwaittime,const void *reason,size_t reasonlength) { if (!created) return; // first, stop the thread so we have full control over all components #ifdef RTP_SUPPORT_THREAD if (pollthread) RTPDelete(pollthread,GetMemoryManager()); #endif // RTP_SUPPORT_THREAD RTPTime stoptime = RTPTime::CurrentTime(); stoptime += maxwaittime; // add bye packet to the list if we've sent data RTCPCompoundPacket *pack; if (sentpackets) { int status; reasonlength = (reasonlength>RTCP_BYE_MAXREASONLENGTH)?RTCP_BYE_MAXREASONLENGTH:reasonlength; status = rtcpbuilder.BuildBYEPacket(&pack,reason,reasonlength,useSR_BYEifpossible); if (status >= 0) { byepackets.push_back(pack); if (byepackets.size() == 1) rtcpsched.ScheduleBYEPacket(pack->GetCompoundPacketLength()); } } if (!byepackets.empty()) { bool done = false; while (!done) { RTPTime curtime = RTPTime::CurrentTime(); if (curtime >= stoptime) done = true; if (rtcpsched.IsTime()) { pack = *(byepackets.begin()); byepackets.pop_front(); rtptrans->SendRTCPData(pack->GetCompoundPacketData(),pack->GetCompoundPacketLength()); OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering RTPDelete(pack,GetMemoryManager()); if (!byepackets.empty()) // more bye packets to send, schedule them rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength()); else done = true; } if (!done) RTPTime::Wait(RTPTime(0,100000)); } } if (deletetransmitter) RTPDelete(rtptrans,GetMemoryManager()); packetbuilder.Destroy(); rtcpbuilder.Destroy(); rtcpsched.Reset(); collisionlist.Clear(); sources.Clear(); // clear rest of bye packets std::list<RTCPCompoundPacket *>::const_iterator it; for (it = byepackets.begin() ; it != byepackets.end() ; it++) RTPDelete(*it,GetMemoryManager()); byepackets.clear(); created = false; }
RTPHandler::~RTPHandler() { sess.BYEDestroy(RTPTime(10,0),0,0); }
/*********************************************************************************************************** **函数:Rtp_Lock **功能: **输入参数: **返回值: ***********************************************************************************************************/ static int RtpUnSetup(void) { sess.BYEDestroy(RTPTime(10,0),0,0); return 0; }