TAO_AV_RTP_Object Class Reference

TAO_AV_Protocol_object for the RTP protocol. More...

#include <RTP.h>

Inheritance diagram for TAO_AV_RTP_Object:

Inheritance graph
[legend]
Collaboration diagram for TAO_AV_RTP_Object:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_AV_RTP_Object (TAO_AV_Callback *callback, TAO_AV_Transport *transport)
virtual ~TAO_AV_RTP_Object (void)
virtual int start (void)
 start/stop the flow.
virtual int stop (void)
virtual int handle_input (void)
virtual int send_frame (ACE_Message_Block *frame, TAO_AV_frame_info *frame_info=0)
 send a data frame.
virtual int send_frame (const iovec *iov, int iovcnt, TAO_AV_frame_info *frame_info=0)
 send a frame in iovecs.
virtual int send_frame (const char *buf, size_t len)
virtual int destroy (void)
virtual int set_policies (const TAO_AV_PolicyList &policy_list)
 set/get policies.
virtual void control_object (TAO_AV_Protocol_Object *object)
 end the stream.

Protected Attributes

ACE_UINT16 sequence_num_
ACE_UINT32 timestamp_offset_
int format_
ACE_UINT32 ssrc_
TAO_AV_Protocol_Objectcontrol_object_
ACE_Message_Block frame_
 Pre-allocated memory to receive the data...
int connection_gone_

Detailed Description

TAO_AV_Protocol_object for the RTP protocol.

Definition at line 358 of file RTP.h.


Constructor & Destructor Documentation

TAO_AV_RTP_Object::TAO_AV_RTP_Object ( TAO_AV_Callback callback,
TAO_AV_Transport transport 
)

Definition at line 622 of file RTP.cpp.

References TAO_AV_RTCP::alloc_srcid(), frame_, ACE_OS::hostname(), ACE_OS::inet_addr(), ACE_OS::rand(), sequence_num_, ACE_Message_Block::size(), ssrc_, and timestamp_offset_.

00624   :TAO_AV_Protocol_Object (callback,transport),
00625    control_object_ (0),
00626    connection_gone_ (0)
00627 {
00628   this->sequence_num_ = static_cast<ACE_UINT16> (ACE_OS::rand ());
00629   this->timestamp_offset_ = ACE_OS::rand ();
00630 
00631   char buf [BUFSIZ];
00632   int result = ACE_OS::hostname (buf, BUFSIZ);
00633   unsigned long ipaddr = 0;
00634   if (result == 0)
00635     ipaddr = ACE_OS::inet_addr (buf);
00636   this->ssrc_ = TAO_AV_RTCP::alloc_srcid (ipaddr);
00637 
00638   this->frame_.size (2 * this->transport_->mtu ());
00639 }

TAO_AV_RTP_Object::~TAO_AV_RTP_Object ( void   )  [virtual]

Definition at line 641 of file RTP.cpp.

00642 {
00643 }


Member Function Documentation

void TAO_AV_RTP_Object::control_object ( TAO_AV_Protocol_Object object  )  [virtual]

end the stream.

Reimplemented from TAO_AV_Protocol_Object.

Definition at line 696 of file RTP.cpp.

References control_object_, TAO_AV_RTCP_Object::ssrc(), and TAO_AV_RTCP_Object::ts_offset().

00697 {
00698   this->control_object_ = object;
00699   TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
00700   rtcp_prot_obj->ssrc (this->ssrc_);
00701   rtcp_prot_obj->ts_offset (this->timestamp_offset_);
00702 }

int TAO_AV_RTP_Object::destroy ( void   )  [virtual]

Implements TAO_AV_Protocol_Object.

Definition at line 646 of file RTP.cpp.

References TAO_AV_Protocol_Object::callback_, control_object_, TAO_AV_Protocol_Object::destroy(), and TAO_AV_Callback::handle_destroy().

00647 {
00648   if(this->control_object_)
00649      this->control_object_->destroy ();
00650 
00651   this->callback_->handle_destroy ();
00652   delete this;
00653 
00654   return 0;
00655 }

int TAO_AV_RTP_Object::handle_input ( void   )  [virtual]

Implements TAO_AV_Protocol_Object.

