Public Member Functions | Protected Attributes

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.

  :TAO_AV_Protocol_Object (callback,transport),
   control_object_ (0),
   connection_gone_ (0)
{
  this->sequence_num_ = static_cast<ACE_UINT16> (ACE_OS::rand ());
  this->timestamp_offset_ = ACE_OS::rand ();

  char buf [BUFSIZ];
  int result = ACE_OS::hostname (buf, BUFSIZ);
  unsigned long ipaddr = 0;
  if (result == 0)
    ipaddr = ACE_OS::inet_addr (buf);
  this->ssrc_ = TAO_AV_RTCP::alloc_srcid (ipaddr);

  this->frame_.size (2 * this->transport_->mtu ());
}

TAO_AV_RTP_Object::~TAO_AV_RTP_Object ( void   )  [virtual]

Definition at line 641 of file RTP.cpp.

{
}


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.

{
  this->control_object_ = object;
  TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
  rtcp_prot_obj->ssrc (this->ssrc_);
  rtcp_prot_obj->ts_offset (this->timestamp_offset_);
}

int TAO_AV_RTP_Object::destroy ( void   )  [virtual]

Implements TAO_AV_Protocol_Object.

Definition at line 646 of file RTP.cpp.

{
  if(this->control_object_)
     this->control_object_->destroy ();

  this->callback_->handle_destroy ();
  delete this;

  return 0;
}

int TAO_AV_RTP_Object::handle_input ( void   )  [virtual]

Implements TAO_AV_Protocol_Object.

Definition at line 318 of file RTP.cpp.

{
  TAO_AV_frame_info frame_info;

  if (TAO_debug_level > 1)
    ACE_DEBUG ((LM_DEBUG,
                "\nTAO_AV_RTP_Object::handle_input\n"));

  // Handles the incoming RTP packet input.
  this->frame_.rd_ptr (this->frame_.base ());

  int n = this->transport_->recv (this->frame_.rd_ptr (),
                                  this->frame_.size ());
  if (n == 0)
    ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:connection closed\n"),-1);
  if (n < 0)
    {
      if ((errno == EADDRNOTAVAIL) || (errno == ECONNRESET))
        {
          this->connection_gone_ = 1;
          return -1;
        }
      else
        ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::handle_input:recv error\n"),-1);
    }

  this->frame_.wr_ptr (this->frame_.rd_ptr () + n);
  ACE_Addr *addr = this->transport_->get_peer_addr ();

  if(this->control_object_)
    this->control_object_->handle_control_input (&this->frame_, *addr);

  // Get payload that has been converted to host byte order
  char *data_ptr;
  ACE_UINT16 length;
  RTP_Packet rtp_packet(this->frame_.rd_ptr (),
                        static_cast<int> (this->frame_.length ()));

  rtp_packet.get_frame_info (&frame_info);
  rtp_packet.get_payload(&data_ptr, length);

  this->frame_.rd_ptr (this->frame_.base ());
  ACE_OS::memcpy (this->frame_.rd_ptr (), data_ptr, length);
  this->frame_.wr_ptr (this->frame_.rd_ptr() + length);

  this->callback_->receive_frame (&this->frame_, &frame_info, *addr);

  return 0;
}

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.

