TAO_AV_Protocol_object for the RTP protocol. More...
#include <RTP.h>
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_Object * | control_object_ |
ACE_Message_Block | frame_ |
Pre-allocated memory to receive the data... | |
int | connection_gone_ |
TAO_AV_Protocol_object for the RTP protocol.
Definition at line 358 of file RTP.h.
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] |
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] |
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 (); }
int TAO_AV_RTP_Object::connection_gone_ [protected] |
TAO_AV_Protocol_Object* TAO_AV_RTP_Object::control_object_ [protected] |
int TAO_AV_RTP_Object::format_ [protected] |
ACE_Message_Block TAO_AV_RTP_Object::frame_ [protected] |
ACE_UINT16 TAO_AV_RTP_Object::sequence_num_ [protected] |
ACE_UINT32 TAO_AV_RTP_Object::ssrc_ [protected] |
ACE_UINT32 TAO_AV_RTP_Object::timestamp_offset_ [protected] |