Definition at line 318 of file RTP.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, TAO_AV_Protocol_Object::callback_, connection_gone_, control_object_, frame_, RTP_Packet::get_frame_info(), RTP_Packet::get_payload(), TAO_AV_Transport::get_peer_addr(), TAO_AV_Protocol_Object::handle_control_input(), ACE_Message_Block::length(), LM_DEBUG, LM_ERROR, ACE_OS::memcpy(), ACE_Message_Block::rd_ptr(), TAO_AV_Callback::receive_frame(), TAO_AV_Transport::recv(), ACE_Message_Block::size(), TAO_debug_level, TAO_AV_Protocol_Object::transport_, and ACE_Message_Block::wr_ptr().

00319 {
00320   TAO_AV_frame_info frame_info;
00321 
00322   if (TAO_debug_level > 1)
00323     ACE_DEBUG ((LM_DEBUG,
00324                 "\nTAO_AV_RTP_Object::handle_input\n"));
00325 
00326   // Handles the incoming RTP packet input.
00327   this->frame_.rd_ptr (this->frame_.base ());
00328 
00329   int n = this->transport_->recv (this->frame_.rd_ptr (),
00330                                   this->frame_.size ());
00331   if (n == 0)
00332     ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:connection closed\n"),-1);
00333   if (n < 0)
00334     {
00335       if ((errno == EADDRNOTAVAIL) || (errno == ECONNRESET))
00336         {
00337           this->connection_gone_ = 1;
00338           return -1;
00339         }
00340       else
00341         ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:recv error\n"),-1);
00342     }
00343 
00344   this->frame_.wr_ptr (this->frame_.rd_ptr () + n);
00345   ACE_Addr *addr = this->transport_->get_peer_addr ();
00346 
00347   if(this->control_object_)
00348     this->control_object_->handle_control_input (&this->frame_, *addr);
00349 
00350   // Get payload that has been converted to host byte order
00351   char *data_ptr;
00352   ACE_UINT16 length;
00353   RTP_Packet rtp_packet(this->frame_.rd_ptr (),
00354                         static_cast<int> (this->frame_.length ()));
00355 
00356   rtp_packet.get_frame_info (&frame_info);
00357   rtp_packet.get_payload(&data_ptr, length);
00358 
00359   this->frame_.rd_ptr (this->frame_.base ());
00360   ACE_OS::memcpy (this->frame_.rd_ptr (), data_ptr, length);
00361   this->frame_.wr_ptr (this->frame_.rd_ptr() + length);
00362 
00363   this->callback_->receive_frame (&this->frame_, &frame_info, *addr);
00364 
00365   return 0;
00366 }

int TAO_AV_RTP_Object::send_frame ( const char *  buf,
size_t  len 
) [virtual]

Implements TAO_AV_Protocol_Object.

Definition at line 615 of file RTP.cpp.

00617 {
00618   return 0;
00619 }

int TAO_AV_RTP_Object::send_frame ( const iovec *  iov,
int  iovcnt,
TAO_AV_frame_info frame_info = 0 
) [virtual]

send a frame in iovecs.

Implements TAO_AV_Protocol_Object.

Definition at line 491 of file RTP.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_IOV_MAX, ACE_NEW_RETURN, TAO_AV_frame_info::boundary_marker, control_object_, TAO_AV_frame_info::format, RTP_Packet::get_packet_data(), ACE_OS::gettimeofday(), LM_DEBUG, LM_ERROR, 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(), TAO_AV_Transport::send(), TAO_AV_frame_info::sequence_num, sequence_num_, TAO_AV_RTCP_Object::ssrc(), TAO_AV_frame_info::ssrc, ssrc_, TAO_AV_frame_info::timestamp, TAO_AV_Protocol_Object::transport_, and ACE_Time_Value::usec().

