📄 rtcp_channel.cpp
字号:
// RTCP_Channel.cpp,v 5.4 2003/04/30 12:30:58 elliott_c Exp
#include "ace/OS.h"
#include "tao/debug.h"
#include "RTCP_Channel.h"
#include "RTP.h"
RTCP_Channel_In::RTCP_Channel_In (ACE_UINT32 ssrc,
const ACE_Addr *peer_addr)
: remote_ssrc_ (ssrc),
cname_ (""),
transit_ (0),
jitter_ (0.0),
first_data_packet_ (1),
ntp_ts_msw_ (0),
ntp_ts_lsw_ (0),
last_sr_time_ (0),
active_ (0),
no_data_counter_ (0),
data_since_last_report_ (0)
{
const ACE_INET_Addr *const_inet_addr = ACE_dynamic_cast (const ACE_INET_Addr*,
peer_addr);
ACE_INET_Addr *inet_addr;
ACE_NEW (inet_addr,
ACE_INET_Addr (*const_inet_addr));
this->peer_address_ = inet_addr;
}
RTCP_Channel_In::~RTCP_Channel_In(void)
{
delete this->peer_address_;
}
void
RTCP_Channel_In::updateStatistics(RTP_Packet* dataPkt)
{
ACE_Time_Value current_time;
ACE_UINT32 arrival;
int transit, d;
this->active_ = 0;
// determine if the source has been declared valid
if (update_seq(dataPkt->sn ()) == 0)
return;
// Set initial values if this is the first data packet.
if (this->first_data_packet_)
{
// store the initial timestamp
this->init_time_stamp_ = dataPkt->ts ();
this->init_local_time_ = ACE_OS::gettimeofday ();
this->first_data_packet_ = 0;
}
// Get the current time.
current_time = ACE_OS::gettimeofday ();
unsigned int samples_per_sec;
double samples_per_usec;
switch (dataPkt->pt())
{
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;
// Calculate the current timestamp.
arrival = (ACE_UINT32)((current_time.sec () -
this->init_local_time_.sec ()) * samples_per_sec +
((double)(current_time.usec () -
(double)this->init_local_time_.usec ()) * samples_per_usec) +
this->init_time_stamp_);
// jitter calc from RFC 1889 app a.8
transit = arrival - dataPkt->ts ();
d = transit - this->transit_;
this->transit_ = transit;
if (d < 0)
d = -d;
// Calculate the inter-arrival jitter.
this->jitter_ += (1./16.)*((double)d - this->jitter_);
// Indicate that data has been received since the last report.
this->data_since_last_report_ = 1;
// Store the payload type.
this->payload_type_ = dataPkt->pt ();
}
int
RTCP_Channel_In::updateStatistics(RTCP_SR_Packet *sr)
{
// calculate the last SR time in 1/65536 sec.
ACE_Time_Value now = ACE_OS::gettimeofday ();
this->last_sr_time_ = (ACE_UINT32)
(now.sec () * 65536 +
now.usec () * 0.065536);
this->ntp_ts_msw_ = sr->ntp_ts_msw ();
this->ntp_ts_lsw_ = sr->ntp_ts_lsw ();
return 0;
}
int
RTCP_Channel_In::updateStatistics(RTCP_RR_Packet * /*rr*/)
{
return 0;
}
void
RTCP_Channel_In::init_seq(ACE_UINT16 seq)
{
this->base_seq_ = seq - 1;
this->max_seq_ = seq;
this->bad_seq_ = RTP_SEQ_MOD + 1;
this->cycles_ = 0;
this->received_ = 0;
this->received_prior_ = 0;
this->expected_prior_ = 0;
}
int
RTCP_Channel_In::update_seq(ACE_UINT16 seq)
{
// The following is taken from RFC 1889 Appendix A.1
ACE_UINT16 udelta = seq - this->max_seq_;
const int MAX_DROPOUT = 3000;
const int MAX_MISORDER = 100;
const int MIN_SEQUENTIAL = 2;
// Source is not valid until MIN_SEQUENTIAL packets with
// sequential sequence numbers have been received.
if (this->probation_)
{
// packet is in sequence
if (seq == this->max_seq_ + (ACE_UINT16)1)
{
this->probation_ --;
this->max_seq_ = seq;
if (this->probation_ == 0)
{
this->init_seq(seq);
this->received_++;
return 1;
}
}
else
{
this->probation_ = MIN_SEQUENTIAL - 1;
this->max_seq_ = seq;
}
return 0;
}
else if (udelta < MAX_DROPOUT)
{
// in order, with permissible gap
if (seq < this->max_seq_)
{
// seq number wrapped - count another 64k cycle
this->cycles_+=RTP_SEQ_MOD;
}
this->max_seq_ = seq;
}
else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER)
{
// the sequence number made a large jump
ACE_UINT32 temp = seq; // Borland reports a warning on the next line
// without this line.
if (temp == this->bad_seq_)
{
// two sequential packets, assume the other side restarted without
// telling us so just re-sync
// (i.e., pretend this was the first packet).
this->init_seq (seq);
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
"RTCP_Channel_In: large jump in sequence number",
"; init seq\n"));
}
else
{
this->bad_seq_ = (seq+1)&(RTP_SEQ_MOD-1);
return 0;
}
}
else
{
// dup or reordered packet
}
this->received_++;
return 1;
}
void
RTCP_Channel_In::recv_rtp_packet(ACE_Message_Block *mb,
const ACE_Addr *peer_address)
{
if (*peer_address != *this->peer_address_)
ACE_DEBUG ((LM_DEBUG,
"RTCP_Channel_In::recv_rtp_packet - possible loop/collision detected"));
RTP_Packet data_packet(mb->rd_ptr (), ACE_static_cast (int, mb->length ()));
// make sure the packet is valid
if (data_packet.is_valid ())
this->updateStatistics(&data_packet);
else
ACE_DEBUG ((LM_DEBUG,
"RTCP_Channel_In::recvDataPacket - invalid RTP packet\n"));
}
RR_Block *
RTCP_Channel_In::getRRBlock(void)
{
// If no data has been received since the last report, don't create a block.
if (!this->data_since_last_report_)
{
this->no_data_counter_++;
// make the source inactive if significant time has passed since last report
if (this->no_data_counter_ == 32)
this->active_ = 0;
return 0;
}
this->no_data_counter_ = 0;
RR_Block *local_block_ptr = 0;
ACE_NEW_RETURN (local_block_ptr,
RR_Block,
0);
ACE_OS::memset(local_block_ptr, 0, sizeof(RR_Block));
// Set the ssrc of the source this report is for.
local_block_ptr->ssrc_ = this->remote_ssrc_;
// Calculate packets expected/lost (from RFC 1889 Appendix A.3)
ACE_UINT32 extended_max;
ACE_UINT32 expected;
ACE_UINT32 expected_interval;
ACE_UINT32 received_interval;
int lost_interval;
extended_max = this->cycles_ + this->max_seq_;
expected = extended_max - this->base_seq_ + 1;
local_block_ptr->lost_ = expected - this->received_;
expected_interval = expected - this->expected_prior_;
this->expected_prior_ = expected;
received_interval = this->received_ - this->received_prior_;
this->received_prior_ = this->received_;
lost_interval = expected_interval - received_interval;
if ((expected_interval == 0) || (lost_interval <= 0))
local_block_ptr->fraction_ = 0;
else
local_block_ptr->fraction_ = (lost_interval << 8) / expected_interval;
local_block_ptr->last_seq_ = extended_max;
// taken from RFC 1889 App A.8
local_block_ptr->jitter_ = (ACE_UINT32)this->jitter_;
// calculate the last SR timestamp (lsr)
local_block_ptr->lsr_ = ((this->ntp_ts_msw_ & 0xFFFF) << 16) |
((this->ntp_ts_lsw_ & 0xFFFF0000) >> 16);
// calculate the delay since last SR (dlsr)
ACE_Time_Value now = ACE_OS::gettimeofday ();
ACE_UINT32 now32 = (ACE_UINT32)
(now.sec () * 65536 +
now.usec () * 0.065536);
local_block_ptr->dlsr_ = now32 - this->last_sr_time_;
// indicate that no data has been received since the last report
this->data_since_last_report_ = 0;
return local_block_ptr;
}
RTCP_Channel_Out::RTCP_Channel_Out(void)
:cname_ ("cname"),
active_ (0),
timestamp_ (0),
timestamp_offset_ (0),
packets_sent_ (0),
octets_sent_ (0)
{
}
RTCP_Channel_Out::~RTCP_Channel_Out(void)
{
}
void
RTCP_Channel_Out::updateStatistics (RTP_Packet *data_packet)
{
// indicate that this source is active
this->active_ = 1;
// Update various counters.
this->octets_sent_ += data_packet->payload_size();
this->packets_sent_ ++;
this->seq_num_ = data_packet->sn ();
this->timestamp_ = data_packet->ts ();
}
ACE_UINT32
RTCP_Channel_Out::timestamp (void)
{
return this->timestamp_;
}
ACE_UINT32
RTCP_Channel_Out::packets_sent (void)
{
return this->packets_sent_;
}
ACE_UINT32
RTCP_Channel_Out::octets_sent (void)
{
return this->octets_sent_;
}
char
RTCP_Channel_Out::active (void)
{
return this->active_;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -