RTP.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1994-1995 Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. All advertising materials mentioning features or use of this software
00014  *    must display the following acknowledgement:
00015  *      This product includes software developed by the University of
00016  *      California, Berkeley and the Network Research Group at
00017  *      Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  */
00034 
00035 // $Id: RTP.cpp 78820 2007-07-07 20:06:46Z sowayaa $
00036 
00037 #include "orbsvcs/AV/RTP.h"
00038 #include "orbsvcs/AV/RTCP.h"
00039 
00040 #include "tao/debug.h"
00041 #include "ace/OS_NS_arpa_inet.h"
00042 #include "ace/OS_NS_strings.h"
00043 
00044 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00045 
00046 // RTP_Packet
00047 
00048 // Constructor for RTP packets received
00049 RTP_Packet::RTP_Packet(char* buffer, int length)
00050 {
00051   // skip the standard header info
00052   int index = 12;
00053 
00054   ACE_OS::memcpy(this->packet_, buffer, length);
00055 
00056   for (int j=0; j<(int)this->cc(); j++)
00057     {
00058       this->host_byte_order_csrc_list_[j] = ntohl(*(ACE_UINT32*)&buffer[index]);
00059       index+=4;
00060     }
00061 
00062   // ignore the header extension if there is one
00063   if (this->ext())
00064     {
00065       index+=2;
00066       int extension_data_size = ntohs(*(ACE_UINT16*)&buffer[index]);
00067       index+=2;
00068       index+=extension_data_size;
00069 
00070       this->extension_bytes_ = 4 + extension_data_size;
00071     }
00072   else
00073     this->extension_bytes_ = 0;
00074 
00075   this->packet_size_ = static_cast<ACE_UINT16> (length);
00076   this->payload_size_ = static_cast<ACE_UINT16> (length-index);
00077 
00078   // This is necessary only for payload types that have 16 bit values to correct
00079   //  the network byte ordering.
00080   if ((this->pt() == RTP_PT_L16_OTHER) ||
00081       (this->pt() == RTP_PT_L16_STEREO) ||
00082       (this->pt() == RTP_PT_L16_MONO))
00083     {
00084       for (int i=0; i < payload_size_; i+=2)
00085         {
00086           *(ACE_UINT16*)&this->host_byte_order_payload_[i] = ntohs(*(ACE_UINT16*)&this->packet_[index]);
00087           index+=2;
00088         }
00089     }
00090   else
00091     for (int i=0; i<this->payload_size_; i++)
00092       {
00093         this->host_byte_order_payload_[i] = this->packet_[index];
00094         index++;
00095       }
00096 }
00097 
00098 RTP_Packet::RTP_Packet(unsigned char padding,
00099                        unsigned char marker,
00100                        unsigned char payload_type,
00101                        ACE_UINT32 seq_num,
00102                        ACE_UINT32 timestamp,
00103                        ACE_UINT32 ssrc,
00104                        unsigned char csrc_count,
00105                        ACE_UINT32 *csrc_list,
00106                        char *data,
00107                        ACE_UINT16 data_size)
00108   :extension_bytes_(0)
00109 {
00110   //size of header (in octets) without contributing sources
00111   ACE_UINT16 size = 3*4;
00112   int index = 0;
00113 
00114   if (data_size > RTP_MTU-12)
00115   {
00116     data_size = RTP_MTU-12;
00117     ACE_DEBUG ((LM_DEBUG, "\n(%N,%l) RTP_Packet: Warning - packet truncated\n"));
00118   }
00119 
00120   if (csrc_count > 15)
00121     csrc_count = 15; // Only 15 contributing sources can be specified.
00122 
00123   if (csrc_list != 0)
00124     for (unsigned char i=0; i<csrc_count; i++)
00125       {
00126         size+=4;
00127         this->host_byte_order_csrc_list_[i] = csrc_list[i];
00128       }
00129 
00130   this->packet_size_ = size + data_size;
00131 
00132   index = 0;
00133   this->packet_[index] = ((RTP_VERSION & 0x3) << 6) |
00134                           ((padding & 0x1) << 5) |
00135                           ((0 & 0x1) << 4) |  // extension bit
00136                           ((csrc_count & 0xf));
00137 
00138   index++;
00139   this->packet_[index] = ((marker & 0x1) << 7 ) |
00140                          ((payload_type & 0x7f));
00141   index++;
00142   *((ACE_UINT16*)&this->packet_[index]) = (ACE_UINT16)htons(static_cast<u_short> (seq_num));
00143   index+=2;
00144   *((ACE_UINT32*)&this->packet_[index]) = (ACE_UINT32)htonl(timestamp);
00145   index+=4;
00146   *((ACE_UINT32*)&this->packet_[index]) = htonl(ssrc);
00147   index+=4;
00148 
00149   for (int i=0; i<csrc_count; i++)
00150     {
00151       *((ACE_UINT32*)&this->packet_[index]) = htonl(this->host_byte_order_csrc_list_[i]);
00152       index+=4;
00153     }
00154 
00155     ACE_OS::memcpy (this->host_byte_order_payload_, data, data_size);
00156 
00157   this->payload_size_ = data_size;
00158 
00159   // Correct byte ordering for multi-byte payload types.
00160   if ((this->pt() == RTP_PT_L16_OTHER) ||
00161       (this->pt() == RTP_PT_L16_STEREO) ||
00162       (this->pt() == RTP_PT_L16_MONO))
00163     {
00164       for (int i=0; i<this->payload_size_; i+=2)
00165         {
00166           *(ACE_UINT16*)&this->packet_[index] = htons(*(ACE_UINT16*)&data[i]);
00167           index+=2;
00168         }
00169     }
00170   else
00171     for (int i=0; i<this->payload_size_; i++)
00172       {
00173         this->packet_[index] = data[i];
00174         index++;
00175       }
00176 }
00177 
00178 RTP_Packet::~RTP_Packet(void)
00179 {
00180 }
00181 
00182 ACE_UINT16
00183 RTP_Packet::packet_size(void)
00184 {
00185     return this->packet_size_;
00186 }
00187 
00188 ACE_UINT16
00189 RTP_Packet::payload_size(void)
00190 {
00191     return this->payload_size_;
00192 }
00193 
00194 unsigned int
00195 RTP_Packet::ver (void)
00196 {
00197   return ( this->packet_[0] & 0xC0 ) >> 6;
00198 }
00199 
00200 unsigned int
00201 RTP_Packet::pad (void)
00202 {
00203   return ( this->packet_[0] & 0x20 ) >> 5;
00204 }
00205 
00206 unsigned int
00207 RTP_Packet::ext (void)
00208 {
00209   return ( this->packet_[0] & 0x10 ) >> 4;
00210 }
00211 
00212 unsigned int
00213 RTP_Packet::cc  (void)
00214 {
00215   return ( this->packet_[0] & 0x0F ) ;
00216 }
00217 
00218 unsigned int
00219 RTP_Packet::mrk (void)
00220 {
00221   return ( this->packet_[1] & 0x80 ) >> 7;
00222 }
00223 
00224 unsigned int
00225 RTP_Packet::pt  (void)
00226 {
00227   return ( this->packet_[1] & 0x7F ) ;
00228 }
00229 
00230 ACE_UINT16
00231 RTP_Packet::sn  (void)
00232 {
00233   return ntohs(*(ACE_UINT16*)(&this->packet_[2])) ;
00234 }
00235 
00236 ACE_UINT32
00237 RTP_Packet::ts  (void)
00238 {
00239   return ntohl(*(ACE_UINT32*)(&this->packet_[4])) ;
00240 }
00241 
00242 ACE_UINT32
00243 RTP_Packet::ssrc (void)
00244 {
00245   return ntohl(*(ACE_UINT32*)(&this->packet_[8])) ;
00246 }
00247 
00248 unsigned int
00249 RTP_Packet::ext_bytes (void)
00250 {
00251   return this->extension_bytes_;
00252 }
00253 
00254 void
00255 RTP_Packet::get_frame_info (TAO_AV_frame_info *frame_info)
00256 {
00257   frame_info->timestamp = this->mrk();
00258   frame_info->timestamp = this->ts();
00259   frame_info->ssrc = this->ssrc();
00260   frame_info->sequence_num = this->sn();
00261   frame_info->format = static_cast<CORBA::Octet> (this->pt());
00262 }
00263 
00264 int
00265 RTP_Packet::is_valid (void)
00266 {
00267   // taken from RFC 1889 - Appendix A.1
00268 
00269   // make sure the RTP version is correct
00270   if (this->ver() != RTP_VERSION)
00271     return 0;
00272 
00273   // make sure the payload type is not SR or RR
00274   if ((this->pt() == RTCP_PT_SR) || (this->pt() == RTCP_PT_RR))
00275     return 0;
00276 
00277   // if the p bit is set, the last octet of the packet must contain a valid
00278   // octet count, in particular, less than the total packet length minus
00279   // the header size.
00280   if (this->pad() != 0)
00281     if ((unsigned int)this->packet_[this->packet_size_] >=
00282         (this->packet_size_ - (12 + this->cc() + this->extension_bytes_)))
00283       return 0;
00284 
00285   // If there is an extension, it is ignored (taken care of in constructor)
00286 
00287   // The length of the packet must be consistent with CC and payload type (if
00288   // payloads have a known length)
00289 
00290   return 1;
00291 }
00292 
00293 void
00294 RTP_Packet::get_csrc_list (ACE_UINT32 **csrc_list, ACE_UINT16 &length)
00295 {
00296   *csrc_list = this->host_byte_order_csrc_list_;
00297   length = static_cast<ACE_UINT16> (this->cc ());
00298 }
00299 
00300 void
00301 RTP_Packet::get_payload (char **payload, ACE_UINT16 &length)
00302 {
00303   *payload = this->host_byte_order_payload_ ;
00304   length = this->payload_size_;
00305 }
00306 
00307 void
00308 RTP_Packet::get_packet_data (char **packet, ACE_UINT16 &length)
00309 {
00310   *packet = this->packet_;
00311   length = this->packet_size_;
00312 }
00313 
00314 
00315 // TAO_AV_RTP_Object
00316 
00317 int
00318 TAO_AV_RTP_Object::handle_input (void)
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 }
00367 
00368 int
00369 TAO_AV_RTP_Object::send_frame (ACE_Message_Block *frame,
00370                                TAO_AV_frame_info *frame_info)
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 }
00489 
00490 int
00491 TAO_AV_RTP_Object::send_frame (const iovec *iov,
00492                                int iovcnt,
00493                                TAO_AV_frame_info *frame_info)
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 }
00613 
00614 int
00615 TAO_AV_RTP_Object::send_frame (const char*,
00616                                size_t)
00617 {
00618   return 0;
00619 }
00620 
00621 
00622 TAO_AV_RTP_Object::TAO_AV_RTP_Object (TAO_AV_Callback *callback,
00623                                       TAO_AV_Transport *transport)
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 }
00640 
00641 TAO_AV_RTP_Object::~TAO_AV_RTP_Object (void)
00642 {
00643 }
00644 
00645 int
00646 TAO_AV_RTP_Object::destroy (void)
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 }
00656 
00657 int
00658 TAO_AV_RTP_Object::set_policies (const TAO_AV_PolicyList &policy_list)
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 }
00694 
00695 void
00696 TAO_AV_RTP_Object::control_object (TAO_AV_Protocol_Object *object)
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 }
00703 
00704 int
00705 TAO_AV_RTP_Object::start (void)
00706 {
00707   this->control_object_->start ();
00708   return this->callback_->handle_start ();
00709 }
00710 
00711 int
00712 TAO_AV_RTP_Object::stop (void)
00713 {
00714   this->control_object_->stop ();
00715   return this->callback_->handle_stop ();
00716 }
00717 
00718 // TAO_AV_RTP_Flow_Factory
00719 TAO_AV_RTP_Flow_Factory::TAO_AV_RTP_Flow_Factory (void)
00720 {
00721 }
00722 
00723 TAO_AV_RTP_Flow_Factory::~TAO_AV_RTP_Flow_Factory (void)
00724 {
00725 }
00726 
00727 int
00728 TAO_AV_RTP_Flow_Factory::init (int /* argc */,
00729                                 char * /* argv */ [])
00730 {
00731   return 0;
00732 }
00733 
00734 TAO_AV_Protocol_Object*
00735 TAO_AV_RTP_Flow_Factory::make_protocol_object (TAO_FlowSpec_Entry *entry,
00736                                                TAO_Base_StreamEndPoint *endpoint,
00737                                                TAO_AV_Flow_Handler *handler,
00738                                                TAO_AV_Transport *transport)
00739 {
00740   TAO_AV_Callback *callback = 0;
00741 
00742   if( endpoint->get_callback (entry->flowname (), callback) ) {
00743     ACE_ERROR_RETURN ((LM_ERROR, "(%N,%l) Invalid callback\n"), 0);
00744   }
00745 
00746   TAO_AV_Protocol_Object *object = 0;
00747   ACE_NEW_RETURN (object,
00748                   TAO_AV_RTP_Object (callback,
00749                                      transport),
00750                   0);
00751   callback->open (object,
00752                   handler);
00753   endpoint->set_protocol_object (entry->flowname (),
00754                                  object);
00755 
00756   endpoint->protocol_object_set ();
00757   return object;
00758 }
00759 
00760 int
00761 TAO_AV_RTP_Flow_Factory::match_protocol (const char *flow_string)
00762 {
00763   if (ACE_OS::strncasecmp (flow_string,"RTP",3) == 0)
00764     {
00765       return 1;
00766     }
00767   return 0;
00768 }
00769 
00770 const char *
00771 TAO_AV_RTP_Flow_Factory::control_flow_factory (void)
00772 {
00773   return "RTCP";
00774 }
00775 
00776 TAO_END_VERSIONED_NAMESPACE_DECL
00777 
00778 ACE_FACTORY_DEFINE (TAO_AV, TAO_AV_RTP_Flow_Factory)
00779 ACE_STATIC_SVC_DEFINE (TAO_AV_RTP_Flow_Factory,
00780                        ACE_TEXT ("RTP_Flow_Factory"),
00781                        ACE_SVC_OBJ_T,
00782                        &ACE_SVC_NAME (TAO_AV_RTP_Flow_Factory),
00783                        ACE_Service_Type::DELETE_THIS |
00784                        ACE_Service_Type::DELETE_OBJ,
00785                        0)

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