{
//  ACE_Addr *addr = this->transport_->get_peer_addr ();

  if (this->connection_gone_)
    {
      errno = ECONNRESET;
      return -1;
    }

  int result = -1;
  RTP_Packet *rtp_packet;
  ACE_UINT32 csrc_count = 0;  // Assume for now no mixers/translators
  ACE_UINT32 *csrc_list = 0;

  if (frame_info != 0)
    {
      if (frame_info->format != this->format_)
        ACE_DEBUG ((LM_DEBUG,
                    "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
      if (frame_info->ssrc != 0)
        this->ssrc_ = frame_info->ssrc;

      TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
      // set the ssrc on the control object so the RTCP traffic can be matched
      // to the RTP traffic
      rtcp_prot_obj->ssrc(this->ssrc_);

      ACE_NEW_RETURN (rtp_packet,
                      RTP_Packet (0,                            // padding
                                  frame_info->boundary_marker,  // marker
                                  static_cast<unsigned char> (this->format_),                // payload type
                                  frame_info->sequence_num,     // sequence num
                                  frame_info->timestamp,        // time stamp
                                  this->ssrc_,                  // ssrc
                                  static_cast<unsigned char> (csrc_count),                   // csrc count
                                  csrc_list,                    // csrc list
                                  frame->rd_ptr (),             // data
                                  (ACE_UINT16)frame->length ()),// data size
                                  -1);

      frame_info->sequence_num ++;
    }
  else
    {
      // TODO: For periodic RTP packets (constant rate), the RFC suggests
      //       increasing the clock by the number of samples each frame rather
      //       than relying on the system time

      // The RFC specifies at least one timestamp unit per sample as well as a
      //  random offset.  It used to be in milliseconds so I left it that way
      //  for non-audio streams.
      unsigned int samples_per_sec;
      double samples_per_usec;

      switch (this->format_)
      {
        case RTP_PT_PCMU:
        case RTP_PT_CELP:
        case RTP_PT_G721:
        case RTP_PT_GSM:
        case RTP_PT_DVI:
        case RTP_PT_LPC:
        case RTP_PT_PCMA:
        case RTP_PT_G722:
          samples_per_sec = 8000;
          break;
        case RTP_PT_L16_STEREO:
        case RTP_PT_L16_MONO:
          samples_per_sec = 44100;
          break;
        default:
          samples_per_sec = 1000000;
      };

      samples_per_usec = samples_per_sec/1000000.0;

      ACE_Time_Value now = ACE_OS::gettimeofday();

      ACE_UINT32 ts = (ACE_UINT32)
                      (now.sec () * samples_per_sec +
                       ((double)now.usec () * samples_per_usec) +
                       this->timestamp_offset_);

      ACE_NEW_RETURN (rtp_packet,
                      RTP_Packet (0,                            // padding
                                  0,                            // marker
                                  static_cast<unsigned char> (this->format_),                // payload type
                                  this->sequence_num_,          // sequence num
                                  ts,                           // time stamp
                                  this->ssrc_,                  // ssrc
                                  static_cast<unsigned char> (csrc_count),                   // csrc count
                                  csrc_list,                    // csrc list
                                  frame->rd_ptr (),             // data
                                  (ACE_UINT16)frame->length ()),// data size
                                  -1);

      this->sequence_num_ ++;
    }

  char *data_ptr;
  ACE_UINT16 data_length;
  rtp_packet->get_packet_data (&data_ptr, data_length);

  ACE_Message_Block mb (data_ptr, data_length);
  mb.wr_ptr (data_length);

  result = this->transport_->send (&mb);
  if (result < 0)
    ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);

  TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
  if (rtcp_prot_obj)
    rtcp_prot_obj->handle_control_output (&mb);

  delete rtp_packet;

  return 0;
}

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.

{
  int result = -1;
  RTP_Packet *rtp_packet = 0;
  ACE_UINT32 csrc_count = 0;  // Assume for now no mixers/translators
  ACE_UINT32 *csrc_list = 0;

  if (this->connection_gone_)
    {
      errno = ECONNRESET;
      return -1;
    }

  if (frame_info != 0)
    {
      if (frame_info->format != this->format_)
        ACE_DEBUG ((LM_DEBUG,
                    "TAO_AV_RTP_Object::send_frame - error: format type mismatch"));
      this->sequence_num_ = static_cast<ACE_UINT16> (frame_info->sequence_num);
      if (frame_info->ssrc != 0)
        this->ssrc_ = frame_info->ssrc;

      TAO_AV_RTCP_Object *rtcp_prot_obj = dynamic_cast<TAO_AV_RTCP_Object*> (this->control_object_);
      // set the ssrc on the control object so the RTCP traffic can be matched
      // to the RTP traffic
      rtcp_prot_obj->ssrc(this->ssrc_);
      ACE_UINT16 data_size = static_cast<ACE_UINT16> (iov[0].iov_len);

      ACE_NEW_RETURN (rtp_packet,
                      RTP_Packet (0,                            // padding
                                  frame_info->boundary_marker,  // marker
                                  static_cast<unsigned char> (this->format_),                // payload type
                                  frame_info->sequence_num,     // sequence num
                                  frame_info->timestamp,        // time stamp
                                  this->ssrc_,                  // ssrc
                                  static_cast<unsigned char> (csrc_count),                   // csrc count
                                  csrc_list,                    // csrc list
                                  (char *)iov[0].iov_base,      // data
                                  data_size),                   // data size
                                  -1);

      frame_info->sequence_num ++;
    }
  else
    {
      // TODO: For periodic RTP packets (constant rate), the RFC suggests
      //       increasing the clock by the number of samples each frame rather
      //       than relying on the system time

      // The RFC specifies at least one timestamp unit per sample as well as a
      //  random offset.  It used to be in milliseconds so I left it that way
      //  for non-audio streams.

      unsigned int samples_per_sec;
      double samples_per_usec;

      switch (this->format_)
      {
        case RTP_PT_PCMU:
        case RTP_PT_CELP:
        case RTP_PT_G721:
        case RTP_PT_GSM:
        case RTP_PT_DVI:
        case RTP_PT_LPC:
        case RTP_PT_PCMA:
        case RTP_PT_G722:
          samples_per_sec = 8000;
          break;
        case RTP_PT_L16_STEREO:
        case RTP_PT_L16_MONO:
          samples_per_sec = 44100;
          break;
        default:
          samples_per_sec = 1000000;
      };

      samples_per_usec = samples_per_sec/1000000.0;

      ACE_Time_Value now = ACE_OS::gettimeofday();

      ACE_UINT32 ts = (ACE_UINT32)
                      (now.sec () * samples_per_sec +
                       ((double)now.usec () * samples_per_usec) +
                       this->timestamp_offset_);
      ACE_UINT16 data_size = static_cast<ACE_UINT16> (iov[0].iov_len);

      ACE_NEW_RETURN (rtp_packet,
                      RTP_Packet (0,                            // padding
                                  0,                            // marker
                                  static_cast<unsigned char> (this->format_),                // payload type
                                  this->sequence_num_,          // sequence num
                                  ts,                           // time stamp
                                  this->ssrc_,                  // ssrc
                                  static_cast<unsigned char> (csrc_count),                   // csrc count
                                  csrc_list,                    // csrc list
                                  (char *)iov[0].iov_base,      // data
                                  data_size),                   // data size
                                  -1);

      this->sequence_num_ ++;
    }

  char *data_ptr;
  ACE_UINT16 data_length;
  rtp_packet->get_packet_data (&data_ptr, data_length);

  iovec send_iov[ACE_IOV_MAX];
  send_iov [0].iov_base = data_ptr;
  send_iov [0].iov_len  = data_length;
  for (int i=1;i<iovcnt; i++)
    send_iov [i] = iov [i];
  result = this->transport_->send (send_iov, iovcnt);

  delete rtp_packet;

  if (result < 0)
    ACE_ERROR_RETURN ((LM_ERROR,"TAO_AV_RTP::send_frame failed\n"),result);

  return 0;
}

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.

{
  return 0;
}

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.

{
  this->policy_list_ = policy_list;
  CORBA::ULong const num_policies = this->policy_list_.length ();
  TAO_AV_Policy *policy = 0;

  for (u_int i=0; i< num_policies;i++)
    {
      policy = this->policy_list_ [i];
      switch (policy->type ())
        {
        case TAO_AV_PAYLOAD_TYPE_POLICY:
          {
            TAO_AV_Payload_Type_Policy *payload_policy =
              static_cast<TAO_AV_Payload_Type_Policy *> (policy);
            if (payload_policy == 0)
              ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:Payload policy not defined\n"),-1);
            this->format_ = payload_policy->value ();
          }
          break;
        case TAO_AV_SSRC_POLICY:
          {
            TAO_AV_SSRC_Policy *ssrc_policy =
              static_cast<TAO_AV_SSRC_Policy *> (policy);
            if (ssrc_policy == 0)
              ACE_ERROR_RETURN ( (LM_ERROR,"TAO_AV_RTP_Object::send_frame:SSRC policy not defined\n"),-1);
            this->ssrc_ = ssrc_policy->value ();;
          }
          break;
        default:
          break;
        }
    }

  return 0;
}

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.

{
  this->control_object_->start ();
  return this->callback_->handle_start ();
}

int TAO_AV_RTP_Object::stop ( void   )  [virtual]

Reimplemented from TAO_AV_Protocol_Object.

Definition at line 712 of file RTP.cpp.

{
  this->control_object_->stop ();
  return this->callback_->handle_stop ();
}


Member Data Documentation

Definition at line 393 of file RTP.h.

Definition at line 388 of file RTP.h.

int TAO_AV_RTP_Object::format_ [protected]

Definition at line 386 of file RTP.h.

Pre-allocated memory to receive the data...

Definition at line 391 of file RTP.h.

ACE_UINT16 TAO_AV_RTP_Object::sequence_num_ [protected]

Definition at line 384 of file RTP.h.

ACE_UINT32 TAO_AV_RTP_Object::ssrc_ [protected]

Definition at line 387 of file RTP.h.

ACE_UINT32 TAO_AV_RTP_Object::timestamp_offset_ [protected]

Definition at line 385 of file RTP.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines