RTCP_Channel_In Class Reference

The RTCP_Channel_In class represents a single incoming data channel, or stream. The class has several responsibilities. When the class is instantiated, the incoming RTP traffic must be declared a valid source based on the RTP packets received. Once declared valie, this class is responsible for keeping up with reception statistics and other information. When an SR or RR is created (outside of this class), this class is used to get the Receiver Report block for this particular stream. More...

#include <RTCP_Channel.h>

Collaboration diagram for RTCP_Channel_In:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 RTCP_Channel_In (ACE_UINT32 ssrc, const ACE_Addr *addr)
 ~RTCP_Channel_In (void)
 Destructor.
void recv_rtp_packet (ACE_Message_Block *mb, const ACE_Addr *peer_addr)
RR_BlockgetRRBlock (void)
 Takes statistics of incoming RTP traffic and creates a receiver report block.
ACE_UINT32 dlsr (void)
 Returns the delay since last sender report.
ACE_UINT32 lsr (void)
 Returns the last sender report timestamp.
int updateStatistics (RTCP_SR_Packet *sr)
 Updates channel information with incoming sender report.
int updateStatistics (RTCP_RR_Packet *rr)
 Updates channel information with incoming receiver report.
int sender (void)
 Returns 1 if data has been sent since the last report, 0 if not.
int active (void)
 Returns 1 if this is an active source, 0 if not.

Private Member Functions

 RTCP_Channel_In (void)
 Don't want default constructor.
 RTCP_Channel_In (const RTCP_Channel_In &ch)
 Don't want copy constructor.
void updateStatistics (RTP_Packet *pkt)
 This operation is used update statistics for the incoming RTP packet.
void init_seq (ACE_UINT16 seq)
 This is called when the first RTP packet is received.
int update_seq (ACE_UINT16 seq)

Private Attributes

ACE_UINT32 remote_ssrc_
 The synchronization source id of the source this channel represents.
ACE_CString cname_
 The canonical name of the source this channel represents.
ACE_UINT16 max_seq_
 The highest sequence number seen.
ACE_UINT32 cycles_
 The shifted count of sequence number cycles (ie when sequence number wraps).
ACE_UINT32 base_seq_
 The first sequence number received.
ACE_UINT32 bad_seq_
 last 'bad' sequence number + 1
ACE_UINT32 probation_
 The number of in sequence packets until a source is declared valid.
ACE_UINT32 received_
 The number of packets received.
ACE_UINT32 expected_prior_
 The packet expected at last interval.
ACE_UINT32 received_prior_
 The packet received at last interval.
ACE_UINT32 transit_
 The last transit time.
double jitter_
 The inter-arrival jitter measured in timestamp units.
char first_data_packet_
 Flag to indicate the first data packet received.
ACE_UINT32 init_time_stamp_
 The first timestamp received.
ACE_Time_Value init_local_time_
 The local time that the initial packet was received.
ACE_Addrpeer_address_
 The address that the first RTP packet was received from.
ACE_UINT32 ntp_ts_msw_
 The most significant word of the last sender report NTP timestamp.
ACE_UINT32 ntp_ts_lsw_
 The least significant word of the last sender report NTP timestamp.
ACE_UINT32 rtp_ts_
 The last sender report RTP timestamp.
ACE_UINT32 last_sr_time_
int active_
 Flag to indicate whether or not the source is active.
int no_data_counter_
char data_since_last_report_
int payload_type_
 The RTP payload type.

Detailed Description

The RTCP_Channel_In class represents a single incoming data channel, or stream. The class has several responsibilities. When the class is instantiated, the incoming RTP traffic must be declared a valid source based on the RTP packets received. Once declared valie, this class is responsible for keeping up with reception statistics and other information. When an SR or RR is created (outside of this class), this class is used to get the Receiver Report block for this particular stream.

Definition at line 27 of file RTCP_Channel.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL RTCP_Channel_In::RTCP_Channel_In ( ACE_UINT32  ssrc,
const ACE_Addr addr 
)

Constructor for an incoming channel. Requires the synchronization source id and address of the sender.

Definition at line 9 of file RTCP_Channel.cpp.

References ACE_NEW, inet_addr(), and peer_address_.

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 }

RTCP_Channel_In::~RTCP_Channel_In ( void   ) 

Destructor.

Definition at line 32 of file RTCP_Channel.cpp.

References peer_address_.

00033 {
00034   delete this->peer_address_;
00035 }

RTCP_Channel_In::RTCP_Channel_In ( void   )  [private]

Don't want default constructor.

RTCP_Channel_In::RTCP_Channel_In ( const RTCP_Channel_In ch  )  [private]

Don't want copy constructor.


Member Function Documentation

int RTCP_Channel_In::active ( void   )  [inline]

Returns 1 if this is an active source, 0 if not.

