RTCP_Channel.cpp

Go to the documentation of this file.
00001 // $Id: RTCP_Channel.cpp 71526 2006-03-14 06:14:35Z jtc $
00002 
00003 #include "orbsvcs/AV/RTCP_Channel.h"
00004 #include "orbsvcs/AV/RTP.h"
00005 #include "tao/debug.h"
00006 
00007 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00008 
00009 RTCP_Channel_In::RTCP_Channel_In (ACE_UINT32 ssrc,
00010                                   const ACE_Addr *peer_addr)
00011  : remote_ssrc_ (ssrc),
00012    cname_ (""),
00013    transit_ (0),
00014    jitter_ (0.0),
00015    first_data_packet_ (1),
00016    ntp_ts_msw_ (0),
00017    ntp_ts_lsw_ (0),
00018    last_sr_time_ (0),
00019    active_ (0),
00020    no_data_counter_ (0),
00021    data_since_last_report_ (0)
00022 {
00023   const ACE_INET_Addr *const_inet_addr = dynamic_cast<const ACE_INET_Addr*> (peer_addr);
00024 
00025   ACE_INET_Addr *inet_addr;
00026   ACE_NEW (inet_addr,
00027            ACE_INET_Addr (*const_inet_addr));
00028 
00029   this->peer_address_ = inet_addr;
00030 }
00031 
00032 RTCP_Channel_In::~RTCP_Channel_In(void)
00033 {
00034   delete this->peer_address_;
00035 }
00036 
00037 void
00038 RTCP_Channel_In::updateStatistics(RTP_Packet* dataPkt)
00039 {
00040   ACE_Time_Value current_time;
00041   ACE_UINT32 arrival;
00042   int transit, d;
00043 
00044   this->active_ = 0;
00045 
00046   // determine if the source has been declared valid
00047   if (update_seq(dataPkt->sn ()) == 0)
00048     return;
00049 
00050   // Set initial values if this is the first data packet.
00051   if (this->first_data_packet_)
00052     {
00053       // store the initial timestamp
00054       this->init_time_stamp_ = dataPkt->ts ();
00055       this->init_local_time_ = ACE_OS::gettimeofday ();
00056       this->first_data_packet_ = 0;
00057     }
00058 
00059   // Get the current time.
00060   current_time = ACE_OS::gettimeofday ();
00061 
00062   unsigned int samples_per_sec;
00063   double samples_per_usec;
00064 
00065 
00066   switch (dataPkt->pt())
00067   {
00068     case RTP_PT_PCMU:
00069     case RTP_PT_CELP:
00070     case RTP_PT_G721:
00071     case RTP_PT_GSM:
00072     case RTP_PT_DVI:
00073     case RTP_PT_LPC:
00074     case RTP_PT_PCMA:
00075     case RTP_PT_G722:
00076       samples_per_sec = 8000;
00077       break;
00078     case RTP_PT_L16_STEREO:
00079     case RTP_PT_L16_MONO:
00080       samples_per_sec = 44100;
00081       break;
00082     default:
00083       samples_per_sec = 1000000;
00084   };
00085 
00086   samples_per_usec = samples_per_sec/1000000.0;
00087 
00088   // Calculate the current timestamp.
00089   arrival = (ACE_UINT32)((current_time.sec () -
00090                 this->init_local_time_.sec ()) * samples_per_sec +
00091             ((double)(current_time.usec () -
00092                 (double)this->init_local_time_.usec ()) * samples_per_usec)  +
00093             this->init_time_stamp_);
00094 
00095 
00096   // jitter calc from RFC 1889 app a.8
00097   transit = arrival - dataPkt->ts ();
00098   d = transit - this->transit_;
00099   this->transit_ = transit;
00100   if (d < 0)
00101     d = -d;
00102 
00103   // Calculate the inter-arrival jitter.
00104   this->jitter_ += (1./16.)*((double)d - this->jitter_);
00105 
00106   // Indicate that data has been received since the last report.
00107   this->data_since_last_report_ = 1;
00108 
00109   // Store the payload type.
00110   this->payload_type_ = dataPkt->pt ();
00111 }
00112 
00113 int
00114 RTCP_Channel_In::updateStatistics(RTCP_SR_Packet *sr)
00115 {
00116   // calculate the last SR time in 1/65536 sec.
00117   ACE_Time_Value now = ACE_OS::gettimeofday ();
00118   this->last_sr_time_ = (ACE_UINT32)
00119                         (now.sec () * 65536 +
00120                          now.usec () * 0.065536);
00121 
00122   this->ntp_ts_msw_ = sr->ntp_ts_msw ();
00123   this->ntp_ts_lsw_ = sr->ntp_ts_lsw ();
00124 
00125   return 0;
00126 }
00127 
00128 int
00129 RTCP_Channel_In::updateStatistics(RTCP_RR_Packet * /*rr*/)
00130 {
00131   return 0;
00132 }
00133 
00134 void
00135 RTCP_Channel_In::init_seq(ACE_UINT16 seq)
00136 {
00137   this->base_seq_ = seq - 1;
00138   this->max_seq_ = seq;
00139   this->bad_seq_ = RTP_SEQ_MOD + 1;
00140   this->cycles_ = 0;
00141   this->received_ = 0;
00142   this->received_prior_ = 0;
00143   this->expected_prior_ = 0;
00144 }
00145 
00146 int
00147 RTCP_Channel_In::update_seq(ACE_UINT16 seq)
00148 {
00149   // The following is taken from RFC 1889 Appendix A.1
00150   ACE_UINT16 udelta = seq - this->max_seq_;
00151   const int MAX_DROPOUT = 3000;
00152   const int MAX_MISORDER = 100;
00153   const int MIN_SEQUENTIAL = 2;
00154 
00155   // Source is not valid until MIN_SEQUENTIAL packets with
00156   // sequential sequence numbers have been received.
00157   if (this->probation_)
00158     {
00159       // packet is in sequence
00160       if (seq == this->max_seq_ + (ACE_UINT16)1)
00161         {
00162           this->probation_ --;
00163           this->max_seq_ = seq;
00164           if (this->probation_ == 0)
00165             {
00166               this->init_seq(seq);
00167               this->received_++;
00168               return 1;
00169             }
00170         }
00171       else
00172         {
00173           this->probation_ = MIN_SEQUENTIAL - 1;
00174           this->max_seq_ = seq;
00175         }
00176       return 0;
00177     }
00178   else if (udelta < MAX_DROPOUT)
00179     {
00180       // in order, with permissible gap
00181       if (seq < this->max_seq_)
00182         {
00183           // seq number wrapped - count another 64k cycle
00184           this->cycles_+=RTP_SEQ_MOD;
00185         }
00186       this->max_seq_ = seq;
00187     }
00188   else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
00189     {
00190       // the sequence number made a large jump
00191       ACE_UINT32 temp = seq; // Borland reports a warning on the next line
00192                              // without this line.
00193       if (temp == this->bad_seq_)
00194         {
00195           // two sequential packets, assume the other side restarted without
00196           // telling us so just re-sync
00197           // (i.e., pretend this was the first packet).
00198           this->init_seq (seq);
00199 
00200           if (TAO_debug_level > 0)
00201           ACE_DEBUG ((LM_DEBUG,
00202                       "RTCP_Channel_In: large jump in sequence number",
00203                       "; init seq\n"));
00204         }
00205       else
00206         {
00207           this->bad_seq_ = (seq+1)&(RTP_SEQ_MOD-1);
00208           return 0;
00209         }
00210     }
00211   else
00212     {
00213       // dup or reordered packet
00214     }
00215   this->received_++;
00216 
00217   return 1;
00218 }
00219 
00220 void
00221 RTCP_Channel_In::recv_rtp_packet(ACE_Message_Block *mb,
00222                                 const ACE_Addr *peer_address)
00223 {
00224   if (*peer_address != *this->peer_address_)
00225     ACE_DEBUG ((LM_DEBUG,
00226                 "RTCP_Channel_In::recv_rtp_packet - possible loop/collision detected"));
00227 
00228   RTP_Packet data_packet(mb->rd_ptr (), static_cast<int> (mb->length ()));
00229 
00230   // make sure the packet is valid
00231   if (data_packet.is_valid ())
00232     this->updateStatistics(&data_packet);
00233   else
00234     ACE_DEBUG ((LM_DEBUG,
00235                 "RTCP_Channel_In::recvDataPacket - invalid RTP packet\n"));
00236 }
00237 
00238 
00239 RR_Block *
00240 RTCP_Channel_In::getRRBlock(void)
00241 {
00242   // If no data has been received since the last report, don't create a block.
00243   if (!this->data_since_last_report_)
00244     {
00245       this->no_data_counter_++;
00246 
00247       // make the source inactive if significant time has passed since last report
00248       if (this->no_data_counter_ == 32)
00249         this->active_ = 0;
00250 
00251       return 0;
00252     }
00253 
00254   this->no_data_counter_ = 0;
00255 
00256   RR_Block *local_block_ptr = 0;
00257 
00258   ACE_NEW_RETURN (local_block_ptr,
00259                   RR_Block,
00260                   0);
00261 
00262   ACE_OS::memset(local_block_ptr, 0, sizeof(RR_Block));
00263 
00264   // Set the ssrc of the source this report is for.
00265   local_block_ptr->ssrc_ = this->remote_ssrc_;
00266 
00267   // Calculate packets expected/lost (from RFC 1889 Appendix A.3)
00268   ACE_UINT32 extended_max;
00269   ACE_UINT32 expected;
00270   ACE_UINT32 expected_interval;
00271   ACE_UINT32 received_interval;
00272   int lost_interval;
00273 
00274   extended_max = this->cycles_ + this->max_seq_;
00275   expected = extended_max - this->base_seq_ + 1;
00276 
00277   local_block_ptr->lost_ = expected - this->received_;
00278   expected_interval = expected - this->expected_prior_;
00279   this->expected_prior_ = expected;
00280   received_interval = this->received_ - this->received_prior_;
00281   this->received_prior_ = this->received_;
00282   lost_interval = expected_interval - received_interval;
00283 
00284   if ((expected_interval == 0) || (lost_interval <= 0))
00285     local_block_ptr->fraction_ = 0;
00286   else
00287     local_block_ptr->fraction_ = (lost_interval << 8) / expected_interval;
00288 
00289 
00290   local_block_ptr->last_seq_ = extended_max;
00291 
00292   // taken from RFC 1889 App A.8
00293   local_block_ptr->jitter_ = (ACE_UINT32)this->jitter_;
00294 
00295   // calculate the last SR timestamp (lsr)
00296   local_block_ptr->lsr_ = ((this->ntp_ts_msw_ & 0xFFFF) << 16) |
00297                           ((this->ntp_ts_lsw_ & 0xFFFF0000) >> 16);
00298 
00299   // calculate the delay since last SR (dlsr)
00300   ACE_Time_Value now = ACE_OS::gettimeofday ();
00301   ACE_UINT32 now32 = (ACE_UINT32)
00302                      (now.sec () * 65536 +
00303                       now.usec () * 0.065536);
00304 
00305   local_block_ptr->dlsr_ = now32 - this->last_sr_time_;
00306 
00307   // indicate that no data has been received since the last report
00308   this->data_since_last_report_ = 0;
00309 
00310   return local_block_ptr;
00311 }
00312 
00313 RTCP_Channel_Out::RTCP_Channel_Out(void)
00314   :cname_ ("cname"),
00315    active_ (0),
00316    timestamp_ (0),
00317    timestamp_offset_ (0),
00318    packets_sent_ (0),
00319    octets_sent_ (0)
00320 {
00321 }
00322 
00323 RTCP_Channel_Out::~RTCP_Channel_Out(void)
00324 {
00325 }
00326 
00327 void
00328 RTCP_Channel_Out::updateStatistics (RTP_Packet *data_packet)
00329 {
00330   // indicate that this source is active
00331   this->active_ = 1;
00332 
00333   // Update various counters.
00334   this->octets_sent_ += data_packet->payload_size();
00335   this->packets_sent_ ++;
00336   this->seq_num_ = data_packet->sn ();
00337   this->timestamp_ = data_packet->ts ();
00338 }
00339 
00340 ACE_UINT32
00341 RTCP_Channel_Out::timestamp (void)
00342 {
00343   return this->timestamp_;
00344 }
00345 
00346 ACE_UINT32
00347 RTCP_Channel_Out::packets_sent (void)
00348 {
00349   return this->packets_sent_;
00350 }
00351 
00352 ACE_UINT32
00353 RTCP_Channel_Out::octets_sent (void)
00354 {
00355   return this->octets_sent_;
00356 }
00357 
00358 char
00359 RTCP_Channel_Out::active (void)
00360 {
00361   return this->active_;
00362 }
00363 
00364 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:47:49 2010 for TAO_AV by  doxygen 1.4.7