#include <RTP.h>
Inheritance diagram for TAO_AV_RTP_Object:
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_ |
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.
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] |
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] |
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 }
int TAO_AV_RTP_Object::connection_gone_ [protected] |
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] |
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] |
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] |