Definition at line 63 of file RTCP_Channel.h.

References active_.

00063 { return this->active_; }

ACE_UINT32 RTCP_Channel_In::dlsr ( void   ) 

Returns the delay since last sender report.

RR_Block * RTCP_Channel_In::getRRBlock ( void   ) 

Takes statistics of incoming RTP traffic and creates a receiver report block.

Definition at line 240 of file RTCP_Channel.cpp.

References ACE_NEW_RETURN, active_, base_seq_, cycles_, data_since_last_report_, RR_Block::dlsr_, expected_prior_, RR_Block::fraction_, ACE_OS::gettimeofday(), RR_Block::jitter_, RR_Block::last_seq_, last_sr_time_, RR_Block::lost_, RR_Block::lsr_, max_seq_, ACE_OS::memset(), no_data_counter_, ntp_ts_lsw_, received_, received_prior_, remote_ssrc_, ACE_Time_Value::sec(), RR_Block::ssrc_, and ACE_Time_Value::usec().

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 }

void RTCP_Channel_In::init_seq ( ACE_UINT16  seq  )  [private]

This is called when the first RTP packet is received.

Definition at line 135 of file RTCP_Channel.cpp.

References bad_seq_, base_seq_, cycles_, expected_prior_, max_seq_, received_, received_prior_, and RTP_SEQ_MOD.

Referenced by update_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 }

ACE_UINT32 RTCP_Channel_In::lsr ( void   ) 

Returns the last sender report timestamp.

void RTCP_Channel_In::recv_rtp_packet ( ACE_Message_Block mb,
const ACE_Addr peer_addr 
)

This operation takes the incoming ACE_Message_Block, converts it to an RTP_Packet and calls updateStatistics. It also uses compares the peer_addr to the stored peer_address_ to check for loops.

Definition at line 221 of file RTCP_Channel.cpp.

References ACE_DEBUG, RTP_Packet::is_valid(), ACE_Message_Block::length(), LM_DEBUG, and ACE_Message_Block::rd_ptr().

Referenced by TAO_AV_RTCP_Callback::receive_frame().

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 }

int RTCP_Channel_In::sender ( void   )  [inline]

Returns 1 if data has been sent since the last report, 0 if not.

Definition at line 60 of file RTCP_Channel.h.

References data_since_last_report_.

00060 { return this->data_since_last_report_; }

int RTCP_Channel_In::update_seq ( ACE_UINT16  seq  )  [private]

This is called when each RTP packet is received. It is used to declare a source as valid.

Definition at line 147 of file RTCP_Channel.cpp.

References ACE_DEBUG, bad_seq_, cycles_, init_seq(), LM_DEBUG, max_seq_, probation_, received_, RTP_SEQ_MOD, and TAO_debug_level.

Referenced by updateStatistics().

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 }

void RTCP_Channel_In::updateStatistics ( RTP_Packet pkt  )  [private]

This operation is used update statistics for the incoming RTP packet.

Definition at line 38 of file RTCP_Channel.cpp.

References active_, data_since_last_report_, first_data_packet_, ACE_OS::gettimeofday(), init_local_time_, init_time_stamp_, jitter_, payload_type_, RTP_Packet::pt(), RTP_PT_CELP, RTP_PT_DVI, RTP_PT_G721, RTP_PT_G722, RTP_PT_GSM, RTP_PT_L16_MONO, RTP_PT_L16_STEREO, RTP_PT_LPC, RTP_PT_PCMA, RTP_PT_PCMU, ACE_Time_Value::sec(), RTP_Packet::sn(), transit_, RTP_Packet::ts(), update_seq(), and ACE_Time_Value::usec().

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 }

int RTCP_Channel_In::updateStatistics ( RTCP_RR_Packet rr  ) 

Updates channel information with incoming receiver report.

Definition at line 129 of file RTCP_Channel.cpp.

00130 {
00131   return 0;
00132 }

int RTCP_Channel_In::updateStatistics ( RTCP_SR_Packet sr  ) 

Updates channel information with incoming sender report.

Definition at line 114 of file RTCP_Channel.cpp.

References ACE_OS::gettimeofday(), last_sr_time_, RTCP_SR_Packet::ntp_ts_lsw(), ntp_ts_lsw_, RTCP_SR_Packet::ntp_ts_msw(), ntp_ts_msw_, ACE_Time_Value::sec(), and ACE_Time_Value::usec().

Referenced by TAO_AV_RTCP_Callback::receive_control_frame().

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 }


Member Data Documentation

int RTCP_Channel_In::active_ [private]

Flag to indicate whether or not the source is active.

Definition at line 136 of file RTCP_Channel.h.

Referenced by active(), getRRBlock(), and updateStatistics().

ACE_UINT32 RTCP_Channel_In::bad_seq_ [private]

last 'bad' sequence number + 1