00494 {
00495   int result = -1;
00496   RTP_Packet *rtp_packet = 0;
00497   ACE_UINT32 csrc_count = 0;  // Assume for now no mixers/translators
00498   ACE_UINT32 *csrc_list = 0;
00499 
00500   if (this->connection_gone_)
00501     {
00502       errno = ECONNRESET;
00503       return -1;
00504     }
00505 
00506   if (frame_info != 0)
00507     {
00508       if (frame_info->format != this->format_)
00509         ACE_DEBUG ((LM_DEBUG,
00510                     "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
00511       this->sequence_num_ = static_cast<ACE_UINT16> (frame_info->sequence_num);
00512       if (frame_info->ssrc != 0)
00513         this->ssrc_ = frame_info->ssrc;
00514 
00515       TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
00516       // set the ssrc on the control object so the RTCP traffic can be matched
00517       // to the RTP traffic
00518       rtcp_prot_obj->ssrc(this->ssrc_);
00519       ACE_UINT16 data_size = static_cast<ACE_UINT16> (iov[0].iov_len);
00520 
00521       ACE_NEW_RETURN (rtp_packet,
00522                       RTP_Packet (0,                            // padding
00523                                   frame_info->boundary_marker,  // marker
00524                                   static_cast<unsigned char> (this->format_),                // payload type
00525                                   frame_info->sequence_num,     // sequence num
00526                                   frame_info->timestamp,        // time stamp
00527                                   this->ssrc_,                  // ssrc
00528                                   static_cast<unsigned char> (csrc_count),                   // csrc count
00529                                   csrc_list,                    // csrc list
00530                                   (char *)iov[0].iov_base,      // data
00531                                   data_size),                   // data size
00532                                   -1);
00533 
00534       frame_info->sequence_num ++;
00535     }
00536   else
00537     {
00538       // TODO: For periodic RTP packets (constant rate), the RFC suggests
00539       //       increasing the clock by the number of samples each frame rather
00540       //       than relying on the system time
00541 
00542       // The RFC specifies at least one timestamp unit per sample as well as a
00543       //  random offset.  It used to be in milliseconds so I left it that way
00544       //  for non-audio streams.
00545 
00546       unsigned int samples_per_sec;
00547       double samples_per_usec;
00548 
00549       switch (this->format_)
00550       {
00551         case RTP_PT_PCMU:
00552         case RTP_PT_CELP:
00553         case RTP_PT_G721:
00554         case RTP_PT_GSM:
00555         case RTP_PT_DVI:
00556         case RTP_PT_LPC:
00557         case RTP_PT_PCMA:
00558         case RTP_PT_G722:
00559           samples_per_sec = 8000;
00560           break;
00561         case RTP_PT_L16_STEREO:
00562         case RTP_PT_L16_MONO:
00563           samples_per_sec = 44100;
00564           break;
00565         default:
00566           samples_per_sec = 1000000;
00567       };
00568 
00569       samples_per_usec = samples_per_sec/1000000.0;
00570 
00571       ACE_Time_Value now = ACE_OS::gettimeofday();
00572 
00573       ACE_UINT32 ts = (ACE_UINT32)
00574                       (now.sec () * samples_per_sec +
00575                        ((double)now.usec () * samples_per_usec) +
00576                        this->timestamp_offset_);
00577       ACE_UINT16 data_size = static_cast<ACE_UINT16> (iov[0].iov_len);
00578 
00579       ACE_NEW_RETURN (rtp_packet,
00580                       RTP_Packet (0,                            // padding
00581                                   0,                            // marker
00582                                   static_cast<unsigned char> (this->format_),                // payload type
00583                                   this->sequence_num_,          // sequence num
00584                                   ts,                           // time stamp
00585                                   this->ssrc_,                  // ssrc
00586                                   static_cast<unsigned char> (csrc_count),                   // csrc count
00587                                   csrc_list,                    // csrc list
00588                                   (char *)iov[0].iov_base,      // data
00589                                   data_size),                   // data size
00590                                   -1);
00591 
00592       this->sequence_num_ ++;
00593     }
00594 
00595   char *data_ptr;
00596   ACE_UINT16 data_length;
00597   rtp_packet->get_packet_data (&data_ptr, data_length);
00598 
00599   iovec send_iov[ACE_IOV_MAX];
00600   send_iov [0].iov_base = data_ptr;
00601   send_iov [0].iov_len  = data_length;
00602   for (int i=1;i<iovcnt; i++)
00603     send_iov [i] = iov [i];
00604   result = this->transport_->send (send_iov, iovcnt);
00605 
00606   delete rtp_packet;
00607 
00608   if (result < 0)
00609     ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
00610 
00611   return 0;
00612 }

int TAO_AV_RTP_Object::send_frame ( ACE_Message_Block frame,
TAO_AV_frame_info frame_info = 0 
) [virtual]

send a data frame.

Implements TAO_AV_Protocol_Object.

Definition at line 369 of file RTP.cpp.

References ACE_DEBUG, ACE_ERROR_RETURN, ACE_NEW_RETURN, TAO_AV_frame_info::boundary_marker, control_object_, TAO_AV_frame_info::format, RTP_Packet::get_packet_data(), ACE_OS::gettimeofday(), TAO_AV_RTCP_Object::handle_control_output(), ACE_Message_Block::length(), LM_DEBUG, LM_ERROR, ACE_Message_Block::rd_ptr(), 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(), TAO_AV_Transport::send(), TAO_AV_frame_info::sequence_num, sequence_num_, TAO_AV_RTCP_Object::ssrc(), TAO_AV_frame_info::ssrc, ssrc_, TAO_AV_frame_info::timestamp, TAO_AV_Protocol_Object::transport_, ACE_Time_Value::usec(), and ACE_Message_Block::wr_ptr().

00371 {
00372 //  ACE_Addr *addr = this->transport_->get_peer_addr ();
00373 
00374   if (this->connection_gone_)
00375     {
00376       errno = ECONNRESET;
00377       return -1;
00378     }
00379 
00380   int result = -1;
00381   RTP_Packet *rtp_packet;
00382   ACE_UINT32 csrc_count = 0;  // Assume for now no mixers/translators
00383   ACE_UINT32 *csrc_list = 0;
00384 
00385   if (frame_info != 0)
00386     {
00387       if (frame_info->format != this->format_)
00388         ACE_DEBUG ((LM_DEBUG,
00389                     "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
00390       if (frame_info->ssrc != 0)
00391         this->ssrc_ = frame_info->ssrc;
00392 
00393       TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
00394       // set the ssrc on the control object so the RTCP traffic can be matched
00395       // to the RTP traffic
00396       rtcp_prot_obj->ssrc(this->ssrc_);
00397 
00398       ACE_NEW_RETURN (rtp_packet,
00399                       RTP_Packet (0,                            // padding
00400                                   frame_info->boundary_marker,  // marker
00401                                   static_cast<unsigned char> (this->format_),                // payload type
00402                                   frame_info->sequence_num,     // sequence num
00403                                   frame_info->timestamp,        // time stamp
00404                                   this->ssrc_,                  // ssrc
00405                                   static_cast<unsigned char> (csrc_count),                   // csrc count
00406                                   csrc_list,                    // csrc list
00407                                   frame->rd_ptr (),             // data
00408                                   (ACE_UINT16)frame->length ()),// data size
00409                                   -1);
00410 
00411       frame_info->sequence_num ++;
00412     }
00413   else
00414     {
00415       // TODO: For periodic RTP packets (constant rate), the RFC suggests
00416       //       increasing the clock by the number of samples each frame rather
00417       //       than relying on the system time
00418 
00419       // The RFC specifies at least one timestamp unit per sample as well as a
00420       //  random offset.  It used to be in milliseconds so I left it that way
00421       //  for non-audio streams.
00422       unsigned int samples_per_sec;
00423       double samples_per_usec;
00424 
00425       switch (this->format_)
00426       {
00427         case RTP_PT_PCMU:
00428         case RTP_PT_CELP:
00429         case RTP_PT_G721:
00430         case RTP_PT_GSM:
00431         case RTP_PT_DVI:
00432         case RTP_PT_LPC:
00433         case RTP_PT_PCMA:
00434         case RTP_PT_G722:
00435           samples_per_sec = 8000;
00436           break;
00437         case RTP_PT_L16_STEREO:
00438         case RTP_PT_L16_MONO:
00439           samples_per_sec = 44100;
00440           break;
00441         default:
00442           samples_per_sec = 1000000;
00443       };
00444 
00445       samples_per_usec = samples_per_sec/1000000.0;
00446 
00447       ACE_Time_Value now = ACE_OS::gettimeofday();
00448 
00449       ACE_UINT32 ts = (ACE_UINT32)
00450                       (now.sec () * samples_per_sec +
00451                        ((double)now.usec () * samples_per_usec) +
00452                        this->timestamp_offset_);
00453 
00454       ACE_NEW_RETURN (rtp_packet,
00455                       RTP_Packet (0,                            // padding
00456                                   0,                            // marker
00457                                   static_cast<unsigned char> (this->format_),                // payload type
00458                                   this->sequence_num_,          // sequence num
00459                                   ts,                           // time stamp
00460                                   this->ssrc_,                  // ssrc
00461                                   static_cast<unsigned char> (csrc_count),                   // csrc count
00462                                   csrc_list,                    // csrc list
00463                                   frame->rd_ptr (),             // data
00464                                   (ACE_UINT16)frame->length ()),// data size
00465                                   -1);
00466 
00467       this->sequence_num_ ++;
00468     }
00469 
00470   char *data_ptr;
00471   ACE_UINT16 data_length;
00472   rtp_packet->get_packet_data (&data_ptr, data_length);
00473 
00474   ACE_Message_Block mb (data_ptr, data_length);
00475   mb.wr_ptr (data_length);
00476 
00477   result = this->transport_->send (&mb);
00478   if (result < 0)
00479     ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);
00480 
00481   TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
00482   if (rtcp_prot_obj)
00483     rtcp_prot_obj->handle_control_output (&mb);
00484 
00485   delete rtp_packet;
00486 
00487   return 0;
00488 }

int TAO_AV_RTP_Object::set_policies ( const TAO_AV_PolicyList policy_list  )  [virtual]

set/get policies.

Reimplemented from TAO_AV_Protocol_Object.

Definition at line 658 of file RTP.cpp.

References ACE_ERROR_RETURN, format_, LM_ERROR, TAO_AV_Protocol_Object::policy_list_, ssrc_, TAO_AV_PAYLOAD_TYPE_POLICY, TAO_AV_SSRC_POLICY, TAO_AV_Policy::type(), and TAO_AV_SSRC_Policy::value().

00659 {
00660   this->policy_list_ = policy_list;
00661   CORBA::ULong const num_policies = this->policy_list_.length ();
00662   TAO_AV_Policy *policy = 0;
00663 
00664   for (u_int i=0; i< num_policies;i++)
00665     {
00666       policy = this->policy_list_ [i];
00667       switch (policy->type ())
00668         {
00669         case TAO_AV_PAYLOAD_TYPE_POLICY:
00670           {
00671             TAO_AV_Payload_Type_Policy *payload_policy =
00672               static_cast<TAO_AV_Payload_Type_Policy *> (policy);
00673             if (payload_policy == 0)
00674               ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:Payload policy not defined\n"),-1);
00675             this->format_ = payload_policy->value ();
00676           }
00677           break;
00678         case TAO_AV_SSRC_POLICY:
00679           {
00680             TAO_AV_SSRC_Policy *ssrc_policy =
00681               static_cast<TAO_AV_SSRC_Policy *> (policy);
00682             if (ssrc_policy == 0)
00683               ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:SSRC policy not defined\n"),-1);
00684             this->ssrc_ = ssrc_policy->value ();;
00685           }
00686           break;
00687         default:
00688           break;
00689         }
00690     }
00691 
00692   return 0;
00693 }

int TAO_AV_RTP_Object::start ( void   )  [virtual]

start/stop the flow.

Reimplemented from TAO_AV_Protocol_Object.

Definition at line 705 of file RTP.cpp.

References TAO_AV_Protocol_Object::callback_, control_object_, TAO_AV_Callback::handle_start(), and TAO_AV_Protocol_Object::start().

00706 {
00707   this->control_object_->start ();
00708   return this->callback_->handle_start ();
00709 }

int TAO_AV_RTP_Object::stop ( void   )  [virtual]

Reimplemented from TAO_AV_Protocol_Object.

Definition at line 712 of file RTP.cpp.

References TAO_AV_Protocol_Object::callback_, control_object_, TAO_AV_Callback::handle_stop(), and TAO_AV_Protocol_Object::stop().

00713 {
00714   this->control_object_->stop ();
00715   return this->callback_->handle_stop ();
00716 }


Member Data Documentation

int TAO_AV_RTP_Object::connection_gone_ [protected]

Definition at line 393 of file RTP.h.

Referenced by handle_input().

TAO_AV_Protocol_Object* TAO_AV_RTP_Object::control_object_ [protected]

Definition at line 388 of file RTP.h.

Referenced by control_object(), destroy(), handle_input(), send_frame(), start(), and stop().

int TAO_AV_RTP_Object::format_ [protected]

Definition at line 386 of file RTP.h.

Referenced by set_policies().

ACE_Message_Block TAO_AV_RTP_Object::frame_ [protected]

Pre-allocated memory to receive the data...

Definition at line 391 of file RTP.h.

Referenced by handle_input(), and TAO_AV_RTP_Object().

ACE_UINT16 TAO_AV_RTP_Object::sequence_num_ [protected]

Definition at line 384 of file RTP.h.

Referenced by send_frame(), and TAO_AV_RTP_Object().

ACE_UINT32 TAO_AV_RTP_Object::ssrc_ [protected]

Definition at line 387 of file RTP.h.

Referenced by send_frame(), set_policies(), and TAO_AV_RTP_Object().

ACE_UINT32 TAO_AV_RTP_Object::timestamp_offset_ [protected]

Definition at line 385 of file RTP.h.

Referenced by TAO_AV_RTP_Object().


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