Reverts a second set of reverts caused by a bug in a dependency.
Revert "Revert r4328" Revert "Revert r4322 "Support sending multiple report blocks and keeping track of statistics on" BUG=1811 R=henrika@webrtc.org, pbos@webrtc.org, tina.legrand@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2072004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4582 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
fbf0f69bf8
commit
1a65d6c36b
@ -171,6 +171,7 @@
|
||||
'rtp_rtcp/source/nack_rtx_unittest.cc',
|
||||
'rtp_rtcp/source/producer_fec_unittest.cc',
|
||||
'rtp_rtcp/source/receiver_fec_unittest.cc',
|
||||
'rtp_rtcp/source/receive_statistics_unittest.cc',
|
||||
'rtp_rtcp/source/rtcp_format_remb_unittest.cc',
|
||||
'rtp_rtcp/source/rtcp_sender_unittest.cc',
|
||||
'rtp_rtcp/source/rtcp_receiver_unittest.cc',
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
|
||||
#define WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "webrtc/modules/interface/module.h"
|
||||
#include "webrtc/modules/interface/module_common_types.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
@ -19,9 +21,16 @@ namespace webrtc {
|
||||
|
||||
class Clock;
|
||||
|
||||
class ReceiveStatistics : public Module {
|
||||
class StreamStatistician {
|
||||
public:
|
||||
struct RtpReceiveStatistics {
|
||||
struct Statistics {
|
||||
Statistics()
|
||||
: fraction_lost(0),
|
||||
cumulative_lost(0),
|
||||
extended_max_sequence_number(0),
|
||||
jitter(0),
|
||||
max_jitter(0) {}
|
||||
|
||||
uint8_t fraction_lost;
|
||||
uint32_t cumulative_lost;
|
||||
uint32_t extended_max_sequence_number;
|
||||
@ -29,26 +38,45 @@ class ReceiveStatistics : public Module {
|
||||
uint32_t max_jitter;
|
||||
};
|
||||
|
||||
virtual ~StreamStatistician();
|
||||
|
||||
virtual bool GetStatistics(Statistics* statistics, bool reset) = 0;
|
||||
virtual void GetDataCounters(uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const = 0;
|
||||
virtual uint32_t BitrateReceived() const = 0;
|
||||
// Resets all statistics.
|
||||
virtual void ResetStatistics() = 0;
|
||||
};
|
||||
|
||||
typedef std::map<uint32_t, StreamStatistician*> StatisticianMap;
|
||||
|
||||
class ReceiveStatistics : public Module {
|
||||
public:
|
||||
virtual ~ReceiveStatistics() {}
|
||||
|
||||
static ReceiveStatistics* Create(Clock* clock);
|
||||
|
||||
// Updates the receive statistics with this packet.
|
||||
virtual void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
|
||||
bool retransmitted, bool in_order) = 0;
|
||||
|
||||
virtual bool Statistics(RtpReceiveStatistics* statistics, bool reset) = 0;
|
||||
// Returns a map of all statisticians which have seen an incoming packet
|
||||
// during the last two seconds.
|
||||
virtual StatisticianMap GetActiveStatisticians() const = 0;
|
||||
|
||||
virtual bool Statistics(RtpReceiveStatistics* statistics, int32_t* missing,
|
||||
bool reset) = 0;
|
||||
|
||||
virtual void GetDataCounters(uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const = 0;
|
||||
|
||||
virtual uint32_t BitrateReceived() = 0;
|
||||
|
||||
virtual void ResetStatistics() = 0;
|
||||
|
||||
virtual void ResetDataCounters() = 0;
|
||||
// Returns a pointer to the statistician of an ssrc.
|
||||
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const = 0;
|
||||
};
|
||||
|
||||
class NullReceiveStatistics : public ReceiveStatistics {
|
||||
public:
|
||||
virtual void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
|
||||
bool retransmitted, bool in_order) OVERRIDE;
|
||||
virtual StatisticianMap GetActiveStatisticians() const OVERRIDE;
|
||||
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE;
|
||||
virtual int32_t TimeUntilNextProcess() OVERRIDE;
|
||||
virtual int32_t Process() OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_INTERFACE_RECEIVE_STATISTICS_H_
|
||||
|
@ -205,13 +205,13 @@ public:
|
||||
const uint32_t rate) = 0;
|
||||
|
||||
virtual void OnIncomingSSRCChanged( const int32_t id,
|
||||
const uint32_t SSRC) = 0;
|
||||
const uint32_t ssrc) = 0;
|
||||
|
||||
virtual void OnIncomingCSRCChanged( const int32_t id,
|
||||
const uint32_t CSRC,
|
||||
const bool added) = 0;
|
||||
|
||||
virtual void ResetStatistics() = 0;
|
||||
virtual void ResetStatistics(uint32_t ssrc) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~RtpFeedback() {}
|
||||
@ -281,13 +281,13 @@ class NullRtpFeedback : public RtpFeedback {
|
||||
}
|
||||
|
||||
virtual void OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC) OVERRIDE {}
|
||||
const uint32_t ssrc) OVERRIDE {}
|
||||
|
||||
virtual void OnIncomingCSRCChanged(const int32_t id,
|
||||
const uint32_t CSRC,
|
||||
const bool added) OVERRIDE {}
|
||||
|
||||
virtual void ResetStatistics() OVERRIDE {}
|
||||
virtual void ResetStatistics(uint32_t ssrc) OVERRIDE {}
|
||||
};
|
||||
|
||||
// Null object version of RtpData.
|
||||
|
@ -56,8 +56,8 @@ class TestRtpFeedback : public NullRtpFeedback {
|
||||
virtual ~TestRtpFeedback() {}
|
||||
|
||||
virtual void OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC) {
|
||||
rtp_rtcp_->SetRemoteSSRC(SSRC);
|
||||
const uint32_t ssrc) {
|
||||
rtp_rtcp_->SetRemoteSSRC(ssrc);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -17,41 +17,39 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
enum { kRateUpdateIntervalMs = 1000 };
|
||||
const int64_t kStatisticsTimeoutMs = 8000;
|
||||
const int kStatisticsProcessIntervalMs = 1000;
|
||||
|
||||
ReceiveStatistics* ReceiveStatistics::Create(Clock* clock) {
|
||||
return new ReceiveStatisticsImpl(clock);
|
||||
}
|
||||
StreamStatistician::~StreamStatistician() {}
|
||||
|
||||
ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
|
||||
: crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
clock_(clock),
|
||||
StreamStatisticianImpl::StreamStatisticianImpl(Clock* clock)
|
||||
: clock_(clock),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
incoming_bitrate_(clock),
|
||||
ssrc_(0),
|
||||
jitter_q4_(0),
|
||||
jitter_max_q4_(0),
|
||||
cumulative_loss_(0),
|
||||
jitter_q4_transmission_time_offset_(0),
|
||||
local_time_last_received_timestamp_(0),
|
||||
last_receive_time_secs_(0),
|
||||
last_receive_time_frac_(0),
|
||||
last_received_timestamp_(0),
|
||||
last_received_transmission_time_offset_(0),
|
||||
|
||||
received_seq_first_(0),
|
||||
received_seq_max_(0),
|
||||
received_seq_wraps_(0),
|
||||
|
||||
first_packet_(true),
|
||||
received_packet_overhead_(12),
|
||||
received_byte_count_(0),
|
||||
received_retransmitted_packets_(0),
|
||||
received_inorder_packet_count_(0),
|
||||
|
||||
last_report_inorder_packets_(0),
|
||||
last_report_old_packets_(0),
|
||||
last_report_seq_max_(0),
|
||||
last_reported_statistics_() {}
|
||||
|
||||
void ReceiveStatisticsImpl::ResetStatistics() {
|
||||
CriticalSectionScoped lock(crit_sect_.get());
|
||||
void StreamStatisticianImpl::ResetStatistics() {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
last_report_inorder_packets_ = 0;
|
||||
last_report_old_packets_ = 0;
|
||||
last_report_seq_max_ = 0;
|
||||
@ -66,33 +64,25 @@ void ReceiveStatisticsImpl::ResetStatistics() {
|
||||
received_byte_count_ = 0;
|
||||
received_retransmitted_packets_ = 0;
|
||||
received_inorder_packet_count_ = 0;
|
||||
first_packet_ = true;
|
||||
}
|
||||
|
||||
void ReceiveStatisticsImpl::ResetDataCounters() {
|
||||
CriticalSectionScoped lock(crit_sect_.get());
|
||||
received_byte_count_ = 0;
|
||||
received_retransmitted_packets_ = 0;
|
||||
received_inorder_packet_count_ = 0;
|
||||
last_report_inorder_packets_ = 0;
|
||||
}
|
||||
|
||||
void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
size_t bytes,
|
||||
bool retransmitted,
|
||||
bool in_order) {
|
||||
void StreamStatisticianImpl::IncomingPacket(const RTPHeader& header,
|
||||
size_t bytes,
|
||||
bool retransmitted,
|
||||
bool in_order) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
ssrc_ = header.ssrc;
|
||||
incoming_bitrate_.Update(bytes);
|
||||
|
||||
received_byte_count_ += bytes;
|
||||
|
||||
if (received_seq_max_ == 0 && received_seq_wraps_ == 0) {
|
||||
if (first_packet_) {
|
||||
first_packet_ = false;
|
||||
// This is the first received report.
|
||||
received_seq_first_ = header.sequenceNumber;
|
||||
received_seq_max_ = header.sequenceNumber;
|
||||
received_inorder_packet_count_ = 1;
|
||||
// Current time in samples.
|
||||
local_time_last_received_timestamp_ =
|
||||
ModuleRTPUtility::GetCurrentRTP(clock_, header.payload_type_frequency);
|
||||
clock_->CurrentNtp(last_receive_time_secs_, last_receive_time_frac_);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -100,8 +90,9 @@ void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
// are received, 4 will be ignored.
|
||||
if (in_order) {
|
||||
// Current time in samples.
|
||||
const uint32_t RTPtime =
|
||||
ModuleRTPUtility::GetCurrentRTP(clock_, header.payload_type_frequency);
|
||||
uint32_t receive_time_secs;
|
||||
uint32_t receive_time_frac;
|
||||
clock_->CurrentNtp(receive_time_secs, receive_time_frac);
|
||||
received_inorder_packet_count_++;
|
||||
|
||||
// Wrong if we use RetransmitOfOldPacket.
|
||||
@ -116,8 +107,12 @@ void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
|
||||
if (header.timestamp != last_received_timestamp_ &&
|
||||
received_inorder_packet_count_ > 1) {
|
||||
int32_t time_diff_samples =
|
||||
(RTPtime - local_time_last_received_timestamp_) -
|
||||
uint32_t receive_time_rtp = ModuleRTPUtility::ConvertNTPTimeToRTP(
|
||||
receive_time_secs, receive_time_frac, header.payload_type_frequency);
|
||||
uint32_t last_receive_time_rtp = ModuleRTPUtility::ConvertNTPTimeToRTP(
|
||||
last_receive_time_secs_, last_receive_time_frac_,
|
||||
header.payload_type_frequency);
|
||||
int32_t time_diff_samples = (receive_time_rtp - last_receive_time_rtp) -
|
||||
(header.timestamp - last_received_timestamp_);
|
||||
|
||||
time_diff_samples = abs(time_diff_samples);
|
||||
@ -134,7 +129,7 @@ void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
// Extended jitter report, RFC 5450.
|
||||
// Actual network jitter, excluding the source-introduced jitter.
|
||||
int32_t time_diff_samples_ext =
|
||||
(RTPtime - local_time_last_received_timestamp_) -
|
||||
(receive_time_rtp - last_receive_time_rtp) -
|
||||
((header.timestamp +
|
||||
header.extension.transmissionTimeOffset) -
|
||||
(last_received_timestamp_ +
|
||||
@ -150,7 +145,8 @@ void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
}
|
||||
}
|
||||
last_received_timestamp_ = header.timestamp;
|
||||
local_time_last_received_timestamp_ = RTPtime;
|
||||
last_receive_time_secs_ = receive_time_secs;
|
||||
last_receive_time_frac_ = receive_time_frac;
|
||||
} else {
|
||||
if (retransmitted) {
|
||||
received_retransmitted_packets_++;
|
||||
@ -166,18 +162,8 @@ void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
received_packet_overhead_ = (15 * received_packet_overhead_ + packet_oh) >> 4;
|
||||
}
|
||||
|
||||
bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
|
||||
bool reset) {
|
||||
int32_t missing;
|
||||
return Statistics(statistics, &missing, reset);
|
||||
}
|
||||
|
||||
bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
|
||||
int32_t* missing, bool reset) {
|
||||
CriticalSectionScoped lock(crit_sect_.get());
|
||||
|
||||
assert(missing);
|
||||
|
||||
bool StreamStatisticianImpl::GetStatistics(Statistics* statistics, bool reset) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
if (received_seq_first_ == 0 && received_byte_count_ == 0) {
|
||||
// We have not received anything.
|
||||
return false;
|
||||
@ -224,20 +210,20 @@ bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
|
||||
received_retransmitted_packets_ - last_report_old_packets_;
|
||||
rec_since_last += retransmitted_packets;
|
||||
|
||||
*missing = 0;
|
||||
int32_t missing = 0;
|
||||
if (exp_since_last > rec_since_last) {
|
||||
*missing = (exp_since_last - rec_since_last);
|
||||
missing = (exp_since_last - rec_since_last);
|
||||
}
|
||||
uint8_t local_fraction_lost = 0;
|
||||
if (exp_since_last) {
|
||||
// Scale 0 to 255, where 255 is 100% loss.
|
||||
local_fraction_lost =
|
||||
static_cast<uint8_t>((255 * (*missing)) / exp_since_last);
|
||||
static_cast<uint8_t>(255 * missing / exp_since_last);
|
||||
}
|
||||
statistics->fraction_lost = local_fraction_lost;
|
||||
|
||||
// We need a counter for cumulative loss too.
|
||||
cumulative_loss_ += *missing;
|
||||
cumulative_loss_ += missing;
|
||||
|
||||
if (jitter_q4_ > jitter_max_q4_) {
|
||||
jitter_max_q4_ = jitter_q4_;
|
||||
@ -260,10 +246,9 @@ bool ReceiveStatisticsImpl::Statistics(RtpReceiveStatistics* statistics,
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReceiveStatisticsImpl::GetDataCounters(
|
||||
void StreamStatisticianImpl::GetDataCounters(
|
||||
uint32_t* bytes_received, uint32_t* packets_received) const {
|
||||
CriticalSectionScoped lock(crit_sect_.get());
|
||||
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
if (bytes_received) {
|
||||
*bytes_received = received_byte_count_;
|
||||
}
|
||||
@ -273,19 +258,124 @@ void ReceiveStatisticsImpl::GetDataCounters(
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ReceiveStatisticsImpl::BitrateReceived() {
|
||||
uint32_t StreamStatisticianImpl::BitrateReceived() const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
return incoming_bitrate_.BitrateNow();
|
||||
}
|
||||
|
||||
int32_t ReceiveStatisticsImpl::TimeUntilNextProcess() {
|
||||
int time_since_last_update = clock_->TimeInMilliseconds() -
|
||||
incoming_bitrate_.time_last_rate_update();
|
||||
return std::max(kRateUpdateIntervalMs - time_since_last_update, 0);
|
||||
void StreamStatisticianImpl::ProcessBitrate() {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
incoming_bitrate_.Process();
|
||||
}
|
||||
|
||||
void StreamStatisticianImpl::LastReceiveTimeNtp(uint32_t* secs,
|
||||
uint32_t* frac) const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
*secs = last_receive_time_secs_;
|
||||
*frac = last_receive_time_frac_;
|
||||
}
|
||||
|
||||
ReceiveStatistics* ReceiveStatistics::Create(Clock* clock) {
|
||||
return new ReceiveStatisticsImpl(clock);
|
||||
}
|
||||
|
||||
ReceiveStatisticsImpl::ReceiveStatisticsImpl(Clock* clock)
|
||||
: clock_(clock),
|
||||
crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
last_rate_update_ms_(0) {}
|
||||
|
||||
ReceiveStatisticsImpl::~ReceiveStatisticsImpl() {
|
||||
while (!statisticians_.empty()) {
|
||||
delete statisticians_.begin()->second;
|
||||
statisticians_.erase(statisticians_.begin());
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiveStatisticsImpl::IncomingPacket(const RTPHeader& header,
|
||||
size_t bytes, bool old_packet,
|
||||
bool in_order) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
StatisticianImplMap::iterator it = statisticians_.find(header.ssrc);
|
||||
if (it == statisticians_.end()) {
|
||||
std::pair<StatisticianImplMap::iterator, uint32_t> insert_result =
|
||||
statisticians_.insert(std::make_pair(
|
||||
header.ssrc, new StreamStatisticianImpl(clock_)));
|
||||
it = insert_result.first;
|
||||
}
|
||||
statisticians_[header.ssrc]->IncomingPacket(header, bytes, old_packet,
|
||||
in_order);
|
||||
}
|
||||
|
||||
void ReceiveStatisticsImpl::ChangeSsrc(uint32_t from_ssrc, uint32_t to_ssrc) {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
StatisticianImplMap::iterator from_it = statisticians_.find(from_ssrc);
|
||||
if (from_it == statisticians_.end())
|
||||
return;
|
||||
if (statisticians_.find(to_ssrc) != statisticians_.end())
|
||||
return;
|
||||
statisticians_[to_ssrc] = from_it->second;
|
||||
statisticians_.erase(from_it);
|
||||
}
|
||||
|
||||
StatisticianMap ReceiveStatisticsImpl::GetActiveStatisticians() const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
StatisticianMap active_statisticians;
|
||||
for (StatisticianImplMap::const_iterator it = statisticians_.begin();
|
||||
it != statisticians_.end(); ++it) {
|
||||
uint32_t secs;
|
||||
uint32_t frac;
|
||||
it->second->LastReceiveTimeNtp(&secs, &frac);
|
||||
if (clock_->CurrentNtpInMilliseconds() -
|
||||
Clock::NtpToMs(secs, frac) < kStatisticsTimeoutMs) {
|
||||
active_statisticians[it->first] = it->second;
|
||||
}
|
||||
}
|
||||
return active_statisticians;
|
||||
}
|
||||
|
||||
StreamStatistician* ReceiveStatisticsImpl::GetStatistician(
|
||||
uint32_t ssrc) const {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
StatisticianImplMap::const_iterator it = statisticians_.find(ssrc);
|
||||
if (it == statisticians_.end())
|
||||
return NULL;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int32_t ReceiveStatisticsImpl::Process() {
|
||||
incoming_bitrate_.Process();
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
for (StatisticianImplMap::iterator it = statisticians_.begin();
|
||||
it != statisticians_.end(); ++it) {
|
||||
it->second->ProcessBitrate();
|
||||
}
|
||||
last_rate_update_ms_ = clock_->TimeInMilliseconds();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ReceiveStatisticsImpl::TimeUntilNextProcess() {
|
||||
CriticalSectionScoped cs(crit_sect_.get());
|
||||
int time_since_last_update = clock_->TimeInMilliseconds() -
|
||||
last_rate_update_ms_;
|
||||
return std::max(kStatisticsProcessIntervalMs - time_since_last_update, 0);
|
||||
}
|
||||
|
||||
|
||||
void NullReceiveStatistics::IncomingPacket(const RTPHeader& rtp_header,
|
||||
size_t bytes,
|
||||
bool retransmitted,
|
||||
bool in_order) {}
|
||||
|
||||
StatisticianMap NullReceiveStatistics::GetActiveStatisticians() const {
|
||||
return StatisticianMap();
|
||||
}
|
||||
|
||||
StreamStatistician* NullReceiveStatistics::GetStatistician(
|
||||
uint32_t ssrc) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t NullReceiveStatistics::TimeUntilNextProcess() { return 0; }
|
||||
|
||||
int32_t NullReceiveStatistics::Process() { return 0; }
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -23,43 +23,43 @@ namespace webrtc {
|
||||
|
||||
class CriticalSectionWrapper;
|
||||
|
||||
class ReceiveStatisticsImpl : public ReceiveStatistics {
|
||||
class StreamStatisticianImpl : public StreamStatistician {
|
||||
public:
|
||||
explicit ReceiveStatisticsImpl(Clock* clock);
|
||||
explicit StreamStatisticianImpl(Clock* clock);
|
||||
|
||||
// Implements ReceiveStatistics.
|
||||
void IncomingPacket(const RTPHeader& header, size_t bytes,
|
||||
bool old_packet, bool in_order);
|
||||
bool Statistics(RtpReceiveStatistics* statistics, bool reset);
|
||||
bool Statistics(RtpReceiveStatistics* statistics, int32_t* missing,
|
||||
bool reset);
|
||||
void GetDataCounters(uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const;
|
||||
uint32_t BitrateReceived();
|
||||
void ResetStatistics();
|
||||
void ResetDataCounters();
|
||||
virtual ~StreamStatisticianImpl() {}
|
||||
|
||||
// Implements Module.
|
||||
int32_t TimeUntilNextProcess();
|
||||
int32_t Process();
|
||||
virtual bool GetStatistics(Statistics* statistics, bool reset) OVERRIDE;
|
||||
virtual void GetDataCounters(uint32_t* bytes_received,
|
||||
uint32_t* packets_received) const OVERRIDE;
|
||||
virtual uint32_t BitrateReceived() const OVERRIDE;
|
||||
virtual void ResetStatistics() OVERRIDE;
|
||||
|
||||
void IncomingPacket(const RTPHeader& rtp_header, size_t bytes,
|
||||
bool retransmitted, bool in_order);
|
||||
void ProcessBitrate();
|
||||
virtual void LastReceiveTimeNtp(uint32_t* secs, uint32_t* frac) const;
|
||||
|
||||
private:
|
||||
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
Clock* clock_;
|
||||
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
Bitrate incoming_bitrate_;
|
||||
uint32_t ssrc_;
|
||||
|
||||
// Stats on received RTP packets.
|
||||
uint32_t jitter_q4_;
|
||||
uint32_t jitter_max_q4_;
|
||||
uint32_t cumulative_loss_;
|
||||
uint32_t jitter_q4_transmission_time_offset_;
|
||||
|
||||
uint32_t local_time_last_received_timestamp_;
|
||||
uint32_t last_receive_time_secs_;
|
||||
uint32_t last_receive_time_frac_;
|
||||
uint32_t last_received_timestamp_;
|
||||
int32_t last_received_transmission_time_offset_;
|
||||
uint16_t received_seq_first_;
|
||||
uint16_t received_seq_max_;
|
||||
uint16_t received_seq_wraps_;
|
||||
bool first_packet_;
|
||||
|
||||
// Current counter values.
|
||||
uint16_t received_packet_overhead_;
|
||||
@ -71,7 +71,34 @@ class ReceiveStatisticsImpl : public ReceiveStatistics {
|
||||
uint32_t last_report_inorder_packets_;
|
||||
uint32_t last_report_old_packets_;
|
||||
uint16_t last_report_seq_max_;
|
||||
RtpReceiveStatistics last_reported_statistics_;
|
||||
Statistics last_reported_statistics_;
|
||||
};
|
||||
|
||||
class ReceiveStatisticsImpl : public ReceiveStatistics {
|
||||
public:
|
||||
explicit ReceiveStatisticsImpl(Clock* clock);
|
||||
|
||||
~ReceiveStatisticsImpl();
|
||||
|
||||
// Implement ReceiveStatistics.
|
||||
virtual void IncomingPacket(const RTPHeader& header, size_t bytes,
|
||||
bool old_packet, bool in_order) OVERRIDE;
|
||||
virtual StatisticianMap GetActiveStatisticians() const OVERRIDE;
|
||||
virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE;
|
||||
|
||||
// Implement Module.
|
||||
virtual int32_t Process() OVERRIDE;
|
||||
virtual int32_t TimeUntilNextProcess() OVERRIDE;
|
||||
|
||||
void ChangeSsrc(uint32_t from_ssrc, uint32_t to_ssrc);
|
||||
|
||||
private:
|
||||
typedef std::map<uint32_t, StreamStatisticianImpl*> StatisticianImplMap;
|
||||
|
||||
Clock* clock_;
|
||||
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
||||
int64_t last_rate_update_ms_;
|
||||
StatisticianImplMap statisticians_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RECEIVE_STATISTICS_IMPL_H_
|
||||
|
135
webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
Normal file
135
webrtc/modules/rtp_rtcp/source/receive_statistics_unittest.cc
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/system_wrappers/interface/clock.h"
|
||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
const int kPacketSize1 = 100;
|
||||
const int kPacketSize2 = 300;
|
||||
const uint32_t kSsrc1 = 1;
|
||||
const uint32_t kSsrc2 = 2;
|
||||
const uint32_t kSsrc3 = 3;
|
||||
|
||||
class ReceiveStatisticsTest : public ::testing::Test {
|
||||
public:
|
||||
ReceiveStatisticsTest() :
|
||||
clock_(0),
|
||||
receive_statistics_(ReceiveStatistics::Create(&clock_)) {
|
||||
memset(&header1_, 0, sizeof(header1_));
|
||||
header1_.ssrc = kSsrc1;
|
||||
header1_.sequenceNumber = 0;
|
||||
memset(&header2_, 0, sizeof(header2_));
|
||||
header2_.ssrc = kSsrc2;
|
||||
header2_.sequenceNumber = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
SimulatedClock clock_;
|
||||
scoped_ptr<ReceiveStatistics> receive_statistics_;
|
||||
RTPHeader header1_;
|
||||
RTPHeader header2_;
|
||||
};
|
||||
|
||||
TEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
|
||||
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
|
||||
++header1_.sequenceNumber;
|
||||
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
|
||||
++header2_.sequenceNumber;
|
||||
clock_.AdvanceTimeMilliseconds(100);
|
||||
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
|
||||
++header1_.sequenceNumber;
|
||||
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
|
||||
++header2_.sequenceNumber;
|
||||
|
||||
StreamStatistician* statistician =
|
||||
receive_statistics_->GetStatistician(kSsrc1);
|
||||
ASSERT_TRUE(statistician != NULL);
|
||||
EXPECT_GT(statistician->BitrateReceived(), 0u);
|
||||
uint32_t bytes_received = 0;
|
||||
uint32_t packets_received = 0;
|
||||
statistician->GetDataCounters(&bytes_received, &packets_received);
|
||||
EXPECT_EQ(200u, bytes_received);
|
||||
EXPECT_EQ(2u, packets_received);
|
||||
|
||||
statistician =
|
||||
receive_statistics_->GetStatistician(kSsrc2);
|
||||
ASSERT_TRUE(statistician != NULL);
|
||||
EXPECT_GT(statistician->BitrateReceived(), 0u);
|
||||
statistician->GetDataCounters(&bytes_received, &packets_received);
|
||||
EXPECT_EQ(600u, bytes_received);
|
||||
EXPECT_EQ(2u, packets_received);
|
||||
|
||||
StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
|
||||
EXPECT_EQ(2u, statisticians.size());
|
||||
// Add more incoming packets and verify that they are registered in both
|
||||
// access methods.
|
||||
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
|
||||
++header1_.sequenceNumber;
|
||||
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
|
||||
++header2_.sequenceNumber;
|
||||
|
||||
statisticians[kSsrc1]->GetDataCounters(&bytes_received, &packets_received);
|
||||
EXPECT_EQ(300u, bytes_received);
|
||||
EXPECT_EQ(3u, packets_received);
|
||||
statisticians[kSsrc2]->GetDataCounters(&bytes_received, &packets_received);
|
||||
EXPECT_EQ(900u, bytes_received);
|
||||
EXPECT_EQ(3u, packets_received);
|
||||
|
||||
receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
|
||||
&bytes_received, &packets_received);
|
||||
EXPECT_EQ(300u, bytes_received);
|
||||
EXPECT_EQ(3u, packets_received);
|
||||
receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
|
||||
&bytes_received, &packets_received);
|
||||
EXPECT_EQ(900u, bytes_received);
|
||||
EXPECT_EQ(3u, packets_received);
|
||||
}
|
||||
|
||||
TEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
|
||||
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
|
||||
++header1_.sequenceNumber;
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
receive_statistics_->IncomingPacket(header2_, kPacketSize2, false, true);
|
||||
++header2_.sequenceNumber;
|
||||
StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
|
||||
// Nothing should time out since only 1000 ms has passed since the first
|
||||
// packet came in.
|
||||
EXPECT_EQ(2u, statisticians.size());
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(7000);
|
||||
// kSsrc1 should have timed out.
|
||||
statisticians = receive_statistics_->GetActiveStatisticians();
|
||||
EXPECT_EQ(1u, statisticians.size());
|
||||
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
// kSsrc2 should have timed out.
|
||||
statisticians = receive_statistics_->GetActiveStatisticians();
|
||||
EXPECT_EQ(0u, statisticians.size());
|
||||
|
||||
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false, true);
|
||||
++header1_.sequenceNumber;
|
||||
// kSsrc1 should be active again and the data counters should have survived.
|
||||
statisticians = receive_statistics_->GetActiveStatisticians();
|
||||
EXPECT_EQ(1u, statisticians.size());
|
||||
StreamStatistician* statistician =
|
||||
receive_statistics_->GetStatistician(kSsrc1);
|
||||
ASSERT_TRUE(statistician != NULL);
|
||||
uint32_t bytes_received = 0;
|
||||
uint32_t packets_received = 0;
|
||||
statistician->GetDataCounters(&bytes_received, &packets_received);
|
||||
EXPECT_EQ(200u, bytes_received);
|
||||
EXPECT_EQ(2u, packets_received);
|
||||
}
|
||||
} // namespace webrtc
|
@ -61,6 +61,7 @@ class RtcpFormatRembTest : public ::testing::Test {
|
||||
RtcpFormatRembTest()
|
||||
: over_use_detector_options_(),
|
||||
system_clock_(Clock::GetRealTimeClock()),
|
||||
receive_statistics_(ReceiveStatistics::Create(system_clock_)),
|
||||
remote_bitrate_observer_(),
|
||||
remote_bitrate_estimator_(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
@ -72,6 +73,7 @@ class RtcpFormatRembTest : public ::testing::Test {
|
||||
OverUseDetectorOptions over_use_detector_options_;
|
||||
Clock* system_clock_;
|
||||
ModuleRtpRtcpImpl* dummy_rtp_rtcp_impl_;
|
||||
scoped_ptr<ReceiveStatistics> receive_statistics_;
|
||||
RTCPSender* rtcp_sender_;
|
||||
RTCPReceiver* rtcp_receiver_;
|
||||
TestTransport* test_transport_;
|
||||
@ -86,7 +88,8 @@ void RtcpFormatRembTest::SetUp() {
|
||||
configuration.clock = system_clock_;
|
||||
configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
|
||||
dummy_rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
|
||||
rtcp_sender_ = new RTCPSender(0, false, system_clock_, dummy_rtp_rtcp_impl_);
|
||||
rtcp_sender_ = new RTCPSender(0, false, system_clock_, dummy_rtp_rtcp_impl_,
|
||||
receive_statistics_.get());
|
||||
rtcp_receiver_ = new RTCPReceiver(0, system_clock_, dummy_rtp_rtcp_impl_);
|
||||
test_transport_ = new TestTransport(rtcp_receiver_);
|
||||
|
||||
@ -115,15 +118,13 @@ TEST_F(RtcpFormatRembTest, TestNonCompund) {
|
||||
uint32_t SSRC = 456789;
|
||||
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpNonCompound));
|
||||
EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 1, &SSRC));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb, NULL));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb));
|
||||
}
|
||||
|
||||
TEST_F(RtcpFormatRembTest, TestCompund) {
|
||||
uint32_t SSRCs[2] = {456789, 98765};
|
||||
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
|
||||
EXPECT_EQ(0, rtcp_sender_->SetREMBData(1234, 2, SSRCs));
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
memset(&receive_stats, 0, sizeof(receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb, &receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRemb));
|
||||
}
|
||||
} // namespace
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,8 @@ class RTCPSender
|
||||
{
|
||||
public:
|
||||
RTCPSender(const int32_t id, const bool audio,
|
||||
Clock* clock, ModuleRtpRtcpImpl* owner);
|
||||
Clock* clock, ModuleRtpRtcpImpl* owner,
|
||||
ReceiveStatistics* receive_statistics);
|
||||
virtual ~RTCPSender();
|
||||
|
||||
void ChangeUniqueId(const int32_t id);
|
||||
@ -93,16 +94,16 @@ public:
|
||||
|
||||
int32_t SendRTCP(
|
||||
uint32_t rtcpPacketTypeFlags,
|
||||
const ReceiveStatistics::RtpReceiveStatistics* receive_stats,
|
||||
int32_t nackSize = 0,
|
||||
const uint16_t* nackList = 0,
|
||||
bool repeat = false,
|
||||
uint64_t pictureID = 0);
|
||||
|
||||
int32_t AddReportBlock(const uint32_t SSRC,
|
||||
const RTCPReportBlock* receiveBlock);
|
||||
int32_t AddExternalReportBlock(
|
||||
uint32_t SSRC,
|
||||
const RTCPReportBlock* receiveBlock);
|
||||
|
||||
int32_t RemoveReportBlock(const uint32_t SSRC);
|
||||
int32_t RemoveExternalReportBlock(uint32_t SSRC);
|
||||
|
||||
/*
|
||||
* REMB
|
||||
@ -155,49 +156,71 @@ private:
|
||||
|
||||
void UpdatePacketRate();
|
||||
|
||||
int32_t AddReportBlocks(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int32_t WriteAllReportBlocksToBuffer(uint8_t* rtcpbuffer,
|
||||
int pos,
|
||||
uint8_t& numberOfReportBlocks,
|
||||
const RTCPReportBlock* received,
|
||||
const uint32_t NTPsec,
|
||||
const uint32_t NTPfrac);
|
||||
|
||||
int32_t WriteReportBlocksToBuffer(
|
||||
uint8_t* rtcpbuffer,
|
||||
int32_t position,
|
||||
const std::map<uint32_t, RTCPReportBlock*>& report_blocks);
|
||||
|
||||
int32_t AddReportBlock(
|
||||
uint32_t SSRC,
|
||||
std::map<uint32_t, RTCPReportBlock*>* report_blocks,
|
||||
const RTCPReportBlock* receiveBlock);
|
||||
|
||||
bool PrepareReport(StreamStatistician* statistician,
|
||||
RTCPReportBlock* report_block,
|
||||
uint32_t* ntp_secs, uint32_t* ntp_frac);
|
||||
|
||||
int32_t BuildSR(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const uint32_t NTPsec,
|
||||
const uint32_t NTPfrac,
|
||||
const RTCPReportBlock* received = NULL);
|
||||
const uint32_t NTPfrac);
|
||||
|
||||
int32_t BuildRR(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const uint32_t NTPsec,
|
||||
const uint32_t NTPfrac,
|
||||
const RTCPReportBlock* received = NULL);
|
||||
const uint32_t NTPfrac);
|
||||
|
||||
int PrepareRTCP(
|
||||
uint32_t packetTypeFlags,
|
||||
int32_t nackSize,
|
||||
const uint16_t* nackList,
|
||||
bool repeat,
|
||||
uint64_t pictureID,
|
||||
uint8_t* rtcp_buffer,
|
||||
int buffer_size);
|
||||
|
||||
bool ShouldSendReportBlocks(uint32_t rtcp_packet_type) const;
|
||||
|
||||
int32_t BuildExtendedJitterReport(
|
||||
uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const uint32_t jitterTransmissionTimeOffset);
|
||||
|
||||
int32_t BuildSDEC(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildPLI(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildREMB(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildTMMBR(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildTMMBN(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildAPP(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildBYE(uint8_t* rtcpbuffer, uint32_t& pos);
|
||||
int32_t BuildFIR(uint8_t* rtcpbuffer, uint32_t& pos, bool repeat);
|
||||
int32_t BuildSDEC(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildPLI(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildREMB(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildTMMBR(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildTMMBN(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildAPP(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildVoIPMetric(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildBYE(uint8_t* rtcpbuffer, int& pos);
|
||||
int32_t BuildFIR(uint8_t* rtcpbuffer, int& pos, bool repeat);
|
||||
int32_t BuildSLI(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const uint8_t pictureID);
|
||||
int32_t BuildRPSI(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const uint64_t pictureID,
|
||||
const uint8_t payloadType);
|
||||
|
||||
int32_t BuildNACK(uint8_t* rtcpbuffer,
|
||||
uint32_t& pos,
|
||||
int& pos,
|
||||
const int32_t nackSize,
|
||||
const uint16_t* nackList,
|
||||
std::string* nackString);
|
||||
@ -231,7 +254,10 @@ private:
|
||||
uint32_t _remoteSSRC; // SSRC that we receive on our RTP channel
|
||||
char _CNAME[RTCP_CNAME_SIZE];
|
||||
|
||||
std::map<uint32_t, RTCPReportBlock*> _reportBlocks;
|
||||
|
||||
ReceiveStatistics* receive_statistics_;
|
||||
std::map<uint32_t, RTCPReportBlock*> internal_report_blocks_;
|
||||
std::map<uint32_t, RTCPReportBlock*> external_report_blocks_;
|
||||
std::map<uint32_t, RTCPUtility::RTCPCnameInformation*> _csrcCNAMEs;
|
||||
|
||||
int32_t _cameraDelayMS;
|
||||
|
@ -285,7 +285,8 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
remote_bitrate_estimator_(
|
||||
RemoteBitrateEstimatorFactory().Create(
|
||||
&remote_bitrate_observer_,
|
||||
system_clock_)) {
|
||||
system_clock_)),
|
||||
receive_statistics_(ReceiveStatistics::Create(system_clock_)) {
|
||||
test_transport_ = new TestTransport();
|
||||
|
||||
RtpRtcp::Configuration configuration;
|
||||
@ -298,7 +299,8 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
|
||||
rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
|
||||
0, system_clock_, test_transport_, NULL, rtp_payload_registry_.get()));
|
||||
rtcp_sender_ = new RTCPSender(0, false, system_clock_, rtp_rtcp_impl_);
|
||||
rtcp_sender_ = new RTCPSender(0, false, system_clock_, rtp_rtcp_impl_,
|
||||
receive_statistics_.get());
|
||||
rtcp_receiver_ = new RTCPReceiver(0, system_clock_, rtp_rtcp_impl_);
|
||||
test_transport_->SetRTCPReceiver(rtcp_receiver_);
|
||||
// Initialize
|
||||
@ -328,6 +330,7 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
TestTransport* test_transport_;
|
||||
MockRemoteBitrateObserver remote_bitrate_observer_;
|
||||
scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
|
||||
scoped_ptr<ReceiveStatistics> receive_statistics_;
|
||||
|
||||
enum {kMaxPacketLength = 1500};
|
||||
uint8_t packet_[kMaxPacketLength];
|
||||
@ -335,7 +338,7 @@ class RtcpSenderTest : public ::testing::Test {
|
||||
|
||||
TEST_F(RtcpSenderTest, RtcpOff) {
|
||||
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpOff));
|
||||
EXPECT_EQ(-1, rtcp_sender_->SendRTCP(kRtcpSr, NULL));
|
||||
EXPECT_EQ(-1, rtcp_sender_->SendRTCP(kRtcpSr));
|
||||
}
|
||||
|
||||
TEST_F(RtcpSenderTest, IJStatus) {
|
||||
@ -372,14 +375,13 @@ TEST_F(RtcpSenderTest, TestCompound) {
|
||||
PayloadUnion payload_specific;
|
||||
EXPECT_TRUE(rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
|
||||
&payload_specific));
|
||||
receive_statistics_->IncomingPacket(header, packet_length, false, true);
|
||||
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(&header, packet_, packet_length,
|
||||
payload_specific, true));
|
||||
|
||||
EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
|
||||
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
memset(&receive_stats, 0, sizeof(receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr, &receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr));
|
||||
|
||||
// Transmission time offset packet should be received.
|
||||
ASSERT_TRUE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
|
||||
@ -389,9 +391,7 @@ TEST_F(RtcpSenderTest, TestCompound) {
|
||||
TEST_F(RtcpSenderTest, TestCompound_NoRtpReceived) {
|
||||
EXPECT_EQ(0, rtcp_sender_->SetIJStatus(true));
|
||||
EXPECT_EQ(0, rtcp_sender_->SetRTCPStatus(kRtcpCompound));
|
||||
// |receive_stats| is NULL since no data has been received.
|
||||
ReceiveStatistics::RtpReceiveStatistics* receive_stats = NULL;
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr, receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpRr));
|
||||
|
||||
// Transmission time offset packet should not be received.
|
||||
ASSERT_FALSE(test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags &
|
||||
@ -409,9 +409,7 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndEmpty) {
|
||||
TMMBRSet bounding_set;
|
||||
EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
|
||||
ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
memset(&receive_stats, 0, sizeof(receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr, &receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr));
|
||||
// We now expect the packet to show up in the rtcp_packet_info_ of
|
||||
// test_transport_.
|
||||
ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
|
||||
@ -433,9 +431,7 @@ TEST_F(RtcpSenderTest, SendsTmmbnIfSetAndValid) {
|
||||
|
||||
EXPECT_EQ(0, rtcp_sender_->SetTMMBN(&bounding_set, 3));
|
||||
ASSERT_EQ(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
memset(&receive_stats, 0, sizeof(receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr, &receive_stats));
|
||||
EXPECT_EQ(0, rtcp_sender_->SendRTCP(kRtcpSr));
|
||||
// We now expect the packet to show up in the rtcp_packet_info_ of
|
||||
// test_transport_.
|
||||
ASSERT_NE(0U, test_transport_->rtcp_packet_info_.rtcpPacketTypeFlags);
|
||||
|
@ -283,7 +283,7 @@ bool RtpReceiverImpl::IncomingRtpPacket(
|
||||
}
|
||||
|
||||
if (should_reset_statistics) {
|
||||
cb_rtp_feedback_->ResetStatistics();
|
||||
cb_rtp_feedback_->ResetStatistics(ssrc_);
|
||||
}
|
||||
|
||||
WebRtcRTPHeader webrtc_rtp_header;
|
||||
@ -418,7 +418,7 @@ void RtpReceiverImpl::CheckSSRCChanged(const RTPHeader* rtp_header) {
|
||||
// We need the payload_type_ to make the call if the remote SSRC is 0.
|
||||
new_ssrc = true;
|
||||
|
||||
cb_rtp_feedback_->ResetStatistics();
|
||||
cb_rtp_feedback_->ResetStatistics(ssrc_);
|
||||
|
||||
last_received_timestamp_ = 0;
|
||||
last_received_sequence_number_ = 0;
|
||||
|
@ -41,7 +41,7 @@ RtpRtcp::Configuration::Configuration()
|
||||
audio(false),
|
||||
clock(NULL),
|
||||
default_module(NULL),
|
||||
receive_statistics(NULL),
|
||||
receive_statistics(NullObjectReceiveStatistics()),
|
||||
outgoing_transport(NULL),
|
||||
rtcp_feedback(NULL),
|
||||
intra_frame_callback(NULL),
|
||||
@ -74,10 +74,9 @@ ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
|
||||
configuration.audio_messages,
|
||||
configuration.paced_sender),
|
||||
rtcp_sender_(configuration.id, configuration.audio, configuration.clock,
|
||||
this),
|
||||
this, configuration.receive_statistics),
|
||||
rtcp_receiver_(configuration.id, configuration.clock, this),
|
||||
clock_(configuration.clock),
|
||||
receive_statistics_(configuration.receive_statistics),
|
||||
id_(configuration.id),
|
||||
audio_(configuration.audio),
|
||||
collision_detected_(false),
|
||||
@ -242,13 +241,7 @@ int32_t ModuleRtpRtcpImpl::Process() {
|
||||
}
|
||||
}
|
||||
if (rtcp_sender_.TimeToSendRTCPReport()) {
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
rtcp_sender_.SendRTCP(kRtcpReport, &receive_stats);
|
||||
} else {
|
||||
rtcp_sender_.SendRTCP(kRtcpReport, NULL);
|
||||
}
|
||||
rtcp_sender_.SendRTCP(kRtcpReport);
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,13 +570,7 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData(
|
||||
if (!have_child_modules) {
|
||||
// Don't send RTCP from default module.
|
||||
if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
rtcp_sender_.SendRTCP(kRtcpReport, &receive_stats);
|
||||
} else {
|
||||
rtcp_sender_.SendRTCP(kRtcpReport, NULL);
|
||||
}
|
||||
rtcp_sender_.SendRTCP(kRtcpReport);
|
||||
}
|
||||
return rtp_sender_.SendOutgoingData(frame_type,
|
||||
payload_type,
|
||||
@ -925,19 +912,7 @@ int32_t ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
|
||||
int32_t ModuleRtpRtcpImpl::SendRTCP(uint32_t rtcp_packet_type) {
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SendRTCP(0x%x)",
|
||||
rtcp_packet_type);
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (rtcp_sender_.Status() == kRtcpCompound ||
|
||||
(rtcp_packet_type & kRtcpReport) ||
|
||||
(rtcp_packet_type & kRtcpSr) ||
|
||||
(rtcp_packet_type & kRtcpRr)) {
|
||||
if (receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
return rtcp_sender_.SendRTCP(rtcp_packet_type, &receive_stats);
|
||||
} else {
|
||||
return rtcp_sender_.SendRTCP(rtcp_packet_type, NULL);
|
||||
}
|
||||
}
|
||||
return rtcp_sender_.SendRTCP(rtcp_packet_type, NULL);
|
||||
return rtcp_sender_.SendRTCP(kRtcpReport);
|
||||
}
|
||||
|
||||
int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
|
||||
@ -993,14 +968,14 @@ int32_t ModuleRtpRtcpImpl::AddRTCPReportBlock(
|
||||
const RTCPReportBlock* report_block) {
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "AddRTCPReportBlock()");
|
||||
|
||||
return rtcp_sender_.AddReportBlock(ssrc, report_block);
|
||||
return rtcp_sender_.AddExternalReportBlock(ssrc, report_block);
|
||||
}
|
||||
|
||||
int32_t ModuleRtpRtcpImpl::RemoveRTCPReportBlock(
|
||||
const uint32_t ssrc) {
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "RemoveRTCPReportBlock()");
|
||||
|
||||
return rtcp_sender_.RemoveReportBlock(ssrc);
|
||||
return rtcp_sender_.RemoveExternalReportBlock(ssrc);
|
||||
}
|
||||
|
||||
// (REMB) Receiver Estimated Max Bitrate.
|
||||
@ -1154,15 +1129,7 @@ int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list,
|
||||
}
|
||||
nack_last_seq_number_sent_ = nack_list[start_id + nackLength - 1];
|
||||
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (rtcp_sender_.Status() == kRtcpCompound && receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
return rtcp_sender_.SendRTCP(kRtcpNack, &receive_stats, nackLength,
|
||||
&nack_list[start_id]);
|
||||
} else {
|
||||
return rtcp_sender_.SendRTCP(kRtcpNack, NULL, nackLength,
|
||||
&nack_list[start_id]);
|
||||
}
|
||||
return rtcp_sender_.SendRTCP(kRtcpNack, nackLength, &nack_list[start_id]);
|
||||
}
|
||||
|
||||
// Store the sent packets, needed to answer to a Negative acknowledgment
|
||||
@ -1357,14 +1324,8 @@ int32_t ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
|
||||
id_,
|
||||
"SendRTCPSliceLossIndication (picture_id:%d)",
|
||||
picture_id);
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (rtcp_sender_.Status() == kRtcpCompound && receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
return rtcp_sender_.SendRTCP(kRtcpSli, &receive_stats, 0, 0, false,
|
||||
picture_id);
|
||||
} else {
|
||||
return rtcp_sender_.SendRTCP(kRtcpSli, NULL, 0, 0, false, picture_id);
|
||||
}
|
||||
|
||||
return rtcp_sender_.SendRTCP(kRtcpSli, 0, 0, false, picture_id);
|
||||
}
|
||||
|
||||
int32_t ModuleRtpRtcpImpl::SetCameraDelay(const int32_t delay_ms) {
|
||||
@ -1562,14 +1523,7 @@ void ModuleRtpRtcpImpl::OnRequestSendReport() {
|
||||
|
||||
int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
|
||||
const uint64_t picture_id) {
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (rtcp_sender_.Status() == kRtcpCompound && receive_statistics_ &&
|
||||
receive_statistics_->Statistics(&receive_stats, true)) {
|
||||
return rtcp_sender_.SendRTCP(kRtcpRpsi, &receive_stats, 0, 0, false,
|
||||
picture_id);
|
||||
} else {
|
||||
return rtcp_sender_.SendRTCP(kRtcpRpsi, NULL, 0, 0, false, picture_id);
|
||||
}
|
||||
return rtcp_sender_.SendRTCP(kRtcpRpsi, 0, 0, false, picture_id);
|
||||
}
|
||||
|
||||
uint32_t ModuleRtpRtcpImpl::SendTimeOfSendReport(
|
||||
|
@ -377,8 +377,6 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
|
||||
private:
|
||||
int64_t RtcpReportInterval();
|
||||
|
||||
ReceiveStatistics* receive_statistics_;
|
||||
|
||||
int32_t id_;
|
||||
const bool audio_;
|
||||
bool collision_detected_;
|
||||
|
@ -61,6 +61,11 @@ RtpAudioFeedback* NullObjectRtpAudioFeedback() {
|
||||
return &null_rtp_audio_feedback;
|
||||
}
|
||||
|
||||
ReceiveStatistics* NullObjectReceiveStatistics() {
|
||||
static NullReceiveStatistics null_receive_statistics;
|
||||
return &null_receive_statistics;
|
||||
}
|
||||
|
||||
namespace ModuleRTPUtility {
|
||||
|
||||
enum {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <stddef.h> // size_t, ptrdiff_t
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
|
||||
#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
@ -25,6 +26,7 @@ const uint8_t kRtpMarkerBitMask = 0x80;
|
||||
RtpData* NullObjectRtpData();
|
||||
RtpFeedback* NullObjectRtpFeedback();
|
||||
RtpAudioFeedback* NullObjectRtpAudioFeedback();
|
||||
ReceiveStatistics* NullObjectReceiveStatistics();
|
||||
|
||||
namespace ModuleRTPUtility
|
||||
{
|
||||
|
@ -76,8 +76,8 @@ class TestRtpFeedback : public NullRtpFeedback {
|
||||
virtual ~TestRtpFeedback() {}
|
||||
|
||||
virtual void OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC) {
|
||||
rtp_rtcp_->SetRemoteSSRC(SSRC);
|
||||
const uint32_t ssrc) {
|
||||
rtp_rtcp_->SetRemoteSSRC(ssrc);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -334,8 +334,10 @@ TEST_F(RtpRtcpRtcpTest, RTCP) {
|
||||
EXPECT_EQ(static_cast<uint32_t>(0),
|
||||
reportBlockReceived.cumulativeLost);
|
||||
|
||||
ReceiveStatistics::RtpReceiveStatistics stats;
|
||||
EXPECT_TRUE(receive_statistics2_->Statistics(&stats, true));
|
||||
StreamStatistician *statistician =
|
||||
receive_statistics2_->GetStatistician(reportBlockReceived.sourceSSRC);
|
||||
StreamStatistician::Statistics stats;
|
||||
EXPECT_TRUE(statistician->GetStatistics(&stats, true));
|
||||
EXPECT_EQ(0, stats.fraction_lost);
|
||||
EXPECT_EQ((uint32_t)0, stats.cumulative_lost);
|
||||
EXPECT_EQ(test_sequence_number, stats.extended_max_sequence_number);
|
||||
|
@ -324,6 +324,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
||||
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: RTP::SetRTCPStatus failure", __FUNCTION__);
|
||||
}
|
||||
|
||||
if (rtp_rtcp_->StorePackets()) {
|
||||
rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
|
||||
} else if (paced_sender_) {
|
||||
@ -1272,10 +1273,12 @@ int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s", __FUNCTION__);
|
||||
|
||||
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
|
||||
uint8_t frac_lost = 0;
|
||||
ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
|
||||
ReceiveStatistics::RtpReceiveStatistics receive_stats;
|
||||
if (!receive_statistics || !receive_statistics->Statistics(
|
||||
StreamStatistician* statistician =
|
||||
vie_receiver_.GetReceiveStatistics()->GetStatistician(remote_ssrc);
|
||||
StreamStatistician::Statistics receive_stats;
|
||||
if (!statistician || !statistician->GetStatistics(
|
||||
&receive_stats, rtp_rtcp_->RTCP() == kRtcpOff)) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not get received RTP statistics", __FUNCTION__);
|
||||
@ -1287,7 +1290,6 @@ int32_t ViEChannel::GetReceivedRtcpStatistics(uint16_t* fraction_lost,
|
||||
*jitter_samples = receive_stats.jitter;
|
||||
*fraction_lost = frac_lost;
|
||||
|
||||
uint32_t remote_ssrc = vie_receiver_.GetRemoteSsrc();
|
||||
uint16_t dummy = 0;
|
||||
uint16_t rtt = 0;
|
||||
if (rtp_rtcp_->RTT(remote_ssrc, &rtt, &dummy, &dummy, &dummy) != 0) {
|
||||
@ -1305,8 +1307,12 @@ int32_t ViEChannel::GetRtpStatistics(uint32_t* bytes_sent,
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
|
||||
__FUNCTION__);
|
||||
|
||||
ReceiveStatistics* receive_statistics = vie_receiver_.GetReceiveStatistics();
|
||||
receive_statistics->GetDataCounters(bytes_received, packets_received);
|
||||
StreamStatistician* statistician = vie_receiver_.GetReceiveStatistics()->
|
||||
GetStatistician(vie_receiver_.GetRemoteSsrc());
|
||||
*bytes_received = 0;
|
||||
*packets_received = 0;
|
||||
if (statistician)
|
||||
statistician->GetDataCounters(bytes_received, packets_received);
|
||||
if (rtp_rtcp_->DataCountersRTP(bytes_sent, packets_sent) != 0) {
|
||||
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: Could not get counters", __FUNCTION__);
|
||||
@ -1888,8 +1894,7 @@ int32_t ViEChannel::OnInitializeDecoder(
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ViEChannel::OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC) {
|
||||
void ViEChannel::OnIncomingSSRCChanged(const int32_t id, const uint32_t ssrc) {
|
||||
if (channel_id_ != ChannelId(id)) {
|
||||
assert(false);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
@ -1898,14 +1903,14 @@ void ViEChannel::OnIncomingSSRCChanged(const int32_t id,
|
||||
}
|
||||
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
|
||||
"%s: %u", __FUNCTION__, SSRC);
|
||||
"%s: %u", __FUNCTION__, ssrc);
|
||||
|
||||
rtp_rtcp_->SetRemoteSSRC(SSRC);
|
||||
rtp_rtcp_->SetRemoteSSRC(ssrc);
|
||||
|
||||
CriticalSectionScoped cs(callback_cs_.get());
|
||||
{
|
||||
if (rtp_observer_) {
|
||||
rtp_observer_->IncomingSSRCChanged(channel_id_, SSRC);
|
||||
rtp_observer_->IncomingSSRCChanged(channel_id_, ssrc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1934,8 +1939,11 @@ void ViEChannel::OnIncomingCSRCChanged(const int32_t id,
|
||||
}
|
||||
}
|
||||
|
||||
void ViEChannel::ResetStatistics() {
|
||||
vie_receiver_.GetReceiveStatistics()->ResetStatistics();
|
||||
void ViEChannel::ResetStatistics(uint32_t ssrc) {
|
||||
StreamStatistician* statistician =
|
||||
vie_receiver_.GetReceiveStatistics()->GetStatistician(ssrc);
|
||||
if (statistician)
|
||||
statistician->ResetStatistics();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -212,11 +212,11 @@ class ViEChannel
|
||||
const uint8_t channels,
|
||||
const uint32_t rate);
|
||||
virtual void OnIncomingSSRCChanged(const int32_t id,
|
||||
const uint32_t SSRC);
|
||||
const uint32_t ssrc);
|
||||
virtual void OnIncomingCSRCChanged(const int32_t id,
|
||||
const uint32_t CSRC,
|
||||
const bool added);
|
||||
virtual void ResetStatistics();
|
||||
virtual void ResetStatistics(uint32_t);
|
||||
|
||||
int32_t SetLocalReceiver(const uint16_t rtp_port,
|
||||
const uint16_t rtcp_port,
|
||||
|
@ -404,8 +404,10 @@ bool ViEReceiver::IsPacketRetransmitted(const RTPHeader& header) const {
|
||||
rtp_receiver_->RTXStatus(&rtx_enabled, &rtx_ssrc, &rtx_payload_type);
|
||||
if (!rtx_enabled) {
|
||||
// Check if this is a retransmission.
|
||||
ReceiveStatistics::RtpReceiveStatistics stats;
|
||||
if (rtp_receive_statistics_->Statistics(&stats, false)) {
|
||||
StreamStatistician::Statistics stats;
|
||||
StreamStatistician* statistician =
|
||||
rtp_receive_statistics_->GetStatistician(header.ssrc);
|
||||
if (statistician && statistician->GetStatistics(&stats, false)) {
|
||||
uint16_t min_rtt = 0;
|
||||
rtp_rtcp_->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
|
||||
return rtp_receiver_->RetransmitOfOldPacket(header, stats.jitter,
|
||||
|
@ -360,20 +360,15 @@ Channel::OnPlayTelephoneEvent(int32_t id,
|
||||
}
|
||||
|
||||
void
|
||||
Channel::OnIncomingSSRCChanged(int32_t id,
|
||||
uint32_t SSRC)
|
||||
Channel::OnIncomingSSRCChanged(int32_t id, uint32_t ssrc)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
|
||||
"Channel::OnIncomingSSRCChanged(id=%d, SSRC=%d)",
|
||||
id, SSRC);
|
||||
id, ssrc);
|
||||
|
||||
int32_t channel = VoEChannelId(id);
|
||||
assert(channel == _channelId);
|
||||
|
||||
// Reset RTP-module counters since a new incoming RTP stream is detected
|
||||
rtp_receive_statistics_->ResetDataCounters();
|
||||
rtp_receive_statistics_->ResetStatistics();
|
||||
|
||||
if (_rtpObserver)
|
||||
{
|
||||
CriticalSectionScoped cs(&_callbackCritSect);
|
||||
@ -381,7 +376,7 @@ Channel::OnIncomingSSRCChanged(int32_t id,
|
||||
if (_rtpObserverPtr)
|
||||
{
|
||||
// Send new SSRC to registered observer using callback
|
||||
_rtpObserverPtr->OnIncomingSSRCChanged(channel, SSRC);
|
||||
_rtpObserverPtr->OnIncomingSSRCChanged(channel, ssrc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -408,8 +403,12 @@ void Channel::OnIncomingCSRCChanged(int32_t id,
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::ResetStatistics() {
|
||||
rtp_receive_statistics_->ResetStatistics();
|
||||
void Channel::ResetStatistics(uint32_t ssrc) {
|
||||
StreamStatistician* statistician =
|
||||
rtp_receive_statistics_->GetStatistician(ssrc);
|
||||
if (statistician) {
|
||||
statistician->ResetStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2231,8 +2230,10 @@ bool Channel::IsPacketRetransmitted(const RTPHeader& header) const {
|
||||
rtp_receiver_->RTXStatus(&rtx_enabled, &rtx_ssrc, &rtx_payload_type);
|
||||
if (!rtx_enabled) {
|
||||
// Check if this is a retransmission.
|
||||
ReceiveStatistics::RtpReceiveStatistics stats;
|
||||
if (rtp_receive_statistics_->Statistics(&stats, false)) {
|
||||
StreamStatistician::Statistics stats;
|
||||
StreamStatistician* statistician =
|
||||
rtp_receive_statistics_->GetStatistician(header.ssrc);
|
||||
if (statistician && statistician->GetStatistics(&stats, false)) {
|
||||
uint16_t min_rtt = 0;
|
||||
_rtpRtcpModule->RTT(rtp_receiver_->SSRC(), NULL, NULL, &min_rtt, NULL);
|
||||
return rtp_receiver_->RetransmitOfOldPacket(header, stats.jitter,
|
||||
@ -3921,8 +3922,10 @@ Channel::GetRTPStatistics(
|
||||
{
|
||||
// The jitter statistics is updated for each received RTP packet and is
|
||||
// based on received packets.
|
||||
ReceiveStatistics::RtpReceiveStatistics statistics;
|
||||
if (!rtp_receive_statistics_->Statistics(
|
||||
StreamStatistician::Statistics statistics;
|
||||
StreamStatistician* statistician =
|
||||
rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
|
||||
if (!statistician || !statistician->GetStatistics(
|
||||
&statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) {
|
||||
_engineStatisticsPtr->SetLastError(
|
||||
VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
|
||||
@ -4016,8 +4019,10 @@ Channel::GetRTPStatistics(CallStatistics& stats)
|
||||
|
||||
// The jitter statistics is updated for each received RTP packet and is
|
||||
// based on received packets.
|
||||
ReceiveStatistics::RtpReceiveStatistics statistics;
|
||||
if (!rtp_receive_statistics_->Statistics(
|
||||
StreamStatistician::Statistics statistics;
|
||||
StreamStatistician* statistician =
|
||||
rtp_receive_statistics_->GetStatistician(rtp_receiver_->SSRC());
|
||||
if (!statistician || !statistician->GetStatistics(
|
||||
&statistics, _rtpRtcpModule->RTCP() == kRtcpOff)) {
|
||||
_engineStatisticsPtr->SetLastError(
|
||||
VE_CANNOT_RETRIEVE_RTP_STAT, kTraceWarning,
|
||||
@ -4087,7 +4092,9 @@ Channel::GetRTPStatistics(CallStatistics& stats)
|
||||
uint32_t bytesReceived(0);
|
||||
uint32_t packetsReceived(0);
|
||||
|
||||
rtp_receive_statistics_->GetDataCounters(&bytesReceived, &packetsReceived);
|
||||
if (statistician) {
|
||||
statistician->GetDataCounters(&bytesReceived, &packetsReceived);
|
||||
}
|
||||
|
||||
if (_rtpRtcpModule->DataCountersRTP(&bytesSent,
|
||||
&packetsSent) != 0)
|
||||
|
@ -329,12 +329,12 @@ public:
|
||||
RTPAliveType alive);
|
||||
|
||||
void OnIncomingSSRCChanged(int32_t id,
|
||||
uint32_t SSRC);
|
||||
uint32_t ssrc);
|
||||
|
||||
void OnIncomingCSRCChanged(int32_t id,
|
||||
uint32_t CSRC, bool added);
|
||||
|
||||
void ResetStatistics();
|
||||
void ResetStatistics(uint32_t ssrc);
|
||||
|
||||
public:
|
||||
// From RtcpFeedback in the RTP/RTCP module
|
||||
|
Loading…
Reference in New Issue
Block a user