Definition at line 89 of file RTCP_Channel.h.

Referenced by init_seq(), and update_seq().

ACE_UINT32 RTCP_Channel_In::base_seq_ [private]

The first sequence number received.

Definition at line 86 of file RTCP_Channel.h.

Referenced by getRRBlock(), and init_seq().

ACE_CString RTCP_Channel_In::cname_ [private]

The canonical name of the source this channel represents.

Definition at line 76 of file RTCP_Channel.h.

ACE_UINT32 RTCP_Channel_In::cycles_ [private]

The shifted count of sequence number cycles (ie when sequence number wraps).

Definition at line 83 of file RTCP_Channel.h.

Referenced by getRRBlock(), init_seq(), and update_seq().

char RTCP_Channel_In::data_since_last_report_ [private]

This flag indicates that data has been received since the last report was sent.

Definition at line 144 of file RTCP_Channel.h.

Referenced by getRRBlock(), sender(), and updateStatistics().

ACE_UINT32 RTCP_Channel_In::expected_prior_ [private]

The packet expected at last interval.

Definition at line 98 of file RTCP_Channel.h.

Referenced by getRRBlock(), and init_seq().

char RTCP_Channel_In::first_data_packet_ [private]

Flag to indicate the first data packet received.

Definition at line 111 of file RTCP_Channel.h.

Referenced by updateStatistics().

ACE_Time_Value RTCP_Channel_In::init_local_time_ [private]

The local time that the initial packet was received.

Definition at line 117 of file RTCP_Channel.h.

Referenced by updateStatistics().

ACE_UINT32 RTCP_Channel_In::init_time_stamp_ [private]

The first timestamp received.

Definition at line 114 of file RTCP_Channel.h.

Referenced by updateStatistics().

double RTCP_Channel_In::jitter_ [private]

The inter-arrival jitter measured in timestamp units.

Definition at line 107 of file RTCP_Channel.h.

Referenced by updateStatistics().

ACE_UINT32 RTCP_Channel_In::last_sr_time_ [private]

The last time a sender report was received in 1/65536 seconds. Used to calculate DLSR.

Definition at line 133 of file RTCP_Channel.h.

Referenced by getRRBlock(), and updateStatistics().

ACE_UINT16 RTCP_Channel_In::max_seq_ [private]

The highest sequence number seen.

Definition at line 80 of file RTCP_Channel.h.

Referenced by getRRBlock(), init_seq(), and update_seq().

int RTCP_Channel_In::no_data_counter_ [private]

This is a counter to indicate the number of reporting intervals that have passed since data has been received. After 32, declare the source inactive.

Definition at line 140 of file RTCP_Channel.h.

Referenced by getRRBlock().

ACE_UINT32 RTCP_Channel_In::ntp_ts_lsw_ [private]

The least significant word of the last sender report NTP timestamp.

Definition at line 126 of file RTCP_Channel.h.

Referenced by getRRBlock(), and updateStatistics().

ACE_UINT32 RTCP_Channel_In::ntp_ts_msw_ [private]

The most significant word of the last sender report NTP timestamp.

Definition at line 123 of file RTCP_Channel.h.

Referenced by updateStatistics().

int RTCP_Channel_In::payload_type_ [private]

The RTP payload type.

Definition at line 147 of file RTCP_Channel.h.

Referenced by updateStatistics().

ACE_Addr* RTCP_Channel_In::peer_address_ [private]

The address that the first RTP packet was received from.

Definition at line 120 of file RTCP_Channel.h.

Referenced by RTCP_Channel_In(), and ~RTCP_Channel_In().

ACE_UINT32 RTCP_Channel_In::probation_ [private]

The number of in sequence packets until a source is declared valid.

Definition at line 92 of file RTCP_Channel.h.

Referenced by update_seq().

ACE_UINT32 RTCP_Channel_In::received_ [private]

The number of packets received.

Definition at line 95 of file RTCP_Channel.h.

Referenced by getRRBlock(), init_seq(), and update_seq().

ACE_UINT32 RTCP_Channel_In::received_prior_ [private]

The packet received at last interval.

Definition at line 101 of file RTCP_Channel.h.

Referenced by getRRBlock(), and init_seq().

ACE_UINT32 RTCP_Channel_In::remote_ssrc_ [private]

The synchronization source id of the source this channel represents.

Definition at line 73 of file RTCP_Channel.h.

Referenced by getRRBlock().

ACE_UINT32 RTCP_Channel_In::rtp_ts_ [private]

The last sender report RTP timestamp.

Definition at line 129 of file RTCP_Channel.h.

ACE_UINT32 RTCP_Channel_In::transit_ [private]

The last transit time.

Definition at line 104 of file RTCP_Channel.h.

Referenced by updateStatistics().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:47:58 2010 for TAO_AV by  doxygen 1.4.7